Ejemplo n.º 1
0
GURLS_EXPORT float* pinv(const float* A, int rows, int cols, int& res_rows, int& res_cols, float* RCOND)
{
    int M = rows;
    int N = cols;

    float* a = new float[rows*cols];
    copy<float>(a, A, rows*cols);

    int LDA = M;
    int LDB = std::max(M, N);
    int NRHS = LDB;


    // float* b = eye(LDB).getData()

    const int b_size = LDB*NRHS;
    float *b = new float[LDB*NRHS];
    set<float>(b, 0.f, b_size);
    set<float>(b, 1.f, std::min(LDB, NRHS), NRHS+1);

    float* S = new float[std::min(M,N)];
//    float condnum = 0.f; // The condition number of A in the 2-norm = S(1)/S(min(m,n)).

    float rcond = (RCOND == NULL)? (std::max(rows, cols)*FLT_EPSILON): *RCOND;

//    if (RCOND < 0)
//        RCOND = 0.f;

    int RANK = -1; // std::min(M,N);
    int LWORK = -1; //2 * (3*LDB + std::max( 2*std::min(M,N), LDB));
    float* WORK = new float[1];

    /*

    subroutine SGELSS 	( 	INTEGER  	M,
      INTEGER  	N,
      INTEGER  	NRHS,
      REAL,dimension( lda, * )  	A,
      INTEGER  	LDA,
      REAL,dimension( ldb, * )  	B,
      INTEGER  	LDB,
      REAL,dimension( * )  	S,
      REAL  	RCOND,
      INTEGER  	RANK,
      REAL,dimension( * )  	WORK,
      INTEGER  	LWORK,
      INTEGER  	INFO
     )

    */

    /*
   INFO:
   = 0:	successful exit
   < 0:	if INFO = -i, the i-th argument had an illegal value.
   > 0:	the algorithm for computing the SVD failed to converge;
     if INFO = i, i off-diagonal elements of an intermediate
     bidiagonal form did not converge to zero.
   */
    int INFO;

    /* Query and allocate the optimal workspace */
    int res = sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &rcond, &RANK, WORK, &LWORK, &INFO);
    LWORK = static_cast<int>(WORK[0]);
    delete [] WORK;
    WORK = new float[LWORK];

    res = sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &rcond, &RANK, WORK, &LWORK, &INFO);

    // TODO: check INFO on exit
    //condnum = S[0]/(S[std::min(M, N)]-1);

    if(INFO != 0)
    {
        std::stringstream str;
        str << "Pinv failed, error code " << INFO << ";" << std::endl;
        throw gException(str.str());
    }

    delete [] S;
    delete [] WORK;
    delete [] a;

    res_rows = LDB;
    res_cols = NRHS;
    return b;

}
Ejemplo n.º 2
0
GURLS_EXPORT int gelss( int *m, int *n, int* nrhs, float *a, int *lda, float* b, int *ldb, float *s, float *rcond, int *rank, float *work, int *lwork, int *info)
{
    return sgelss_( m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, info);
}
Ejemplo n.º 3
0
GURLS_EXPORT void pinv(const gMat2D<float>& A, gMat2D<float>& Ainv, float RCOND){

    /*

subroutine SGELSS 	( 	INTEGER  	M,
  INTEGER  	N,
  INTEGER  	NRHS,
  REAL,dimension( lda, * )  	A,
  INTEGER  	LDA,
  REAL,dimension( ldb, * )  	B,
  INTEGER  	LDB,
  REAL,dimension( * )  	S,
  REAL  	RCOND,
  INTEGER  	RANK,
  REAL,dimension( * )  	WORK,
  INTEGER  	LWORK,
  INTEGER  	INFO
 )

*/

    int M = A.rows();
    int N = A.cols();

    // The following step is required because we are currently storing
    // the matrices using a column-major order while LAPACK's
    // routines require row-major ordering
    float* a = new float[M*N];
    const float* ptr_A = A.getData();
    float* ptr_a = a;
    for (int j = 0; j < N ; j++){
        for (int i = 0; i < M ; i++){
            *ptr_a++ = *(ptr_A+i*N+j);
        }
    }
    int LDA = M;
    int LDB = std::max(M, N);
    int NRHS = LDB;

    float *b = new float[LDB*NRHS], *b_ptr = b;
    for (int i = 0; i < LDB*NRHS; i++){
        *b_ptr++=0.f;
    }
    b_ptr = b;
    for (int i = 0; i < std::min(LDB, NRHS); i++, b_ptr+=(NRHS+1)){
        *b_ptr = 1.f;
    }

    float* S = new float[std::min(M,N)];
    float condnum = 0.f; // The condition number of A in the 2-norm = S(1)/S(min(m,n)).

    if (RCOND < 0){
        RCOND = 0.f;
    }
    int RANK = -1; // std::min(M,N);
    int LWORK = -1; //2 * (3*LDB + std::max( 2*std::min(M,N), LDB));
    float* WORK = new float[1];
    /*
   INFO:
   = 0:	successful exit
   < 0:	if INFO = -i, the i-th argument had an illegal value.
   > 0:	the algorithm for computing the SVD failed to converge;
     if INFO = i, i off-diagonal elements of an intermediate
     bidiagonal form did not converge to zero.
   */
    int INFO;

    /* Query and allocate the optimal workspace */
    /*int res = */sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &RCOND, &RANK, WORK, &LWORK, &INFO);
    LWORK = static_cast<int>(WORK[0]);
    delete [] WORK;
    WORK = new float[LWORK];

    /*res = */sgelss_( &M, &N, &NRHS, a, &LDA, b, &LDB, S, &RCOND, &RANK, WORK, &LWORK, &INFO);
    // TODO: check INFO on exit
    condnum = S[0]/(S[std::min(M, N)]-1);


//    gMat2D<float> *tmp = new gMat2D<float>(b, LDB, LDB, false);

    float *ainv = new float[N*M];
    float* ptr_b = ainv;
    float* ptr_B = b;
    for (int i = 0; i < N ; i++){
        for (int j = 0; j < M ; j++){
            *(ptr_b+i*M+j) = *(ptr_B+j*NRHS+i);
        }
    }
    Ainv = * new gMat2D<float>(ainv, N, M, true);

//	gMat2D<float> *tmp = new gMat2D<float>(b, LDB, NRHS, false);
//	gMat2D<float> *tmp1 = new gMat2D<float>(NRHS, LDB);
//	tmp->transpose(*tmp1);
//	Ainv = * new gMat2D<float>(tmp1->getData(), N, M, true);
//	std::cout << "A = " << std::endl << A << std::endl;
//	std::cout << "pinv(A) = " << std::endl << Ainv << std::endl;
    delete [] S;
    delete [] WORK;
    delete [] a;
//	delete tmp, tmp1;
    delete [] b;
}