/* \file MatlabVectorToDoubleVector.cpp
 * \brief: convert a sparse or dense matlab vector to a serial vector:
 */


#ifdef HAVE_CONFIG_H
	#include <config.h>
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif


#include <string.h>

/*Matlab includes: */
#include "mex.h"

#include "../../shared/shared.h"

int MatlabVectorToDoubleVector(double** pvector,int* pvector_rows,const mxArray* mxvector){

	int rows,cols;
	double* mxvector_ptr=NULL;
	int ierr;
	int i,j;

	/*output: */
	double* vector=NULL;

	/*matlab indices: */
	mwIndex*    ir=NULL;
	mwIndex*    jc=NULL;
	double* pr=NULL;
	int     count;
	int     nnz;
	int     nz;

	/*Ok, first check if we are dealing with a sparse or full vector: */
	if (mxIsSparse(mxvector)){

		/*Dealing with sparse vector: recover size first: */
		mxvector_ptr=(double*)mxGetPr(mxvector);
		rows=mxGetM(mxvector);
		cols=mxGetN(mxvector);
		nnz=mxGetNzmax(mxvector);
		
		/*Check that input is actualy a vector*/
		if (cols!=1) _error_("input vector of size %ix%i should have only one column",rows,cols);

		nz=(int)((double)nnz/(double)rows);

		if(rows){
			vector=(double*)xcalloc(rows,sizeof(double));

			/*Now, get ir,jc and pr: */
			pr=mxGetPr(mxvector);
			ir=mxGetIr(mxvector);
			jc=mxGetJc(mxvector);

			/*Now, start inserting data into sparse vector: */
			count=0;
			for(i=0;i<cols;i++){
				for(j=0;j<(jc[i+1]-jc[i]);j++){
					vector[ir[count]]=pr[count];
					count++;
				}
			}
		}

	}
	else{

		/*Dealing with dense vector: recover pointer and size: */
		mxvector_ptr=(double*)mxGetPr(mxvector);
		rows=mxGetM(mxvector);
		cols=mxGetN(mxvector);

		/*Check that input is actualy a vector*/
		if (cols!=1) _error_("input vector of size %ix%i should have only one column",rows,cols);

		/*allocate and memcpy*/
		if(rows){
			vector=(double*)xmalloc(rows*sizeof(double));
			memcpy(vector,mxvector_ptr,rows*sizeof(double));
		}
		else{
			vector=NULL;
		}
	}

	/*Assign output pointer: */
	*pvector=vector;
	*pvector_rows=rows;

	return 1;
}
