Made my own equally wrong QR factorization
Some checks failed
Merge-Checker / build_and_test (pull_request) Failing after 17s

This commit is contained in:
2025-06-02 20:39:44 -04:00
parent 64820553c7
commit c0e07eac56
2 changed files with 52 additions and 47 deletions

View File

@@ -451,16 +451,6 @@ float Matrix<rows, columns>::EuclideanNorm() const {
return sqrt(sum); return sqrt(sum);
} }
template <uint8_t rows, uint8_t columns>
float Matrix<rows, columns>::L2Norm() const {
float sum{0};
Matrix<rows, 1> columnMatrix{};
for (uint8_t column = 0; column < columns; column++) {
this.GetColumn(column, columnMatrix);
sum += columnMatrix.EuclideanNorm();
}
return sqrt(sum);
}
template <uint8_t rows, uint8_t columns> template <uint8_t rows, uint8_t columns>
template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset, template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset,
@@ -485,20 +475,37 @@ Matrix<sub_rows, sub_columns> Matrix<rows, columns>::SubMatrix() const {
} }
template <uint8_t rows, uint8_t columns> template <uint8_t rows, uint8_t columns>
template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset, template <uint8_t sub_rows, uint8_t sub_columns>
uint8_t column_offset>
void Matrix<rows, columns>::SetSubMatrix( void Matrix<rows, columns>::SetSubMatrix(
uint8_t rowOffset, uint8_t columnOffset,
const Matrix<sub_rows, sub_columns> &sub_matrix) { const Matrix<sub_rows, sub_columns> &sub_matrix) {
static_assert(sub_rows + row_offset <= rows, int16_t adjustedSubRows = sub_rows;
"The submatrix you're trying to set is out of bounds (rows)"); int16_t adjustedSubColumns = sub_columns;
static_assert( int16_t adjustedRowOffset = rowOffset;
sub_columns + column_offset <= columns, int16_t adjustedColumnOffset = columnOffset;
"The submatrix you're trying to set is out of bounds (columns)");
for (uint8_t row_idx{0}; row_idx < sub_rows; row_idx++) { // a bunch of safety checks to make sure we don't overflow the matrix
for (uint8_t column_idx{0}; column_idx < sub_columns; column_idx++) { if (sub_rows > rows) {
this->matrix[(row_idx + row_offset) * columns + column_idx + adjustedSubRows = rows;
column_offset] = sub_matrix.Get(row_idx, column_idx); }
if (sub_columns > columns) {
adjustedSubColumns = columns;
}
if (adjustedSubRows + adjustedRowOffset >= rows) {
adjustedRowOffset =
std::max(0, static_cast<int16_t>(rows) - adjustedSubRows);
}
if (adjustedSubColumns + adjustedColumnOffset >= columns) {
adjustedColumnOffset =
std::max(0, static_cast<int16_t>(columns) - adjustedSubColumns);
}
for (uint8_t row_idx{0}; row_idx < adjustedSubRows; row_idx++) {
for (uint8_t column_idx{0}; column_idx < adjustedSubColumns; column_idx++) {
this->matrix[(row_idx + adjustedRowOffset) * columns + column_idx +
adjustedColumnOffset] = sub_matrix.Get(row_idx, column_idx);
} }
} }
} }
@@ -510,33 +517,32 @@ void Matrix<rows, columns>::QRDecomposition(Matrix<rows, columns> &Q,
Matrix<columns, columns> &R) const { Matrix<columns, columns> &R) const {
static_assert(columns <= rows, "QR decomposition requires columns <= rows"); static_assert(columns <= rows, "QR decomposition requires columns <= rows");
Matrix<rows, 1> a_col, u, q_col, proj;
Q.Fill(0); Q.Fill(0);
R.Fill(0); R.Fill(0);
Matrix<rows, 1> a_col, e, u, Q_column_k{};
Matrix<1, rows> a_T, e_T{};
for (uint8_t k = 0; k < columns; ++k) { for (uint8_t column = 0; column < columns; column++) {
this->GetColumn(k, a_col); this->GetColumn(column, a_col);
u = a_col; u = a_col;
// -----------------------
for (uint8_t j = 0; j < k; ++j) { // ----- CALCULATE Q -----
Q.GetColumn(j, q_col); // -----------------------
float r_jk = Matrix<rows, 1>::DotProduct( for (uint8_t k = 0; k <= column; k++) {
q_col, u); // FIXED: use u instead of a_col Q.GetColumn(k, Q_column_k);
R[j][k] = r_jk; Matrix<1, rows> Q_column_k_T = Q_column_k.Transpose();
u = u - Q_column_k * (Q_column_k_T * a_col);
proj = q_col * r_jk;
u = u - proj;
} }
u = u / u.EuclideanNorm();
Q.SetSubMatrix(0, column, u);
float norm = sqrt(Matrix<rows, 1>::DotProduct(u, u)); // -----------------------
if (norm < 1e-12f) // ----- CALCULATE R -----
norm = 1e-12f; // for stability // -----------------------
for (uint8_t k = 0; k <= column; k++) {
for (uint8_t i = 0; i < rows; ++i) { Q.GetColumn(k, e);
Q[i][k] = u[i][0] / norm; R[k][column] = (a_col.Transpose() * e).Get(0, 0);
} }
R[k][k] = norm;
} }
} }

View File

@@ -129,13 +129,12 @@ public:
Matrix<columns, rows> Transpose() const; Matrix<columns, rows> Transpose() const;
/** /**
* @brief reduce the matrix so the sum of its elements equal 1 * @brief Returns the euclidean magnitude of the matrix. Also known as the L2
* norm
* @param result a buffer to store the result into * @param result a buffer to store the result into
*/ */
float EuclideanNorm() const; float EuclideanNorm() const;
float L2Norm() const;
/** /**
* @brief Get a row from the matrix * @brief Get a row from the matrix
* @param row_index the row index to get * @param row_index the row index to get
@@ -209,9 +208,9 @@ public:
uint8_t column_offset> uint8_t column_offset>
Matrix<sub_rows, sub_columns> SubMatrix() const; Matrix<sub_rows, sub_columns> SubMatrix() const;
template <uint8_t sub_rows, uint8_t sub_columns, uint8_t row_offset, template <uint8_t sub_rows, uint8_t sub_columns>
uint8_t column_offset> void SetSubMatrix(uint8_t rowOffset, uint8_t columnOffset,
void SetSubMatrix(const Matrix<sub_rows, sub_columns> &sub_matrix); const Matrix<sub_rows, sub_columns> &sub_matrix);
/** /**
* @brief take the dot product of the two vectors * @brief take the dot product of the two vectors