Esempio n. 1
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  int m, n, nzmax, nnz;
  int i;
  double *apr, *bpr, *cpr;

  if (nrhs != 2)
    mexErrMsgTxt("Two input arguments required.");
  if (!mxIsSparse(A) || !mxIsSparse(B))
    mexErrMsgTxt("Input arguments must be sparse.");

  m = mxGetM(A);
  n = mxGetN(A);
  nzmax = mxGetNzmax(A);
  nnz = *(mxGetJc(A)+n);

  if ((mxGetM(B) != m) || (mxGetN(B) != n) || (mxGetNzmax(B) != nzmax))
    mexErrMsgTxt("Input matrices must have same sparcity structure.");

  apr = mxGetPr(A);
  bpr = mxGetPr(B);

  if ((C = mxCreateSparse(m,n,nzmax,mxREAL)) == NULL)
    mexErrMsgTxt("Could not allocate sparse matrix.");
  cpr = mxGetPr(C);

  memcpy(mxGetIr(C), mxGetIr(A), nnz*sizeof(int));
  memcpy(mxGetJc(C), mxGetJc(A), (n+1)*sizeof(int));

  for (i=0; i<nnz; i++)
    cpr[i] = apr[i]/bpr[i];

}
/*
 *	c o n t a i n s N a N o r I n f
 */
BooleanType containsNaNorInf(	const mxArray* prhs[], int_t rhs_index,
								bool mayContainInf
								)
{
	uint_t dim;
	char msg[MAX_STRING_LENGTH];

	if ( rhs_index < 0 )
		return BT_FALSE;

	/* overwrite dim for sparse matrices */
	if (mxIsSparse(prhs[rhs_index]) == 1)
		dim = (uint_t)mxGetNzmax(prhs[rhs_index]);
	else
		dim = (uint_t)(mxGetM(prhs[rhs_index]) * mxGetN(prhs[rhs_index]));

	if (containsNaN((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) {
		snprintf(msg, MAX_STRING_LENGTH,
				"ERROR (qpOASES): Argument %d contains 'NaN' !", rhs_index + 1);
		myMexErrMsgTxt(msg);
		return BT_TRUE;
	}

	if (mayContainInf == 0) {
		if (containsInf((real_t*) mxGetPr(prhs[rhs_index]), dim) == BT_TRUE) {
			snprintf(msg, MAX_STRING_LENGTH,
					"ERROR (qpOASES): Argument %d contains 'Inf' !",
					rhs_index + 1);
			myMexErrMsgTxt(msg);
			return BT_TRUE;
		}
	}

	return BT_FALSE;
}
Esempio n. 3
0
void fillMatrix(Matrix<T>& mat, const mxArray* mx, bool cp = false)
{
  //clear
  mat.clear();
  
  //get rows and columns
  size_t m = mxGetM(mx);
  size_t n = mxGetN(mx);
     
  //sparse matrix
  if (mxIsSparse(mx))
  {
    //get nz
    index_t nz = mxGetNzmax(mx);
    //set the sparse data
    mat.set((T*) mxGetPr(mx), (index_t*) mxGetJc(mx), (index_t*) mxGetIr(mx), 
            m, n, nz, cp);
  }
  //full matrix
  else
  {
    //set the data
    mat.set((T*) mxGetData(mx), m, n, cp);
//     cout << "mat.m=" << mat.m << " mat.n=" << mat.n << endl;
  }
}
Esempio n. 4
0
void
mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    int nzmax, nnz, columns;
    
    /* Check for proper number of input and output arguments */    
    if (nrhs != 1) {
	mexErrMsgTxt("One input argument required.");
    } 
    if(nlhs > 1){
	mexErrMsgTxt("Too many output arguments.");
    }
    
    if (!mxIsSparse(prhs[0]))  {
	mexErrMsgTxt("Input argument must be a sparse array.");
    } 
    nzmax = mxGetNzmax(prhs[0]);
    columns = mxGetN(prhs[0]);
    
    /* NOTE: nnz is the actual number of nonzeros and is stored as the
       last element of the jc array where the size of the jc array is the
       number of columns + 1 */
    nnz = *(mxGetJc(prhs[0]) + columns);
    
    mexPrintf("Contains %d nonzero elements.\n", nnz);
    mexPrintf("Can store up to %d nonzero elements.\n", nzmax);
}
Esempio n. 5
0
void get_matrix(const mxArray*prhs[], int i,  int** beg, int** ind, double**val)
{
  int n;     /* number of columns */
  int nnz;   /* number of non-zeros */
  int j;
  int *matbeg, *matind;
  double *matval;

  if (! mxIsSparse(prhs[i])) 
    {
      char msgbuf[1024];
      sprintf(msgbuf,"Arg %d: Expected a sparse matrix",i+1);
      AbortMsgTxt(msgbuf);
    }
  
  n      = mxGetN(prhs[i]);
  nnz    = mxGetNzmax(prhs[i]);
  *beg   = (int *)mxCalloc(n+1,sizeof(int));
  matbeg = mxGetJc(prhs[i]);
  memcpy(*beg,matbeg,(n+1)*sizeof(int));
  *ind   = (int *)mxCalloc(nnz,sizeof(int));
  matind = mxGetIr(prhs[i]);
  memcpy(*ind,matind,nnz*sizeof(int));
  
  *val   = mxCalloc(nnz,sizeof(double));
  matval = mxGetPr(prhs[i]);
  memcpy(*val,matval,nnz*sizeof(double));
}
Esempio n. 6
0
sparse_mat *mxarray_to_sparse( const mxArray *mxA, unsigned row_major )
{
  sparse_mat *A;

  if( row_major ) {
    mwSize M = mxGetM( mxA );
    mwSize N = mxGetN( mxA );
    mwSize nnz = mxGetNzmax( mxA );

    register const mwIndex *mxi = mxGetIr( mxA );
    register const mwIndex *mxj = mxGetJc( mxA );
    register const double  *mxv = mxGetPr( mxA );
    
    register int     *i;
    register int     *j;
    register double  *v;
    register int     row;
    register int     col;
    register int     idx;
  
    A = alloc_sparse_mat( M, N, nnz, row_major );
    i = A->is;
    j = A->js;
    v = A->vs;
    
    *(i++) = 0;
    for(row = 0; row < M; ++row, ++i ) {
      *i = *(i-1);
      for( mxj = mxGetJc(mxA), col = 0; col < N; ++mxj, ++col ) {
	binsearch( row, mxi, *(mxj), *(mxj+1), idx );
	if( idx >= 0 ) {
	  *(j++) = col;
	  *(v++) = mxv[idx];
	  (*i)++;
	}
      }
    }
  } else
    A = init_sparse_mat( mxGetM(mxA),  mxGetN(mxA), mxGetNzmax(mxA), 0,
			 mxGetIr(mxA), mxGetJc(mxA), mxGetPr(mxA) );

  return A;
}
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    //mex  -O 'CXXOPTIMFLAGS=-DNDEBUG -O3' -largeArrayDims SparsifyCollapsingMex.c COMPFLAGS="$COMPFLAGS -openmp" LINKFALGS="$LINKFALGS -openmp"
    mwIndex id, Nthrds, istart, iend;
    mwIndex naux = 0;
// // 
    mwIndex *R_A0 = mxGetIr(prhs[0]);
    mwIndex *starts_A0 = mxGetJc(prhs[0]);
    double  *V_A0 = mxGetPr(prhs[0]);
    //mwIndex nzmax_A0 = mxGetNzmax(prhs[0]);
    mwIndex n = mxGetN(prhs[0]);
    
    mwIndex *R_Aomega = mxGetIr(prhs[1]);
    mwIndex *starts_Aomega = mxGetJc(prhs[1]);
    double  *V_Aomega = mxGetPr(prhs[1]);
    mwIndex nzmax_Aomega = mxGetNzmax(prhs[1]);

    mwIndex *R_RP0 = mxGetIr(prhs[2]);
    mwIndex *starts_RP0 = mxGetJc(prhs[2]);
    double  *V_RP0 = mxGetPr(prhs[2]);

    mwIndex *C_R0P = mxGetIr(prhs[3]);
    mwIndex *starts_R0P = mxGetJc(prhs[3]);
    double  *V_R0P = mxGetPr(prhs[3]);
    
    
    mwIndex *C_A0_cols = mxGetIr(prhs[4]);
    mwIndex *starts_A0_cols = mxGetJc(prhs[4]);
    double  *V_A0_cols = mxGetPr(prhs[4]);
   
    mwIndex* globalDiagonal = (mwIndex*)malloc(n*sizeof(mwIndex));
    
    
    
    #pragma omp parallel private(id, Nthrds, istart, iend) num_threads(omp_get_num_procs())
    {
        //printf("%d",);
        id = omp_get_thread_num();
        Nthrds = omp_get_num_threads();
        istart = id * n / Nthrds;
        iend = (id+1) * n / Nthrds;
        if (id == Nthrds-1) iend = n;
        splitMatrices(istart, iend, R_A0, starts_A0, V_A0, R_Aomega, starts_Aomega, V_Aomega);
        #pragma omp barrier
                GenerateDiagonalGlobalIndices(0,n,R_A0,starts_A0,globalDiagonal);
        #pragma omp barrier
                Sparsify(istart,iend,naux, R_A0 , starts_A0, V_A0, R_Aomega, starts_Aomega, V_Aomega,
                R_RP0, starts_RP0, V_RP0, C_R0P, starts_R0P, V_R0P,
                C_A0_cols, starts_A0_cols, V_A0_cols,globalDiagonal);
		#pragma omp barrier
    }
    free(globalDiagonal);
}
Esempio n. 8
0
/* get a real or complex MATLAB sparse matrix and convert to cs_cl */
cs_cl *cs_cl_mex_get_sparse (cs_cl *A, int square, const mxArray *Amatlab)
{
    cs_mex_check (0, -1, -1, square, 1, 1, Amatlab) ;
    A->m = mxGetM (Amatlab) ;
    A->n = mxGetN (Amatlab) ;
    A->p = (CS_INT *) mxGetJc (Amatlab) ;
    A->i = (CS_INT *) mxGetIr (Amatlab) ;
    A->nzmax = mxGetNzmax (Amatlab) ;
    A->x = cs_cl_get_vector (A->p [A->n], A->nzmax, Amatlab) ;
    A->nz = -1 ;    /* denotes a compressed-col matrix, instead of triplet */
    return (A) ;
}
Esempio n. 9
0
/* get a MATLAB sparse matrix and convert to cs */
cs *cs_mex_get_sparse (cs *A, int square, int values, const mxArray *Amatlab)
{
    cs_mex_check (0, -1, -1, square, 1, values, Amatlab) ;
    A->m = mxGetM (Amatlab) ;
    A->n = mxGetN (Amatlab) ;
    A->p = mxGetJc (Amatlab) ;
    A->i = mxGetIr (Amatlab) ;
    A->x = values ? mxGetPr (Amatlab) : NULL ;
    A->nzmax = mxGetNzmax (Amatlab) ;
    A->nz = -1 ;    /* denotes a compressed-col matrix, instead of triplet */
    return (A) ;
}
Esempio n. 10
0
int mfiles_mx2cs(const mxArray *in, cs *out) {
    if (!out) {
        return EXIT_FAILURE;
    }
    out->m = mxGetM(in);
    out->n = mxGetN(in);
    out->nzmax = mxGetNzmax(in);
    out->nz = -1;
    out->p = (size_t *) mxGetJc(in);
    out->i = (size_t *) mxGetIr(in);
    out->x = (double *) mxGetPr(in);
    return EXIT_SUCCESS;
}
Esempio n. 11
0
void mexFunction( int nlhs, mxArray *plhs[], 
		  int nrhs, const mxArray *prhs[] )
     
{ 
    double *result; 
    double *rhs; 
    mwSize m,n, nnzmax;
    mwIndex * cols;
    mwIndex * rows;
    double * entries;
    
    /* Check for proper number of arguments */
    
    if (nrhs != 2) { 
	    mexErrMsgTxt("Two input arguments required."); 
    } else if (nlhs > 1) {
	    mexErrMsgTxt("Wrong number of output arguments."); 
    } 
    
    /* Check the dimensions of Y.  Y can be 4 X 1 or 1 X 4. */ 
    
    m = mxGetM(prhs[0]); 
    n = mxGetN(prhs[0]);
    if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) ||  !mxIsSparse(prhs[0]) ) { 
	    mexErrMsgTxt("viennacl_gmres requires a double precision real sparse matrix."); 
        return;
    } 
    if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1])) { 
	    mexErrMsgTxt("viennacl_gmres requires a double precision real right hand side vector.");
        return; 
    } 
    
    /* Create a vector for the return argument (the solution :-) ) */ 
    plhs[0] = mxCreateDoubleMatrix(MAX(m,n), 1, mxREAL); //return vector with 5 entries
    
    /* Assign pointers to the various parameters */ 
    result = mxGetPr(plhs[0]);
    
    cols    = mxGetJc(prhs[0]);
    rows    = mxGetIr(prhs[0]);
    entries = mxGetPr(prhs[0]);
    nnzmax  = mxGetNzmax(prhs[0]);
    rhs     = mxGetPr(prhs[1]);
        
    /* Do the actual computations in a subroutine */
    viennacl_gmres(result, cols, rows, entries, rhs, n, nnzmax);

    return;
    
}
Esempio n. 12
0
void mexFunction(
          int nlhs, mxArray *plhs[], 
		  int nrhs, const mxArray* prhs[] )
{
    if(!mxIsDouble(pM) || !mxIsDouble(pX))
        mexErrMsgTxt("M and X must be of type DOUBLE.");
    if(!mxIsSparse(pM))
        mexErrMsgTxt("M must be sparse.");
    if(mxGetNzmax(pM) < mxGetNumberOfElements(pX))
        mexErrMsgTxt("M must be able to contain at least as many elements as X.");
    
    memcpy(mxGetPr(pM), mxGetPr(pX), mxGetNumberOfElements(pX) * sizeof(double));
    
    return;
}
Esempio n. 13
0
void printSparse(mxArray *X) 
{
    double *Xpr = mxGetPr(X), *Xpi = mxGetPi(X);
    mwIndex *Xir = mxGetIr(X), *Xjc = mxGetJc(X);
    mwSize M = mxGetM(X), N = mxGetN(X);
    mwSize nz = Xjc[N];
    mexPrintf("X: %d-by-%d (nz = %d, nzmax = %d)\n", M, N, nz, mxGetNzmax(X));
    for (int i = 0; i != nz; ++i) {
        mexPrintf("%d: X[%d] = %.2f + %.2fi\n", i, Xir[i], Xpr[i], Xpi[i]);
    }
    mexPrintf("jc:");
    for (int i = 0; i != N + 1; ++i) {
        mexPrintf(" %d", Xjc[i]);
    }
    mexPrintf("\n\n");
}
Esempio n. 14
0
void spqr_mx_get_usage
(
    mxArray *A,         // mxArray to check
    int tight,          // if true, then nnz(A) must equal nzmax(A)
    Long *p_usage,      // bytes used
    Long *p_count,      // # of malloc'd blocks
    cholmod_common *cc
)
{
    Long nz, m, n, nzmax, is_complex, usage, count, *Ap ;
    m = mxGetM (A) ;
    n = mxGetN (A) ;
    is_complex = mxIsComplex (A) ;
    if (mxIsSparse (A))
    {
        nzmax = mxGetNzmax (A) ;
        Ap = (Long *) mxGetJc (A) ;
        nz = MAX (Ap [n], 1) ;
        if (tight && nz != nzmax)
        {
            // This should never occur.
            mexErrMsgIdAndTxt ("QR:internalError", "nnz (A) < nzmax (A)!") ;
        }
        usage = sizeof (Long) * (n+1 + nz) ;
        count = 2 ;
    }
    else
    {
        nz = MAX (m*n,1) ;
        nzmax = nz ;
        usage = 0 ;
        count = 0 ;
    }
    if (is_complex)
    {
        usage += nzmax * sizeof (double) * 2 ;
        count += 2 ;
    }
    else
    {
        usage += nzmax * sizeof (double) ;
        count += 1 ;
    }
    *p_usage = usage ;
    *p_count = count ;
}
Esempio n. 15
0
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{   
    mwIndex *irs,*jcs;
    double *si,*sr;
    int nnz, m,n;
    
    nnz = mxGetNzmax(prhs[0]);
    sr  = mxGetPr(prhs[0]);
    si  = mxGetPi(prhs[0]);
    irs = mxGetIr(prhs[0]);
    jcs = mxGetJc(prhs[0]);
    
    m  = mxGetM(prhs[0]);
    n  = mxGetN(prhs[0]);

    printSparse(m,n,nnz,sr,si,irs,jcs);
    
}
Esempio n. 16
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	mwIndex *ir, *jc;
	double *values;
	int m = (int) mxGetM(prhs[0]);
	int n = (int) mxGetN(prhs[0]);
	values = mxGetPr(prhs[0]);
	ir = mxGetIr(prhs[0]);
	jc = mxGetJc(prhs[0]);
	long nnz = (long)mxGetNzmax(prhs[0]);

	int m1 = mxGetM(prhs[1]);
	int n1 = mxGetN(prhs[1]);
	double *uvalues = mxGetPr(prhs[1]);

	int m2 = mxGetM(prhs[2]);
	int n2 = mxGetN(prhs[2]);
	double *vvalues = mxGetPr(prhs[2]);
	int k = m1;

	plhs[0] = mxCreateSparse(m, n, nnz, mxREAL);
	mwIndex *start_of_ir = mxGetIr(plhs[0]);
	memcpy(start_of_ir, ir, nnz*sizeof(mwIndex));
	mwIndex *start_of_jc = mxGetJc(plhs[0]);
	memcpy(start_of_jc, jc, (n+1)*sizeof(mwIndex));
	double *res_values = mxGetPr(plhs[0]);

	int j;
	for ( j=0 ; j<n ; j++)
	{
		double *jjnow = &(vvalues[j*k]);
		int idx;
		for ( idx = jc[j] ; idx < jc[j+1] ; idx++) 
		{
			int i = ir[idx];
			res_values[idx] = values[idx];
			int t,ii,jj;
			for ( t=0, ii = i*k, jj=j*k ; t<k ; t++, ii++, jj++ )
				res_values[idx] -= (uvalues[ii]*jjnow[t]);
		}
	}
}
Esempio n. 17
0
struct svm_model *matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
{
	int i, j, n, num_of_fields;
	double *ptr;
	int id = 0;
	struct svm_node *x_space;
	struct svm_model *model;
	mxArray **rhs;

	num_of_fields = mxGetNumberOfFields(matlab_struct);
	if(num_of_fields != NUM_OF_RETURN_FIELD)
	{
		*msg = "number of return field is not correct";
		return NULL;
	}
	rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);

	for(i=0;i<num_of_fields;i++)
		rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);

	model = Malloc(struct svm_model, 1);
	model->rho = NULL;
	model->probA = NULL;
	model->probB = NULL;
	model->label = NULL;
	model->nSV = NULL;
	model->free_sv = 1; /* XXX */

	ptr = mxGetPr(rhs[id]);
	model->param.svm_type = (int)ptr[0];
	model->param.kernel_type  = (int)ptr[1];
	model->param.degree	  = (int)ptr[2];
	model->param.gamma	  = ptr[3];
	model->param.coef0	  = ptr[4];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->nr_class = (int)ptr[0];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->l = (int)ptr[0];
	id++;

	/* rho */
	n = model->nr_class * (model->nr_class-1)/2;
	model->rho = (double*) malloc(n*sizeof(double));
	ptr = mxGetPr(rhs[id]);
	for(i=0;i<n;i++)
		model->rho[i] = ptr[i];
	id++;

	/* label */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->label = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->label[i] = (int)ptr[i];
	}
	id++;

	/* probA */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probA = (double*) malloc(n*sizeof(double));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<n;i++)
			model->probA[i] = ptr[i];
	}
	id++;

	/* probB */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probB = (double*) malloc(n*sizeof(double));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<n;i++)
			model->probB[i] = ptr[i];
	}
	id++;

	/* nSV */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->nSV = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->nSV[i] = (int)ptr[i];
	}
	id++;

	/* sv_coef */
	ptr = mxGetPr(rhs[id]);
	model->sv_coef = (double**) malloc((model->nr_class-1)*sizeof(double));
	for( i=0 ; i< model->nr_class -1 ; i++ )
		model->sv_coef[i] = (double*) malloc((model->l)*sizeof(double));
	for(i = 0; i < model->nr_class - 1; i++)
		for(j = 0; j < model->l; j++)
			model->sv_coef[i][j] = ptr[i*(model->l)+j];
	id++;

	/* SV */
	{
		int sr, sc, elements;
		int num_samples;
		mwIndex *ir, *jc;
		mxArray *pprhs[1], *pplhs[1];

		/* transpose SV */
		pprhs[0] = rhs[id];
		if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
		{
			svm_destroy_model(model);
			*msg = "cannot transpose SV matrix";
			return NULL;
		}
		rhs[id] = pplhs[0];

		sr = (int)mxGetN(rhs[id]);
		sc = (int)mxGetM(rhs[id]);

		ptr = mxGetPr(rhs[id]);
		ir = mxGetIr(rhs[id]);
		jc = mxGetJc(rhs[id]);

		num_samples = (int)mxGetNzmax(rhs[id]);

		elements = num_samples + sr;

		model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *));
		x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node));

		/* SV is in column */
		for(i=0;i<sr;i++)
		{
			int low = (int)jc[i], high = (int)jc[i+1];
			int x_index = 0;
			model->SV[i] = &x_space[low+i];
			for(j=low;j<high;j++)
			{
				model->SV[i][x_index].index = (int)ir[j] + 1;
				model->SV[i][x_index].value = ptr[j];
				x_index++;
			}
			model->SV[i][x_index].index = -1;
		}

		id++;
	}
	mxFree(rhs);

	return model;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
                 const mxArray *prhs[])
{
  double *srwp, *srdp, *srtd, *probs, *Z, *WS, *DS, *ZIN;
  double ALPHA,BETA;
  mwIndex *irwp, *jcwp, *irdp, *jcdp, *irtd, *jctd;
  int *z,*d,*w, *order, *wp, *ztot;
  int W,T,D,NN,SEED,OUTPUT, nzmax, nzmaxwp, nzmaxdp, ntokens;
  int i,j,c,n,nt,wi,di, startcond, n1,n2, TAVAIL, topic;
  
  /* Check for proper number of arguments. */
  if (nrhs < 8) {
    mexErrMsgTxt("At least 8 input arguments required");
  } else if (nlhs < 3) {
    mexErrMsgTxt("3 output arguments required");
  }
  
  startcond = 0;
  if (nrhs == 9) startcond = 1;
  
  /* process the input arguments */
  if (mxIsDouble( prhs[ 0 ] ) != 1) mexErrMsgTxt("WS input vector must be a double precision matrix");
  if (mxIsDouble( prhs[ 1 ] ) != 1) mexErrMsgTxt("DS input vector must be a double precision matrix");
  
  // pointer to word indices
  WS = mxGetPr( prhs[ 0 ] );
     
  // pointer to document indices
  DS = mxGetPr( prhs[ 1 ] );
  
  // get the number of tokens
  ntokens = (int) mxGetM( prhs[ 0 ] ) * (int) mxGetN( prhs[ 0 ] );
  
  
  if (ntokens == 0) mexErrMsgTxt("WS vector is empty"); 
  if (ntokens != ( mxGetM( prhs[ 1 ] ) * mxGetN( prhs[ 1 ] ))) mexErrMsgTxt("WS and DS vectors should have same number of entries");
  
  // Input Sparse-Tag-Document Matrix
  srtd  = mxGetPr(prhs[2]);
  irtd = mxGetIr(prhs[2]);
  jctd = mxGetJc(prhs[2]);
  nzmaxdp = (int) mxGetNzmax(prhs[2]); // number of nonzero entries in tag-document matrix
   
  NN    = (int) mxGetScalar(prhs[3]);
  if (NN<0) mexErrMsgTxt("Number of iterations must be positive");
  
  ALPHA = (double) mxGetScalar(prhs[4]);
  if (ALPHA<=0) mexErrMsgTxt("ALPHA must be greater than zero");
  
  BETA = (double) mxGetScalar(prhs[5]);
  if (BETA<=0) mexErrMsgTxt("BETA must be greater than zero");
  
  SEED = (int) mxGetScalar(prhs[6]);
  
  OUTPUT = (int) mxGetScalar(prhs[7]);
  
  if (startcond == 1) {
      ZIN = mxGetPr( prhs[ 8 ] );
      if (ntokens != ( mxGetM( prhs[ 8 ] ) * mxGetN( prhs[ 8 ] ))) mexErrMsgTxt("WS and ZIN vectors should have same number of entries");
  }
  
  // seeding
  seedMT( 1 + SEED * 2 ); // seeding only works on uneven numbers
    
  /* allocate memory */
  z  = (int *) mxCalloc( ntokens , sizeof( int ));
  
  if (startcond == 1) {
     for (i=0; i<ntokens; i++) z[ i ] = (int) ZIN[ i ] - 1;   
  }
  
  d  = (int *) mxCalloc( ntokens , sizeof( int ));
  w  = (int *) mxCalloc( ntokens , sizeof( int ));
  order  = (int *) mxCalloc( ntokens , sizeof( int ));  
  
  
  // copy over the word and document indices into internal format
  for (i=0; i<ntokens; i++) {
     w[ i ] = (int) WS[ i ] - 1;
     d[ i ] = (int) DS[ i ] - 1;
  }
  
  n = ntokens;
  
  W = 0;
  D = 0;
  for (i=0; i<n; i++) {
     if (w[ i ] > W) W = w[ i ];
     if (d[ i ] > D) D = d[ i ];
  }
  W = W + 1;
  D = D + 1;
   
  // Number of topics is based on number of tags in sparse tag-document matrix 
  T  = (int) mxGetM( prhs[ 2 ] );
  
  // check number of docs in sparse tag-document matrix
  if (D != (int) mxGetN( prhs[ 2 ])) mexErrMsgTxt("Mismatch in number of documents in DS vector TAGSET sparse matrix");
  
  ztot  = (int *) mxCalloc( T , sizeof( int ));
  probs  = (double *) mxCalloc( T , sizeof( double ));
  wp  = (int *) mxCalloc( T*W , sizeof( int ));
  

  // create sparse DP matrix that is T x D and not the other way around !!!!
  plhs[1] = mxCreateSparse( T,D,nzmaxdp,mxREAL);
  srdp  = mxGetPr(plhs[1]);
  irdp = mxGetIr(plhs[1]);
  jcdp = mxGetJc(plhs[1]);
  
  // now copy the structure from TD over to DP
  for (i=0; i<D; i++) {
     n1 = (int) *( jctd + i     );
     n2 = (int) *( jctd + i + 1 );
     
     // copy over the row-index start and end indices
     *( jcdp + i ) = (int) n1;
    
     // number of available topics for this document
     TAVAIL = (n2-n1);     
     for (j = 0; j < TAVAIL; j++) {
         topic = (int) *( irtd + n1 + j );
         *( irdp + n1 + j ) = topic;
         *( srdp + n1 + j ) = 0; // initialize DP counts with ZERO
     }        
  }
  // copy over final column indices
  n1 = (int) *( jctd + D     );
  *( jcdp + D ) = (int) n1;
  

  if (OUTPUT==2) {
      mexPrintf( "Running LDA Gibbs Sampler Version 1.0\n" );
      if (startcond==1) mexPrintf( "Starting from previous state ZIN\n" );
      mexPrintf( "Arguments:\n" );
      mexPrintf( "\tNumber of words      W = %d\n"    , W );
      mexPrintf( "\tNumber of docs       D = %d\n"    , D );
      mexPrintf( "\tNumber of tags       T = %d\n"    , T );
      mexPrintf( "\tNumber of iterations N = %d\n"    , NN );
      mexPrintf( "\tHyperparameter   ALPHA = %4.4f\n" , ALPHA );
      mexPrintf( "\tHyperparameter    BETA = %4.4f\n" , BETA );
      mexPrintf( "\tSeed number            = %d\n"    , SEED );
      mexPrintf( "\tNumber of tokens       = %d\n"    , ntokens );
      mexPrintf( "\tNumber of nonzeros in tag matrix  = %d\n"    , nzmaxdp );
  }
  
  /* run the model */
  GibbsSamplerLDA( ALPHA, BETA, W, T, D, NN, OUTPUT, n, z, d, w, wp, ztot, order, probs, startcond,
                   irtd, jctd, srdp, irdp, jcdp );
  
  /* convert the full wp matrix into a sparse matrix */
  nzmaxwp = 0;
  for (i=0; i<W; i++) {
     for (j=0; j<T; j++)
         nzmaxwp += (int) ( *( wp + j + i*T )) > 0;
  }  
  
  // MAKE THE WP SPARSE MATRIX
  plhs[0] = mxCreateSparse( W,T,nzmaxwp,mxREAL);
  srwp  = mxGetPr(plhs[0]);
  irwp = mxGetIr(plhs[0]);
  jcwp = mxGetJc(plhs[0]);  
  n = 0;
  for (j=0; j<T; j++) {
      *( jcwp + j ) = n;
      for (i=0; i<W; i++) {
         c = (int) *( wp + i*T + j );
         if (c >0) {
             *( srwp + n ) = c;
             *( irwp + n ) = i;
             n++;
         }
      }    
  }  
  *( jcwp + T ) = n;    
   
  plhs[ 2 ] = mxCreateDoubleMatrix( 1,ntokens , mxREAL );
  Z = mxGetPr( plhs[ 2 ] );
  for (i=0; i<ntokens; i++) Z[ i ] = (double) z[ i ] + 1;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{
	double *srwd, *srad, *MUZIN, *MUXIN, *theta, *phi, *thetad, *muz, *mux;
	double ALPHA,BETA;	
	int W, J, D, A, MA = 0, NN, SEED, OUTPUT, nzmaxwd, nzmaxad, i, j, a, startcond;
	mwIndex *irwd, *jcwd, *irad, *jcad;

	/* Check for proper number of arguments. */
	if (nrhs < 8) {
		mexErrMsgTxt("At least 8 input arguments required");
	} else if (nlhs < 1) {
		mexErrMsgTxt("At least 1 output arguments required");
	}

	startcond = 0;
	if (nrhs > 8) startcond = 1;

	/* dealing with sparse array WD */
	if (mxIsDouble(prhs[0]) != 1) mexErrMsgTxt("WD must be a double precision matrix");
	srwd = mxGetPr(prhs[0]);
	irwd = mxGetIr(prhs[0]);
	jcwd = mxGetJc(prhs[0]);
	nzmaxwd = (int) mxGetNzmax(prhs[0]);
	W = (int) mxGetM(prhs[0]);
	D = (int) mxGetN(prhs[0]);

	/* dealing with sparse array AD */
	if (mxIsDouble(prhs[1]) != 1) mexErrMsgTxt("AD must be a double precision matrix");
	srad = mxGetPr(prhs[1]);
	irad = mxGetIr(prhs[1]);
	jcad = mxGetJc(prhs[1]);
	nzmaxad = (int) mxGetNzmax(prhs[1]);
	A = (int) mxGetM(prhs[1]);
	if ((int) mxGetN(prhs[1]) != D) mexErrMsgTxt("WD and AD must have the same number of columns");

	/* check that every document has some authors */
	for (i=0; i<D; i++) {
		if ((jcad[i + 1] - jcad[i]) == 0) mexErrMsgTxt("there are some documents without authors in AD matrix ");
		if ((jcad[i + 1] - jcad[i]) > NAMAX) mexErrMsgTxt("Too many authors in some documents ... reached the NAMAX limit");
		if ((jcad[i + 1] - jcad[i]) > MA) MA = (int) (jcad[i + 1] - jcad[i]);
	}

	phi = mxGetPr(prhs[2]);
	J = (int) mxGetM(prhs[2]);
	if (J<=0) mexErrMsgTxt("Number of topics must be greater than zero");
	if ((int) mxGetN(prhs[2]) != W) mexErrMsgTxt("Vocabulary mismatches");

	NN = (int) mxGetScalar(prhs[3]);
	if (NN<0) mexErrMsgTxt("Number of iterations must be greater than zero");

	ALPHA = (double) mxGetScalar(prhs[4]);
	if (ALPHA<0) mexErrMsgTxt("ALPHA must be greater than zero");

	BETA = (double) mxGetScalar(prhs[5]);
	if (BETA<0) mexErrMsgTxt("BETA must be greater than zero");

	SEED = (int) mxGetScalar(prhs[6]);
	// set the seed of the random number generator

	OUTPUT = (int) mxGetScalar(prhs[7]);

	if (startcond == 1) {
		MUZIN = mxGetPr(prhs[8]);
		if (nzmaxwd != mxGetN(prhs[8])) mexErrMsgTxt("WD and MUZIN mismatch");
		if (J != mxGetM( prhs[ 8 ])) mexErrMsgTxt("J and MUZIN mismatch");
		MUXIN = mxGetPr(prhs[9]);
		if (nzmaxwd != mxGetN( prhs[9])) mexErrMsgTxt("WD and MUXIN mismatch");
		if (MA != mxGetM(prhs[9])) mexErrMsgTxt("MA and MUXIN mismatch");
	}

	// seeding
	seedMT( 1 + SEED * 2 ); // seeding only works on uneven numbers

	/* allocate memory */
	muz  = dvec(J*nzmaxwd);
	mux  = dvec(MA*nzmaxwd);

	if (startcond == 1) {
		for (i=0; i<J*nzmaxwd; i++) muz[i] = (double) MUZIN[i]; 
		for (a=0; a<MA*nzmaxwd; a++) mux[i] = (double) MUXIN[i];
	}

	theta = dvec(J*A);

	/* run the model */
	ATMBP( ALPHA, BETA, W, J, D, A, MA, NN, OUTPUT, irwd, jcwd, srwd, irad, jcad, muz, mux, phi, theta, startcond );

	/* output */
	plhs[0] = mxCreateDoubleMatrix(J, A, mxREAL);
	mxSetPr(plhs[0], theta);

	plhs[1] = mxCreateDoubleMatrix(J, nzmaxwd, mxREAL);
	mxSetPr(plhs[1], muz);

	plhs[2] = mxCreateDoubleMatrix(MA, nzmaxwd, mxREAL);
	mxSetPr(plhs[2], mux);
}
Esempio n. 20
0
int read_problem_sparse(const mxArray *label_vec, const mxArray *instance_mat)
{
	int i, j, k, low, high;
	mwIndex *ir, *jc;
	int elements, max_index, num_samples, label_vector_row_num;
	double *samples, *labels;
	mxArray *instance_mat_col; // transposed instance sparse matrix

	prob.x = NULL;
	prob.y = NULL;
	x_space = NULL;

	// transpose instance matrix
	{
		mxArray *prhs[1], *plhs[1];
		prhs[0] = mxDuplicateArray(instance_mat);
		if(mexCallMATLAB(1, plhs, 1, prhs, "transpose"))
		{
			mexPrintf("Error: cannot transpose training instance matrix\n");
			return -1;
		}
		instance_mat_col = plhs[0];
		mxDestroyArray(prhs[0]);
	}

	// each column is one instance
	labels = mxGetPr(label_vec);
	samples = mxGetPr(instance_mat_col);
	ir = mxGetIr(instance_mat_col);
	jc = mxGetJc(instance_mat_col);

	num_samples = (int)mxGetNzmax(instance_mat_col);

	// the number of instance
	prob.l = (int)mxGetN(instance_mat_col);
	label_vector_row_num = (int)mxGetM(label_vec);

	if(label_vector_row_num!=prob.l)
	{
		mexPrintf("Length of label vector does not match # of instances.\n");
		return -1;
	}

	elements = num_samples + prob.l;
	max_index = (int)mxGetM(instance_mat_col);

	prob.y = Malloc(double,prob.l);
	prob.x = Malloc(struct svm_node *,prob.l);
	x_space = Malloc(struct svm_node, elements);

	j = 0;
	for(i=0;i<prob.l;i++)
	{
		prob.x[i] = &x_space[j];
		prob.y[i] = labels[i];
		low = (int)jc[i], high = (int)jc[i+1];
		for(k=low;k<high;k++)
		{
			x_space[j].index = (int)ir[k] + 1;
			x_space[j].value = samples[k];
			j++;
	 	}
		x_space[j++].index = -1;
	}

	if(param.gamma == 0 && max_index > 0)
		param.gamma = 1.0/max_index;

	return 0;
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    double   *m_w_d, *p_w_z, *p_z_d, *p_w_d;
    mwIndex  *ir, *jc;
    size_t   d, k;
    size_t   n_w, n_d, n_z;
    mwSize   ndim = 1, dims[1];
    mwSize   nsubs = 1;
    mxArray  *temp_array;
    double   *temp;
    size_t   beg_row_id, end_row_id, cur_row_id;
    mwIndex  index, subs[1];
    mwIndex  *beg_of_ir, *beg_of_jc;
    mwSize   nzmax;
    size_t total = 0;
    
    
    if(!mxIsSparse(prhs[0]))
    {
        printf("word-doc matrix should be sparse matrix\n");
        return;
    }
    else if(nrhs != 4 || nlhs != 1)
    {
        printf("usage: p_z_wd = mex_Estep_sparse(m_w_d, p_w_z_n, p_z_d_n, p_w_d)\n");
        return;
    }
    
    m_w_d = mxGetPr(prhs[0]);
    jc = mxGetJc(prhs[0]);
    ir = mxGetIr(prhs[0]);
    nzmax = mxGetNzmax(prhs[0]);
    
    n_w = mxGetM(prhs[0]);
    n_d = mxGetN(prhs[0]);

    p_w_z = mxGetPr(prhs[1]);
    n_z = mxGetN(prhs[1]);
    
    
    
    p_z_d = mxGetPr(prhs[2]);
    
    p_w_d = mxGetPr(prhs[3]);
    
    dims[0] = n_z;
    plhs[0] = mxCreateCellArray(ndim, dims);
    //total_num_of_cells = mxGetNumberOfElements(plhs[0]);
    
    for(k = 0; k < n_z; k++)
    {
        total = 0;
        subs[0] = k;
        index = mxCalcSingleSubscript(plhs[0], nsubs, subs);
        
        temp_array = mxCreateSparse(n_w, n_d, nzmax, mxREAL);
        temp = mxGetPr(temp_array);
        mxSetNzmax(temp_array, nzmax);
        
        //Place ir data into the newly created sparse array.
        beg_of_ir = mxGetIr(temp_array);
        memcpy(beg_of_ir, ir, nzmax * sizeof(mwIndex));
        
        //Place jc data into the newly created sparse array.
        beg_of_jc = mxGetJc(temp_array);
        memcpy(beg_of_jc, jc, (n_d + 1) * sizeof(mwIndex));
        
        for (d = 0; d < n_d; d++)
        {
            beg_row_id = jc[d];
            end_row_id = jc[d + 1];
            
            if (beg_row_id == end_row_id)
                continue;
            else
            {
                for (cur_row_id = beg_row_id; cur_row_id < end_row_id; cur_row_id++)
                {
                    temp[total] = p_w_z[k * n_w + ir[cur_row_id]] * p_z_d[d * n_z + k] / p_w_d[total];
                    total++;
                }
            }
        }
        
        mxSetCell(plhs[0], index, temp_array);
    }
    return;
}
Esempio n. 22
0
void mexFunction
(
    /* === Parameters ======================================================= */

    int nlhs,			/* number of left-hand sides */
    mxArray *plhs [],		/* left-hand side matrices */
    int nrhs,			/* number of right--hand sides */
    const mxArray *prhs []	/* right-hand side matrices */
)
{
    Zmat A;
    ZAMGlevelmat *PRE;
    ZILUPACKparam *param;
    integer n;

    const char **fnames;

    const mwSize  *dims;
    mxClassID  *classIDflags;
    mxArray    *tmp, *fout, *A_input , *b_input, *x0_input, *options_input,
               *PRE_input, *options_output, *x_output;
    char       *pdata, *input_buf, *output_buf;
    mwSize     mrows, ncols, buflen, ndim,nnz;
    int        ifield, status, nfields, ierr,i,j,k,l,m;
    size_t     sizebuf;
    double     dbuf, *A_valuesR, *A_valuesI, *convert, *sr, *pr, *pi;
    doublecomplex *sol, *rhs;
    mwIndex    *irs, *jcs,
               *A_ja,                 /* row indices of input matrix A */
               *A_ia;                 /* column pointers of input matrix A */
    

    if (nrhs != 5)
       mexErrMsgTxt("five input arguments required.");
    else if (nlhs !=2)
       mexErrMsgTxt("Too many output arguments.");
    else if (!mxIsStruct(prhs[2]))
       mexErrMsgTxt("Third input must be a structure.");
    else if (!mxIsNumeric(prhs[0]))
       mexErrMsgTxt("First input must be a matrix.");

    /* The first input must be a square matrix.*/
    A_input = (mxArray *) prhs [0] ;
    /* get size of input matrix A */
    mrows = mxGetM (A_input) ;
    ncols = mxGetN (A_input) ;
    nnz = mxGetNzmax(A_input);
    if (mrows!=ncols) {
       mexErrMsgTxt("First input must be a square matrix.");
    }
    if (!mxIsSparse (A_input))
    {
        mexErrMsgTxt ("ILUPACK: input matrix must be in sparse format.") ;
    }





    /* copy input matrix to sparse row format */
    A.nc=A.nr=mrows;
    A.ia=(integer *) MAlloc((size_t)(A.nc+1)*sizeof(integer),"ZGNLSYMilupacksolver");
    A.ja=(integer *) MAlloc((size_t)nnz     *sizeof(integer),"ZGNLSYMilupacksolver");
    A. a=(doublecomplex *) MAlloc((size_t)nnz     *sizeof(doublecomplex), "ZGNLSYMilupacksolver");

    A_ja         = (mwIndex *) mxGetIr (A_input) ;
    A_ia         = (mwIndex *) mxGetJc (A_input) ;
    A_valuesR    = (double *) mxGetPr(A_input);
    if (mxIsComplex(A_input)) 
       A_valuesI = (double *) mxGetPi(A_input);

    /* -------------------------------------------------------------------- */
    /* ..  Convert matrix from 0-based C-notation to Fortran 1-based        */
    /*     notation.                                                        */
    /* -------------------------------------------------------------------- */

    /*
    for (i = 0 ; i < ncols ; i++)
      for (j = A_ia[i] ; j < A_ia[i+1] ; j++)
	printf("i=%d j=%d  A.real=%e\n", i+1,  A_ja[j]+1, A_valuesR[j]);
    */

    for (i=0; i<=A.nr; i++)
        A.ia[i]=0;
    /* remember that MATLAB uses storage by columns and NOT by rows! */
    for (i=0; i<A.nr; i++) {
	for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	    k=A_ja[j];
	    A.ia[k+1]++;
	}
    }
    /* now we know how many entries are located in every row */

    /* switch to pointer structure */
    for (i=0; i<A.nr; i++) 
        A.ia[i+1]+=A.ia[i];

    if (mxIsComplex(A_input)) {
       for (i=0; i<ncols; i++) {
	   for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	       /* row index l in C-notation */
	       l=A_ja[j];
	       /* where does row l currently start */
	       k=A.ia[l];
	       /* column index will be i in FORTRAN notation */
	       A.ja[k]=i+1;
	       A.a [k].r  =A_valuesR[j];
	       A.a [k++].i=A_valuesI[j];
	       A.ia[l]=k; 
	   }
       }
    }
    else {
       for (i=0; i<ncols; i++) {
	   for (j=A_ia[i]; j<A_ia[i+1]; j++) {
	       /* row index l in C-notation */
	       l=A_ja[j];
	       /* where does row l currently start */
	       k=A.ia[l];
	       /* column index will be i in FORTRAN notation */
	       A.ja[k]=i+1;
	       A.a [k].r  =A_valuesR[j];
	       A.a [k++].i=0;
	       A.ia[l]=k; 
	   }
       }
    }

    /* switch to FORTRAN style */
    for (i=A.nr; i>0; i--) 
        A.ia[i]=A.ia[i-1]+1;
    A.ia[0]=1;


    /*
    for (i = 0 ; i < A.nr ; i++)
      for (j = A.ia[i]-1 ; j < A.ia[i+1]-1 ; j++)
	  printf("i=%d j=%d  A.real=%e  A.imag=%e\n", i+1,  A.ja[j], A.a[j].r, A.a[j].i);
    */

    /* import pointer to the preconditioner */
    PRE_input = (mxArray*) prhs [1] ;
    /* get number of levels of input preconditioner structure `PREC' */
    /* nlev=mxGetN(PRE_input); */

    nfields = mxGetNumberOfFields(PRE_input);
    /* allocate memory  for storing pointers */
    fnames = mxCalloc((size_t)nfields, (size_t)sizeof(*fnames));
    for (ifield = 0; ifield < nfields; ifield++) {
        fnames[ifield] = mxGetFieldNameByNumber(PRE_input,ifield);
	/* check whether `PREC.ptr' exists */
	if (!strcmp("ptr",fnames[ifield])) {
	   /* field `ptr' */
	   tmp = mxGetFieldByNumber(PRE_input,0,ifield);
	   pdata = mxGetData(tmp);
	   memcpy(&PRE, pdata, (size_t)sizeof(size_t));
	}
	else if (!strcmp("param",fnames[ifield])) {
	   /* field `param' */
	   tmp = mxGetFieldByNumber(PRE_input,0,ifield);
	   pdata = mxGetData(tmp);
	   memcpy(&param, pdata, (size_t)sizeof(size_t));
	}
    }
    mxFree(fnames);

    /* rescale input matrix */
    /* obsolete
    for (i=0; i <A.nr; i++) {
	for (j=A.ia[i]-1; j<A.ia[i+1]-1; j++) {
	    A.a[j].r*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r;
	    A.a[j].i*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r;
	}
    }
    */

    /* Get third input argument `options' */
    options_input=(mxArray*)prhs[2];
    nfields = mxGetNumberOfFields(options_input);

    /* Allocate memory  for storing classIDflags */
    classIDflags = (mxClassID *) mxCalloc((size_t)nfields+1, (size_t)sizeof(mxClassID));
    
    /* allocate memory  for storing pointers */
    fnames = mxCalloc((size_t)nfields+1, (size_t)sizeof(*fnames));

    /* Get field name pointers */
    j=-1;
    for (ifield = 0; ifield < nfields; ifield++) {
        fnames[ifield] = mxGetFieldNameByNumber(options_input,ifield);
	/* check whether `options.niter' already exists */
	if (!strcmp("niter",fnames[ifield]))
	   j=ifield;
    }
    if (j==-1)
       fnames[nfields]="niter";
    /* mexPrintf("search for niter completed\n"); fflush(stdout); */


    /* import data */
    for (ifield = 0; ifield < nfields; ifield++) {
        /* mexPrintf("%2d\n",ifield+1); fflush(stdout); */
	tmp = mxGetFieldByNumber(options_input,0,ifield);
	classIDflags[ifield] = mxGetClassID(tmp); 

	ndim = mxGetNumberOfDimensions(tmp);
	dims = mxGetDimensions(tmp);

	/* Create string/numeric array */
	if (classIDflags[ifield] == mxCHAR_CLASS) {
	   /* Get the length of the input string. */
	   buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1;

	   /* Allocate memory for input and output strings. */
	   input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));

	   /* Copy the string data from tmp into a C string 
	      input_buf. */
	   status = mxGetString(tmp, input_buf, buflen);
	   
	   if (!strcmp("amg",fnames[ifield])) {
              if (strcmp(param->amg,input_buf)) {
		 param->amg=(char *)MAlloc((size_t)buflen*sizeof(char),"ilupacksolver");
		 strcpy(param->amg,input_buf);
	      }
	   }
	   else if (!strcmp("presmoother",fnames[ifield])) {
              if (strcmp(param->presmoother,input_buf)) {
		 param->presmoother=(char *)MAlloc((size_t)buflen*sizeof(char),
						   "ilupacksolver");
		 strcpy(param->presmoother,input_buf);
	      }
	   }
	   else if (!strcmp("postsmoother",fnames[ifield])) {
              if (strcmp(param->postsmoother,input_buf)) {
		 param->postsmoother=(char *)MAlloc((size_t)buflen*sizeof(char),
						    "ilupacksolver");
		 strcpy(param->postsmoother,input_buf);
	      }
	   }
	   else if (!strcmp("typecoarse",fnames[ifield])) {
              if (strcmp(param->typecoarse,input_buf)) {
		 param->typecoarse=(char *)MAlloc((size_t)buflen*sizeof(char),
						  "ilupacksolver");
		 strcpy(param->typecoarse,input_buf);
	      }
	   }
	   else if (!strcmp("typetv",fnames[ifield])) {
              if (strcmp(param->typetv,input_buf)) {
		 param->typetv=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->typetv,input_buf);
	      }
	   }
	   else if (!strcmp("FCpart",fnames[ifield])) {
              if (strcmp(param->FCpart,input_buf)) {
		 param->FCpart=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->FCpart,input_buf);
	      }
	   }
	   else if (!strcmp("solver",fnames[ifield])) {
              if (strcmp(param->solver,input_buf)) {
		 param->solver=(char *)MAlloc((size_t)buflen*sizeof(char),
					      "ilupacksolver");
		 strcpy(param->solver,input_buf);
	      }
	   }
	   else if (!strcmp("ordering",fnames[ifield])) {
              if (strcmp(param->ordering,input_buf)) {
	         param->ordering=(char *)MAlloc((size_t)buflen*sizeof(char),
						"ilupacksolver");
		 strcpy(param->ordering,input_buf);
	      }
	   }
	   else {
	      /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */
	   }
	} 
	else {
	   if (!strcmp("elbow",fnames[ifield])) {
	      param->elbow=*mxGetPr(tmp);
	   }
	   else if (!strcmp("lfilS",fnames[ifield])) {
	      param->lfilS=*mxGetPr(tmp);
	   }
	   else if (!strcmp("lfil",fnames[ifield])) {
	      param->lfil=*mxGetPr(tmp);
	   }
	   else if (!strcmp("maxit",fnames[ifield])) {
	      param->maxit=*mxGetPr(tmp);
	   }
	   else if (!strcmp("droptolS",fnames[ifield])) {
	      param->droptolS=*mxGetPr(tmp);
	   }
	   else if (!strcmp("droptolc",fnames[ifield])) {
	      param->droptolc=*mxGetPr(tmp);
	   }
	   else if (!strcmp("droptol",fnames[ifield])) {
	      param->droptol=*mxGetPr(tmp);
	   }
	   else if (!strcmp("condest",fnames[ifield])) {
	      param->condest=*mxGetPr(tmp);
	   }
	   else if (!strcmp("restol",fnames[ifield])) {
	      param->restol=*mxGetPr(tmp);
	   }
	   else if (!strcmp("npresmoothing",fnames[ifield])) {
	      param->npresmoothing=*mxGetPr(tmp);
	   }
	   else if (!strcmp("npostmoothing",fnames[ifield])) {
	      param->npostsmoothing=*mxGetPr(tmp);
	   }
	   else if (!strcmp("ncoarse",fnames[ifield])) {
	      param->ncoarse=*mxGetPr(tmp);
	   }
	   else if (!strcmp("matching",fnames[ifield])) {
	      param->matching=*mxGetPr(tmp);
	   }
	   else if (!strcmp("nrestart",fnames[ifield])) {
	      param->nrestart=*mxGetPr(tmp);
	   }
	   else if (!strcmp("damping",fnames[ifield])) {
	      param->damping.r=*mxGetPr(tmp);
	      if (mxIsComplex(tmp))
		 param->damping.i=*mxGetPi(tmp);
	      else
		 param->damping.i=0;
	   }
	   else if (!strcmp("mixedprecision",fnames[ifield])) {
	      param->mixedprecision=*mxGetPr(tmp);
	   }
	   else {
	     /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */
	   }
	}
    }


    /* copy right hand side `b' */
    b_input = (mxArray *) prhs [3] ;
    /* get size of input matrix A */
    rhs=(doublecomplex*) MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:rhs");
    pr=mxGetPr(b_input);

    if (!mxIsComplex(b_input)) {
       for (i=0; i<A.nr; i++) {
	   rhs[i].r=pr[i];
	   rhs[i].i=0;
       }
    }
    else {
       pi=mxGetPi(b_input);
       for (i=0; i<A.nr; i++) {
	   rhs[i].r=pr[i];
	   rhs[i].i=pi[i];
       }
    }




    /* copy initial solution `x0' */
    x0_input = (mxArray *) prhs [4] ;
    /* numerical solution */
    sol=(doublecomplex *)MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:sol");
    pr=mxGetPr(x0_input);
    if (!mxIsComplex(x0_input)) {
       for (i=0; i<A.nr; i++) {
	   sol[i].r=pr[i];
	   sol[i].i=0;
       }
    }
    else {
       pi=mxGetPi(x0_input);
       for (i=0; i<A.nr; i++) {
	  sol[i].r=pr[i];
	  sol[i].i=pi[i];
       }
    }



    /* set bit 2, transpose */
    param->ipar[4]|=4;
    /* set bit 3, conjugate */
    param->ipar[4]|=8;
    ierr=ZGNLSYMAMGsolver(&A, PRE, param, rhs, sol);


    
    /* Create a struct matrices for output */
    nlhs=2;
    if (j==-1)
       plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields+1, fnames);
    else
       plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields, fnames);
    if (plhs[1]==NULL)
       mexErrMsgTxt("Could not create structure mxArray\n");
    options_output=plhs[1];

    /* export data */
    for (ifield = 0; ifield<nfields; ifield++) {
	tmp = mxGetFieldByNumber(options_input,0,ifield);
	classIDflags[ifield] = mxGetClassID(tmp); 

	ndim = mxGetNumberOfDimensions(tmp);
	dims = mxGetDimensions(tmp);

	/* Create string/numeric array */
	if (classIDflags[ifield] == mxCHAR_CLASS) {
	   if (!strcmp("amg",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->amg)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->amg);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("presmoother",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->presmoother)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->presmoother);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("postsmoother",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->postsmoother)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->postsmoother);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("typecoarse",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->typecoarse)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->typecoarse);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("typetv",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->typetv)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->typetv);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("FCpart",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->FCpart)+1, (size_t)sizeof(char));
	      strcpy(output_buf,param->FCpart);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("solver",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->solver)+1, (size_t)sizeof(char));
	      strcpy(output_buf, param->solver);
	      fout = mxCreateString(output_buf);
	   }
	   else if (!strcmp("ordering",fnames[ifield])) {
	      output_buf = (char *) mxCalloc((size_t)strlen(param->ordering)+1, (size_t)sizeof(char));
	      strcpy(output_buf, param->ordering);
	      fout = mxCreateString(output_buf);
	   }
	   else {
	      /* Get the length of the input string. */
	      buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1;

	      /* Allocate memory for input and output strings. */
	      input_buf  = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));
	      output_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char));
	      
	      /* Copy the string data from tmp into a C string 
		 input_buf. */
	      status = mxGetString(tmp, input_buf, buflen);
	      
	      sizebuf = (size_t)buflen*sizeof(char);
	      memcpy(output_buf, input_buf, sizebuf);
	      fout = mxCreateString(output_buf);
	   }
	} 
	else {
	   /* real case */
	   if (mxGetPi(tmp)==NULL && strcmp("damping",fnames[ifield]))
	      fout = mxCreateNumericArray(ndim, dims, 
					  classIDflags[ifield], mxREAL);
	   else { /* complex case */
	      fout = mxCreateNumericArray(ndim, dims, 
					  classIDflags[ifield], mxCOMPLEX);
	   }
	   pdata = mxGetData(fout);

	   sizebuf = mxGetElementSize(tmp);
	   if (!strcmp("elbow",fnames[ifield])) {
	      dbuf=param->elbow;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("lfilS",fnames[ifield])) {
	      dbuf=param->lfilS;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("lfil",fnames[ifield])) {
	      dbuf=param->lfil;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("maxit",fnames[ifield])) {
	      dbuf=param->maxit;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("droptolS",fnames[ifield])) {
	      dbuf=param->droptolS;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("droptolc",fnames[ifield])) {
	      dbuf=param->droptolc;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("droptol",fnames[ifield])) {
	      dbuf=param->droptol;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("condest",fnames[ifield])) {
	      dbuf=param->condest;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("restol",fnames[ifield])) {
	      dbuf=param->restol;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("npresmoothing",fnames[ifield])) {
	      dbuf=param->npresmoothing;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("npostmoothing",fnames[ifield])) {
	      dbuf=param->npostsmoothing;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("ncoarse",fnames[ifield])) {
	      dbuf=param->ncoarse;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("matching",fnames[ifield])) {
	      dbuf=param->matching;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("nrestart",fnames[ifield])) {
	      dbuf=param->nrestart;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else if (!strcmp("damping",fnames[ifield])) {
	      pr=mxGetPr(fout);
	      pi=mxGetPi(fout);
	      *pr=param->damping.r;
	      *pi=param->damping.i;
	   }
	   else if (!strcmp("mixedprecision",fnames[ifield])) {
	      dbuf=param->mixedprecision;
	      memcpy(pdata, &dbuf, sizebuf);
	   }
	   else {
	      memcpy(pdata, mxGetData(tmp), sizebuf);
	   }
	}


	/* Set each field in output structure */
	mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout);
    }

    /* store number of iteration steps */
    if (j==-1)
       ifield=nfields;
    else
       ifield=j;
    fout=mxCreateDoubleMatrix((mwSize)1,(mwSize)1, mxREAL);
    pr=mxGetPr(fout);
    
    *pr=param->ipar[26];
    
    /* set each field in output structure */
    mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout);      

    mxFree(fnames);
    mxFree(classIDflags);
    /* mexPrintf("options exported\n"); fflush(stdout); */


    /* export approximate solution */
    plhs[0] = mxCreateDoubleMatrix((mwSize)A.nr, (mwSize)1, mxCOMPLEX);
    x_output=plhs[0];
    pr=mxGetPr(x_output);
    pi=mxGetPi(x_output);
    
    for (i=0; i<A.nr; i++) {
        pr[i]=sol[i].r;
	pi[i]=sol[i].i;
    }



    /* release right hand side */
    free(rhs);

    /* release solution */
    free(sol);

    /* release input matrix */
    free(A.ia);
    free(A.ja);
    free(A.a);
    

    switch (ierr) {
    case  0: /* perfect! */
      break;
    case -1: /* too many iteration steps */
      mexPrintf("!!! ILUPACK Warning !!!\n");
      mexPrintf("number of iteration steps exceeded its limit.\nEither increase `options.maxit'\n or recompute ILUPACK preconditioner using a smaller `options.droptol'");
      break;
    case -2: /* weird, should not occur */
      mexErrMsgTxt("not enough workspace provided.");
      plhs[0]=NULL;
      break;
    case -3: /* breakdown */
      mexErrMsgTxt("iterative solver breaks down.\nMost likely you need to recompute ILUPACK preconditioner using a smaller `options.droptol'");
      plhs[0]=NULL;
      break;
    default: /* zero pivot encountered at step number ierr */
      mexPrintf("iterative solver exited with error code %d",ierr);
      mexErrMsgTxt(".");
      plhs[0]=NULL;
      break;
    } /* end switch */
    
    return;
}
Esempio n. 23
0
/**
 * This function scales a matrix on the left of right side with a diagonal:
 *
 * anju('dscale', 'L/R', 'pathToX', 'Y/N', D, 'Y/N', 'pathToXD', 'Y/N');
 *
 * CAVEAT: Not checking the dimensions. Assuming it's right.
 */
void dscale (int numOutputs,
             mxArray** outputArray,
             int numInputs,
             const mxArray** inputArray) {
  const char* usage = "Usage\n\
anju('dscale','L/R','pathToX','Y/N',D,'Y/N','pathToXD','Y/N');\n";

  /* 0. Check that everything is right with the parameters */
  if (0 != numOutputs) {
    mexPrintf ("This function has no outputs\n%s", usage);
    return;
  } else if (8 != numInputs) {
    mexPrintf ("Incorrect number of input parameters (need 8)\n%s", usage);
    return;
  }

  /* 1. Figure out if we are applying from the left or the right */
  std::string direction = getString (inputArray[1]);
  mexPrintf ("Application direction = %s\n", direction.c_str());

  /* 2. Get the name of the file that we need */
  std::string fileNameX = getString (inputArray[2]);
  mexPrintf ("File for X = %s\n", fileNameX.c_str());

  /* 3. Get the caching information */
  std::string cacheX = getString (inputArray[3]);
  mexPrintf ("Caching X? %s\n", cacheX.c_str());

  /* 4. Write out the entries of the diagonal matrix */
  if ((false == mxIsSparse(inputArray[4])) ||
      (mxGetM(inputArray[4]) != mxGetN(inputArray[4]) ||
      (mxGetM(inputArray[4]) != mxGetNzmax(inputArray[4])))) {
    mexPrintf ("D has to be a sparse diagonal matrix\n");
    return;
  }
  std::string fileNameD = fileNameX + "-D";
  double* elementsOfD = mxGetPr(inputArray[4]);
  int numElementsInD = mxGetNzmax(inputArray[4]);
  writeMatrix (numElementsInD, 1, elementsOfD, fileNameD);
  mexPrintf ("File for D = %s\n", fileNameD.c_str());

  /* 5. Get the caching information */
  std::string cacheD = getString (inputArray[5]);
  mexPrintf ("Caching D? %s\n", cacheD.c_str());

  /* 6. Get the name of the file to output to */
  std::string fileNameXD = getString (inputArray[6]);
  mexPrintf ("File for XD = %s\n", fileNameXD.c_str());

  /* 7. Get the caching information */
  std::string cacheXD = getString (inputArray[7]);
  mexPrintf ("Caching XD? %s\n", cacheXD.c_str());

  /* 8. Combine everything into one request */
  std::string request("dscale ");
  request += direction + " ";
  request += fileNameX + " ";
  request += cacheX + " ";
  request += fileNameD + " ";
  request += cacheD + " ";
  request += fileNameXD + " ";
  request += cacheXD;

  /* 7. Send it away for multiplication */
  mexPrintf ("Request = %s\n", request.c_str());
  sendRequest (request);
}
Esempio n. 24
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, 
        const mxArray *prhs[])
{   
    /*declaration of variables*/
    /*iteration variables*/
    mwIndex i,j,k,numofnz;
    
    /*Auxillary variables*/
    double tmplij, tmpljj;
    mwIndex tmprowind;

    /*Step 2:*/
    mwSize m, n;/*m:number of rows, n:number of columns*/
    mwSize nzmax;/*nnz of input*/
    
    mwIndex rnzmax=100000000;/*rnzmax should be comparable with nzmax*/
    
    mwIndex *ajc, *air;
    double *apr;/*CSC format of prhs[0]*/

    double mu, eta1, eta2;/* mu is the shift, and eta1 is threshold*/
    double *threshold;
    
    /*Step 3: */
    mwIndex *zcolstart, *zcolend, *zrow;
    double *zval;
    mwIndex gap = 5000;
    
    /*Step 4:*/
    double pjj,pij,lambda,zji;
    double  *tmpAzj;
    
    /*Output:*/    
    mwIndex *ljc, *lir;
    double *lpr;
    /*---------------------------------------------*/
    
    /* Step 1: Check input---------*/
    if(nrhs != 4 && nrhs !=5)
    {
        mexErrMsgTxt("Four or Five Input Arguments are required");
    }
    
    if(nlhs != 1)
        mexErrMsgTxt("One Output Argument Required\n");
        
    /*Check whether prhs[] is sparse*/
    if(mxIsSparse(prhs[0]) != 1)
        mexErrMsgTxt("Input Matrix Must Be Sparse\n");
    /* ------------------------------*/
    
    
    /* Step 2: Get Input Values------------*/
    /*Read m and n from prhs[0]*/
    m = mxGetM(prhs[0]);
    n = mxGetN(prhs[0]);
    nzmax = mxGetNzmax(prhs[0]);
    
    /*CSC format of A=prhs[0]*/
    ajc = mxGetJc(prhs[0]);
    air = mxGetIr(prhs[0]);
    apr = mxGetPr(prhs[0]);
       
    
    /* Get shift*/
    mu = mxGetScalar(prhs[1]);
    
    /*Get threshold*/
    eta1 = mxGetScalar(prhs[2]);
    threshold = (double *)mxCalloc(n,sizeof(double));
    
    for(j=0;j<n;j++)
    {
        for(i=ajc[j];i<ajc[j+1];i++)threshold[j] += absval(apr[i]);
        threshold[j] = eta1 * threshold[j];
    }
    
    /*Get threshold parameter for Z*/
    eta2 = mxGetScalar(prhs[3]);
    
    /* Get allocation parameter*/
    if(nrhs == 5)
    {
        gap = (mwIndex)mxGetScalar(prhs[4]);
        if(gap > n)gap = n;
    }
    
    if(gap * m > rnzmax)rnzmax = (mwIndex)(gap*m);
    
    /*---------------------------------------*/
    

    /*Step 3: Initialization of Z and L----------    */
    zcolstart = (mwIndex *)mxCalloc(n, sizeof(mwIndex));
    zcolend = (mwIndex *)mxCalloc(n, sizeof(mwIndex));
    zrow = (mwIndex *)mxCalloc(rnzmax,sizeof(mwIndex));
    zval = (double *)mxCalloc(rnzmax,sizeof(double));
    
    if(zrow == NULL || zval == NULL){
        printf("Out of memory, please use a smaller gap value\n");
        return;
    }
    
    eyeinit(n, zcolstart, zcolend, zrow, zval, gap);/* Let Z be eye(n,n)*/
    
    /*---------------------------------------*/
    
    
    /* Step : Output    */
    plhs[0] = mxCreateSparse(n,n,rnzmax,mxREAL);
    
    ljc = mxGetJc(plhs[0]);
    lir = mxGetIr(plhs[0]);
    lpr = mxGetPr(plhs[0]);
    
    
    
    /*Step 4: Compute L*/
    
    numofnz = 0;
    
    for(j=0;j<n;j++)
    {
        
        pjj = 0;
        tmpAzj = (double *)mxCalloc(m,sizeof(double));
        matxvec(n,ajc,air,apr,zcolstart,zcolend,zrow,zval,j,tmpAzj);
        for(k=0;k<m;k++)
            if(tmpAzj[k] != 0)pjj += tmpAzj[k] * tmpAzj[k];
        if(mu != 0){
            for(i = zcolstart[j]; i <= zcolend[j]; i++)
                pjj -= mu * mu * zval[i] * zval[i];
        }
        ljc[j] = numofnz;
        lir[numofnz] = j;
        lpr[numofnz] = sqrt(absval(pjj));
        tmpljj = lpr[numofnz];
        numofnz = numofnz + 1;
        if(tmpljj < 2.2e-16 ){
            lpr[numofnz-1] = (threshold[j]>0)?threshold[j]:2.2e-16;
            continue;
        }
        for(i=j+1;i<n;i++)
        {
            pij = 0;
            for(k=ajc[i];k<ajc[i+1];k++)
            {
                tmprowind = air[k];
            	pij += apr[k] * tmpAzj[tmprowind];
            }
            zji = 0;
            for(k=zcolend[i];k>=zcolstart[i];k--)
            {
                if(zrow[k]==j)zji = zval[k];
            }
            pij -= mu * mu * zji;

            lambda = pij / pjj;
            tmplij = pij / tmpljj * signfun(pjj);
            if(absval(tmplij) > threshold[i])
            {
                lir[numofnz] = i;
                lpr[numofnz] = tmplij;
                numofnz = numofnz + 1;
                addspvecs(zcolstart,zcolend,zrow,zval,i,j,-lambda,eta2);
            }
        }
        mxFree(tmpAzj);
    }
    ljc[n] = numofnz;
}
Esempio n. 25
0
void mexFunction(int			nlhs, 		/* number of expected outputs */
				 mxArray		*plhs[],	/* mxArray output pointer array */
				 int			nrhs, 		/* number of inputs */
				 const mxArray	*prhs[]		/* mxArray input pointer array */)
{
	// input checks
	if (nrhs != 2 || !mxIsSparse(prhs[0]) || !mxIsSparse(prhs[1]))
	{
		mexErrMsgTxt ("USAGE: [flow,labels] = maxflowmex(A,T)");
	}
	const mxArray *A = prhs[0];
	const mxArray *T = prhs[1];
	if (mxIsComplex(A) || mxIsComplex(T))
	{
		mexErrMsgTxt ("Complex entries are not supported!");
	}
	// fetch its dimensions
	// actually, we must have m=n
	mwSize m = mxGetM(A);
	mwSize n = mxGetN(A);
	mwSize nzmax = mxGetNzmax(A);
	if (m != n)
	{
		mexErrMsgTxt ("Matrix A should be square!");
	}
	if (n != mxGetM(T) || mxGetN(T) != 2)
	{
		mexErrMsgTxt ("T should be of size Nx2");
	}

	// sparse matrices have a different storage convention from that of full matrices in MATLAB. 
	// The parameters pr and pi are still arrays of double-precision numbers, but these arrays 
	// contain only nonzero data elements. There are three additional parameters: nzmax, ir, and jc.
	// nzmax - is an integer that contains the length of ir, pr, and, if it exists, pi. It is the maximum 
	// possible number of nonzero elements in the sparse matrix.
	// ir - points to an integer array of length nzmax containing the row indices of the corresponding 
	// elements in pr and pi.
	// jc - points to an integer array of length n+1, where n is the number of columns in the sparse matrix. 
	// The jc array contains column index information. If the jth column of the sparse matrix has any nonzero
	// elements, jc[j] is the index in ir and pr (and pi if it exists) of the first nonzero element in the jth
	// column, and jc[j+1] - 1 is the index of the last nonzero element in that column. For the jth column of 
	// the sparse matrix, jc[j] is the total number of nonzero elements in all preceding columns. The last 
	// element of the jc array, jc[n], is equal to nnz, the number of nonzero elements in the entire sparse matrix. 
	// If nnz is less than nzmax, more nonzero entries can be inserted into the array without allocating additional 
	// storage.

	double *pr = mxGetPr(A);
	mwIndex *ir = mxGetIr(A);
	mwIndex *jc = mxGetJc(A);

	// create graph
	typedef Graph<float,float,float> GraphType;
	// estimations for number of nodes and edges - we know these exactly!
	GraphType *g = new GraphType(/*estimated # of nodes*/ n, /*estimated # of edges*/ jc[n]); 
	
	// add the nodes
	// NOTE: their indices are 0-based
    g->add_node(n);

	// traverse the adjacency matrix and add n-links
	unsigned int i, j, k;
	float v;
	for (j = 0; j < n; j++)
	{
		// this is a simple check whether there are non zero
		// entries in the j'th column
		if (jc[j] == jc[j+1])
		{
			continue; // nothing in this column
		}
		for (k = jc[j]; k <= jc[j+1]-1; k++)
		{
			i = ir[k];
			v = (float)pr[k];
			//mexPrintf("non zero entry: (%d,%d) = %.2f\n", i+1, j+1, v);
			g->add_edge(i, j, v, 0.0f);
		}
	}

	// traverse the terminal matrix and add t-links
	pr = mxGetPr(T);
	ir = mxGetIr(T);
	jc = mxGetJc(T);
	for (j = 0; j <= 1; j++)
	{
		if (jc[j] == jc[j+1])
		{
			continue;
		}
		for (k = jc[j]; k <= jc[j+1]-1; k++)
		{
			i = ir[k];
			v = (float)pr[k];

			if (j == 0) // source weight
			{
				g->add_tweights(i, v, 0.0f);
			}
			else if (j == 1) // sink weight
			{
				g->add_tweights(i, 0.0f, v);
			}
		}
	}

	plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
	double* flow = mxGetPr(plhs[0]);
	*flow = g->maxflow();

	// figure out segmentation
	plhs[1] = mxCreateNumericMatrix(n, 1, mxINT32_CLASS, mxREAL);
	int* labels = (int*)mxGetData(plhs[1]);
	for (i = 0; i < n; i++)
	{
		labels[i] = g->what_segment(i);
	}

	// cleanup
	delete g;
}
Esempio n. 26
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    /* counters */
    mwIndex c, r, nv, oc, or, vc, tc;
    mwSize m, n;
    double iv;

    /* pointers */
    mwIndex *io, *jo;
    const double *v, *i, *j;
    double *vo;

    /* input check */
    if ((nrhs != 1) &&
        (nrhs != 2) &&
        (nrhs != 5))
        mexErrMsgTxt("Requires 1, 2, or 5 input arguments.");
    if ((mxGetClassID(*prhs) != mxDOUBLE_CLASS) ||
         mxIsSparse(*prhs))
        mexErrMsgTxt("First input argument must be of type full double.");
    nv = mxGetNumberOfElements(*prhs);
    if ((nrhs == 2) &&
        ((!mxIsSparse(prhs[1])) ||
         (mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) ||
         (mxGetNzmax(prhs[1]) < nv)))
        mexErrMsgTxt("For two-argument call, second input argument must be of type sparse double with at least V values.");
    else if ((nrhs == 5) &&
        ((mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) ||
         (mxIsSparse(prhs[1])) ||
         (mxGetNumberOfElements(prhs[1]) != 1) ||
         (mxGetClassID(prhs[2]) != mxDOUBLE_CLASS) ||
         (mxIsSparse(prhs[2])) ||
         (mxGetNumberOfElements(prhs[2]) != 1) ||
         (mxGetClassID(prhs[3]) != mxDOUBLE_CLASS) ||
         (mxIsSparse(prhs[3])) ||
         (mxGetNumberOfElements(prhs[3]) != nv) ||
         (mxGetClassID(prhs[4]) != mxDOUBLE_CLASS) ||
         (mxIsSparse(prhs[4])) ||
         (mxGetNumberOfElements(prhs[4]) != nv)))
        mexErrMsgTxt("For five-argument call, arguments must be Vx1 v, 1x1 m, 1x1 n, Vx1 i, and Vx1 j.");

    /* get data */
    v = (const double *) mxGetData(*prhs);

    /* one argument only */
    if (nrhs == 1) {

        /* create output */
        *plhs = mxCreateSparse(nv, nv, nv, mxREAL);
        if (*plhs == NULL)
            mexErrMsgTxt("Error creating sparse double matrix.");
        vo = (double *) mxGetData(*plhs);
        if (vo == NULL)
            mexErrMsgTxt("Error retrieving double data pointer.");
        io = (mwIndex *) mxGetIr(*plhs);
        if (io == NULL)
            mexErrMsgTxt("Error retrieving Ir index pointer.");
        jo = (mwIndex *) mxGetJc(*plhs);
        if (jo == NULL)
            mexErrMsgTxt("Error retrieving Jc index pointer.");

        /* loop */
        for (vc = 0; vc < nv; ++vc) {
            *vo++ = *v++;
            *io++ = vc;
            *jo++ = vc;
        }
        *jo = vc;

    /* two arguments, overwrite existing sparse */
    } else if (nrhs == 2) {

        /* copy pointer */
        *plhs = (mxArray *) ((void *) prhs[1]);

        /* get data pointer */
        vo = (double *) mxGetData(*plhs);

        /* loop */
        for (vc = nv; vc > 0; --vc)
            *vo++ = *v++;

    /* five arguments, create new sparse from complex data */
    } else {

        /* get size */
        i = (const double *) mxGetData(prhs[1]);
        m = (int) *i;
        i = (const double *) mxGetData(prhs[2]);
        n = (int) *i;
        i = (const double *) mxGetData(prhs[3]);
        j = (const double *) mxGetData(prhs[4]);

        /* create sparse matrix */
        *plhs = mxCreateSparse(m, n, nv, mxREAL);
        if (*plhs == NULL)
            mexErrMsgTxt("Error creating sparse double matrix.");
        vo = (double *) mxGetData(*plhs);
        if (vo == NULL)
            mexErrMsgTxt("Error retrieving double data pointer.");
        io = (mwIndex *) mxGetIr(*plhs);
        if (io == NULL)
            mexErrMsgTxt("Error retrieving Ir index pointer.");
        jo = (mwIndex *) mxGetJc(*plhs);
        if (jo == NULL)
            mexErrMsgTxt("Error retrieving Jc index pointer.");

        /* loop */
        for (vc = nv, or = 0, oc = 0, tc = 0; vc > 0; --vc) {

            /* get target index */
            r = (mwIndex) *i++;
            c = (mwIndex) *j++;
            iv = *v++;

            /* only allow if valid */
            if ((c < oc) ||
                ((c == oc) && (r <= or)) ||
                (r < 1) ||
                (r > m) ||
                (c < 1) ||
                (c > n))
                continue;

            /* update column ? */
            while (c > oc) {
                *jo++ = tc;
                ++oc;
            }

            /* write into arrays */
            *io++ = (r - 1);
            *vo++ = iv;

            /* keep track of written values */
            or = r;
            ++tc;
        }

        /* extend column */
        while (oc <= n) {
            *jo++ = tc;
            ++oc;
        }
    }
}
Esempio n. 27
0
void mexFunction
(
    int	nargout,
    mxArray *pargout [ ],
    int	nargin,
    const mxArray *pargin [ ]
    )
{
  double dummy = 0, beta [2], *px, *C, *Ct, *C2, *fil, *Zt, *zt, done=1.0, *zz, dzero=0.0;
  cholmod_sparse Amatrix, *A, *Lsparse ;
  cholmod_factor *L ;
  cholmod_common Common, *cm ;
  Int minor, *It2, *Jt2 ;
  mwIndex l, k2, h, k, i, j, ik, *I, *J, *Jt, *It, *I2, *J2, lfi, *w, *w2, *r;
  mwSize nnz, nnzlow, m, n;
  int nz = 0;
  mwSignedIndex one=1, lfi_si;
  mxArray *Am, *Bm;
  char *uplo="L", *trans="N";
  

  /* ---------------------------------------------------------------------- */
  /* Only one input. We have to find first the Cholesky factorization.      */ 
  /* start CHOLMOD and set parameters */ 
  /* ---------------------------------------------------------------------- */

  if (nargin == 1) {
    cm = &Common ;
    cholmod_l_start (cm) ;
    sputil_config (SPUMONI, cm) ;
    
    /* convert to packed LDL' when done */
    cm->final_asis = FALSE ;
    cm->final_super = FALSE ;
    cm->final_ll = FALSE ;
    cm->final_pack = TRUE ;
    cm->final_monotonic = TRUE ;

    /* since numerically zero entries are NOT dropped from the symbolic
     * pattern, we DO need to drop entries that result from supernodal
     * amalgamation. */
    cm->final_resymbol = TRUE ;

    cm->quick_return_if_not_posdef = (nargout < 2) ;
  }

  /* This will disable the supernodal LL', which will be slow. */
  /* cm->supernodal = CHOLMOD_SIMPLICIAL ; */
  
  /* ---------------------------------------------------------------------- */
  /* get inputs */
  /* ---------------------------------------------------------------------- */
  
  if (nargin > 3)
    {
      mexErrMsgTxt ("usage: Z = sinv(A), or Z = sinv(LD, 1)") ;
    }
  
  n = mxGetM (pargin [0]) ;
  m = mxGetM (pargin [0]) ;
  
  if (!mxIsSparse (pargin [0]))
    {
      mexErrMsgTxt ("A must be sparse") ;
    }
  if (n != mxGetN (pargin [0]))
    {
      mexErrMsgTxt ("A must be square") ;
    }

  /* Only one input. We have to find first the Cholesky factorization.      */
  if (nargin == 1) {
    /* get sparse matrix A, use tril(A)  */
    A = sputil_get_sparse (pargin [0], &Amatrix, &dummy, -1) ; 
    
    A->stype = -1 ;	    /* use lower part of A */
    beta [0] = 0 ;
    beta [1] = 0 ;
    
    /* ---------------------------------------------------------------------- */
    /* analyze and factorize */
    /* ---------------------------------------------------------------------- */
    
    L = cholmod_l_analyze (A, cm) ;
    cholmod_l_factorize_p (A, beta, NULL, 0, L, cm) ;
    
    if (cm->status != CHOLMOD_OK)
      {
	mexErrMsgTxt ("matrix is not positive definite") ;
      }
    
    /* ---------------------------------------------------------------------- */
    /* convert L to a sparse matrix */
    /* ---------------------------------------------------------------------- */

    Lsparse = cholmod_l_factor_to_sparse (L, cm) ;
    if (Lsparse->xtype == CHOLMOD_COMPLEX)
      {
	mexErrMsgTxt ("matrix is complex") ;
      }
    
    /* ---------------------------------------------------------------------- */
    /* Set the sparse Cholesky factorization in Matlab format */
    /* ---------------------------------------------------------------------- */
    /*Am = sputil_put_sparse (&Lsparse, cm) ;
      I = mxGetIr(Am);
      J = mxGetJc(Am);
      C = mxGetPr(Am);
      nnz = mxGetNzmax(Am); */

    It2 = Lsparse->i;
    Jt2 = Lsparse->p;
    Ct = Lsparse->x;
    nnz = (mwSize) Lsparse->nzmax;

    Am = mxCreateSparse(m, m, nnz, mxREAL) ;
    I = mxGetIr(Am);
    J = mxGetJc(Am);
    C = mxGetPr(Am);
    for (j = 0 ;  j < n+1 ; j++)  J[j] = (mwIndex) Jt2[j];
    for ( i = 0 ; i < nnz ; i++) {
	I[i] = (mwIndex) It2[i];
	C[i] = Ct[i];
    }
    
    cholmod_l_free_sparse (&Lsparse, cm) ;

    /*FILE *out1 = fopen( "output1.txt", "w" );
    if( out1 != NULL )
      fprintf( out1, "Hello %d\n", nnz );
      fclose (out1);*/
    
  } else {
    /* The cholesky factorization is given as an input.      */
    /* We have to copy it into workspace                     */
    It = mxGetIr(pargin [0]);
    Jt = mxGetJc(pargin [0]);
    Ct = mxGetPr(pargin [0]);
    nnz = mxGetNzmax(pargin [0]);
    
    Am = mxCreateSparse(m, m, nnz, mxREAL) ;
    I = mxGetIr(Am);
    J = mxGetJc(Am);
    C = mxGetPr(Am);
    for (j = 0 ;  j < n+1 ; j++)  J[j] = Jt[j];
    for ( i = 0 ; i < nnz ; i++) {
	I[i] = It[i];
	C[i] = Ct[i];
    }    
  }

  /* Evaluate the sparse inverse */
  C[nnz-1] = 1.0/C[J[m-1]];               /* set the last element of sparse inverse */
  fil = mxCalloc((mwSize)1,sizeof(double));
  zt = mxCalloc((mwSize)1,sizeof(double));
  Zt = mxCalloc((mwSize)1,sizeof(double));
  zz = mxCalloc((mwSize)1,sizeof(double));
  for (j=m-2;j!=-1;j--){
    lfi = J[j+1]-(J[j]+1);
    
    /* if (lfi > 0) */
    if ( J[j+1] > (J[j]+1) )
      {
	/*	printf("lfi = %u \n ", lfi);
	printf("lfi*double = %u \n", (mwSize)lfi*sizeof(double));
	printf("lfi*lfi*double = %u \n", (mwSize)lfi*(mwSize)lfi*sizeof(double));
	printf("\n \n");
	*/
	
	fil = mxRealloc(fil,(mwSize)lfi*sizeof(double));
	for (i=0;i<lfi;i++) fil[i] = C[J[j]+i+1];                   /* take the j'th lower triangular column of the Cholesky */
	
	zt = mxRealloc(zt,(mwSize)lfi*sizeof(double));              /* memory for the sparse inverse elements to be evaluated */
	Zt = mxRealloc(Zt,(mwSize)lfi*(mwSize)lfi*sizeof(double));  /* memory for the needed sparse inverse elements */
	
	/* Set the lower triangular for Zt */
	k2 = 0;
	for (k=J[j]+1;k<J[j+1];k++){
	  ik = I[k];
	  h = k2;
	  for (l=J[ik];l<=J[ik+1];l++){
	    if (I[l] == I[ J[j]+h+1 ]){
	      Zt[h+lfi*k2] = C[l];
	      h++;
	    }
	  }
	  k2++;
	}
	
	
	/* evaluate zt = fil*Zt */
	lfi_si = (mwSignedIndex) lfi;
	dsymv(uplo, &lfi_si, &done, Zt, &lfi_si, fil, &one, &dzero, zt, &one);
	
	/* Set the evaluated sparse inverse elements, zt, into C */
	k=lfi-1;
	for (i = J[j+1]-1; i!=J[j] ; i--){
	  C[i] = -zt[k];
	  k--;
	}
	/* evaluate the j'th diagonal of sparse inverse */
	dgemv(trans, &one, &lfi_si, &done, fil, &one, zt, &one, &dzero, zz, &one); 
	C[J[j]] = 1.0/C[J[j]] + zz[0];
      }
    else
      {
	/* evaluate the j'th diagonal of sparse inverse */
	C[J[j]] = 1.0/C[J[j]];	
      }
  }
    
  /* Free the temporary variables */
  mxFree(fil);
  mxFree(zt);
  mxFree(Zt);
  mxFree(zz);

  /* ---------------------------------------------------------------------- */
  /* Permute the elements according to r(q) = 1:n                           */
  /* Done only if the Cholesky was evaluated here                           */
  /* ---------------------------------------------------------------------- */
  if (nargin == 1) {
   
    Bm = mxCreateSparse(m, m, nnz, mxREAL) ;     
    It = mxGetIr(Bm);
    Jt = mxGetJc(Bm);
    Ct = mxGetPr(Bm);                            /* Ct = C(r,r) */ 
    
    r = (mwIndex *) L->Perm;                         /* fill reducing ordering */
    w = mxCalloc(m,sizeof(mwIndex));                 /* column counts of Am */
    
    /* count entries in each column of Bm */
    for (j=0; j<m; j++){
      k = r ? r[j] : j ;       /* column j of Bm is column k of Am */
      for (l=J[j] ; l<J[j+1] ; l++){
	i = I[l];
	ik = r ? r[i] : i ;    /* row i of Bm is row ik of Am */
	w[ max(ik,k) ]++;
      }
    }
    cumsum2(Jt, w, m);
    for (j=0; j<m; j++){
      k = r ? r[j] : j ;             /* column j of Bm is column k of Am */
      for (l=J[j] ; l<J[j+1] ; l++){
	i= I[l];
	ik = r ? r[i] : i ;          /* row i of Bm is row ik of Am */
	It [k2 = w[max(ik,k)]++ ] = min(ik,k);
	Ct[k2] = C[l];
      }
    }
    mxFree(w);
    
    /* ---------------------------------------------------------------------- */
    /* Transpose the permuted (upper triangular) matrix Bm into Am */
    /* (this way we get sorted columns)                            */
    /* ---------------------------------------------------------------------- */
    w = mxCalloc(m,sizeof(mwIndex));                 
    for (i=0 ; i<Jt[m] ; i++) w[It[i]]++;        /* row counts of Bm */
    cumsum2(J, w, m);                            /* row pointers */
    for (j=0 ; j<m ; j++){
      for (i=Jt[j] ; i<Jt[j+1] ; i++){
	I[ l=w[ It[i] ]++ ] = j;
	C[l] = Ct[i];
      }
    }
    mxFree(w);
    mxDestroyArray(Bm);
  }
  
  /* ---------------------------------------------------------------------- */
  /* Fill the upper triangle of the sparse inverse */
  /* ---------------------------------------------------------------------- */
  
  w = mxCalloc(m,sizeof(mwIndex));        /* workspace */
  w2 = mxCalloc(m,sizeof(mwIndex));       /* workspace */
  for (k=0;k<J[m];k++) w[I[k]]++;     /* row counts of the lower triangular */
  for (k=0;k<m;k++) w2[k] = w[k] + J[k+1] - J[k] - 1;   /* column counts of the sparse inverse */
  
  nnz = (mwSize)2*nnz - m;                       /* The number of nonzeros in Z */
  pargout[0] = mxCreateSparse(m,m,nnz,mxREAL);   /* The sparse matrix */
  It = mxGetIr(pargout[0]);
  Jt = mxGetJc(pargout[0]);
  Ct = mxGetPr(pargout[0]);
  
  cumsum2(Jt, w2, m);               /* column starting points */
  for (j = 0 ; j < m ; j++){           /* fill the upper triangular */
    for (k = J[j] ; k < J[j+1] ; k++){
      It[l = w2[ I[k]]++] = j ;	 /* place C(i,j) as entry Ct(j,i) */
      if (Ct) Ct[l] = C[k] ;
    }
  }
  for (j = 0 ; j < m ; j++){           /* fill the lower triangular */
    for (k = J[j]+1 ; k < J[j+1] ; k++){
      It[l = w2[j]++] = I[k] ;         /* place C(j,i) as entry Ct(j,i) */
      if (Ct) Ct[l] = C[k] ;
    }
  }
  
  mxFree(w2);
  mxFree(w);
  
  /* ---------------------------------------------------------------------- */
  /* return to MATLAB */
  /* ---------------------------------------------------------------------- */
  
  /* ---------------------------------------------------------------------- */
  /* free workspace and the CHOLMOD L, except for what is copied to MATLAB */
  /* ---------------------------------------------------------------------- */
  if (nargin == 1) {
    cholmod_l_free_factor (&L, cm) ;
    cholmod_l_finish (cm) ;
    cholmod_l_print_common (" ", cm) ;
  }
  mxDestroyArray(Am);
  
}
Esempio n. 28
0
const char *matlab_matrix_to_model(struct svm_model *model, const mxArray *matlab_struct)
{
	int i, j, n, num_of_fields;
	double *ptr;
	int id = 0;
	struct svm_node *x_space;
	mxArray **rhs;

	num_of_fields = mxGetNumberOfFields(matlab_struct);
	rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);

	for(i=0;i<num_of_fields;i++)
		rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);

	model->rho = NULL;
	model->probA = NULL;
	model->probB = NULL;
	model->label = NULL;
	model->nSV = NULL;
	model->free_sv = 1; // XXX

	ptr = mxGetPr(rhs[id]);
	model->param.svm_type	  = (int)ptr[0];
	model->param.kernel_type  = (int)ptr[1];
	model->param.degree	  = (int)ptr[2];
	model->param.gamma	  = ptr[3];
	model->param.coef0	  = ptr[4];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->nr_class = (int)ptr[0];
	id++;

	ptr = mxGetPr(rhs[id]);
	model->l = (int)ptr[0];
	id++;

	// rho
	n = model->nr_class * (model->nr_class-1)/2;
	model->rho = (double*) malloc(n*sizeof(double));
	ptr = mxGetPr(rhs[id]);
	for(i=0;i<n;i++)
		model->rho[i] = ptr[i];
	id++;

	// label
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->label = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->label[i] = (int)ptr[i];
	}
	id++;

	// probA, probB
	if(mxIsEmpty(rhs[id]) == 0 &&
	   mxIsEmpty(rhs[id+1]) == 0)
	{
		model->probA = (double*) malloc(n*sizeof(double));
		model->probB = (double*) malloc(n*sizeof(double));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<n;i++)
			model->probA[i] = ptr[i];
		ptr = mxGetPr(rhs[id+1]);
		for(i=0;i<n;i++)
			model->probB[i] = ptr[i];
	}
	id += 2;

	// nSV
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->nSV = (int*) malloc(model->nr_class*sizeof(int));
		ptr = mxGetPr(rhs[id]);
		for(i=0;i<model->nr_class;i++)
			model->nSV[i] = (int)ptr[i];
	}
	id++;

	// sv_coef
	ptr = mxGetPr(rhs[id]);
	model->sv_coef = (double**) malloc((model->nr_class-1)*sizeof(double));
	for( i=0 ; i< model->nr_class -1 ; i++ )
		model->sv_coef[i] = (double*) malloc((model->l)*sizeof(double));
	for(i = 0; i < model->nr_class - 1; i++)
		for(j = 0; j < model->l; j++)
			model->sv_coef[i][j] = ptr[i*(model->l)+j];
	id++;

	// SV
	{
		int sr, sc, elements;
		int num_samples;
		mwIndex *ir, *jc;
		mxArray *pprhs[1], *pplhs[1];

		// transpose SV
		pprhs[0] = rhs[id];
		if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
			return "cannot transpose SV matrix";
		rhs[id] = pplhs[0];

		sr = mxGetN(rhs[id]);
		sc = mxGetM(rhs[id]);

		ptr = mxGetPr(rhs[id]);
		ir = mxGetIr(rhs[id]);
		jc = mxGetJc(rhs[id]);

		num_samples = mxGetNzmax(rhs[id]);

		elements = num_samples + sr;

		model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *));
		x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node));

		// SV is in column
		for(i=0;i<sr;i++)
		{
			int low = jc[i], high = jc[i+1];
			int x_index = 0;
			model->SV[i] = &x_space[low+i];
			for(j=low;j<high;j++)
			{
				model->SV[i][x_index].index = ir[j] + 1; 
				model->SV[i][x_index].value = ptr[j];
				x_index++;
			}
			model->SV[i][x_index].index = -1;
		}

		id++;
	}
	mxFree(rhs);

	return NULL;
}
Esempio n. 29
0
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] )
{
  double C, TolRel, TolAbs, QPBound, trn_err, MaxTime;
  double *vec_C;   
  double *ptr;
  uint32_t num_of_Cs;
  uint32_t i, j, BufSize;
  uint16_t Method;
  int verb;
  ocas_return_value_T ocas;

  /* timing variables */
  double init_time;
  double total_time;

  total_time = get_time();
  init_time = total_time;

  if(nrhs < 1)
    mexErrMsgTxt("Improper number of input arguments.");

  /* get input arguments */ 
  if(mxIsChar(prhs[0]) == false) 
  {
    /* [W,W0,stat] = svmocas_mex(X,X0,y,C,Method,TolRel,TolAbs,QPBound,BufSize,nData,MaxTime); */

    if(nrhs < 4 || nrhs > 12)
      mexErrMsgTxt("Improper number of input arguments.");

    if(nrhs >= 12)
      verb = (int)mxGetScalar(prhs[11]);
    else
      verb = DEFAULT_VERB;


    data_X = (mxArray*)prhs[0];
    if (!(mxIsDouble(data_X)))
        mexErrMsgTxt("Input argument X must be of type double.");

    if (mxGetNumberOfDimensions(data_X) != 2)
        mexErrMsgTxt("Input argument X must be two dimensional");

    X0 = mxGetScalar(prhs[1]);
    data_y = (double*)mxGetPr(prhs[2]);

    if(LIBOCAS_MAX(mxGetM(prhs[2]),mxGetN(prhs[2])) != mxGetN(prhs[0]))
      mexErrMsgTxt("Length of vector y must equl to the number of columns of matrix X.");

    nDim = mxGetM(prhs[0]);

    if(verb)
    {
      mexPrintf("Input data statistics:\n"
                "   # of examples  : %d\n"
                "   dimensionality : %d\n",
                mxGetN(data_X), nDim);
    
      if( mxIsSparse(data_X)== true ) 
        mexPrintf("   density        : %.2f%%\n",
                  100.0*(double)mxGetNzmax(data_X)/((double)nDim*(double)(mxGetN(data_X))));
      else
        mexPrintf("   density        : 100%% (full)\n");
    }


    num_of_Cs = LIBOCAS_MAX(mxGetN(prhs[3]),mxGetM(prhs[3]));
    if(num_of_Cs == 1)
    {
       C = (double)mxGetScalar(prhs[3]);
    }
    else
    {
       vec_C = (double*)mxGetPr(prhs[3]);
    }

    if(nrhs >= 5)
      Method = (uint32_t)mxGetScalar(prhs[4]);
    else
      Method = DEFAULT_METHOD;

    if(nrhs >= 6)
      TolRel = (double)mxGetScalar(prhs[5]);
    else
      TolRel = DEFAULT_TOLREL;

    if(nrhs >= 7)    
      TolAbs = (double)mxGetScalar(prhs[6]);
    else
      TolAbs = DEFAULT_TOLABS;

    if(nrhs >= 8)
      QPBound = (double)mxGetScalar(prhs[7]);
    else
      QPBound = DEFAULT_QPVALUE;

    if(nrhs >= 9)
      BufSize = (uint32_t)mxGetScalar(prhs[8]);
    else
      BufSize = DEFAULT_BUFSIZE;

    if(nrhs >= 10 && mxIsInf(mxGetScalar(prhs[9])) == false)
      nData = (uint32_t)mxGetScalar(prhs[9]);
    else
      nData = mxGetN(data_X);
      
    if(nData < 1 || nData > mxGetN(prhs[0])) 
      mexErrMsgTxt("Improper value of argument nData.");

    if(num_of_Cs > 1 && num_of_Cs < nData)
      mexErrMsgTxt("Length of the vector C less than the number of examples.");

    if(nrhs >= 11)
      MaxTime = (double)mxGetScalar(prhs[10]);
    else
      MaxTime = DEFAULT_MAXTIME;
  } 
  else
  {
    /* [W,W0,stat] = svmocas_mex(svmlight_data_file,X0,C,Method,TolRel,TolAbs,QPBound,BufSize,nData,MaxTime); */
    char *fname;
    int fname_len;

    if(nrhs < 3 || nrhs > 11)
      mexErrMsgTxt("Improper number of input arguments.");

    if(nrhs >= 11)
      verb = (int)mxGetScalar(prhs[10]);
    else
      verb = DEFAULT_VERB;

    if(!mxIsChar(prhs[0]))
      mexErrMsgTxt("First input argument must be of type string.");

    fname_len = mxGetNumberOfElements(prhs[0]) + 1;   
    fname = mxCalloc(fname_len, sizeof(char));    

    if (mxGetString(prhs[0], fname, fname_len) != 0)     
      mexErrMsgTxt("Could not convert first input argument to string.");

    if( load_svmlight_file(fname,verb) == -1 || data_X == NULL || data_y == NULL)
      mexErrMsgTxt("Cannot load input file.");

    nDim = mxGetM(data_X);
    X0 = mxGetScalar(prhs[1]);

/*    C = (double)mxGetScalar(prhs[2]);*/
    num_of_Cs = LIBOCAS_MAX(mxGetN(prhs[2]),mxGetM(prhs[2]));
    if(num_of_Cs == 1)
    {
       C = (double)mxGetScalar(prhs[2]);
    }
    else
    {
       vec_C = (double*)mxGetPr(prhs[2]);
    }

    if(verb)
      mexPrintf("Input data statistics:\n"
                "   # of examples  : %d\n"
                "   dimensionality : %d\n"
                "   density        : %.2f%%\n",
                mxGetN(data_X), nDim, 100.0*(double)mxGetNzmax(data_X)/((double)nDim*(double)(mxGetN(data_X))));
    
    if(nrhs >= 4)
      Method = (uint32_t)mxGetScalar(prhs[3]);
    else
      Method = DEFAULT_METHOD;

    if(nrhs >= 5)
      TolRel = (double)mxGetScalar(prhs[4]);
    else
      TolRel = DEFAULT_TOLREL;

    if(nrhs >= 6)
      TolAbs = (double)mxGetScalar(prhs[5]);
    else
      TolAbs = DEFAULT_TOLABS;

    if(nrhs >= 7)
      QPBound = (double)mxGetScalar(prhs[6]);
    else
      QPBound = DEFAULT_QPVALUE;

    if(nrhs >= 8)    
      BufSize = (uint32_t)mxGetScalar(prhs[7]);
    else
      BufSize = DEFAULT_BUFSIZE;

    if(nrhs >= 9 && mxIsInf(mxGetScalar(prhs[8])) == false) 
      nData = (uint32_t)mxGetScalar(prhs[8]);
    else
      nData = mxGetN(data_X);

    if(nData < 1 || nData > mxGetN(data_X)) 
      mexErrMsgTxt("Improper value of argument nData.");

    if(num_of_Cs > 1 && num_of_Cs < nData)
      mexErrMsgTxt("Length of the vector C less than the number of examples.");

    if(nrhs >= 10)
      MaxTime = (double)mxGetScalar(prhs[9]);
    else
      MaxTime = DEFAULT_MAXTIME;

  } 


  /*----------------------------------------------------------------
    Print setting
  -------------------------------------------------------------------*/
  if(verb)
  {
    mexPrintf("Setting:\n");

    if( num_of_Cs == 1)
      mexPrintf("   C              : %f\n", C);
    else
      mexPrintf("   C              : different for each example\n");

    mexPrintf("   bias           : %.0f\n"
              "   # of examples  : %d\n"
              "   solver         : %d\n"
              "   cache size     : %d\n"
              "   TolAbs         : %f\n"
              "   TolRel         : %f\n"
              "   QPValue        : %f\n"
              "   MaxTime        : %f [s]\n"
              "   verb           : %d\n",
              X0, nData, Method,BufSize,TolAbs,TolRel, QPBound, MaxTime, verb);
  }
  
  /* learned weight vector */
  plhs[0] = (mxArray*)mxCreateDoubleMatrix(nDim,1,mxREAL);
  W = (double*)mxGetPr(plhs[0]);
  if(W == NULL) mexErrMsgTxt("Not enough memory for vector W.");

  oldW = (double*)mxCalloc(nDim,sizeof(double));
  if(oldW == NULL) mexErrMsgTxt("Not enough memory for vector oldW.");

  W0 = 0;
  oldW0 = 0;

  A0 = mxCalloc(BufSize,sizeof(A0[0]));
  if(A0 == NULL) mexErrMsgTxt("Not enough memory for vector A0.");

  /* allocate buffer for computing cutting plane */
  new_a = (double*)mxCalloc(nDim,sizeof(double));
  if(new_a == NULL) 
    mexErrMsgTxt("Not enough memory for auxciliary cutting plane buffer new_a.");  


  if(num_of_Cs > 1)
  {
    for(i=0; i < nData; i++) 
      data_y[i] = data_y[i]*vec_C[i];
  }


  if( mxIsSparse(data_X)== true ) {

    /* for i=1:nData, X(:,i) = X(:,i)*y(i); end*/
    for(i=0; i < nData; i++) 
        mul_sparse_col(data_y[i], data_X, i);           
  

    /* init cutting plane buffer */
    sparse_A.nz_dims = mxCalloc(BufSize,sizeof(uint32_t));
    sparse_A.index = mxCalloc(BufSize,sizeof(sparse_A.index[0]));
    sparse_A.value = mxCalloc(BufSize,sizeof(sparse_A.value[0]));
    if(sparse_A.nz_dims == NULL || sparse_A.index == NULL || sparse_A.value == NULL) 
      mexErrMsgTxt("Not enough memory for cutting plane buffer sparse_A.");  

    init_time=get_time()-init_time;

    if(verb)
    {
      mexPrintf("Starting optimization:\n");

      if(num_of_Cs == 1)
      {
        ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                              &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, 
                              &sparse_compute_output, &qsort_data, &ocas_print, 0);
      }  
      else
      {
        ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                                     &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, 
                                     &sparse_compute_output, &qsort_data, &ocas_print, 0);
      }  

    }
    else
    {
      if(num_of_Cs == 1)
      {
        ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                              &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, 
                              &sparse_compute_output, &qsort_data, &ocas_print_null, 0);
      }
      else
      {
        ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                              &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, 
                              &sparse_compute_output, &qsort_data, &ocas_print_null, 0);
      }
    }

  }
  else
  {

    ptr = mxGetPr(data_X);
    for(i=0; i < nData; i++) {
      for(j=0; j < nDim; j++ ) {
        ptr[LIBOCAS_INDEX(j,i,nDim)] = ptr[LIBOCAS_INDEX(j,i,nDim)]*data_y[i];
      }
    }

    /* init cutting plane buffer */
    full_A = mxCalloc(BufSize*nDim,sizeof(double));
    if( full_A == NULL )
      mexErrMsgTxt("Not enough memory for cutting plane buffer full_A.");    

    init_time=get_time()-init_time;

    if(verb)
    {
      mexPrintf("Starting optimization:\n");
    
      if(num_of_Cs == 1)
        ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                                &full_compute_W, &full_update_W, &full_add_new_cut, 
                                &full_compute_output, &qsort_data, &ocas_print, 0);
      else
        ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                                &full_compute_W, &full_update_W, &full_add_new_cut, 
                                &full_compute_output, &qsort_data, &ocas_print, 0);

    }
    else
    {
      if(num_of_Cs == 1)
        ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                                &full_compute_W, &full_update_W, &full_add_new_cut, 
                                &full_compute_output, &qsort_data, &ocas_print_null, 0);
      else
        ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, 
                                     &full_compute_W, &full_update_W, &full_add_new_cut, 
                                     &full_compute_output, &qsort_data, &ocas_print_null, 0);
    }
  }

  if(verb)
  {
    mexPrintf("Stopping condition: ");
    switch( ocas.exitflag )
    {
       case 1: mexPrintf("1-Q_D/Q_P <= TolRel(=%f) satisfied.\n", TolRel); break;
       case 2: mexPrintf("Q_P-Q_D <= TolAbs(=%f) satisfied.\n", TolAbs); break;
       case 3: mexPrintf("Q_P <= QPBound(=%f) satisfied.\n", QPBound); break;
       case 4: mexPrintf("Optimization time (=%f) >= MaxTime(=%f).\n", ocas.ocas_time, MaxTime); break;
       case -1: mexPrintf("Has not converged!\n" ); break;
       case -2: mexPrintf("Not enough memory for the solver.\n" ); break;
    }
  }

  total_time=get_time()-total_time;
  if(verb)
  {
    mexPrintf("Timing statistics:\n"
              "   init_time      : %f[s]\n"
              "   qp_solver_time : %f[s]\n"
              "   sort_time      : %f[s]\n"
              "   output_time    : %f[s]\n"
              "   add_time       : %f[s]\n"
              "   w_time         : %f[s]\n"
              "   print_time     : %f[s]\n"
              "   ocas_time      : %f[s]\n"
              "   total_time     : %f[s]\n",
              init_time, ocas.qp_solver_time, ocas.sort_time, ocas.output_time, 
              ocas.add_time, ocas.w_time, ocas.print_time, ocas.ocas_time, total_time);

    mexPrintf("Training error: %.4f%%\n", 100*(double)ocas.trn_err/(double)nData);
  }

  /* multiply data ba labels as it was at the begining */
  if( mxIsSparse(data_X)== true ) {
    /* for i=1:nData, X(:,i) = X(:,i)*y(i); end*/
    for(i=0; i < nData; i++) 
    {
        mul_sparse_col(1/data_y[i], data_X, i);
    }
  }
  else
  {
    ptr = mxGetPr(data_X);
    for(i=0; i < nData; i++) {
      for(j=0; j < nDim; j++ ) {
        ptr[LIBOCAS_INDEX(j,i,nDim)] = ptr[LIBOCAS_INDEX(j,i,nDim)]/data_y[i];
      }
    }
  }

  if(num_of_Cs > 1)
  {
    for(i=0; i < nData; i++) 
      data_y[i] = data_y[i]/vec_C[i];
  }


  plhs[1] = mxCreateDoubleScalar( W0 );
  
  /* return ocas optimizer statistics */
  /* typedef struct {
     uint32_t nIter;    
     uint32_t nCutPlanes;
     double trn_err;      
     double Q_P;          
     double Q_D;
     double output_time;
     double sort_time;
     double solver_time;
     int8_t exitflag;       
     } ocas_return_value_T; */

  const char *field_names[] = {"nTrnErrors","Q_P","Q_D","nIter","nCutPlanes","exitflag",
                               "init_time","output_time","sort_time","qp_solver_time","add_time",
                               "w_time","print_time","ocas_time","total_time"}; 
  mwSize dims[2] = {1,1};  

  plhs[2] = mxCreateStructArray(2, dims, (sizeof(field_names)/sizeof(*field_names)), field_names);
  
  mxSetField(plhs[2],0,"nIter",mxCreateDoubleScalar((double)ocas.nIter));
  mxSetField(plhs[2],0,"nCutPlanes",mxCreateDoubleScalar((double)ocas.nCutPlanes));
  mxSetField(plhs[2],0,"nTrnErrors",mxCreateDoubleScalar(ocas.trn_err)); 
  mxSetField(plhs[2],0,"Q_P",mxCreateDoubleScalar(ocas.Q_P)); 
  mxSetField(plhs[2],0,"Q_D",mxCreateDoubleScalar(ocas.Q_D)); 
  mxSetField(plhs[2],0,"init_time",mxCreateDoubleScalar(init_time)); 
  mxSetField(plhs[2],0,"output_time",mxCreateDoubleScalar(ocas.output_time)); 
  mxSetField(plhs[2],0,"sort_time",mxCreateDoubleScalar(ocas.sort_time)); 
  mxSetField(plhs[2],0,"qp_solver_time",mxCreateDoubleScalar(ocas.qp_solver_time)); 
  mxSetField(plhs[2],0,"add_time",mxCreateDoubleScalar(ocas.add_time)); 
  mxSetField(plhs[2],0,"w_time",mxCreateDoubleScalar(ocas.w_time)); 
  mxSetField(plhs[2],0,"print_time",mxCreateDoubleScalar(ocas.print_time)); 
  mxSetField(plhs[2],0,"ocas_time",mxCreateDoubleScalar(ocas.ocas_time)); 
  mxSetField(plhs[2],0,"total_time",mxCreateDoubleScalar(total_time)); 
  mxSetField(plhs[2],0,"exitflag",mxCreateDoubleScalar((double)ocas.exitflag)); 

  return;
}
Esempio n. 30
0
struct svm_model *matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
{
	int i, j, n, num_of_fields;
	SVM_REAL *ptr;
	int id = 0;
	struct svm_node *x_space;
	struct svm_model *model;
	mxArray **rhs;

	num_of_fields = mxGetNumberOfFields(matlab_struct);
	if(num_of_fields != NUM_OF_RETURN_FIELD) 
	{
		*msg = "number of return field is not correct";
		return NULL;
	}
	rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);

	for(i=0;i<num_of_fields;i++)
		rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);

	model = Malloc(struct svm_model, 1);
	model->rho = NULL;
	model->probA = NULL;
	model->probB = NULL;
	model->label = NULL;
	model->nSV = NULL;
	model->free_sv = 1; 

#ifdef _USE_CHI_SQUARE
	model->param.multiple_kernel_parm = NULL;
	model->param.feat_parm_text[0] = NULL;
#endif

#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
	model->param.svm_type = (int)ptr[0];
	model->param.kernel_type  = (int)ptr[1];
	model->param.degree	  = (int)ptr[2];
	model->param.gamma	  = ptr[3];
	model->param.coef0	  = ptr[4];
	id++;

#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
	model->nr_class = (int)ptr[0];
	id++;

#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
	model->l = (int)ptr[0];
	id++;

	/* rho */
	n = model->nr_class * (model->nr_class-1)/2;
	model->rho = (SVM_REAL*) malloc(n*sizeof(SVM_REAL));
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
	for(i=0;i<n;i++)
		model->rho[i] = ptr[i];
	id++;

	/* label */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->label = (int*) malloc(model->nr_class*sizeof(int));
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
		for(i=0;i<model->nr_class;i++)
			model->label[i] = (int)ptr[i];
	}
	id++;

	/* probA */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probA = (SVM_REAL*) malloc(n*sizeof(SVM_REAL));
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
		for(i=0;i<n;i++)
			model->probA[i] = ptr[i];
	}
	id++;

	/* probB */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->probB = (SVM_REAL*) malloc(n*sizeof(SVM_REAL));
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
		for(i=0;i<n;i++)
			model->probB[i] = ptr[i];
	}
	id++;

	/* nSV */
	if(mxIsEmpty(rhs[id]) == 0)
	{
		model->nSV = (int*) malloc(model->nr_class*sizeof(int));
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
		for(i=0;i<model->nr_class;i++)
			model->nSV[i] = (int)ptr[i];
	}
	id++;

	/* sv_coef */
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
	model->sv_coef = (SVM_REAL**) malloc((model->nr_class-1)*sizeof(SVM_REAL *));
	for( i=0 ; i< model->nr_class -1 ; i++ )
		model->sv_coef[i] = (SVM_REAL*) malloc((model->l)*sizeof(SVM_REAL));
	for(i = 0; i < model->nr_class - 1; i++)
		for(j = 0; j < model->l; j++)
			model->sv_coef[i][j] = ptr[i*(model->l)+j];
	id++;

	/* SV */
	{
#ifdef _DENSE_REP
		int sr, sc;
#ifdef _ALL_FLOAT
	ptr = (float *)mxGetData(rhs[id]);
#else
	ptr = mxGetPr(rhs[id]);
#endif
		sr = (int)mxGetM(rhs[id]);
		sc = (int)mxGetN(rhs[id]);
		model->SV = (struct svm_node *) malloc(sr * sizeof(struct svm_node));
		x_space = NULL;
		for(j=0;j < model->l;j++)
		{
			model->SV[j].values = (SVM_REAL *)malloc(sc * sizeof(SVM_REAL));
			model->SV[j].dim = sc;
			for(i=0;i < sc;i++)
				model->SV[j].values[i] = ptr[(i*(model->l))+j];
		}
#else
		int sr, sc, elements;
		int num_samples;
		mwIndex *ir, *jc;
		mxArray *pprhs[1], *pplhs[1];

		/* transpose SV */
		pprhs[0] = rhs[id];
		if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose")) 
		{
			svm_destroy_model(model);
			*msg = "cannot transpose SV matrix";
			return NULL;
		}
		rhs[id] = pplhs[0];

		sr = (int)mxGetN(rhs[id]);
		sc = (int)mxGetM(rhs[id]);

		double *ptr2;
		ptr2 = mxGetPr(rhs[id]);
		ir = mxGetIr(rhs[id]);
		jc = mxGetJc(rhs[id]);

		num_samples = (int)mxGetNzmax(rhs[id]);

		elements = num_samples + sr;

		model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *));
		x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node));

		/* SV is in column */
		for(i=0;i<sr;i++)
		{
			int low = (int)jc[i], high = (int)jc[i+1];
			int x_index = 0;
			model->SV[i] = &x_space[low+i];
			for(j=low;j<high;j++)
			{
				model->SV[i][x_index].index = (int)ir[j] + 1; 
				model->SV[i][x_index].value = ptr2[j];
				x_index++;
			}
			model->SV[i][x_index].index = -1;
		}
#endif
		id++;
	}
#ifdef _USE_CHI_SQUARE
	if(mxIsEmpty(rhs[id]) == 0)
	{
		if(model->param.kernel_type == MULTIPLE_CHI_SQUARE)
		{
			new_featparm(model->param);
			mxGetString(rhs[id], model->param.feat_parm_text,1024);
			parse_custom_arguments(model->param.feat_parm_text, model->param.multiple_kernel_parm);
		}
	}
#endif
	mxFree(rhs);

	return model;
}