bool ON_Matrix::Multiply( const ON_Matrix& a, const ON_Matrix& b ) { int i, j, k, mult_count; double x; if (a.ColCount() != b.RowCount() ) return false; if ( a.RowCount() < 1 || a.ColCount() < 1 || b.ColCount() < 1 ) return false; if ( this == &a ) { ON_Matrix tmp(a); return Multiply(tmp,b); } if ( this == &b ) { ON_Matrix tmp(b); return Multiply(a,tmp); } Create( a.RowCount(), b.ColCount() ); mult_count = a.ColCount(); double const*const* am = a.ThisM(); double const*const* bm = b.ThisM(); double** this_m = ThisM(); for ( i = 0; i < m_row_count; i++ ) for ( j = 0; j < m_col_count; j++ ) { x = 0.0; for (k = 0; k < mult_count; k++ ) { x += am[i][k] * bm[k][j]; } this_m[i][j] = x; } return true; }
void NurbsTools::pca (const vector_vec3d &data, ON_3dVector &mean, Eigen::Matrix3d &eigenvectors, Eigen::Vector3d &eigenvalues) { if (data.empty ()) { printf ("[NurbsTools::pca] Error, data is empty\n"); abort (); } mean = computeMean (data); unsigned s = data.size (); ON_Matrix Q(3, s); for (unsigned i = 0; i < s; i++) { Q[0][i] = data[i].x - mean.x; Q[1][i] = data[i].y - mean.y; Q[2][i] = data[i].z - mean.z; } ON_Matrix Qt = Q; Qt.Transpose(); ON_Matrix oC; oC.Multiply(Q,Qt); Eigen::Matrix3d C(3,3); for (unsigned i = 0; i < 3; i++) { for (unsigned j = 0; j < 3; j++) { C(i,j) = oC[i][j]; } } Eigen::SelfAdjointEigenSolver < Eigen::Matrix3d > eigensolver (C); if (eigensolver.info () != Eigen::Success) { printf ("[NurbsTools::pca] Can not find eigenvalues.\n"); abort (); } for (int i = 0; i < 3; ++i) { eigenvalues (i) = eigensolver.eigenvalues () (2 - i); if (i == 2) eigenvectors.col (2) = eigenvectors.col (0).cross (eigenvectors.col (1)); else eigenvectors.col (i) = eigensolver.eigenvectors ().col (2 - i); } }
bool ON_Matrix::Add( const ON_Matrix& a, const ON_Matrix& b ) { int i, j; if (a.ColCount() != b.ColCount() ) return false; if (a.RowCount() != b.RowCount() ) return false; if ( a.RowCount() < 1 || a.ColCount() < 1 ) return false; if ( this != &a && this != &b ) { Create( a.RowCount(), b.ColCount() ); } double const*const* am = a.ThisM(); double const*const* bm = b.ThisM(); double** this_m = ThisM(); for ( i = 0; i < m_row_count; i++ ) for ( j = 0; j < m_col_count; j++ ) { this_m[i][j] = am[i][j] + bm[i][j]; } return true; }
void ON_TextLog::Print( const ON_Matrix& M, const char* sPreamble, int precision ) { double x; char digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; char* sRow; char* sIJ; int xi, row_count, column_count, row_index, column_index; row_count = M.RowCount(); column_count = M.ColCount(); sRow = (char*)alloca( (5*column_count + 2 + 64)*sizeof(*sRow) ); if ( !sPreamble ) sPreamble = "Matrix"; Print("%s (%d rows %d columns)\n",sPreamble,row_count,column_count); for ( row_index = 0; row_index < row_count; row_index++ ) { sIJ = sRow; Print("%5d:",row_index); if ( precision > 3 ) { for ( column_index = 0; column_index < column_count; column_index++ ) { x = M.m[row_index][column_index]; Print( " %8f",x); } Print("\n"); } else { for ( column_index = 0; column_index < column_count; column_index++ ) { x = M.m[row_index][column_index]; if ( x == 0.0 ) { strcpy( sIJ, " 0 " ); sIJ += 4; } else { *sIJ++ = ' '; *sIJ++ = ( x >0.0 ) ? '+' : '-'; x = fabs( x ); if ( x >= 10.0 ) { *sIJ++ = '*'; *sIJ++ = ' '; *sIJ++ = ' '; } else if ( x <= ON_SQRT_EPSILON) { *sIJ++ = '0'; *sIJ++ = ' '; *sIJ++ = ' '; } else if ( x < 0.1) { *sIJ++ = '~'; *sIJ++ = ' '; *sIJ++ = ' '; } else if ( x < .95 ) { *sIJ++ = '.'; xi = (int)floor(x*10.0); if ( xi > 9 ) xi = 9; else if (xi < 1) xi = 1; *sIJ++ = digit[xi]; *sIJ++ = '~'; } else { xi = (int)floor(x); if ( xi < 1 ) xi = 1; else if (xi > 9) xi = 9; *sIJ++ = digit[xi]; if ( x == floor(x) ) { *sIJ++ = ' '; *sIJ++ = ' '; } else { *sIJ++ = '.'; *sIJ++ = '~'; } } } } *sIJ = 0; Print("%s\n",sRow); } } }