예제 #1
0
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;  
}
예제 #2
0
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);
  }
}
예제 #3
0
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;  
}
예제 #4
0
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);
    }
  }
}