int CLapack::syev(char jobz,char uplo,CFortranMatrix& a,CVector& w) { int info = 0; int nrows = a.GetNumberOfRows(); int nwork = -1; double twork[1]; // query workspace length dsyev_(&jobz,&uplo,&nrows,a.GetRawDataField(),&nrows,w.GetRawDataField(), twork,&nwork,&info); if( info != 0 ){ CSmallString error; error << "unable to determine lwork, info = " << info; INVALID_ARGUMENT(error); } // allocate work space CVector work; nwork = static_cast<int>(twork[0]) + 1; work.CreateVector(nwork); // run again dsyev_(&jobz,&uplo,&nrows,a.GetRawDataField(),&nrows,w.GetRawDataField(), work.GetRawDataField(),&nwork,&info); return(info); }
int CLapack::gelsd(CFortranMatrix& a,CVector& rhs,double rcond,int& rank) { int m = a.GetNumberOfRows(); int n = a.GetNumberOfColumns(); int nrhs = 1; int lda = m; int ldb = std::max(m,n); CVector s; int ns = std::min(m,n); s.CreateVector(ns); int info = 0; // query work size int lwork = -1; double twork[1]; // printf("lwork = %d\n",lwork); CSimpleVector<int> iwork; int li = 3*std::min(m,n)*std::min(m,n) + 11*std::min(m,n); iwork.CreateVector(li); dgelsd_(&m,&n,&nrhs,a.GetRawDataField(),&lda,rhs.GetRawDataField(),&ldb,s.GetRawDataField(), &rcond,&rank,twork,&lwork,iwork.GetRawDataField(),&info); if( info != 0 ){ CSmallString error; error << "unable to determine lwork, info = " << info; INVALID_ARGUMENT(error); } lwork = static_cast<int>(twork[0]) + 1; // printf("lwork = %d\n",lwork); CSimpleVector<double> work; work.CreateVector(lwork); // run svd dgelsd_(&m,&n,&nrhs,a.GetRawDataField(),&lda,rhs.GetRawDataField(),&ldb,s.GetRawDataField(), &rcond,&rank,work.GetRawDataField(),&lwork,iwork.GetRawDataField(),&info); return(info); }
bool CABFIntegratorRBF::IntegrateByLS(CVerboseStr& vout) { vout << " Creating A and rhs ..." << endl; // number of equations int neq = Accumulator->GetNumberOfBins()*NumOfCVs; CSimpleVector<double> spos; // best sampled bin spos.CreateVector(NumOfCVs); CSimpleVector<double> ipos; // best sampled bin ipos.CreateVector(NumOfCVs); CSimpleVector<double> lpos; // best sampled bin lpos.CreateVector(NumOfCVs); vout << " Dim: " << neq << " x " << NumOfRBFs << endl; CFortranMatrix A; A.CreateMatrix(neq,NumOfRBFs); CVector rhs; int nrhs = std::max(neq,NumOfRBFs); rhs.CreateVector(nrhs); // calculate A and rhs int j=0; for(int i=0; i < Accumulator->GetNumberOfBins(); i++){ Accumulator->GetPoint(i,ipos); // A for(int l=0; l < NumOfRBFs; l++){ GetRBFPosition(l,lpos); // cout << lpos[0] << " " << lpos[1] << endl; double av = 1.0; for(int k=0; k < NumOfCVs; k++){ double dvc = Accumulator->GetCoordinate(k)->GetDifference(ipos[k],lpos[k]); double sig = Sigmas[k]; av *= exp( - dvc*dvc/(2.0*sig*sig) ); } for(int k=0; k < NumOfCVs; k++){ double dvc = Accumulator->GetCoordinate(k)->GetDifference(ipos[k],lpos[k]); double sig = Sigmas[k]; double fc = -dvc/(sig*sig); // switch to derivatives A[j+k][l] = av * fc; } } // rhs for(int k=0; k < NumOfCVs; k++){ rhs[j+k] = Accumulator->GetABFForceSum(k,i); } j += NumOfCVs; } int result = 0; switch(Method){ case EARBF_SVD:{ vout << " Solving least square problem by SVD ..." << endl; // solve least square problem via GELSD int rank = 0; result = CLapack::gelsd(A,rhs,RCond,rank); vout << " Rank = " << rank << "; Info = " << result << endl; if( result != 0 ) return(false); } break; case EARBF_QRLQ:{ vout << " Solving least square problem by QRLQ ..." << endl; // solve least square problem via GELS result = CLapack::gels(A,rhs); if( result != 0 ) return(false); } break; default: INVALID_ARGUMENT("unsupported method"); } // copy results to Weights for(int l=0; l < NumOfRBFs; l++){ Weights[l] = rhs[l]; } cout << Weights[0] << endl; return( true ); }