50 template <
class T=
double>
51 class Matrix :
protected std::vector<T> {
55 Matrix(
size_t rows=0,
size_t columns = 0) : std::vector<T>(rows*columns), rows(rows), columns(columns) {
58 Matrix(
const Matrix &m) : std::vector<T>(m), rows(m.rows), columns(m.columns) {
64 void setSize(
size_t rows,
size_t columns){
66 this->columns = columns;
67 std::vector<T>::resize(rows * columns);
71 size_t getSize()
const {
return std::vector<T>::size(); }
75 size_t getRows()
const {
81 size_t getColumns()
const {
86 T & operator()(
const size_t & i){
91 const T & operator()(
const size_t & i)
const {
96 T & operator()(
const size_t & i,
const size_t & j){
98 return (*
this)[i*columns + j];
102 const T & operator()(
const size_t & i,
const size_t & j)
const {
104 return (*
this)[i*columns + j];
111 for (
typename std::vector<T>::iterator it=this->begin(); it != this->end(); ++it){
117 typename std::vector<T>::iterator begin() {
return std::vector<T>::begin(); }
120 typename std::vector<T>::iterator end() {
return std::vector<T>::end(); }
123 typename std::vector<T>::const_iterator begin()
const {
return std::vector<T>::begin(); }
126 typename std::vector<T>::const_iterator end()
const {
return std::vector<T>::end(); }
130 Matrix<T> & operator=(
const std::vector<T2> &v){
132 std::vector<T>::operator=(v);
136 operator std::vector<T> &()
const {
140 void transpose(Matrix<T> & dst);
142 template <
class T2,
class T3>
143 void multiply(
const Matrix<T2> & src2, Matrix<T3> & dst);
179 const bool SELF = (&dst ==
this);
181 const Matrix<T> & s = SELF ? tmp : *
this;
185 dst.setSize(getColumns(), getRows());
186 for (
size_t i = 0; i < getRows(); ++i) {
187 for (
size_t j = 0; j < getColumns(); ++j) {
197 template <
class T2,
class T3>
198 void Matrix<T>::multiply(
const Matrix<T2> & src, Matrix<T3> & dst){
200 if (getColumns() != src.getRows()){
201 std::cerr <<
"a=" << *
this << std::endl;
202 std::cerr << getColumns() << std::endl;
203 std::cerr <<
"b=" << src << std::endl;
204 std::cerr << getRows() << std::endl;
205 throw std::runtime_error(
"multiply: w1 != h2");
208 dst.setSize(getRows(), src.getColumns());
216 for (
size_t i = 0; i < getRows(); ++i) {
217 for (
size_t j = 0; j < src.getColumns(); ++j) {
220 for (
size_t k = 0; k < src.getRows(); ++k) {
221 x += (*this)(i,k)*src(k,j);
238 std::cerr << getRows() << std::endl;
239 throw std::runtime_error(
"inverse: not implemented for n>3");
249 if ((getRows() != 3) || (getColumns() != 3))
250 throw std::runtime_error(
"inverse: matrix not 3x3");
260 const T & a = (*this)(0,0);
261 const T & b = (*this)(1,0);
262 const T & c = (*this)(2,0);
264 const T & d = (*this)(0,1);
265 const T & e = (*this)(1,1);
266 const T & f = (*this)(2,1);
268 const T & g = (*this)(0,2);
269 const T & h = (*this)(1,2);
270 const T & i = (*this)(2,2);
273 const double det = a*(e*i-f*h) - d*(b*i-c*h) + g*(b*f-c*e);
275 throw std::runtime_error(
"inverse: zero determinant");
278 const double detInv = 1.0/det;
281 const T & A = (*this)(0,0);
282 const T & B = (*this)(0,1);
283 const T & C = (*this)(0,2);
285 const T & D = (*this)(1,0);
286 const T & E = (*this)(1,1);
287 const T & F = (*this)(1,2);
289 const T & G = (*this)(2,0);
290 const T & H = (*this)(2,1);
291 const T & I = (*this)(2,2);
297 dst(0,0) = detInv * +(E*I - F*H);
298 dst(0,1) = detInv * -(B*I - C*H);
299 dst(0,2) = detInv * +(B*F - C*E);
301 dst(1,0) = detInv * -(D*I - F*G);
302 dst(1,1) = detInv * +(A*I - C*G);
303 dst(1,2) = detInv * -(A*F - C*D);
305 dst(2,0) = detInv * +(D*H - E*G);
306 dst(2,1) = detInv * -(A*H - B*G);
307 dst(2,2) = detInv * +(A*E - B*D);
313 template <
class T=
double>
318 Vector(
size_t size=0,
bool vertical=
true) :
Matrix<T>(vertical?size:1, vertical?1:size), vertical(vertical) {
334 Vector<T> & operator=(
const std::vector<T2> &v){
338 std::vector<T>::operator=(v);
344 if (src.size() != std::vector<T>::size()){
345 std::cerr << (*this) << std::vector<T>::size() << std::endl;
346 std::cerr << src << src.size() << std::endl;
347 throw std::runtime_error(
"Vector::innerProduct: different sizes");
351 typename std::vector<T>::const_iterator it = std::vector<T>::begin();
352 typename std::vector<T2>::const_iterator it2 = src.begin();
353 while (it != std::vector<T>::end()){
354 result += *it * *it2;
383 double sumX0, sumX1, sumX2, sumX3, sumX4;
384 sumX0 = sumX1 = sumX2 = sumX3 = sumX4 = 0.0;
389 double & sumY = XTy(0);
390 double & sumYX = XTy(1);
391 double & sumYXX = XTy(2);
392 sumY = sumYX = sumYXX = 0.0;
397 typename T::const_iterator its = src.begin();
398 typename T::const_iterator itw = weight.begin();
400 while (its != src.end()){
420 XTX(0,0) =
static_cast<double>(sumX0);
421 XTX(0,1) = XTX(1,0) = sumX1;
422 XTX(0,2) = XTX(1,1) = XTX(2,0) = sumX2;
423 XTX(1,2) = XTX(2,1) = sumX3;
429 XTXinv.multiply( XTy, coeffVector);
430 coeff = (
const std::vector<double> &)coeffVector;
438 std::ostream & operator<<(std::ostream &ostr,
const Matrix<T> & m){
440 for (
size_t i = 0; i < m.getRows(); ++i) {
441 for (
size_t j = 0; j < m.getColumns(); ++j) {
442 ostr <<
' ' << m(i,j) ;
447 ostr <<
" (" << m.getSize() <<
" elements)";
void inverse(Matrix< T2 > &dst)
Computes the inverse of a matrix.
Definition: Math.h:231
void fill(const T &x)
Resets the values, leaving geomatry.
Definition: Math.h:110
void inverse3(Matrix< T2 > &dst)
Computes the inverse of a 3-by-3 matrix.
Definition: Math.h:247
Definition: DataSelector.cpp:1277
void polynomialFit2nd(const T &src, const T &weight, std::vector< double > &coeff)
Fits a 2nd order polynomial to a curve.
Definition: Math.h:374