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