Changeset 77

Show
Ignore:
Timestamp:
10/23/08 17:12:36 (3 months ago)
Author:
pernet
Message:

Add the NullSpaceBasis? routine to ffpack.
Add the corresponding test.

Files:
1 added
2 modified

Legend:

Unmodified
Added
Removed
  • include/fflas-ffpack/ffpack.h

    r57 r77  
    684684        } 
    685685 
     686 
     687        /** NullSpaceBasis 
     688         * Computes a basis of the Left/Right nullspace of the matrix A 
     689         * return the dimension of the nullspace. 
     690         *  
     691         * @param A: input matrix of dimension M x N, A is modified 
     692         * @param NS: output matrix of dimension N x NSdim (allocated here) 
     693         * @param NSdim: the dimension of the Nullspace (N-rank(A)) 
     694         *  
     695         */ 
     696        template <class Field> 
     697        static size_t NullSpaceBasis (const Field& F, const FFLAS_SIDE Side, 
     698                                      const size_t M, const size_t N, 
     699                                      typename Field::Element* A, const size_t lda, 
     700                                      typename Field::Element*& NS, size_t& ldn, 
     701                                      size_t& NSdim){ 
     702 
     703                typename Field::Element one, zero,mone; 
     704                F.init(one, 1.0); 
     705                F.init(zero, 0.0); 
     706                F.neg(mone, one); 
     707                 
     708                if (Side == FflasRight) { // Right NullSpace 
     709                        size_t* P = new size_t[N]; 
     710                        size_t* Qt = new size_t[M]; 
     711 
     712                        size_t R = LUdivine (F, FflasNonUnit, FflasNoTrans, M, N, A, lda, P, Qt); 
     713 
     714                        ldn = N-R; 
     715                        NSdim = ldn; 
     716                        NS = new typename Field::Element [N*ldn]; 
     717 
     718                        for (size_t i=0; i<R; ++i) 
     719                                fcopy (F, ldn, NS + i*ldn, 1, A + R + i*lda, 1); 
     720 
     721                        ftrsm (F, FflasLeft, FflasUpper, FflasNoTrans, FflasNonUnit, R, ldn, 
     722                               mone, A, lda, NS, ldn); 
     723 
     724                        for (size_t i=R; i<N; ++i){ 
     725                                for (size_t j=0; j < ldn; ++j) 
     726                                        F.assign (*(NS+i*ldn+j), zero); 
     727                                F.assign (*(NS + i*ldn + i-R), one); 
     728                        } 
     729                        applyP (F, FflasLeft, FflasTrans, NSdim, 0, R, NS, ldn, P); 
     730                        delete [] P; 
     731                        delete [] Qt; 
     732                        return N-R; 
     733                } else { // Left NullSpace 
     734                        size_t* P = new size_t[M]; 
     735                        size_t* Qt = new size_t[N]; 
     736                         
     737                        size_t R = LUdivine (F, FflasNonUnit, FflasTrans, M, N, A, lda, P, Qt); 
     738                         
     739                        write_field (F,cerr<<"LU="<<endl,A,M,N,lda); 
     740                        ldn = M; 
     741                        NSdim = M-R; 
     742                        NS = new typename Field::Element [NSdim*ldn]; 
     743                        for (size_t i=0; i<NSdim; ++i) 
     744                                fcopy (F, R, NS + i*ldn, 1, A + (R + i)*lda, 1); 
     745                        ftrsm (F, FflasRight, FflasLower, FflasNoTrans, FflasNonUnit, NSdim, R, 
     746                               mone, A, lda, NS, ldn); 
     747 
     748                        for (size_t i=0; i<NSdim; ++i){ 
     749                                for (size_t j=R; j < M; ++j) 
     750                                        F.assign (*(NS+i*ldn+j), zero); 
     751                                F.assign (*(NS + i*ldn + i+R), one); 
     752                        } 
     753                        std::cerr<<"NSdim, M = "<<NSdim<<" "<<M<<std::endl; 
     754                        write_field (F,cerr<<"NS="<<endl,NS,NSdim,M,ldn); 
     755                        applyP (F, FflasRight, FflasNoTrans, NSdim, 0, R, NS, ldn, P); 
     756                        delete [] P; 
     757                        delete [] Qt; 
     758                        return N-R; 
     759                } 
     760        } 
     761                 
    686762        /** RowRankProfile 
    687763         * Computes the row rank profile of A. 
    688764         * 
    689          * @param A: input matrix of dimension  
     765         * @param A: input matrix of dimension M x N 
    690766         * @param rklprofile: return the rank profile as an array of row indexes, of dimension r=rank(A) 
    691767         * 
  • tests/Makefile.template

    r67 r77  
    4141CXX=g++ ${INCLUDES} 
    4242 
    43 all: test-fgemm test-invert test-det test-rank test-charpoly test-lqup dense_generator 
     43all: test-fgemm test-invert test-det test-rank test-charpoly test-lqup test-nullspace dense_generator 
    4444 
    4545regression: testeur_fgemm testeur_lqup testeur_ftrsm