Example #1
0
void Matrix<real>::RemoveRows(int rowStart, int rowEnd)
{
  InPlaceTransposeMatrix(m, n, data);
  int mBuf = m;
  m = n;
  n = mBuf;
  RemoveColumns(rowStart, rowEnd);
  InPlaceTransposeMatrix(m, n, data);
  mBuf = m;
  m = n;
  n = mBuf;
}
Example #2
0
Matrix<real> & Matrix<real>::InPlaceTranspose()
{
  InPlaceTransposeMatrix(m, n, data);
  // swap m,n
  int swap = m;
  m = n;
  n = swap;
  return (*this);
}
Example #3
0
void Matrix<real>::AppendRows(const Matrix<real> & rows)
{
  if (rows.Getn() != n)
  {
    printf("Error: mismatch in number of columns in AppendRows.\n");
    throw 42;
  }

  InPlaceTransposeMatrix(m, n, data);
  int mBuf = m;
  m = n;
  n = mBuf;
  Matrix<real> rowsT = Transpose(rows);
  AppendColumns(rowsT);
  InPlaceTransposeMatrix(m, n, data);
  mBuf = m;
  m = n;
  n = mBuf;
}
Example #4
0
int MatrixPCA(ThresholdingSpecification * thresholdingSpecification,
              int m, int n, double * A, int * r, double * weights)
{
  if (!A)
  {
    printf("Error: input matrix is NULL.\n");
    return -1;
  }

  if (weights != NULL)
  {
    // transform row i of A by sqrt(weights[i])
    for(int row=0; row<m; row++)
    {
      double rowWeight = sqrt(weights[row]);
      for(int column=0; column<n; column++)
        A[ELT(m, row, column)] *= rowWeight;
    }
  }

  bool transpose = false;
  if (m > n)
  {
    transpose = true;
    InPlaceTransposeMatrix(m,n,A);

    // swap m,n
    int bufferi = m;
    m = n;
    n = bufferi;
  }

  // do SVD

  char jobu  = 'O';//overwrites A with U (left singular vectors)
  //char jobu  = 'N';
  char jobvt = 'S';//all rows returned in VT
  //char jobvt = 'N';

  int ldA = m;

  int ldU = m;

  int lwork = 64*MAX(3*MIN( m, n)+MAX(m,n), 5*MIN(m,n)-4);

  double * work = (double*) malloc (sizeof(double) * lwork);
  if (!work)
  {
    printf("Error: failed to allocate workspace.\n");
    return -2;
  }

  //printf("Workspace size is: %G Mb .\n",1.0 * lwork * sizeof(int) / 1024 / 1024);

  // allocate array for singular vectors
  double * S = (double *) malloc (sizeof(double) * MIN(m,n));
  if (!S)
  {
    printf("Error: failed to allocate singular vectors.\n");
    return -2;
  }

  double * dummyU = NULL;

  // allocate array for VT
  int ldVT = MIN(m,n);
  double * VT = (double *) malloc (sizeof(double) * ldVT * n);
  if (!VT)
  {
    printf("Error: failed to allocate VT.\n");
    return -2;
  }

  #ifdef __APPLE__
    #define DGESVD dgesvd_
    #define INTEGER __CLPK_integer
  #else
    #define DGESVD dgesvd
    #define INTEGER int
  #endif

  INTEGER M = m;
  INTEGER N = n;
  INTEGER LDA = ldA;
  INTEGER LDU = ldU;
  INTEGER LDVT = ldVT;
  INTEGER LWORK = lwork;
  INTEGER INFO;

  //printf("Calling LAPACK dgesvd routine...\n");fflush(NULL);

  //SUBROUTINE SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO )

  DGESVD (&jobu, &jobvt, &M, &N, A, &LDA,
	  S, dummyU, &LDU, VT,
	  &LDVT, work, &LWORK, &INFO);

  if (INFO != 0)
  {
    int code = INFO;
    printf("Error: SVD solver returned non-zero exit code: %d.\n", code);
    free(VT);
    free(S);
    free(work);
    return code;
  }

  free(work);

  if (transpose)
  {
    InPlaceTransposeMatrix(m,n,VT);
    memcpy(A, VT, sizeof(double) * m * n);

    // swap m and n
    int bufferii = m;
    m = n;
    n = bufferii;
  }

  free(VT);

  if (weights != NULL)
  {
    // transform row i of A by sqrt(weights[i])^{-1}
    for(int row=0; row<m; row++)
    {
      double rowWeight = 1.0 / sqrt(weights[row]);
      for(int column=0; column<n; column++)
        A[ELT(m, row, column)] *= rowWeight;
    }
  }

  //double totalEnergy = 0;

  //printf ("Singular values:\n");fflush(NULL);
  //for (int i=0; i< MIN(m,n); i++)
    //printf("%f ",S[i]);
  //printf ("\n");

  // discard unneccesary modes
  //printf("Discarding unnecessary components...\n");fflush(NULL);
  if (thresholdingSpecification->tresholdingType == ThresholdingSpecification::epsilonBased)
    DoTresholding_Epsilon(S,MIN(m,n),r,thresholdingSpecification->epsilon);
  else
    DoTresholding_NumberOfModes(S,MIN(m,n),r,thresholdingSpecification->rDesired);

  // now, variable r has been set to the number of retained modes

  free(S);

  return 0;
}
void MatrixSVD(int m, int n, real * mtx, real * U, real * Sigma, real * VT)
{
  real * A = (real*) malloc (sizeof(real) * m * n);
  memcpy(A, mtx, sizeof(real) * m * n);

  // must deal with transpose since Intel MKL sometimes crashes on thin matrices
  bool transpose = (m > n);
  if (transpose)
  {
    InPlaceTransposeMatrix(m, n, A);

    // swap arguments
    int buffer = m;
    m = n;
    n = buffer;

    real * bufferr = U;
    U = VT;
    VT = bufferr;
  }

  // now, we always have m <= n

  char jobu  = 'S'; //left singular vectors returned in U
  char jobvt = 'S'; //right singular vectors returned in VT

  INTEGER NB = 32; // optimal block size; could also call ilaenv
  int lwork = NB*MAX(3*MIN( m, n)+MAX(m,n), 5*MIN(m,n)-4);

  real * work = (real*) malloc (sizeof(real) * lwork);
  if (!work)
  {
    printf("Error: failed to allocate workspace.\n");
    throw 1;
  }

  //printf("Workspace size is: %G Mb .\n",1.0 * lwork * sizeof(int) / 1024 / 1024);

  INTEGER M = m;
  INTEGER N = n;
  INTEGER LDA = m;
  INTEGER LDU = m;
  INTEGER LDVT = MIN(m,n);
  INTEGER LWORK = lwork;
  INTEGER INFO;

  //printf("Calling LAPACK dgesvd routine...\n");fflush(NULL);

  //SUBROUTINE SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO )

  _xgesvd<sizeof(real)==sizeof(float)>::f 
                 (&jobu, &jobvt, &M, &N, A, &LDA,
                  Sigma, U, &LDU, VT,
                  &LDVT, work, &LWORK, &INFO);

  if (INFO != 0)
  {
    int code = INFO;
    printf("Error: SVD solver returned non-zero exit code: %d.\n", code);
    free(work);
    free(A);
    throw 2;
  }

  free(work);
  free(A);

  if (transpose)
  {
    InPlaceTransposeMatrix(m, MIN(m,n), U);
    InPlaceTransposeMatrix(MIN(m,n), n, VT);
  }
}
real * PseudoInverseMatrix(int m, int n, real * mtx, real singularValueThreshold, int * rank_, real * output)
{
  real * A = (real*) malloc (sizeof(real) * m * n);
  memcpy(A, mtx, sizeof(real) * m * n);

  bool transpose = (m > n);
  if (transpose)
  {
    // swap m,n
    InPlaceTransposeMatrix(m,n, A);
    int buffer = m;
    m = n;
    n = buffer;
  }

  // now, we always have m <= n

  char jobu  = 'O';//overwrites A with U (left singular vectors)
  char jobvt = 'S';//all rows returned in VT

  int ldA = m;
  int ldU = m;

  INTEGER NB = 32; // optimal block size; could also call ilaenv
  int lwork = NB*MAX(3*MIN( m, n)+MAX(m,n), 5*MIN(m,n)-4);

  real * work = (real*) malloc (sizeof(real) * lwork);
  if (!work)
  {
    printf("Error: failed to allocate workspace.\n");
    throw 1;
  }

  //printf("Workspace size is: %G Mb .\n",1.0 * lwork * sizeof(int) / 1024 / 1024);

  // allocate array for singular vectors
  real * S = (real *) malloc (sizeof(real) * MIN(m,n));
  if (!S)
  {
    printf("Error: failed to allocate singular vectors.\n");
    free(work);
    throw 2;
  }

  // allocate array for VT
  int ldVT = MIN(m,n);
  real * VT = (real *) malloc (sizeof(real) * ldVT * n);
  if (!VT)
  {
    printf("Error: failed to allocate VT.\n");
    free(S);
    free(work);
    throw 3;
  }

  INTEGER M = m;
  INTEGER N = n;
  INTEGER LDA = ldA;
  INTEGER LDU = ldU;
  INTEGER LDVT = ldVT;
  INTEGER LWORK = lwork;
  INTEGER INFO;

  //printf("Calling LAPACK dgesvd routine...\n");fflush(NULL);

  //SUBROUTINE SGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO )

  _xgesvd<sizeof(real)==sizeof(float)>::f 
                 (&jobu, &jobvt, &M, &N, A, &LDA,
                  S, NULL, &LDU, VT,
                  &LDVT, work, &LWORK, &INFO);

  if (INFO != 0)
  {
    int code = INFO;
    printf("Error: SVD solver returned non-zero exit code: %d.\n", code);
    free(VT);
    free(S);
    free(work);
    throw 4;
  }

  free(work);

  //printf ("Singular values:\n");fflush(NULL);
  //for (int i=0; i< MIN(m,n); i++)
   // printf("%f ",S[i]);
  //printf ("\n");

  // discard small singular values
  int rank = MIN(m,n);
  for(int i=0; i< MIN(m,n); i++)
  {
    if (S[i] / S[0] < singularValueThreshold)
    {
      rank = i;
      break;
    }
  }

  for(int i=0; i< rank; i++)
    S[i] = ((real)1.0) / S[i];

  for(int i=rank; i< MIN(m,n); i++)
    S[i] = 0.0;

  real * U = A;
  memset(&U[ELT(m,0,rank)], 0, sizeof(real) * m * (n-rank));
  InPlaceTransposeMatrix(m, m, U);
  real * UT = U;
  // UT is now m x m

  InPlaceTransposeMatrix(m,n,VT);
  real * V = VT;
  // V is now n x m

  // multiply A^{\dagger} = V * Sigma^{-1} * U^T
  for(int j=0; j<m; j++) // over all columns
    for(int i=0; i<n; i++) // over all rows
      V[ELT(n, i, j)] *= S[j];

  real * target = output;
  if (target == NULL)
    target = (real*) malloc (sizeof(real) * n * m);

  // V * UT
  // (n x m) * (m x m)
  // output is n x m
  MultiplyMatrices(n, m, m, V, UT, target);

  if (transpose)
    InPlaceTransposeMatrix(n, m, target);

  free(A);
  free(S);
  free(VT);

  if (rank_ != NULL)
    *rank_ = rank;

  return target;
}