コード例 #1
0
ファイル: dlpack.c プロジェクト: BrechtBa/casadi
int DTPUMatEigs(void*AA,double W[],double IIWORK[], int nn1, double *mineig){
  dtpumat* AAA=(dtpumat*) AA;
  ffinteger info,INFO=0,M,N=AAA->n;
  ffinteger IL=1,IU=1,LDZ=1,IFAIL;
  ffinteger *IWORK=(ffinteger*)IIWORK;
  double *AP=AAA->val,ABSTOL=1e-13;
  double Z=0,VL=-1e10,VU=1;
  double *WORK;
  char UPLO=AAA->UPLO,JOBZ='N',RANGE='I';

  DSDPCALLOC2(&WORK,double,7*N,&info);DSDPCHKERR(info);
  DSDPCALLOC2(&IWORK,ffinteger,5*N,&info);DSDPCHKERR(info);
  dspevx(&JOBZ,&RANGE,&UPLO,&N,AP,&VL,&VU,&IL,&IU,&ABSTOL,&M,W,&Z,&LDZ,WORK,IWORK,&IFAIL,&INFO);

  /*
  DSDPCALLOC2(&WORK,double,2*N,&info);
  LWORK=2*N;
  dspevd(&JOBZ,&UPLO,&N,AP,W,&Z,&LDZ,WORK,&LWORK,IWORK,&LIWORK,&INFO);
  */
  *mineig=W[0];
  DSDPFREE(&WORK,&info);DSDPCHKERR(info);
  DSDPFREE(&IWORK,&info);DSDPCHKERR(info);
  return INFO;
}
コード例 #2
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	/* Declare Variables */
	char *ch1 = "V", *ch2 = "I", *ch3 = "L";	
	void *A, *W, *Z, *work;
	double ABSTOLD = 0.0, VLD = 0.0, VUD = 0.0;
	float ABSTOLF = 0.0, VLF = 0.0, VUF = 0.0;
	
#ifdef MWSIZE
	mwSize N, *iwork, *ifail, info = 0, numElem, optional, IL, IU, M, num_eigs, isDouble = 1;
#else
	int N, *iwork, *ifail, info = 0, numElem, optional, IL, IU, M, num_eigs, isDouble = 1;
#endif	

	/****** Do Error check *************/
	if (nrhs != 4) 
	{
		mexErrMsgTxt("icatb_eig_symm_sel function accepts four input arguments.\nThe usage of the function is [eigen_vectors, eigen_values] = icatb_eig_symm_sel(A, N, num_eigs, opt);\nwhere A is the lower triangular matrix without zeros entered as a vector, N is the original dimension, num_eigs is the number of eigen values and opt is parameter to operate on copy of the matrix or the original array.");
	}
	
#ifdef MWSIZE	
	/* Inputs Matrix (A), order (N), number of eigen values (num_eigs), parameter (opt) to operate on copy or original matrix*/   
	numElem = (mwSize) mxGetNumberOfElements(prhs[0]);  
	N = (mwSize) mxGetScalar(prhs[1]); 
	num_eigs = (mwSize) mxGetScalar(prhs[2]);	
	/* Parameter for using the copy or original array to do operations*/	
	optional = (mwSize) mxGetScalar(prhs[3]);
#else
	numElem = (int) mxGetNumberOfElements(prhs[0]);
	N = (int) mxGetScalar(prhs[1]);
	num_eigs = (int) mxGetScalar(prhs[2]);	
	optional = (int) mxGetScalar(prhs[3]);	
#endif	
		
	
	if (numElem != (N*(N + 1)/2))
	{
		mexErrMsgTxt("Number of elements of input matrix (A) must be equal to N*(N+1)/2"); 
	}
		
	
	if (num_eigs > N)
	{
		mexErrMsgTxt("Number of eigen values desired is greater than the number of rows of matrix");
	}
	
	if (nlhs > 2) 
	{
		mexErrMsgTxt("Maximum allowed output arguments is 2."); 
	}    
	/********* End for doing error check *********/
	
	/* Eigen values desired */
	IL = N - num_eigs + 1;
	IU = N; 	
	
	/* Check isdouble */
	if (mxIsDouble(prhs[0]))
	{		
		isDouble = 1;
		
		if (optional == 1) 
		{			
			A = (void *) mxCalloc(numElem, sizeof(double));
			memcpy(A, mxGetData(prhs[0]), numElem*sizeof(double));   			
		}
		else
		{
			A = mxGetData(prhs[0]);
		}		
		
		A = (double *) A;
		
		/* Pointer to work */
		work = (double *) mxCalloc(8*N, sizeof(double));		
		
		/* Pointer to eigen vectors */
		plhs[0] = mxCreateDoubleMatrix(N, num_eigs, mxREAL);
		Z = mxGetPr(plhs[0]);			
		
		/* Pointer to eigen values */
		plhs[1] = mxCreateDoubleMatrix(1, num_eigs, mxREAL);
		W = mxGetPr(plhs[1]);		

		/* Tolerance */		
		ABSTOLD = mxGetEps();		
	}
	else
	{
		isDouble = 0;
		
		if (optional == 1) 
		{
			A = (void *) mxCalloc(numElem, sizeof(float));
			memcpy(A, mxGetData(prhs[0]), numElem*sizeof(float));   
		}
		else
		{
			A = mxGetData(prhs[0]);
		}
		
		A = (float *) A;
		
		/* Pointer to work */
		work = (float *) mxCalloc(8*N, sizeof(float));
		
		/* Pointer to eigen vectors */
		plhs[0] = mxCreateNumericMatrix(N, num_eigs, mxSINGLE_CLASS, mxREAL);	
		Z = (float *) mxGetData(plhs[0]);			
		
		/* Pointer to eigen values */
		plhs[1] = mxCreateNumericMatrix(1, num_eigs, mxSINGLE_CLASS, mxREAL);	
		W = (float *) mxGetData(plhs[1]); 
		
		ABSTOLF = (float) mxGetEps();		
	}		

	
#ifdef MWSIZE
	/* Pointer to iwork */
	iwork = (mwSize *) mxCalloc(5*N, sizeof(mwSize)); 	
	/* Pointer to ifail */
	ifail = (mwSize *) mxCalloc(N, sizeof(mwSize));		
#else	
	/* Pointer to iwork */
	iwork = (int *) mxCalloc(5*N, sizeof(int)); 	
	/* Pointer to ifail */
	ifail = (int *) mxCalloc(N, sizeof(int));		
#endif	
	
	/* Call subroutine to find eigen values and vectors */
#ifdef PC	
	/* Handle Windows */
	if (isDouble == 1)
	{	
		/* Double precision */
		dspevx(ch1, ch2, ch3, &N, A, &VLD, &VUD, &IL, &IU, &ABSTOLD, &M, W, Z, &N, work, iwork, ifail, &info);	
	}
	else
	{
		/* Use single precision routine */
#ifdef SINGLE_SUPPORT		
		sspevx(ch1, ch2, ch3, &N, A, &VLF, &VUF, &IL, &IU, &ABSTOLF, &M, W, Z, &N, work, iwork, ifail, &info);			
#else
		mexErrMsgTxt("Error executing sspevx function on this MATLAB version.\nUse double precision to solve eigen value problem");
#endif
	}
	/* End for handling Windows */
#else
	/* Handle other OS */
	if (isDouble == 1)
	{
		dspevx_(ch1, ch2, ch3, &N, A, &VLD, &VUD, &IL, &IU, &ABSTOLD, &M, W, Z, &N, work, iwork, ifail, &info);	
	}
	else
	{
		/* Use single precision routine */
#ifdef SINGLE_SUPPORT
		sspevx_(ch1, ch2, ch3, &N, A, &VLF, &VUF, &IL, &IU, &ABSTOLF, &M, W, Z, &N, work, iwork, ifail, &info);	
#else
		mexErrMsgTxt("Error executing sspevx_ function on this MATLAB version.\nUse double precision to solve eigen value problem");
#endif
	}
	/* End for handling other OS */
#endif
	/* End for calling subroutine to find eigen values and vectors */
	
	if (M != num_eigs)
	{
		mexPrintf("%s%d\t%s%d\n", "No. of eigen values estimated: ", M, "No. of eigen values desired: ", num_eigs);
		mexErrMsgTxt("Error executing dspevx function\n");
	}
	
	if (info == 1) 
	{
		mexErrMsgTxt("Error executing dspevx/sspevx function.");
	}
	
	/* Free memory */
	if (optional == 1) 
	{
		mxFree(A);
	}	
	mxFree(work);
	mxFree(iwork);
	mxFree(ifail);

}