예제 #1
0
파일: qr.cpp 프로젝트: nvmd/itpp
bool qr(const cmat &A, cmat &Q, cmat &R, bmat &P)
{
  int info;
  int m = A.rows();
  int n = A.cols();
  int lwork = n;
  int k = std::min(m, n);
  cvec tau(k);
  cvec work(lwork);
  vec rwork(std::max(1, 2*n));
  ivec jpvt(n);
  jpvt.zeros();

  R = A;

  // perform workspace query for optimum lwork value
  int lwork_tmp = -1;
  zgeqp3_(&m, &n, R._data(), &m, jpvt._data(), tau._data(), work._data(),
          &lwork_tmp, rwork._data(), &info);
  if (info == 0) {
    lwork = static_cast<int>(real(work(0)));
    work.set_size(lwork, false);
  }
  zgeqp3_(&m, &n, R._data(), &m, jpvt._data(), tau._data(), work._data(),
          &lwork, rwork._data(), &info);

  Q = R;
  Q.set_size(m, m, true);

  // construct permutation matrix
  P = zeros_b(n, n);
  for (int j = 0; j < n; j++)
    P(jpvt(j) - 1, j) = 1;

  // construct R
  for (int i = 0; i < m; i++)
    for (int j = 0; j < std::min(i, n); j++)
      R(i, j) = 0;

  // perform workspace query for optimum lwork value
  lwork_tmp = -1;
  zungqr_(&m, &m, &k, Q._data(), &m, tau._data(), work._data(), &lwork_tmp,
          &info);
  if (info == 0) {
    lwork = static_cast<int>(real(work(0)));
    work.set_size(lwork, false);
  }
  zungqr_(&m, &m, &k, Q._data(), &m, tau._data(), work._data(), &lwork,
          &info);

  return (info == 0);
}
예제 #2
0
void PolyFit1D(UInt nsamples, const double coord[], const double vals[], const std::vector<POLY*> &poly, double coef[])
{
#ifdef ESMCI_LAPACK
  UInt ncoef = poly.size();
  int m = nsamples, n = ncoef, nrhs = 1, info = 0, rank, ldb;
  ldb = std::max(std::max(m,n),1);
  std::vector<double> mat(nsamples*ncoef);
  std::vector<double> rhs(ldb);

  for (UInt i = 0; i < nsamples; i++) {
    rhs[i] = vals[i]; // sizing might not be right, so copy
    for (UInt j = 0; j < ncoef; j++) {
      mat[j*nsamples + i] = EvalPoly<POLY>()(*poly[j], coord[i]);
    }
  }

  std::vector<int> jpvt(ncoef, 0);
  //int lwork = std::max(std::min(m,n)+2*n+1, 2*std::min(m,n)+nrhs);
  // TODO figure this out
  int lwork = 4028;
  std::vector<double> work(lwork, 0);
  double rcond=0.0000000000001;

  FTN(dgelsy)(
    &m, &n, &nrhs, &mat[0], &m, &rhs[0], &ldb, &jpvt[0], &rcond, &rank, &work[0], &lwork, &info);

  for (UInt i = 0; i < ncoef; i++) coef[i] = rhs[i];

#endif
}
예제 #3
0
파일: lsfit.cpp 프로젝트: tjgiese/ccdl
int ccdl::LeastSquaresFit
( int const nobs, int const nparam,
  double const * A_obs_by_param,
  double * x_param,
  double const * b_obs,
  double relative_accuracy_of_the_obs )
{
  // min (xt.At-bt).(A.x-b)

  std::vector<double> A( A_obs_by_param, A_obs_by_param + nparam*nobs );
  int nmax = std::max( nparam, nobs );
  std::vector<double> X( nmax, 0. );
  std::copy( b_obs, b_obs + nobs, X.data() );
  std::vector<int> jpvt( nparam, 0 );
  int LWORK = -1;
  int INFO = 0;
  double twork = 0;
  int rank = 0;
  int nrhs=1;
  dgelsy_( &nobs, &nparam, &nrhs, 
	   A.data(), &nobs, X.data(), &nmax, 
	   jpvt.data(), &relative_accuracy_of_the_obs, &rank,
	   &twork, &LWORK, &INFO );
  if ( INFO == 0 )
    {
      LWORK = twork+1;
      std::vector<double> WORK( LWORK, 0. );
#ifdef PDBG
      std::printf("dgelsy_\n");
#endif
      dgelsy_( &nobs, &nparam, &nrhs, 
	       A.data(), &nobs, X.data(), &nmax, 
	       jpvt.data(), &relative_accuracy_of_the_obs, &rank,
	       WORK.data(), &LWORK, &INFO );
#ifdef PDBG
      std::printf("return %i\n",INFO);
#endif
      std::copy( X.data(), X.data() + nparam, x_param );
    }
  else
    {
      std::fill( x_param, x_param + nparam, 0. );
    };
  return INFO;
}
예제 #4
0
파일: Simplex.cpp 프로젝트: pletzer/egface
int
Simplex::solve(std::vector<double>& rhs) const {

  // save the input matrix and rhs vector so we get a chance to
  // recover in case of a singular matrix.

  const double residualTol = 1.e-8;

  std::vector<double> mat(mnpdims * mndims);
  // build the matrix system
  for (size_t jcol = 0; jcol < mnpdims; ++jcol) {
    for (size_t irow = 0; irow < mndims; ++irow) {
      mat[irow + jcol*mndims] = mvertices[jcol + 1][irow] - mvertices[0][irow];
    }
  }

  std::vector<double> matCopy(mnpdims * mndims);
  std::vector<double> bCopy(rhs.size());
  std::copy(mat.begin(), mat.end(), matCopy.begin());
  std::copy(rhs.begin(), rhs.end(), bCopy.begin());

  int nrow = (int) mndims;
  int ncol = (int) mnpdims;
  char t = 'n';
  int one = 1;
  int mn = ncol;
  int nb = 1; // optimal block size
  int lwork = mn + mn*nb;
  std::vector<double> work((size_t) lwork);
  int errCode = 0;
  _GELS_(&t, &nrow, &ncol, &one,
     &matCopy.front(), &nrow,
     &rhs.front(), &nrow,
     &work.front(), &lwork, &errCode);

  if (!errCode) {
    // merrCode == 0 indicates everything was fine
    // merrCode < 0 indicates bad entry
    // in either case return
    return errCode;
  }
  else if (errCode > 0) {

    if (nrow <= 1) {
      return errCode;
    }

    for (size_t i = 0; i < mndims; ++i) {
      rhs[i] = bCopy[i];
    }
    errCode = 0;
    // relative accuracy in the matrix data
    double rcond = std::numeric_limits<double>::epsilon();
    int rank;
    std::vector<int> jpvt(ncol);
    lwork = mn + 3*ncol + 1 > 2*mn + nb*1? mn + 3*ncol + 1: 2*mn + nb*1;
    work.resize(lwork);
    _GELSY_(&nrow, &ncol, &one,
        &matCopy.front(), &nrow,
        &rhs.front(), &nrow,
        &jpvt.front(), &rcond, &rank, &work.front(), &lwork, &errCode);

    // check if this is a good solution
    double residualError = 0.0;
    for (size_t i = 0; i < mndims; ++i) {
      double rowSum = 0.0;
      for (size_t j = 0; j < mnpdims; ++j) {
        rowSum += mat[i + nrow*j]*rhs[j];
      }
      residualError += std::abs(rowSum - bCopy[i]);
    }
    if (residualError < residualTol) {
      // good enough
      errCode = 1;
      return errCode;
    }

    // some error
    errCode = 2;
    return errCode;
  }

  // we should never reach that point
  errCode = 0;
  return errCode;
}