2 * psychlops_m_matrix.cpp
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2006/03/30 by Kenchi HOSOKAWA
6 * (C) 2005 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
18 #include "../ApplicationInterfaces/psychlops_code.h"
19 #include "../devices/psychlops_io_file.h"
20 #include "../data/psychlops_d_misc.h"
21 #include "psychlops_m_interval.h"
22 #include "psychlops_m_function.h"
23 #include "psychlops_m_matrix.h"
29 struct Matrix::elem_ptr {
32 double *origin, *begin, *row, *col, *rowend, *colend;
33 int rowstep, colwidth;
34 elem_ptr(const Matrix &mtx);
36 Matrix::elem_ptr::elem_ptr(const Matrix &mtx) {
37 mtx.get_element_ptr( origin, begin, rowstep);
38 rowend = begin + (rowstep*mtx.rows_);
43 Matrix::Matrix(const Matrix &mtx) : rows_(0), cols_(0), has_instance_(false), element_(NULL), op_(INSTANCE) {
45 if(typeid(mtx) == typeid(MatrixExpression)) {
46 tmp = dynamic_cast<const MatrixExpression &>(mtx);
47 set_roughly(mtx.rows_, mtx.cols_);
50 set_roughly(mtx.rows_, mtx.cols_);
54 Matrix::Matrix() : rows_(0), cols_(0), has_instance_(false), element_(NULL), op_(INSTANCE) {
56 Matrix::Matrix(int rows, int cols) : rows_(0), cols_(0), has_instance_(false), element_(NULL), op_(INSTANCE) {
59 Matrix & Matrix::set(int rows, int cols) {
61 set_roughly(rows, cols);
66 Matrix & Matrix::from(double *array)
69 memcpy(element_, array, rows_*cols_*sizeof(double));
73 Matrix & Matrix::from(double *array, int rows, int cols)
75 if(!has_instance_ || rows*cols != rows_*cols_) {
\r
77 set_roughly(rows, cols);
79 memcpy(element_, array, rows*cols*sizeof(double));
82 Matrix & Matrix::set(Range row, double interval_rows, Range col, double interval_cols) {
83 int rows = (int)( (row.end-row.begin) / interval_rows );
84 int cols = (int)( (col.end-col.begin) / interval_cols );
85 double rown = row.begin - interval_rows, coln = col.begin;
87 set_roughly(rows, cols);
88 for(int i=1; i<=rows; i++) {
89 rown += interval_rows;
90 coln = col.begin - interval_cols;
91 for(int j=1; j<=cols; j++) {
92 coln += interval_cols;
93 operator ()(i,j) = rown + coln;
99 Matrix & Matrix::set_roughly(int rows, int cols) {
100 if(rows<=0) throw Exception(typeid(*this), "FORMAT ERROR", "Number of rows must be positive integer.");
101 if(cols<=0) throw Exception(typeid(*this), "FORMAT ERROR", "Number of columns must be positive integer.");
105 elementSize_ = rows_ * cols_;
106 element_ = new double[elementSize_];
107 has_instance_ = true;
114 void Matrix::destroy() {
117 void Matrix::release() {
121 rows_ = cols_ = elementSize_ = 0;
122 has_instance_ = false;
125 void Matrix::swap(Matrix &rhs) {
130 if(has_instance_ && rhs.has_instance_) {
133 elementSize = elementSize_;
138 elementSize_ = rhs.elementSize_;
139 element_ = rhs.element_;
143 rhs.elementSize_ = elementSize;
144 rhs.element_ = element;
145 } else if(has_instance() && rhs.has_instance()) {
146 mtx.set(rows_, cols_);
151 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
155 void Matrix::track(int n) const {
156 for(int i=0; i<n; i++) std::cout << " ";
157 std::cout << "Matrix " << rows_ << "*" << cols_ << ":" << this << std::endl;
159 bool Matrix::has_instance() const {
160 return has_instance_;
162 Matrix* Matrix::instance_ptr() const {
163 if(has_instance_) return const_cast<Matrix *>(this);
166 void Matrix::get_element_ptr(double *&ptr_origin, double *&ptr_start, int &row_step) const {
168 ptr_origin = element_;
169 ptr_start = element_;
174 else throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
176 void Matrix::track_and_calculate(Matrix& target, bool add_posi, bool mul_posi) {
177 throw Exception(typeid(*this), "SYSTEM EXPRESSION ERROR", "Please notify this error to developers");
179 bool Matrix::track_self(const Matrix* self, int &cnt_in_add, int &cnt_in_mul, bool in_mul) {
181 if(in_mul) cnt_in_add++;
189 Matrix& Matrix::operator =(double rhs) {
190 if(has_instance_) substitute(rhs);
191 else throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
194 Matrix& Matrix::operator =(const Matrix &rhs) {
195 if(!has_instance_) set_roughly(rhs.rows_, rhs.cols_);
196 if(check_size_equal(rhs)) {
198 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix size did not matched");
201 Matrix& Matrix::operator =(const MatrixExpression &rhs) {
202 if(!has_instance_) set_roughly(rhs.rows_, rhs.cols_);
203 if(check_size_equal(rhs)) {
204 if(rhs.has_instance()) substitute(rhs);
205 else const_cast<MatrixExpression &>(rhs).evaluate(*this);
206 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix size did not matched");
209 void Matrix::substitute(double rhs) {
211 for(t.row=t.begin; t.row<t.rowend; t.row+=t.rowstep) {
212 t.colend=t.row+this->cols_;
213 for(t.col=t.row; t.col<t.colend; t.col++)
217 void Matrix::substitute(const Matrix &rhs) {
218 elem_ptr t(*this), r(rhs);
219 for(t.row=t.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,r.row+=r.rowstep) {
220 t.colend=t.row+this->cols_;
221 for(t.col=t.row,r.col=r.row; t.col<t.colend; t.col++,r.col++)
226 double& Matrix::xy(int x, int y) const {
227 return element_[y*cols_+x];
229 double& Matrix::operator ()(int row, int col) const {
230 if(element_==NULL) throw Exception(typeid(*this), "OPERAND ERROR", "This operated matrix has no instance");
231 return element_[(row-1)*cols_+(col-1)];
232 // elem_ptr elm(*this);
233 // if(elm.begin==NULL) throw Exception(typeid(*this), "OPERAND ERROR", "This operated matrix has no instance");
234 // return *(elm.begin + ((row-1)*elm.rowstep) + (col-1));
237 bool Matrix::check_size_equal(const Matrix& rhs) const {
238 if((rows_==rhs.rows_) && (cols_==rhs.cols_) ) return true;
241 bool Matrix::check_size_mul(const Matrix& rhs) const {
242 if(cols_==rhs.rows_) return true;
247 // add or sub rhs to *this
248 void Matrix::add(double rhs, bool add_posi) {
251 for(t.row=t.begin; t.row<t.rowend; t.row+=t.rowstep) {
252 t.colend=t.row+this->cols_;
253 for(t.col=t.row; t.col<t.colend; t.col++)
257 for(t.row=t.begin; t.row<t.rowend; t.row+=t.rowstep) {
258 t.colend=t.row+this->cols_;
259 for(t.col=t.row; t.col<t.colend; t.col++)
264 void Matrix::add(const Matrix &rhs, bool add_posi) {
265 elem_ptr t(*this), r(rhs);
267 for(t.row=t.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,r.row+=r.rowstep) {
268 t.colend=t.row+this->cols_;
269 for(t.col=t.row,r.col=r.row; t.col<t.colend; t.col++,r.col++)
273 for(t.row=t.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,r.row+=r.rowstep) {
274 t.colend=t.row+this->cols_;
275 for(t.col=t.row,r.col=r.row; t.col<t.colend; t.col++,r.col++)
280 // add lhs multified by rhs to *this
281 void Matrix::mul(const Matrix &lhs, double rhs, bool add_posi) {
282 elem_ptr t(*this), l(lhs);
284 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
285 t.colend=t.row+this->cols_;
286 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
287 *(t.col)+=*(l.col)*rhs;
290 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
291 t.colend=t.row+this->cols_;
292 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
293 *(t.col)-=*(l.col)*rhs;
297 void Matrix::mul(const Matrix &lhs, const Matrix &rhs, bool add_posi) {
298 elem_ptr t(*this), l(lhs), r(rhs);
300 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
301 t.colend=t.row+this->cols_;
302 l.colend=l.row+lhs.cols_;
303 for(t.col=t.row,r.col=r.begin; t.col<t.colend; t.col++,r.col++) {
304 for(l.col=l.row,r.row=r.col; l.col<l.colend; l.col++,r.row+=r.rowstep) {
305 (*t.col)+=(*l.col)*(*r.row);
310 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
311 t.colend=t.row+this->cols_;
312 l.colend=l.row+lhs.cols_;
313 for(t.col=t.row,r.col=r.begin; t.col<t.colend; t.col++,r.col++) {
314 for(l.col=l.row,r.row=r.col; l.col<l.colend; l.col++,r.row+=r.rowstep) {
315 (*t.col)-=(*l.col)*(*r.row);
321 void Matrix::mul_mask(const Matrix &lhs, const Matrix &rhs, bool add_posi) {
322 elem_ptr t(*this), l(lhs), r(rhs);
324 for(t.row=t.begin,l.row=l.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep,r.row+=r.rowstep) {
325 t.colend=t.row+this->cols_;
326 for(t.col=t.row,l.col=l.row,r.col=r.row; t.col<t.colend; t.col++,l.col++,r.col++)
327 *(t.col)+=(*(l.col))*(*(r.col));
330 for(t.row=t.begin,l.row=l.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep,r.row+=r.rowstep) {
331 t.colend=t.row+this->cols_;
332 for(t.col=t.row,l.col=l.row,r.col=r.row; t.col<t.colend; t.col++,l.col++,r.col++)
333 *(t.col)-=(*(l.col))*(*(r.col));
337 // add lhs multified by rhs to *this
338 void Matrix::pow(const Matrix &lhs, double rhs, bool add_posi) {
339 int n = (int)floor(rhs);
340 if(n != rhs) throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix must powered by int.");
341 if(n < 0) throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix must powered by int.");
344 for(int i=0; i<n; i++) tmp = tmp * lhs;
346 void Matrix::pow_mask(const Matrix &lhs, double rhs, bool add_posi) {
347 elem_ptr t(*this), l(lhs);
349 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
350 t.colend=t.row+this->cols_;
351 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
352 *(t.col)+=::pow(*(l.col), rhs);
355 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
356 t.colend=t.row+this->cols_;
357 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
358 *(t.col)-=::pow(*(l.col), rhs);
362 // add lhs divided by rhs to *this
363 void Matrix::div(const Matrix &lhs, double rhs, bool add_posi) {
364 elem_ptr t(*this), l(lhs);
366 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
367 t.colend=t.row+this->cols_;
368 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
369 *(t.col)+=*(l.col)/rhs;
372 for(t.row=t.begin,l.row=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.row+=l.rowstep) {
373 t.colend=t.row+this->cols_;
374 for(t.col=t.row,l.col=l.row; t.col<t.colend; t.col++,l.col++)
375 *(t.col)-=*(l.col)/rhs;
380 Matrix & Matrix::slide(int drow, int dcol) {
381 Matrix after(rows_, cols_);
382 elem_ptr t(*this), a(after);
383 int d_row = (drow>0) ? drow % rows_ : rows_ - (abs(drow) % rows_),
384 d_col = (dcol>0) ? dcol % cols_ : cols_ - (abs(dcol) % cols_);
385 size_t size_double = sizeof(double);
386 for(int i=0; i<rows_; i++) {
387 memcpy(reinterpret_cast<void *>( a.begin+(a.rowstep*((d_row+i)%rows_))+d_col ), reinterpret_cast<void *>( t.begin+t.rowstep*i ), size_double*(cols_-d_col));
388 memcpy(reinterpret_cast<void *>( a.begin+(a.rowstep*((d_row+i)%rows_)) ), reinterpret_cast<void *>( t.begin+t.rowstep*i+(cols_-d_col) ), size_double*(d_col));
393 Matrix & Matrix::transpose() {
394 Matrix after(cols_, rows_);
395 elem_ptr t(*this), l(after);
396 for(t.row=t.begin,l.col=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.col++) {
397 t.colend=t.row+this->cols_;
398 for(t.col=t.row,l.row=l.col; t.col<t.colend; t.col++,l.row+=l.rowstep)
404 Matrix & Matrix::rot90(int times) {
406 int time = times>=0 ? times%4 : 4-(-times)%4;
414 after.set(cols_, rows_);
417 after.set(rows_, cols_);
420 elem_ptr t(*this), l(after);
426 for(t.row=t.begin,l.col=l.begin; t.row<t.rowend; t.row+=t.rowstep,l.col++) {
427 t.colend=t.row+this->cols_;
428 for(t.col=t.row,l.row=l.col+l.rowstep*(after.rows_-1); t.col<t.colend; t.col++,l.row-=l.rowstep)
433 for(t.row=t.begin,l.col=l.begin+(after.cols_-1); t.row<t.rowend; t.row+=t.rowstep,l.col--) {
434 t.colend=t.row+this->cols_;
435 for(t.col=t.row,l.row=l.col; t.col<t.colend; t.col++,l.row+=l.rowstep)
440 for(t.row=t.begin,l.row=l.rowend-l.rowstep; t.row<t.rowend; t.row+=t.rowstep,l.row-=l.rowstep) {
441 t.colend=t.row+this->cols_;
442 for(t.col=t.row,l.col=l.row+(after.cols_-1); t.col<t.colend; t.col++,l.col--)
447 throw Exception(typeid(*this), "ARGUMENT ERROR", "Notify this error to developers.");
452 Matrix & Matrix::reshape(int rows, int cols) {
453 if(rows*cols!=rows*cols) throw Exception(typeid(*this), "EXPRESSION ERROR", "Rows*Cols must be equal before and after the reshape.");
458 Matrix & Matrix::catRow(Matrix &rhs) {
459 Matrix tmp(rows_+rhs.rows_, cols_);
461 if(has_instance_ && rhs.has_instance_ && (cols_==rhs.cols_) ) {
462 tmp(1<=rng1<=rows_, 1<=rng2<=cols_) = *this;
463 tmp(rows_+1<=rng1<=tmp.rows_, 1<=rng2<=cols_) = rhs;
466 throw Exception(typeid(*this), "EXPRESSION ERROR", "Both cols must be same when cat Matrix in row.");
472 double Matrix::max() {
473 double tmpmax=operator ()(1,1), tmp;
474 for(int i=1; i<=rows_; i++) {
475 for(int j=1; j<=cols_; j++) {
476 tmp = operator ()(i,j);
477 tmpmax = ( tmpmax<=tmp ? tmp : tmpmax );
482 double Matrix::min() {
483 double tmpmin=operator ()(1,1), tmp;
484 for(int i=1; i<=rows_; i++) {
485 for(int j=1; j<=cols_; j++) {
486 tmp = operator ()(i,j);
487 tmpmin = ( tmpmin>=tmp ? tmp : tmpmin );
493 double Matrix::trace() {
494 if(rows_!=cols_) throw Exception(typeid(Matrix), "EXPRESSION ERROR", "Matrix size did not matched");
495 double tmptrace = 0.0;
496 for(int i=1; i<=rows_; i++) {
497 tmptrace += operator ()(i,i);
503 /* Matrix& Matrix::convolute(const Matrix &rhs) {
504 elem_ptr t(*this), r(rhs);
505 for(t.row=t.begin,r.row=r.begin; t.row<t.rowend; t.row+=t.rowstep,r.row+=r.rowstep) {
506 t.colend=t.row+this->cols_;
507 for(t.col=t.row,r.col=r.row; t.col<t.colend; t.col++,r.col++)
508 *(t.col) *= *(r.col);
514 int Matrix::getRows() const { return rows_; }
515 int Matrix::getCols() const { return cols_; }
518 Matrix & Matrix::each(double (*f)(double)) { // this method only for test. Don't use for your code.
520 for(t.row=t.begin; t.row<t.rowend; t.row+=t.rowstep) {
521 t.colend=t.row+this->cols_;
522 for(t.col=t.row; t.col<t.colend; t.col++)
523 *(t.col)=f(*(t.col));
527 Matrix & Matrix::each(double (*f)(double, double), double second) { // this method only for test. Don't use for your code.
529 for(t.row=t.begin; t.row<t.rowend; t.row+=t.rowstep) {
530 t.colend=t.row+this->cols_;
531 for(t.col=t.row; t.col<t.colend; t.col++)
532 *(t.col)=f(*(t.col), second);
538 Matrix Matrix::mesh(const Wave &roww, int rows, const Wave &colw, int cols) {
542 return mesh(roww, row, colw, col);
544 Matrix Matrix::mesh(const Wave &roww, const Range rowrng, const Wave &colw, const Range colrng) {
545 int rowf = rowrng.int_floor(), rowc = rowrng.int_ceil(), colf = colrng.int_floor(), colc = colrng.int_ceil();
546 Matrix mtx(rowc-rowf+1, colc-colf+1);
549 for(row=rowf, p.row=p.begin; row<=rowc; row++, p.row+=p.rowstep) {
550 p.colend=p.row+mtx.cols_;
551 for(col=colf, p.col=p.row; col<=colc; col++, p.col++) {
552 *(p.col) = roww(row)+colw(col);
557 Matrix Matrix::mesh(const Range rowrng, const Range colrng) {
558 return mesh(Waveform::LINEAR(1), rowrng, Waveform::LINEAR(1), colrng);
560 // MatrixExpression Matrix::mesh(Wave &roww, Wave &colw) {
561 // return MatrixExpression(SIZE_UNDEFINED, SIZE_UNDEFINED, roww, colw, MatrixExpression::MESH);
564 void Matrix::mesh(const Range rowrng, Matrix &rowmtx, const Range colrng, Matrix &colmtx) {
565 int rowf = rowrng.int_floor(), rowc = rowrng.int_ceil(), colf = colrng.int_floor(), colc = colrng.int_ceil();
566 rowmtx = mesh(rowrng, colc-colf+1);
567 colmtx = mesh(rowc-rowf+1, colrng);
569 Matrix Matrix::mesh(int rows, const Range colrng) {
570 int colf = colrng.int_floor(), colc = colrng.int_ceil();
571 Matrix mtx(rows, colc-colf+1);
574 for(row=0, p.row=p.begin; row<rows; row++, p.row+=p.rowstep) {
575 p.colend=p.row+mtx.cols_;
576 for(col=colf, p.col=p.row; col<=colc; col++, p.col++) {
582 Matrix Matrix::mesh(const Range rowrng, int cols) {
583 int rowf = rowrng.int_floor(), rowc = rowrng.int_ceil();
584 Matrix mtx(rowc-rowf+1, cols);
587 for(row=rowf, p.row=p.begin; row<=rowc; row++, p.row+=p.rowstep) {
588 p.colend=p.row+mtx.cols_;
589 for(col=0, p.col=p.row; col<cols; col++, p.col++) {
596 double* Matrix::getElementPtr()
598 if(op_==INSTANCE) return element_;
602 void Matrix::copy(double *target, Interval init_col, int row)
604 int top = init_col.int_ceil(cols_), bottom = init_col.int_floor(0), num = top-bottom;
605 for(int i=0; i<num; i++) {
606 target[i] = (*this)(row, i+bottom);
610 void Matrix::load(std::string filename)
612 std::vector<std::vector<std::string> > csv;
613 Data::loadCSVraw( File::decodePath(filename).c_str(), csv );
615 int max_row = csv.size();
616 int max_col = 0, tmp_col = 0;
617 for(int row=0; row<max_row; row++) {
618 tmp_col = csv[row].size();
619 if(tmp_col > max_col) max_col = tmp_col;
622 set(max_row, max_col);
624 for(int row=0; row<max_row; row++) {
625 for(int col=0; col<csv[row].size(); col++) {
626 num = atof( csv[row][col].c_str() );
627 (*this)(row+1, col+1) = num;
632 void Matrix::save(const std::string filename)
634 std::ofstream of( File::decodePath(filename).c_str());
635 for(int row=0; row<getRows(); row++) {
636 for(int col=0; col<getCols()-1; col++) {
637 of << (*this)(row+1, col+1) << ", ";
639 of << (*this)(row+1, getCols()) << std::endl;
646 char MatrixExpression::OPERAND_SYMBOL[10] = {'N','S','+','-','*','/','+','-','*','/'};
648 MatrixExpression Matrix::operator ()(int row, Range col) {
650 return MatrixExpression(1, col.int_ceil(cols_)-col.int_floor(1)+1, *this, row<=rng<=row, col, MatrixExpression::SLICE);
652 MatrixExpression Matrix::operator ()(Range row, int col) {
654 return MatrixExpression(row.int_ceil(rows_)-row.int_floor(1)+1, 1, *this, row, col<=rng<=col, MatrixExpression::SLICE);
656 MatrixExpression Matrix::operator ()(Range row, Range col) {
657 return MatrixExpression(row.int_ceil(rows_)-row.int_floor(1)+1, col.int_ceil(cols_)-col.int_floor(1)+1, *this, row, col, MatrixExpression::SLICE);
659 MatrixExpression operator +(const Matrix &lhs, double rhs) {
660 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::ADD_SC);
662 MatrixExpression operator -(const Matrix &lhs, double rhs) {
663 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::SUB_SC);
665 MatrixExpression operator *(const Matrix &lhs, double rhs) {
666 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::MUL_SC);
668 MatrixExpression operator /(const Matrix &lhs, double rhs) {
669 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::DIV_SC);
671 MatrixExpression operator ^(const Matrix &lhs, double rhs) {
672 if(lhs.op_!=Matrix::MASK) {
673 if(lhs.rows_==lhs.cols_) return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::POW);
674 else throw Exception("Argument Error ^: This operator is under testing.");
676 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::POW_MASK);
679 MatrixExpression operator +(const Matrix &lhs, const Matrix &rhs) {
680 if(lhs.check_size_equal(rhs)) return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::ADD);
681 else throw Exception("Argument Error +: Matrix size was unmatched.");
683 MatrixExpression operator -(const Matrix &lhs, const Matrix &rhs) {
684 if(lhs.check_size_equal(rhs)) return MatrixExpression(lhs.rows_, lhs.cols_, lhs, rhs, MatrixExpression::SUB);
685 else throw Exception("Argument Error -: Matrix size was unmatched.");
687 MatrixExpression operator *(const Matrix &lhs, const Matrix &rhs) {
688 if(lhs.op_!=Matrix::MASK && rhs.op_!=Matrix::MASK) {
689 if(lhs.check_size_mul(rhs)) return MatrixExpression(lhs.rows_, rhs.cols_, lhs, rhs, MatrixExpression::MUL);
690 else throw Exception("Argument Error *: Matrix size was unmatched.");
692 if(lhs.check_size_equal(rhs)) return MatrixExpression(lhs.rows_, rhs.cols_, lhs, rhs, MatrixExpression::MUL_MASK);
693 else throw Exception("Argument Error *~: Matrix size was unmatched.");
696 MatrixExpression operator ~(const Matrix &lhs) {
698 return MatrixExpression(lhs.rows_, lhs.cols_, lhs, 1<=rng<=lhs.rows_, 1<=rng<=lhs.cols_, MatrixExpression::MASK);
700 // MatrixExpression operator /(const Matrix &lhs, const Matrix &rhs) {
701 // if(lhs.check_size_equal(rhs)) return MatrixExpression(lhs.rows_, rhs.cols_, lhs, rhs, MatrixExpression::DIV);
702 // else throw Exception();
705 MatrixExpression::MatrixExpression() : lhs_(NULL), rhs_(NULL) {}
706 MatrixExpression::MatrixExpression(int rows, int cols, const Matrix &f, const Matrix &f2, OPERAND op)
707 : lhs_(const_cast<Matrix*>(&f)), rhs_(const_cast<Matrix*>(&f2)) {
708 if(op==ADD || op==SUB || op==MUL || op==DIV || op==MUL_MASK) {
709 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Operad format was failed.");
715 MatrixExpression::MatrixExpression(int rows, int cols, const Matrix &f, double f2, OPERAND op)
716 : lhs_(const_cast<Matrix*>(&f)), rhs_(NULL), scholar_(f2) {
717 if(op==ADD_SC || op==SUB_SC || op==MUL_SC || op==DIV_SC || op==POW || op==POW_MASK) {
718 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Operad format was failed.");
724 MatrixExpression::MatrixExpression(int rows, int cols, const Matrix& f, Range& rowrng, Range& colrng, OPERAND op)
725 : lhs_(const_cast<Matrix*>(&f)), rhs_(NULL), rowrng_(rowrng), colrng_(colrng) {
726 if(op==SLICE || op==MASK) {
727 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Operad format was failed.");
733 MatrixExpression::MatrixExpression(int rows, int cols, Wave &roww, Wave &colw, OPERAND op)
734 : lhs_(NULL), rhs_(NULL), meshrow_(&roww), meshcol_(&colw) {
736 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Operad format was failed.");
742 MatrixExpression::MatrixExpression(const MatrixExpression &mtxc) : lhs_(mtxc.rhs_), rhs_(mtxc.rhs_) {
747 void MatrixExpression::swap(Matrix &rhs) {
749 if(has_instance() && rhs.has_instance()) {
750 mtx.set(rows_, cols_);
755 else throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
757 void MatrixExpression::track(int n) const {
758 for(int i=0; i<n; i++) std::cout << " ";
759 std::cout << "Matrix op" << MatrixExpression::OPERAND_SYMBOL[op_] << ":" << this << std::endl;
760 if(lhs_!=(Matrix*)this) lhs_->track(++n);
761 if(rhs_!=(Matrix*)this) rhs_->track(n);
763 MatrixExpression::~MatrixExpression() {
764 //std::cout << "DEST-MatrixExpression op" << MatrixExpression::OPERAND_SYMBOL[op_] << " " << rows_ << "*" << cols_ << ":" << this << std::endl;
768 bool MatrixExpression::has_instance() const {
769 if(op_==SLICE || op_==MASK) return lhs_->has_instance();
772 Matrix* MatrixExpression::instance_ptr() const {
773 if(op_==SLICE || op_==MASK) return lhs_->instance_ptr();
776 void MatrixExpression::get_element_ptr(double *&ptr_origin, double *&ptr_start, int &row_step) const {
777 if(op_==SLICE || op_==MASK) {
778 lhs_->get_element_ptr(ptr_origin, ptr_start, row_step);
779 ptr_start = ptr_origin+(colrng_.int_floor(1)-1)+((rowrng_.int_floor(1)-1)*row_step);
782 } else throw Exception(typeid(*this), "MEMORY ERROR", "No instance.");
785 //void MatrixExpression::substitute(double rhs) {
786 // Matrix::substitute(rhs);
788 //void MatrixExpression::substitute(const Matrix &mtx) {
789 // const_cast<Matrix &>(mtx).track_and_calculate(*this, true, true);
792 void MatrixExpression::evaluate(Matrix& target) {
793 Matrix *newself = NULL, *actualtarget = target.instance_ptr();
794 int cnt_in_add=0, cnt_in_mul=0;
795 if( track_self(actualtarget, cnt_in_add, cnt_in_mul, false) ) {
796 newself = new Matrix(actualtarget->rows_, actualtarget->cols_);
797 track_and_calculate(*newself, true, true);
798 actualtarget->swap(*newself);
801 target.substitute(0.0);
802 track_and_calculate(target, true, true);
805 void MatrixExpression::evaluate(MatrixExpression& target) {
806 Matrix *newself = NULL, *actualtarget = target.instance_ptr();
807 int cnt_in_add=0, cnt_in_mul=0;
808 if( track_self(actualtarget, cnt_in_add, cnt_in_mul, false) ) {
809 newself = new Matrix(*actualtarget);
810 actualtarget = target.lhs_;
811 target.lhs_ = newself;
813 track_and_calculate(target, true, true);
814 actualtarget->swap(*newself);
817 target.substitute(0.0);
818 track_and_calculate(target, true, true);
821 bool MatrixExpression::track_self(const Matrix* self, int &cnt_in_add, int &cnt_in_mul, bool in_mul) {
822 bool found = false, in_mult = in_mul;
835 if(lhs_!=NULL) found = found || lhs_->track_self(self,cnt_in_add,cnt_in_mul,in_mult);
836 if(rhs_!=NULL) found = found || rhs_->track_self(self,cnt_in_add,cnt_in_mul,in_mult);
839 void MatrixExpression::track_and_calculate(Matrix& target, bool add_posi, bool mul_posi) {
841 bool made_buf1=false, made_buf2=false;
843 if(lhs_->has_instance()) target.add(*lhs_, add_posi);
844 else lhs_->track_and_calculate(target, add_posi, mul_posi);
845 if(rhs_->has_instance()) target.add(*rhs_, add_posi);
846 else rhs_->track_and_calculate(target, add_posi, mul_posi);
847 } else if(op_==SUB) {
848 if(lhs_->has_instance()) target.add(*lhs_, add_posi);
849 else lhs_->track_and_calculate(target, add_posi, mul_posi);
850 if(rhs_->has_instance()) target.add(*rhs_, !add_posi);
851 else rhs_->track_and_calculate(target, !add_posi, mul_posi);
852 } else if(op_==MUL) {
853 if(lhs_->has_instance()) buf1=lhs_;
855 buf1 = new Matrix(lhs_->rows_, lhs_->cols_);
857 lhs_->track_and_calculate(*buf1, true, true);
859 if(rhs_->has_instance()) buf2=rhs_;
861 buf2 = new Matrix(rhs_->rows_, rhs_->cols_);
863 rhs_->track_and_calculate(*buf2, true, true);
865 target.mul(*buf1, *buf2, add_posi);
866 if(made_buf1) delete buf1;
867 if(made_buf2) delete buf2;
868 } else if(op_==ADD_SC) {
869 if(lhs_->has_instance()) target.add(*lhs_, add_posi);
870 else lhs_->track_and_calculate(target, add_posi, mul_posi);
871 target.add(scholar_, add_posi);
872 } else if(op_==SUB_SC) {
873 if(lhs_->has_instance()) target.add(*lhs_, add_posi);
874 else lhs_->track_and_calculate(target, add_posi, mul_posi);
875 target.add(scholar_, !add_posi);
876 } else if(op_==MUL_SC) {
877 if(lhs_->has_instance()) buf1=lhs_;
879 buf1 = new Matrix(lhs_->rows_, lhs_->cols_);
881 lhs_->track_and_calculate(*buf1, true, true);
883 target.mul(*buf1, scholar_, add_posi);
884 if(made_buf1) delete buf1;
885 } else if(op_==DIV_SC) {
886 if(lhs_->has_instance()) buf1=lhs_;
888 buf1 = new Matrix(lhs_->rows_, lhs_->cols_);
890 lhs_->track_and_calculate(*buf1, true, true);
892 target.div(*buf1, scholar_, add_posi);
893 if(made_buf1) delete buf1;
894 } else if(op_==MUL_MASK) {
895 if(lhs_->has_instance()) buf1=lhs_;
897 buf1 = new Matrix(lhs_->rows_, lhs_->cols_);
899 lhs_->track_and_calculate(*buf1, true, true);
901 if(rhs_->has_instance()) buf2=rhs_;
903 buf2 = new Matrix(rhs_->rows_, rhs_->cols_);
905 rhs_->track_and_calculate(*buf2, true, true);
907 target.mul_mask(*buf1, *buf2, add_posi);
908 if(made_buf1) delete buf1;
909 if(made_buf2) delete buf2;
910 } else if(op_==SLICE) {
911 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
912 // if(lhs_->has_instance()) buf1=lhs_;
914 // buf1 = new Matrix(lhs_->rows_, lhs_->cols_);
916 // lhs_->track_and_calculate(*buf1, true, true);
918 // target.div(*buf1, scholar_, add_posi);
919 // if(made_buf1) delete buf1;
923 double& MatrixExpression::xy(int x, int y) const {
926 if(elm.begin==NULL) throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
927 return *(elm.begin + (y*elm.rowstep) + x);
929 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
932 double& MatrixExpression::operator ()(int row, int col) const {
935 if(elm.begin==NULL) throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
936 return *(elm.begin + ((row-1)*elm.rowstep) + (col-1));
938 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
941 MatrixExpression MatrixExpression::operator ()(int row, Range col) { return (*this).Matrix::operator ()(row, col); }
942 MatrixExpression MatrixExpression::operator ()(Range row, int col) { return (*this).Matrix::operator ()(row, col); }
943 MatrixExpression MatrixExpression::operator ()(Range row, Range col) { return (*this).Matrix::operator ()(row, col); }
945 Matrix& MatrixExpression::operator =(double rhs) {
946 if(has_instance()) substitute(rhs);
947 else throw Exception();
950 Matrix& MatrixExpression::operator =(const Matrix &rhs) {
951 if(check_size_equal(rhs)) {
954 } else throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
955 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix size did not matched");
958 Matrix& MatrixExpression::operator =(const MatrixExpression &rhs) {
959 if(check_size_equal(rhs)) {
961 if(rhs.has_instance()) substitute(rhs);
962 else const_cast<MatrixExpression &>(rhs).evaluate(*this);
963 } else throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
964 } else throw Exception(typeid(*this), "EXPRESSION ERROR", "Matrix size did not matched");
969 Matrix & MatrixExpression::slide(int drow, int dcol) {
970 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
973 Matrix & MatrixExpression::transpose() {
974 throw Exception(typeid(*this), "NO MEMORY ERROR", "Memory not allocated");
978 std::ostream& operator<<(std::ostream& ost, const Matrix &mtx) {
979 if(mtx.has_instance()) {
980 for(int row=1; row<=mtx.rows_; row++) {
981 for(int col=1; col<=mtx.cols_; col++) {
982 ost << mtx(row,col) << "\t";
991 namespace MatrixOverload {
992 Matrix sin(const Matrix &m) {
994 return mtx.each(&::sin);
996 Matrix cos(const Matrix &m) {
998 return mtx.each(&::cos);
1000 Matrix tan(const Matrix &m) {
1002 return mtx.each(&::tan);
1004 Matrix asin(const Matrix &m) {
1006 return mtx.each(&::asin);
1008 Matrix acos(const Matrix &m) {
1010 return mtx.each(&::acos);
1012 Matrix atan(const Matrix &m) {
1014 return mtx.each(&::atan);
1016 Matrix exp(const Matrix &m) {
1018 return mtx.each(&::exp);
1020 Matrix log(const Matrix &m) {
1022 return mtx.each(&::log);
1024 Matrix log10(const Matrix &m) {
1026 return mtx.each(&::log10);
1028 Matrix sqrt(const Matrix &m) {
1030 return mtx.each(&::sqrt);
1033 Matrix abs(const Matrix &m) {
1035 return mtx.each(&::fabs);
1037 Matrix pow(const Matrix &m, double ex) {
1039 return mtx.each(&::pow, ex);
1043 Matrix max(const Matrix& a, const Matrix b) {
1044 if(!a.check_size_equal(b)) throw Exception(typeid(Matrix), "EXPRESSION ERROR", "Matrix size did not matched");
1045 Matrix tmp(a.getRows(), a.getCols());
1046 for(int col=0; col<a.getCols(); col++) {
1047 for(int row=0; row<a.getRows(); row++) {
1048 tmp(row, col) = ( a(row, col) > b(row, col) ? a(row, col) : b(row, col) );
1054 Matrix min(const Matrix& a, const Matrix b) {
1055 if(!a.check_size_equal(b)) throw Exception(typeid(Matrix), "EXPRESSION ERROR", "Matrix size did not matched");
1056 Matrix tmp(a.getRows(), a.getCols());
1057 for(int col=0; col<a.getCols(); col++) {
1058 for(int row=0; row<a.getRows(); row++) {
1059 tmp(row, col) = ( a(row, col) < b(row, col) ? a(row, col) : b(row, col) );
1066 } /* <- namespace Psycholops */