This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
reprapfirmware-dc42/Matrix.h
David Crocker 6e0f113927 Version 1.04d
Tidied up delta auto-calibration code. We now use least squares for 3,
4, 6 or 7-factor calibration.
When doing delta calibration, if a probe offset was used to adjust the
head position when probing, use the actual head coordinates instead the
probed coordinates.
Bug fix: newline was missing at end of SD card file list sent to USB
when in Marlin emulation mode.
Bug fix: Heater average PWM report (M573) sometimes gave inaccurate
values when the S parameter was used.
2015-04-08 18:03:59 +01:00

132 lines
3 KiB
C++

/*
* Matrix.h
*
* Created on: 31 Mar 2015
* Author: David
*/
#ifndef MATRIX_H_
#define MATRIX_H_
#include <cstddef> // for size_t
// Base class for matrices, allows us to write functions that work with any size matrix
template<class T> class MathMatrix
{
public:
virtual size_t rows() const = 0;
virtual size_t cols() const = 0;
virtual T& operator() (size_t r, size_t c) = 0;
virtual const T& operator() (size_t r, size_t c) const = 0;
virtual ~MathMatrix() { } // to keep Eclipse code analysis happy
};
// Fixed size matrix class
template<class T, size_t ROWS, size_t COLS> class FixedMatrix : public MathMatrix<T>
{
public:
size_t rows() const override { return ROWS; }
size_t cols() const override { return COLS; }
// Indexing operator, non-const version
T& operator() (size_t r, size_t c) override
//pre(r < ROWS; c < COLS)
{
return data[r * COLS + c];
}
// Indexing operator, const version
const T& operator() (size_t r, size_t c) const override
//pre(r < ROWS; c < COLS)
{
return data[r * COLS + c];
}
void SwapRows(size_t i, size_t j, size_t numCols = COLS)
//pre(i < ROWS; j < ROWS)
;
void GaussJordan(T *solution, size_t numRows)
//pre(numRows <= ROWS; numRows + 1 <= COLS)
;
// Return a pointer to a specified row, non-const version
T* GetRow(size_t r)
//pre(r < ROWS)
{
return data + (r * COLS);
}
// Return a pointer to a specified row, const version
const T* GetRow(size_t r) const
//pre(r < ROWS)
{
return data + (r * COLS);
}
private:
T data[ROWS * COLS];
};
// Swap 2 rows of a matrix
template<class T, size_t ROWS, size_t COLS> inline void FixedMatrix<T, ROWS, COLS>::SwapRows(size_t i, size_t j, size_t numCols)
{
if (i != j)
{
for (size_t k = i; k < numCols; ++k)
{
T temp = (*this)(i, k);
(*this)(i, k) = (*this)(j, k);
(*this)(j, k) = temp;
}
}
}
// Perform Gauss-Jordan elimination on a N x (N+1) matrix.
// Returns a pointer to the solution vector.
template<class T, size_t ROWS, size_t COLS> void FixedMatrix<T, ROWS, COLS>::GaussJordan(T *solution, size_t numRows)
{
for (size_t i = 0; i < numRows; ++i)
{
// Swap the rows around for stable Gauss-Jordan elimination
float vmax = fabs((*this)(i, i));
for (size_t j = i + 1; j < numRows; ++j)
{
const float rmax = fabs((*this)(j, i));
if (rmax > vmax)
{
SwapRows(i, j);
vmax = rmax;
}
}
// Use row i to eliminate the ith element from previous and subsequent rows
float v = (*this)(i, i);
for (size_t j = 0; j < i; ++j)
{
float factor = (*this)(j, i)/v;
(*this)(j, i) = 0.0;
for (size_t k = i + 1; k <= numRows; ++k)
{
(*this)(j, k) -= (*this)(i, k) * factor;
}
}
for (size_t j = i + 1; j < numRows; ++j)
{
float factor = (*this)(j, i)/v;
(*this)(j, i) = 0.0;
for (size_t k = i + 1; k <= numRows; ++k)
{
(*this)(j, k) -= (*this)(i, k) * factor;
}
}
}
for (size_t i = 0; i < numRows; ++i)
{
solution[i] = (*this)(i, numRows) / (*this)(i, i);
}
}
#endif /* MATRIX_H_ */