Example #1
0
File: ardblas.c Project: rforge/gcb
void d_gemm(SEXP rtransa, SEXP rtransb, SEXP ralpha, SEXP ra, SEXP rlda,
	SEXP rb, SEXP rldb, SEXP rbeta, SEXP rc, SEXP rldc)
{
	char
		transa = getTranspose(rtransa),
		transb = getTranspose(rtransb);
	double
		alpha = asReal(ralpha), beta = asReal(rbeta),
		* a, * b, * c;
	int
		m, n, k,
		rowsa, colsa, lda = asInteger(rlda),
		rowsb, colsb, ldb = asInteger(rldb),
		rowsc, colsc, ldc = asInteger(rldc);	
		
	unpackMatrix(ra, &rowsa, &colsa, &a);
	unpackMatrix(rb, &rowsb, &colsb, &b);
	unpackMatrix(rc, &rowsc, &colsc, &c);
	
	m = rowsa;
	n = colsb;
	k = colsa;
	
	if(isTranspose(transa)) {
		m = colsa;
		k = rowsa;
	}
	
	if(isTranspose(transb))
		n = rowsb;
	
	cublasDgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
	checkCublasError("d_gemm");
}
gMatrixSparse gMatrixSparse::operator*(gMatrixSparse &right)
{
    assert(numCols == right.numRows);
    
    vector<elm> vect;
    
    gMatrixSparse trans = getTranspose();
    bool nempty[numRows];
    std::map<int, gMatrixSparse::gColumnSparse> rowMap;
    for (int i = 0; i < numRows; i++) {
        nempty[i] = !trans.colIsEmpty(i);
        if (nempty[i]) rowMap[i] = trans.getColumn(i);
    }
    
    for (int c = 0; c < right.numCols; c++) {
        if (right.colIsEmpty(c)) continue;
        gColumnSparse col = right.getColumn(c);
        for (int r = 0; r < numRows; r++) {
            if (nempty[r]) {
                double val = col.dot(rowMap[r]);
                vect.push_back(elm(r, c, val));
            }
        }
    }
    
    return gMatrixSparse(numRows, right.numCols, vect, true);
}
Example #3
0
File: ardblas.c Project: rforge/gcb
void d_syr2k(SEXP ruplo, SEXP rtrans, SEXP ralpha, SEXP ra, SEXP rlda,
	SEXP rb, SEXP rldb, SEXP rbeta, SEXP rc, SEXP rldc)
{
	char
		trans = getTranspose(rtrans),
		uplo = getSymLoc(ruplo);
	double
		alpha = asReal(ralpha), beta = asReal(rbeta),
		* a, * b, * c;
	int
		k,
		rowsa, colsa, lda = asInteger(rlda),
		rowsb, colsb, ldb = asInteger(rldb),
		rowsc, colsc, ldc = asInteger(rldc);	
	
	k = rowsa;
	if((trans == 'N') || (trans == 'n')) {
		k = colsa;
	}
		
	unpackMatrix(ra, &rowsa, &colsa, &a);
	unpackMatrix(rb, &rowsb, &colsb, &b);
	unpackMatrix(rc, &rowsc, &colsc, &c);
	
	cublasDsyr2k(uplo, trans, rowsc, k, alpha, a, lda, b, ldb, beta, c, ldc);
	checkCublasError("d_syr2k");
}
gMatrixSparse gMatrixSparse::getNearSymmetric()
{
    gMatrixSparse trans = getTranspose();    
    
    struct miniMapper : public dualMapper {
        vector<elm> vect;
        virtual void map(int row, int col, double valLeft, double valRight) {
            vect.push_back(elm(row, col, (valLeft + valRight) * .5));
        }
    } mapper;
    
    gMatrixSparse::dualMap(*this, trans, mapper);
    
    return gMatrixSparse(numRows, numCols, mapper.vect, true);
}
Example #5
0
File: ardblas.c Project: rforge/gcb
void d_tpsv(SEXP ruplo, SEXP rtrans, SEXP rdiag, SEXP ra, SEXP rx, SEXP rincx)
{
	char
		uplo = getSymLoc(ruplo),
		trans = getTranspose(rtrans), 
		diag = getUnitTri(rdiag);
	double
		* a, * x;
	int
		rowsa, colsa,
		nx, incx = asInteger(rincx);

	unpackVector(rx, &nx, &x);
	unpackMatrix(ra, &rowsa, &colsa, &a);

	cublasDtpsv(uplo, trans, diag, rowsa, a, x, incx);
	checkCublasError("d_tpsv");
}
Example #6
0
File: ardblas.c Project: rforge/gcb
void d_trsm(SEXP rside, SEXP ruplo, SEXP rtrans, SEXP rdiag,
	SEXP ralpha, SEXP ra, SEXP rlda, SEXP rb, SEXP rldb)
{
	char
		trans = getTranspose(rtrans),
		diag = getUnitTri(rdiag),
		side = getSide(rside),
		uplo = getSymLoc(ruplo);
	double
		alpha = asReal(ralpha),
		* a, * b;
	int
		rowsa, colsa, lda = asInteger(rlda),
		rowsb, colsb, ldb = asInteger(rldb);	
		
	unpackMatrix(ra, &rowsa, &colsa, &a);
	unpackMatrix(rb, &rowsb, &colsb, &b);
	
	cublasDtrsm(side, uplo, trans, diag, rowsb, colsb, alpha, a, lda, b, ldb);
	checkCublasError("d_trsm");
}
Example #7
0
File: ardblas.c Project: rforge/gcb
void d_gemv(SEXP rtrans, SEXP ralpha, SEXP ra, SEXP rlda, SEXP rx, SEXP rincx,
	SEXP rbeta, SEXP ry, SEXP rincy)
{
	char
		trans = getTranspose(rtrans);
	double
		alpha = asReal(ralpha), beta = asReal(rbeta),
		* a, * x, * y;
	int
		nx, ny, rowsa, colsa,
		lda = asInteger(rlda),
		incx = asInteger(rincx),
		incy = asInteger(rincy);
		
	unpackVector(rx, &nx, &x);
	unpackVector(ry, &ny, &y);
	unpackMatrix(ra, &rowsa, &colsa, &a);
	
	cublasDgemv(trans, rowsa, colsa, alpha, a, lda, x, incx, beta, y, incy);
	checkCublasError("d_gemv");
}
Example #8
0
// Fakes a midi piano keyboard using the PC keyboard
bool CSong::pcKeyPress(int key, bool down)
{
    int i;
    size_t j;
    CMidiEvent midi;
    const int cfg_pcKeyVolume = 64;
    const int cfg_pcKeyChannel = 1-1;

    if (key == 't') // the tab key on the PC fakes good notes
    {

        if (down)
            m_fakeChord = getWantedChord();
        for (i = 0; i < m_fakeChord.length(); i++)
        {
            if (down)
                midi.noteOnEvent(0, cfg_pcKeyChannel, m_fakeChord.getNote(i).pitch() + getTranspose(), cfg_pcKeyVolume);
            else
                midi.noteOffEvent(0, cfg_pcKeyChannel, m_fakeChord.getNote(i).pitch() + getTranspose(), cfg_pcKeyVolume);
            expandPianistInput(midi);
        }
        return true;
    }

    for (j = 0; j < arraySize(pcNoteLookup); j++)
    {
        if ( key==pcNoteLookup[j].key)
        {
            if (down)
                midi.noteOnEvent(0, cfg_pcKeyChannel, pcNoteLookup[j].note, cfg_pcKeyVolume);
            else
                midi.noteOffEvent(0, cfg_pcKeyChannel, pcNoteLookup[j].note, cfg_pcKeyVolume);

            expandPianistInput(midi);
            return true;
        }
    }
    //printf("pcKeyPress %d %d\n", m_pcNote, key);
    return false;
}
Example #9
0
 Matrix4& Matrix4::transpose() {
   return (*this = getTranspose());
 }
Example #10
0
 Matrix3& Matrix3::transpose() {
   return (*this = getTranspose());
 }
bool gMatrixSparse::isSymmetric()
{
    if (numRows != numCols) return false;
    
    return (getTranspose() - *this).nnz == 0;
}
Example #12
0
void Matrix3x3::transpose()
{
    (*this) = getTranspose();
}
Example #13
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *Prhs[])
{
register int i;
register double *pdbl;
mxArray **prhs=(mxArray **)&Prhs[0], *At, *Ct;
struct mexdata mdata;
int len, status;
double *p, *p0, *ret, *x;
int m, n, havejac, Arows, Crows, itmax, nopts, mintype, nextra;
double opts[LM_OPTS_SZ]={LM_INIT_MU, LM_STOP_THRESH, LM_STOP_THRESH, LM_STOP_THRESH, LM_DIFF_DELTA};
double info[LM_INFO_SZ];
double *lb=NULL, *ub=NULL, *A=NULL, *b=NULL, *wghts=NULL, *C=NULL, *d=NULL, *covar=NULL;

  /* parse input args; start by checking their number */
  if((nrhs<5))
    matlabFmtdErrMsgTxt("levmar: at least 5 input arguments required (got %d).", nrhs);
  if(nlhs>4)
    matlabFmtdErrMsgTxt("levmar: too many output arguments (max. 4, got %d).", nlhs);
  else if(nlhs<2)
    matlabFmtdErrMsgTxt("levmar: too few output arguments (min. 2, got %d).", nlhs);
    
  /* note that in order to accommodate optional args, prhs & nrhs are adjusted accordingly below */

  /** func **/
  /* first argument must be a string , i.e. a char row vector */
  if(mxIsChar(prhs[0])!=1)
    mexErrMsgTxt("levmar: first argument must be a string.");
  if(mxGetM(prhs[0])!=1)
    mexErrMsgTxt("levmar: first argument must be a string (i.e. char row vector).");
  /* store supplied name */
  len=mxGetN(prhs[0])+1;
  mdata.fname=mxCalloc(len, sizeof(char));
  status=mxGetString(prhs[0], mdata.fname, len);
  if(status!=0)
    mexErrMsgTxt("levmar: not enough space. String is truncated.");

  /** jac (optional) **/
  /* check whether second argument is a string */
  if(mxIsChar(prhs[1])==1){
    if(mxGetM(prhs[1])!=1)
      mexErrMsgTxt("levmar: second argument must be a string (i.e. row vector).");
    /* store supplied name */
    len=mxGetN(prhs[1])+1;
    mdata.jacname=mxCalloc(len, sizeof(char));
    status=mxGetString(prhs[1], mdata.jacname, len);
    if(status!=0)
      mexErrMsgTxt("levmar: not enough space. String is truncated.");
    havejac=1;

    ++prhs;
    --nrhs;
  }
  else{
    mdata.jacname=NULL;
    havejac=0;
  }

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: %s analytic Jacobian\n", havejac? "with" : "no");
#endif /* DEBUG */

/* CHECK 
if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 && mxGetN(prhs[1])==1))
*/

  /** p0 **/
  /* the second required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]) || !(mxGetM(prhs[1])==1 || mxGetN(prhs[1])==1))
    mexErrMsgTxt("levmar: p0 must be a real vector.");
  p0=mxGetPr(prhs[1]);
  /* determine if we have a row or column vector and retrieve its 
   * size, i.e. the number of parameters
   */
  if(mxGetM(prhs[1])==1){
    m=mxGetN(prhs[1]);
    mdata.isrow_p0=1;
  }
  else{
    m=mxGetM(prhs[1]);
    mdata.isrow_p0=0;
  }
  /* copy input parameter vector to avoid destroying it */
  p=mxMalloc(m*sizeof(double));
  for(i=0; i<m; ++i)
    p[i]=p0[i];
    
  /** x **/
  /* the third required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || !(mxGetM(prhs[2])==1 || mxGetN(prhs[2])==1))
    mexErrMsgTxt("levmar: x must be a real vector.");
  x=mxGetPr(prhs[2]);
  n=__MAX__(mxGetM(prhs[2]), mxGetN(prhs[2]));

  /** itmax **/
  /* the fourth required argument must be a scalar */
  if(!mxIsDouble(prhs[3]) || mxIsComplex(prhs[3]) || mxGetM(prhs[3])!=1 || mxGetN(prhs[3])!=1)
    mexErrMsgTxt("levmar: itmax must be a scalar.");
  itmax=(int)mxGetScalar(prhs[3]);
    
  /** opts **/
  /* the fifth required argument must be a real row or column vector */
  if(!mxIsDouble(prhs[4]) || mxIsComplex(prhs[4]) || (!(mxGetM(prhs[4])==1 || mxGetN(prhs[4])==1) &&
                                                      !(mxGetM(prhs[4])==0 && mxGetN(prhs[4])==0)))
    mexErrMsgTxt("levmar: opts must be a real vector.");
  pdbl=mxGetPr(prhs[4]);
  nopts=__MAX__(mxGetM(prhs[4]), mxGetN(prhs[4]));
  if(nopts!=0){ /* if opts==[], nothing needs to be done and the defaults are used */
    if(nopts>LM_OPTS_SZ)
      matlabFmtdErrMsgTxt("levmar: opts must have at most %d elements, got %d.", LM_OPTS_SZ, nopts);
    else if(nopts<((havejac)? LM_OPTS_SZ-1 : LM_OPTS_SZ))
      matlabFmtdWarnMsgTxt("levmar: only the %d first elements of opts specified, remaining set to defaults.", nopts);
    for(i=0; i<nopts; ++i)
      opts[i]=pdbl[i];
  }
#ifdef DEBUG
  else{
    fflush(stderr);
    fprintf(stderr, "LEVMAR: empty options vector, using defaults\n");
  }
#endif /* DEBUG */

  /** mintype (optional) **/
  /* check whether sixth argument is a string */
  if(nrhs>=6 && mxIsChar(prhs[5])==1 && mxGetM(prhs[5])==1){
    char *minhowto;

    /* examine supplied name */
    len=mxGetN(prhs[5])+1;
    minhowto=mxCalloc(len, sizeof(char));
    status=mxGetString(prhs[5], minhowto, len);
    if(status!=0)
      mexErrMsgTxt("levmar: not enough space. String is truncated.");

    for(i=0; minhowto[i]; ++i)
      minhowto[i]=tolower(minhowto[i]);
    if(!strncmp(minhowto, "unc", 3)) mintype=MIN_UNCONSTRAINED;
    else if(!strncmp(minhowto, "bc", 2)) mintype=MIN_CONSTRAINED_BC;
    else if(!strncmp(minhowto, "lec", 3)) mintype=MIN_CONSTRAINED_LEC;
    else if(!strncmp(minhowto, "blec", 4)) mintype=MIN_CONSTRAINED_BLEC;
    else if(!strncmp(minhowto, "bleic", 5)) mintype=MIN_CONSTRAINED_BLEIC;
    else if(!strncmp(minhowto, "blic", 4)) mintype=MIN_CONSTRAINED_BLIC;
    else if(!strncmp(minhowto, "leic", 4)) mintype=MIN_CONSTRAINED_LEIC;
    else if(!strncmp(minhowto, "lic", 3)) mintype=MIN_CONSTRAINED_BLIC;
    else matlabFmtdErrMsgTxt("levmar: unknown minimization type '%s'.", minhowto);

    mxFree(minhowto);

    ++prhs;
    --nrhs;
  }
  else
    mintype=MIN_UNCONSTRAINED;

  if(mintype==MIN_UNCONSTRAINED) goto extraargs;

  /* arguments below this point are optional and their presence depends
   * upon the minimization type determined above
   */
  /** lb, ub **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_BC || mintype==MIN_CONSTRAINED_BLEC || mintype==MIN_CONSTRAINED_BLIC || mintype==MIN_CONSTRAINED_BLEIC)){
    /* check if the next two arguments are real row or column vectors */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5])))!=m)
          matlabFmtdErrMsgTxt("levmar: lb must have %d elements, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=m)
          matlabFmtdErrMsgTxt("levmar: ub must have %d elements, got %d.", m, i);

        lb=mxGetPr(prhs[5]);
        ub=mxGetPr(prhs[6]);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /** A, b **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_LEC || mintype==MIN_CONSTRAINED_BLEC || mintype==MIN_CONSTRAINED_LEIC || mintype==MIN_CONSTRAINED_BLEIC)){
    /* check if the next two arguments are a real matrix and a real row or column vector */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && mxGetM(prhs[5])>=1 && mxGetN(prhs[5])>=1){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=mxGetN(prhs[5]))!=m)
          matlabFmtdErrMsgTxt("levmar: A must have %d columns, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=(Arows=mxGetM(prhs[5])))
          matlabFmtdErrMsgTxt("levmar: b must have %d elements, got %d.", Arows, i);

        At=prhs[5];
        b=mxGetPr(prhs[6]);
        A=getTranspose(At);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /* wghts */
  /* check if we have a weights vector */
  if(nrhs>=6 && mintype==MIN_CONSTRAINED_BLEC){ /* only check if we have seen both box & linear constraints */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && (mxGetM(prhs[5])==1 || mxGetN(prhs[5])==1)){
      if(__MAX__(mxGetM(prhs[5]), mxGetN(prhs[5]))==m){
        wghts=mxGetPr(prhs[5]);

        ++prhs;
        --nrhs;
      }
    }
  }

  /** C, d **/
  if(nrhs>=7 && (mintype==MIN_CONSTRAINED_BLEIC || mintype==MIN_CONSTRAINED_BLIC || mintype==MIN_CONSTRAINED_LEIC || mintype==MIN_CONSTRAINED_LIC)){
    /* check if the next two arguments are a real matrix and a real row or column vector */
    if(mxIsDouble(prhs[5]) && !mxIsComplex(prhs[5]) && mxGetM(prhs[5])>=1 && mxGetN(prhs[5])>=1){
      if(mxIsDouble(prhs[6]) && !mxIsComplex(prhs[6]) && (mxGetM(prhs[6])==1 || mxGetN(prhs[6])==1)){
        if((i=mxGetN(prhs[5]))!=m)
          matlabFmtdErrMsgTxt("levmar: C must have %d columns, got %d.", m, i);
        if((i=__MAX__(mxGetM(prhs[6]), mxGetN(prhs[6])))!=(Crows=mxGetM(prhs[5])))
          matlabFmtdErrMsgTxt("levmar: d must have %d elements, got %d.", Crows, i);

        Ct=prhs[5];
        d=mxGetPr(prhs[6]);
        C=getTranspose(Ct);

        prhs+=2;
        nrhs-=2;
      }
    }
  }

  /* arguments below this point are assumed to be extra arguments passed
   * to every invocation of the fitting function and its Jacobian
   */

extraargs:
  /* handle any extra args and allocate memory for
   * passing the current parameter estimate to matlab
   */
  nextra=nrhs-5;
  mdata.nrhs=nextra+1;
  mdata.rhs=(mxArray **)mxMalloc(mdata.nrhs*sizeof(mxArray *));
  for(i=0; i<nextra; ++i)
    mdata.rhs[i+1]=(mxArray *)prhs[nrhs-nextra+i]; /* discard 'const' modifier */
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: %d extra args\n", nextra);
#endif /* DEBUG */

  if(mdata.isrow_p0){ /* row vector */
    mdata.rhs[0]=mxCreateDoubleMatrix(1, m, mxREAL);
    /*
    mxSetM(mdata.rhs[0], 1);
    mxSetN(mdata.rhs[0], m);
    */
  }
  else{ /* column vector */
    mdata.rhs[0]=mxCreateDoubleMatrix(m, 1, mxREAL);
    /*
    mxSetM(mdata.rhs[0], m);
    mxSetN(mdata.rhs[0], 1);
    */
  }

  /* ensure that the supplied function & Jacobian are as expected */
  if(checkFuncAndJacobian(p, m, n, havejac, &mdata)){
    status=LM_ERROR;
    goto cleanup;
  }

  if(nlhs>3) /* covariance output required */
    covar=mxMalloc(m*m*sizeof(double));

  /* invoke levmar */
  switch(mintype){
    case MIN_UNCONSTRAINED: /* no constraints */
      if(havejac)
        status=dlevmar_der(func, jacfunc, p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_dif(func,          p, x, m, n, itmax, opts, info, NULL, covar, (void *)&mdata);
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_der()/dlevmar_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BC: /* box constraints */
      if(havejac)
        status=dlevmar_bc_der(func, jacfunc, p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bc_dif(func,          p, x, m, n, lb, ub, itmax, opts, info, NULL, covar, (void *)&mdata);
#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_bc_der()/dlevmar_bc_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LEC:  /* linear equation constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_lec_der(func, jacfunc, p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_lec_dif(func,          p, x, m, n, A, b, Arows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_lec_der()/dlevmar_lec_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLEC: /* box & linear equation constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_blec_der(func, jacfunc, p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_blec_dif(func,          p, x, m, n, lb, ub, A, b, Arows, wghts, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box & linear constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_blec_der()/dlevmar_blec_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLEIC: /* box, linear equation & inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, lb, ub, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, lb, ub, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box, linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_bleic_der()/dlevmar_bleic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_BLIC: /* box, linear inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, lb, ub, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, lb, ub, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no box & linear inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_blic_der()/dlevmar_blic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LEIC: /* linear equation & inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, NULL, NULL, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, NULL, NULL, A, b, Arows, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_leic_der()/dlevmar_leic_dif()\n");
#endif /* DEBUG */
    break;
    case MIN_CONSTRAINED_LIC: /* linear inequalities constraints */
#ifdef HAVE_LAPACK
      if(havejac)
        status=dlevmar_bleic_der(func, jacfunc, p, x, m, n, NULL, NULL, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
      else
        status=dlevmar_bleic_dif(func, p, x, m, n, NULL, NULL, NULL, NULL, 0, C, d, Crows, itmax, opts, info, NULL, covar, (void *)&mdata);
#else
      mexErrMsgTxt("levmar: no linear equation & inequality constraints support, HAVE_LAPACK was not defined during MEX-file compilation.");
#endif /* HAVE_LAPACK */

#ifdef DEBUG
  fflush(stderr);
  fprintf(stderr, "LEVMAR: calling dlevmar_lic_der()/dlevmar_lic_dif()\n");
#endif /* DEBUG */
    break;
    default:
      mexErrMsgTxt("levmar: unexpected internal error.");
  }

#ifdef DEBUG
  fflush(stderr);
  printf("LEVMAR: minimization returned %d in %g iter, reason %g\n\tSolution: ", status, info[5], info[6]);
  for(i=0; i<m; ++i)
    printf("%.7g ", p[i]);
  printf("\n\n\tMinimization info:\n\t");
  for(i=0; i<LM_INFO_SZ; ++i)
    printf("%g ", info[i]);
  printf("\n");
#endif /* DEBUG */

  /* copy back return results */
  /** ret **/
  plhs[0]=mxCreateDoubleMatrix(1, 1, mxREAL);
  ret=mxGetPr(plhs[0]);
  ret[0]=(double)status;

  /** popt **/
  plhs[1]=(mdata.isrow_p0==1)? mxCreateDoubleMatrix(1, m, mxREAL) : mxCreateDoubleMatrix(m, 1, mxREAL);
  pdbl=mxGetPr(plhs[1]);
  for(i=0; i<m; ++i)
    pdbl[i]=p[i];

  /** info **/
  if(nlhs>2){
    plhs[2]=mxCreateDoubleMatrix(1, LM_INFO_SZ, mxREAL);
    pdbl=mxGetPr(plhs[2]);
    for(i=0; i<LM_INFO_SZ; ++i)
      pdbl[i]=info[i];
  }

  /** covar **/
  if(nlhs>3){
    plhs[3]=mxCreateDoubleMatrix(m, m, mxREAL);
    pdbl=mxGetPr(plhs[3]);
    for(i=0; i<m*m; ++i) /* covariance matrices are symmetric, thus no need to transpose! */
      pdbl[i]=covar[i];
  }

cleanup:
  /* cleanup */
  mxDestroyArray(mdata.rhs[0]);
  if(A) mxFree(A);
  if(C) mxFree(C);

  mxFree(mdata.fname);
  if(havejac) mxFree(mdata.jacname);
  mxFree(p);
  mxFree(mdata.rhs);
  if(covar) mxFree(covar);

  if(status==LM_ERROR)
    mexWarnMsgTxt("levmar: optimization returned with an error!");
}
Example #14
0
//------------------------------------------------------------------------------
// getTriDiagonal
//------------------------------------------------------------------------------
bool Matrix::getTriDiagonal(Matrix* const pA) const
{
   //-------------------------------------------------------
   // initial compatibility and error checks
   //-------------------------------------------------------
   //if (!isSymmetric()) return 0;

   const int N = getRows();
   const auto pAI = new Matrix(*this);

   for (int k=0; k<N-2; k++) {
      double gama = (*pAI)(k+1,k);
      double alfa = (gama * gama);
      for (int j=k+2; j<N; j++) {
         double zeta = (*pAI)(j,k);
         alfa += (zeta * zeta);
      }

      alfa = -sign(gama) * std::sqrt(alfa);
      double beta = std::sqrt(0.5 * alfa * (alfa - gama));

      //----------------------------------------------------
      // construct column vector X
      //----------------------------------------------------
      const auto pX = new CVector(N);
      for (int p=0; p<k+1; p++) {
         (*pX)[p] = 0.0;
      }

      (*pX)[k+1] = (gama - alfa) / beta / 2.0;

      for (int q=k+2; q<N; q++) {
         (*pX)[q] = (*pAI)(q,k) / beta / 2.0;
      }

      //----------------------------------------------------
      // construct row vector Y = X'
      //----------------------------------------------------
      RVector* pY = pX->getTranspose();

      //----------------------------------------------------
      // M = 2*X*Y = 2*X*X'
      //----------------------------------------------------
      Matrix* pM = outerProduct(*pX, *pY);
      pM->multiply(2.0);

      //----------------------------------------------------
      // H = I - M = I - 2*X*X'
      //----------------------------------------------------
      const auto pH = new Matrix(N,N);
      pH->makeIdent();
      pH->subtract(*pM);

      //----------------------------------------------------
      // A = H*A*H
      //----------------------------------------------------
      Matrix* pAI0 = base::multiply(*pH, *pAI);
      Matrix* pAI1 = base::multiply(*pAI0, *pH);
      *pAI = *pAI1;

      //----------------------------------------------------
      // unref intermediate loop pointers
      //----------------------------------------------------
      pX->unref();
      pY->unref();
      pM->unref();
      pH->unref();
      pAI0->unref();
      pAI1->unref();
   }

   //-------------------------------------------------------
   // A = H(N-3)*...*H1*H0* A *H0*H1*...*H(N-3)
   //-------------------------------------------------------
   *pA = *pAI;

   //----------------------------------------------------
   // unref pointers
   //----------------------------------------------------
   pAI->unref();

   return true;
}
Example #15
0
//------------------------------------------------------------------------------
// getQR
// Returns pre-ref'd pointers to the lower QR (pQ) and upper QR (pR) matrices
// of 'this' matrix, or zero if the matrix can not be QR-ized
//------------------------------------------------------------------------------
bool Matrix::getQR(Matrix* const pQ, Matrix* const pR) const
{
   //-------------------------------------------------------
   // initial compatibility and error checks
   //-------------------------------------------------------
   bool b1 = isGoodMatrix();
   bool b2 = isSquare();
   if (!b1 || !b2) return false;

   //-------------------------------------------------------
   // Initialize intermediate R matrix to 'this' matrix
   //-------------------------------------------------------
   const auto pRI = new Matrix(*this);

   //-------------------------------------------------------
   // Initialize intermediate Q matrix to 'identity' matrix
   //-------------------------------------------------------
   const int N = getRows();
   const auto pQI = new Matrix(N,N);
   pQI->makeIdent();

   //-------------------------------------------------------
   // X and V are intermediate vectors
   //-------------------------------------------------------
   const auto pX = new CVector(N);
   const auto pV = new CVector(N);

   //-------------------------------------------------------
   // Begin loop
   //-------------------------------------------------------
   for (int k = 0; k < N-1; k++) {

      pX->fillWith(0.0);
      for (int i = k; i<N ; i++) {
         (*pX)[i] = (*pRI)(i,k);
      }

      double g = pX->getNorm();
      (*pV) = (*pX);
      (*pV)[k] += g;
      double s = pV->getNorm();

      if (s == 0.0) {
         pQI->unref();
         pRI->unref();
         pX->unref();
         pV->unref();
         return false;
      }

      CVector* pW = base::multiply((*pV), 1.0/s);
      RVector* pWT = pW->getTranspose();

      {
         //----------------------------------------------------
         // U' = (2*R'*W)'
         //----------------------------------------------------
         Matrix* pRIT = pRI->getTranspose();
         CVector* pU0 = base::multiply((*pRIT), (*pW));
         CVector* pU = base::multiply((*pU0), 2.0);
         RVector* pUT = pU->getTranspose();
         pU0->unref();
         pU->unref();
         pRIT->unref();

         //----------------------------------------------------
         // R = R - W*U'
         //----------------------------------------------------
         Matrix* pM1 = outerProduct(*pW, *pUT);
         pRI->subtract(*pM1);
         pM1->unref();
         pUT->unref();
      }

      //----------------------------------------------------
      // Q = Q - 2*Q*W*W'
      //----------------------------------------------------
      {
         Matrix* pM2 = outerProduct(*pW, *pWT);
         Matrix* pM3 = base::multiply(*pQI, *pM2);
         Matrix* pM4 = base::multiply(*pM3, 2.0);
         pQI->subtract(*pM4);
         pM2->unref();
         pM3->unref();
         pM4->unref();
      }

      //-------------------------------------------------------
      // Unref pointers
      //-------------------------------------------------------
      pW->unref();
      pWT->unref();
   }

   //-------------------------------------------------------
   // Assign results to argument list variables for output
   //-------------------------------------------------------
   *pQ = *pQI;
   *pR = *pRI;

   //-------------------------------------------------------
   // Unref pointers
   //-------------------------------------------------------
   pQI->unref();
   pRI->unref();
   pX->unref();
   pV->unref();

   return true;
}
Example #16
0
//------------------------------------------------------------------------------
// Dominant Eigenvalue Power Method
//------------------------------------------------------------------------------
bool Matrix::getEigenPower(const double maxErr, const int maxIter,
   double* const pEigenVal, CVector* const pEigenVec)
{
   //-------------------------------------------------------
   // initial compatibility and error checks
   //-------------------------------------------------------
   if (!isGoodMatrix() || !isSquare()) return false;

   //-------------------------------------------------------
   // initialize variables
   //-------------------------------------------------------
   int Iter = 0;                          // iterator initialized to zero
   double Err = 10.0*maxErr;              // make Err > maxErr on entry

   const auto pA = new Matrix(*this);     // A is a buffer matrix for 'this' matrix
   const int N = pA->getRows();           // pA->getCols works too since A is square

   double alfa = 0.0;                     // current eigenvalue estimate
   const auto pZ = new CVector(N);        // current eigenvector estimate
   pZ->fillWith(1.0);                     // all 1's in initial estimate

   //-------------------------------------------------------
   // iterate solutions to desired accuracy or iteration limit
   //-------------------------------------------------------
   while ((Err > maxErr) && (Iter < maxIter))
   {
      {
         //----------------------------------------------------
         // get estimate of eigenvector
         //----------------------------------------------------
         CVector* pW = base::multiply(*pA, *pZ);   // get new estimate (W) based on old estimate (Z)
         const double Wmag = pW->getMaxMag();      // max mag value from elements of vector W
         if (Wmag == 0.0) {
            // mag value is zero; cleanup and leave
            pW->unref();
            pZ->unref();
            pA->unref();
            return false;
         }
         pW->multiply(1.0/Wmag);           // normalize eigenvector with max element of W

         //----------------------------------------------------
         // get estimate of eigenvalue
         //----------------------------------------------------
         alfa = Wmag;                   // save Wmag eigenvalue estimate

         //----------------------------------------------------
         // refine eigenvalue estimate by using Rayleigh quotient
         // (may or may not be worth the additional calculations)
         //----------------------------------------------------
#if 0
         {
            RVector* pZT = pZ->getTranspose();
            double num = base::dotProduct(*pZT, *pW);
            double den = base::dotProduct(*pZT, *pZ);
            alfa *= (num / den);  // save Rayleigh eigenvalue estimate
            pZT->unref();
         }
#endif

         //----------------------------------------------------
         // save eigenvector W estimate in vector Z to begin next loop
         //----------------------------------------------------
         *pZ = *pW;                        // save eigenvector estimate for next iteration
         pW->unref();
      }

      //----------------------------------------------------
      // calculate error of estimate: Err = ||A*Z - alfa*Z||
      //----------------------------------------------------
      {
         CVector* pE = base::multiply(*pA, *pZ);
         CVector* pW1 = base::multiply(*pZ, alfa);  // pW1 used here as intermediate vector
         pE->subtract(*pW1);
         Err = pE->getNorm();              // magnitude of error vector
         pE->unref();
         pW1->unref();
      }

      //----------------------------------------------------
      // increment iterator for next loop
      //----------------------------------------------------
      Iter++;
   }

   //-------------------------------------------------------
   // copy eigenvalue and eigenvector results to output
   //-------------------------------------------------------
   *pEigenVal = alfa;
   *pEigenVec = *pZ;

   //-------------------------------------------------------
   // unref pointers
   //-------------------------------------------------------
   pZ->unref();
   pA->unref();

   return true;
}