示例#1
0
void add_cutting_plane(
		bmrm_ll**	tail,
		bool*		map,
		float64_t*	A,
		uint32_t 	free_idx,
		float64_t*	cp_data,
		uint32_t 	dim)
{
	ASSERT(map[free_idx]);

	LIBBMRM_MEMCPY(A+free_idx*dim, cp_data, dim*sizeof(float64_t));
	map[free_idx]=false;

	bmrm_ll *cp=(bmrm_ll*)LIBBMRM_CALLOC(1, sizeof(bmrm_ll));

	if (cp==NULL)
	{
		SG_SERROR("Out of memory.\n");
		return;
	}

	cp->address=A+(free_idx*dim);
	cp->prev=*tail;
	cp->next=NULL;
	cp->idx=free_idx;
	(*tail)->next=cp;
	*tail=cp;
}
示例#2
0
SGMatrix<float64_t> SGMatrix<T>::matrix_multiply(
		SGMatrix<float64_t> A, SGMatrix<float64_t> B,
		bool transpose_A, bool transpose_B, float64_t scale)
{
	/* these variables store size of transposed matrices*/
	index_t cols_A=transpose_A ? A.num_rows : A.num_cols;
	index_t rows_A=transpose_A ? A.num_cols : A.num_rows;
	index_t rows_B=transpose_B ? B.num_cols : B.num_rows;
	index_t cols_B=transpose_B ? B.num_rows : B.num_cols;

	/* do a dimension check */
	if (cols_A!=rows_B)
	{
		SG_SERROR("SGMatrix::matrix_multiply(): Dimension mismatch: "
				"A(%dx%d)*B(%dx%D)\n", rows_A, cols_A, rows_B, cols_B);
	}

	/* allocate result matrix */
	SGMatrix<float64_t> C(rows_A, cols_B);

	/* multiply */
	cblas_dgemm(CblasColMajor,
			transpose_A ? CblasTrans : CblasNoTrans,
			transpose_B ? CblasTrans : CblasNoTrans,
			rows_A, cols_B, cols_A, scale,
			A.matrix, A.num_rows, B.matrix, B.num_rows,
			0.0, C.matrix, C.num_rows);

	return C;
}
CKLDualInferenceMethod* CKLDualInferenceMethod::obtain_from_generic(
		CInference* inference)
{
	if (inference==NULL)
		return NULL;

	if (inference->get_inference_type()!=INF_KL_DUAL)
	{
		SG_SERROR("Provided inference is not of type CKLDualInferenceMethod!\n");
	}

	SG_REF(inference);
	return (CKLDualInferenceMethod*)inference;
}
示例#4
0
SGVector<float64_t> SGMatrix<T>::compute_eigenvectors(SGMatrix<float64_t> matrix)
{
	if (matrix.num_rows!=matrix.num_rows)
	{
		SG_SERROR("SGMatrix::compute_eigenvectors(SGMatrix<float64_t>): matrix"
				" rows and columns are not equal!\n");
	}

	/* use reference counting for SGVector */
	SGVector<float64_t> result(NULL, 0, true);
	result.vlen=matrix.num_rows;
	result.vector=compute_eigenvectors(matrix.matrix, matrix.num_rows,
			matrix.num_rows);
	return result;
}
示例#5
0
SEXP Rsg(SEXP args)
{
	/* The SEXP (Simple Expression) args is a list of arguments of the .External call. 
	 * it consists of "sg", "func" and additional arguments.
	 * */

	try
	{
		if (!interface)
		{
			// init_shogun has to be called before anything else
			// exit_shogun is called upon destruction of the interface (see
			// destructor of CRInterface
			init_shogun(&r_print_message, &r_print_warning,
					&r_print_error, &r_cancel_computations);
			interface=new CRInterface(args);
#ifdef HAVE_PYTHON
	CPythonInterface::run_python_init();
#endif
#ifdef HAVE_OCTAVE
	COctaveInterface::run_octave_init();
#endif
		}
		else
			((CRInterface*) interface)->reset(args);

		if (!interface->handle())
			SG_SERROR("Unknown command.\n");
	}
	catch (std::bad_alloc)
	{
		error("Out of memory error.\n");
		return R_NilValue;
	}
	catch (ShogunException e)
	{
		error("%s", e.get_exception_string());
		return R_NilValue;
	}
	catch (...)
	{
		error("%s", "Returning from SHOGUN in error.");
		return R_NilValue;
	}

	return ((CRInterface*) interface)->get_return_values();
}
示例#6
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	try
	{
		if (!interface)
		{
			// init_shogun has to be called before anything else
			// exit_shogun is called upon destruction of the interface (see
			// destructor of CMatlabInterface
			init_shogun(&matlab_print_message, &matlab_print_warning,
					&matlab_print_error, &matlab_cancel_computations);
			interface=new CMatlabInterface(nlhs, plhs, nrhs, prhs);

#ifdef HAVE_PYTHON
			CPythonInterface::run_python_init();
#endif
#ifdef HAVE_OCTAVE
			COctaveInterface::run_octave_init();
#endif
#ifdef HAVE_R
			CRInterface::run_r_init();
#endif
		}
		else
			((CMatlabInterface*) interface)->reset(nlhs, plhs, nrhs, prhs);

		if (!interface->handle())
			SG_SERROR("Unknown command.\n");
	}
	catch (std::bad_alloc)
	{
		mexErrMsgTxt("Out of memory error.");
	}
	catch (ShogunException e)
	{
		mexErrMsgTxt(e.get_exception_string());
	}
	catch (...)
	{
		mexErrMsgTxt("Returning from SHOGUN in error.");
	}
}
示例#7
0
double* SGMatrix<T>::compute_eigenvectors(double* matrix, int n, int m)
{
	ASSERT(n == m);

	char V='V';
	char U='U';
	int info;
	int ord=n;
	int lda=n;
	double* eigenvalues=SG_CALLOC(float64_t, n+1);

	// lapack sym matrix eigenvalues+vectors
	wrap_dsyev(V, U,  ord, matrix, lda,
			eigenvalues, &info);

	if (info!=0)
		SG_SERROR("DSYEV failed with code %d\n", info);

	return eigenvalues;
}
示例#8
0
bmrm_return_value_T svm_bmrm_solver(
		bmrm_data_T*    data,
		float64_t*      W,
		float64_t       TolRel,
		float64_t       TolAbs,
		float64_t       lambda,
		uint32_t        _BufSize,
		bool            cleanICP,
		uint32_t        cleanAfter,
		float64_t       K,
		uint32_t        Tmax,
		CRiskFunction*  risk_function)
{
	bmrm_return_value_T bmrm = {0, 0, 0, 0, 0, 0, 0};
	libqp_state_T qp_exitflag;
	float64_t *b, *beta, *diag_H, sq_norm_W;
	float64_t R, *subgrad, *A, QPSolverTolRel, rsum, C=1.0;
	uint32_t *I, *ICPcounter, *ICPs, cntICP=0;
	uint8_t S = 1;
	uint32_t nDim=data->w_dim;
	CTime ttime;
	float64_t tstart, tstop;

	float64_t *b2, *beta2, *diag_H2, *A2, *H2;
	uint32_t *I2, *ICPcounter2, nCP_new=0, idx=0, idx2=0, icp_iter=0, icp_iter2=0;
	int32_t idx_icp=0, idx_icp2=0;
	bool flag1=true, flag2=true;

	tstart=ttime.cur_time_diff(false);

	BufSize=_BufSize;
	QPSolverTolRel=TolRel*0.5;

	H=NULL;
	b=NULL;
	beta=NULL;
	A=NULL;
	subgrad=NULL;
	diag_H=NULL;
	I=NULL;
	ICPcounter=NULL;
	ICPs=NULL;

	b2=NULL;
	beta2=NULL;
	H2=NULL;
	I2=NULL;
	ICPcounter2=NULL;
	A2=NULL;
	diag_H2=NULL;

	H=(float64_t*)LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
	if (H==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	A=(float64_t*)LIBBMRM_CALLOC(nDim*BufSize, sizeof(float64_t));
	if (A==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	b=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	if (b==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	beta=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	if (beta==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	subgrad=(float64_t*)LIBBMRM_CALLOC(nDim, sizeof(float64_t));
	if (subgrad==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	diag_H=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	if (diag_H==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	I=(uint32_t*)LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	if (I==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	ICPcounter=(uint32_t*)LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	if (ICPcounter==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	ICPs=(uint32_t*)LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	if (ICPs==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	/* Temporary buffers for ICP removal */
	b2=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	beta2=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	ICPcounter2=(uint32_t*)LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	I2=(uint32_t*)LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	diag_H2=(float64_t*)LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
	A2=(float64_t*)LIBBMRM_CALLOC(nDim*BufSize, sizeof(float64_t));
	H2=(float64_t*)LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
	if (b2==NULL || beta2==NULL || ICPcounter2==NULL || I2==NULL || diag_H2==NULL || A2==NULL || H2==NULL)
	{
		bmrm.exitflag=-2;
	}

	/* Iinitial solution */
	risk_function->risk(data, &R, subgrad, W);

	bmrm.nCP=0;
	bmrm.nIter=0;
	bmrm.exitflag=0;

	b[0]=-R;
	LIBBMRM_MEMCPY(A, subgrad, nDim*sizeof(float64_t));

	/* Compute initial value of Fp, Fd, assuming that W is zero vector */
	sq_norm_W=0;
	bmrm.Fp=R+0.5*lambda*sq_norm_W;
	bmrm.Fd=-LIBBMRM_PLUS_INF;

	tstop=ttime.cur_time_diff(false);

	/* Verbose output */
	SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf\n",
			bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, R);

	/* main loop */
	while (bmrm.exitflag==0)
	{
		tstart=ttime.cur_time_diff(false);
		bmrm.nIter++;

		/* Update H */
		if (bmrm.nCP>0)
		{
			for (uint32_t i=0; i<bmrm.nCP; ++i)
			{
				rsum=0.0;
				for (uint32_t j=0; j<nDim; ++j)
				{
					rsum+=A[LIBBMRM_INDEX(j, i, nDim)]*A[LIBBMRM_INDEX(j, bmrm.nCP, nDim)];
				}
				H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)]=rsum/lambda;
			}
			for (uint32_t i=0; i<bmrm.nCP; ++i)
			{
				H[LIBBMRM_INDEX(bmrm.nCP, i, BufSize)]=H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)];
			}
		}
		H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]=0.0;

		for (uint32_t i=0; i<nDim; ++i)
			H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]+=A[LIBBMRM_INDEX(i, bmrm.nCP, nDim)]*A[LIBBMRM_INDEX(i, bmrm.nCP, nDim)]/lambda;

		diag_H[bmrm.nCP]=H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)];
		I[bmrm.nCP]=1;

		bmrm.nCP++;

		/* call QP solver */
		qp_exitflag = libqp_splx_solver(&get_col, diag_H, b, &C, I, &S, beta,
				bmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);

		bmrm.qp_exitflag=qp_exitflag.exitflag;

		/* Update ICPcounter (add one to unused and reset used) + compute number of active CPs*/
		bmrm.nzA=0;
		for (uint32_t aaa=0; aaa<bmrm.nCP; ++aaa)
		{
			if (beta[aaa]>epsilon)
			{
				bmrm.nzA+=1;
				ICPcounter[aaa]=0;
			} else {
				ICPcounter[aaa]+=1;
			}
		}

		/* W update */
		for (uint32_t i=0; i<nDim; ++i)
		{
			rsum = 0.0;
			for (uint32_t j=0; j<bmrm.nCP; ++j)
			{
				rsum += A[LIBBMRM_INDEX(i, j, nDim)]*beta[j];
			}
			W[i] = -rsum/lambda;
		}

		/* risk and subgradient computation */
		risk_function->risk(data, &R, subgrad, W);
		LIBBMRM_MEMCPY(A+bmrm.nCP*nDim, subgrad, nDim*sizeof(float64_t));
		b[bmrm.nCP]=-R;
		for (uint32_t j=0; j<nDim; ++j)
			b[bmrm.nCP]+=subgrad[j]*W[j];

		sq_norm_W = 0;
		for (uint32_t j=0; j<nDim; ++j)
			sq_norm_W+=W[j]*W[j];

		bmrm.Fp=R+0.5*lambda*sq_norm_W;
		bmrm.Fd=-qp_exitflag.QP;

		/* Stopping conditions */
		if (bmrm.Fp - bmrm.Fd <= TolRel*LIBBMRM_ABS(bmrm.Fp)) bmrm.exitflag=1;
		if (bmrm.Fp - bmrm.Fd <= TolAbs) bmrm.exitflag=2;
		if (bmrm.nCP >= BufSize) bmrm.exitflag=-1;

		tstop=ttime.cur_time_diff(false);

		/* Verbose output */
		SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d\n",
				bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, bmrm.Fp-bmrm.Fd, (bmrm.Fp-bmrm.Fd)/bmrm.Fp, R, bmrm.nCP, bmrm.nzA);

		/* Check size of Buffer */
		if (bmrm.nCP>=BufSize)
		{
			bmrm.exitflag=-2;
			SG_SERROR("Buffer exceeded.\n");
		}

		/* Inactive Cutting Planes (ICP) removal */
		if (cleanICP)
		{
			/* find ICP */
			cntICP = 0;
			for (uint32_t aaa=0; aaa<bmrm.nCP; ++aaa)
				if (ICPcounter[aaa]>=cleanAfter)
				{
					ICPs[cntICP++]=aaa;
				}

			/* do ICP */
			if (cntICP > 0)
			{
				nCP_new=bmrm.nCP-cntICP;

				idx=0;
				idx2=0;
				icp_iter=0;
				icp_iter2=0;
				idx_icp=ICPs[icp_iter];
				idx_icp2=ICPs[icp_iter2];
				flag1=true; flag2=true;

				for (uint32_t i=0; i<bmrm.nCP; ++i)
				{
					if ((int32_t)i != idx_icp)
					{
						b2[idx]=b[i];
						beta2[idx]=beta[i];
						ICPcounter2[idx]=ICPcounter[i];
						I2[idx]=I[i];
						diag_H2[idx]=diag_H[i];
						LIBBMRM_MEMCPY(A2+idx*nDim, A+i*nDim, nDim*sizeof(float64_t));

						idx2=0;
						icp_iter2=0;
						idx_icp2=ICPs[icp_iter2];
						flag2=true;
						for (uint32_t j=0; j<bmrm.nCP; ++j)
						{
							if ((int32_t)j != idx_icp2)
							{
								H2[LIBBMRM_INDEX(idx, idx2, BufSize)]=H[LIBBMRM_INDEX(i, j, BufSize)];
								idx2++;
							} else {
								if (flag2 && icp_iter2+1 < cntICP)
								{
									idx_icp2=ICPs[++icp_iter2];
								} else {
									flag2=false;
									idx_icp2=-1;
								}
							}
						}

						idx++;
					} else {
						if (flag1 && icp_iter+1 < cntICP)
						{
							idx_icp=ICPs[++icp_iter];
						} else {
							flag1=false;
							idx_icp=-1;
						}
					}
				}

				/* copy data from tmps back to original */
				LIBBMRM_MEMCPY(b, b2, nCP_new*sizeof(float64_t));
				LIBBMRM_MEMCPY(beta, beta2, nCP_new*sizeof(float64_t));
				LIBBMRM_MEMCPY(ICPcounter, ICPcounter2, nCP_new*sizeof(uint32_t));
				LIBBMRM_MEMCPY(I, I2, nCP_new*sizeof(uint32_t));
				LIBBMRM_MEMCPY(diag_H, diag_H2, nCP_new*sizeof(float64_t));
				LIBBMRM_MEMCPY(A, A2, nDim*nCP_new*sizeof(float64_t));
				for (uint32_t i=0; i<nCP_new; ++i)
					for (uint32_t j=0; j<nCP_new; ++j)
						H[LIBBMRM_INDEX(i, j, BufSize)]=H2[LIBBMRM_INDEX(i, j, BufSize)];

				bmrm.nCP=nCP_new;
			}
		}

	} /* end of main loop */

cleanup:

	LIBBMRM_FREE(H);
	LIBBMRM_FREE(b);
	LIBBMRM_FREE(beta);
	LIBBMRM_FREE(A);
	LIBBMRM_FREE(subgrad);
	LIBBMRM_FREE(diag_H);
	LIBBMRM_FREE(I);
	LIBBMRM_FREE(ICPcounter);
	LIBBMRM_FREE(ICPs);

	LIBBMRM_FREE(H2);
	LIBBMRM_FREE(b2);
	LIBBMRM_FREE(beta2);
	LIBBMRM_FREE(A2);
	LIBBMRM_FREE(diag_H2);
	LIBBMRM_FREE(I2);
	LIBBMRM_FREE(ICPcounter2);

	return(bmrm);
}
SparsityStructure* CSparseMatrixOperator<complex128_t>
	::get_sparsity_structure(int64_t power) const
  {
    SG_SERROR("Not supported for complex128_t\n");
    return new SparsityStructure();
  }
示例#10
0
bmrm_return_value_T svm_bmrm_solver(
		CStructuredModel* model,
		float64_t*       W,
		float64_t        TolRel,
		float64_t        TolAbs,
		float64_t        _lambda,
		uint32_t         _BufSize,
		bool             cleanICP,
		uint32_t         cleanAfter,
		float64_t        K,
		uint32_t         Tmax,
		bool             verbose)
{
	bmrm_return_value_T bmrm;
	libqp_state_T qp_exitflag={0, 0, 0, 0};
	float64_t *b, *beta, *diag_H, *prevW;
	float64_t R, *subgrad, *A, QPSolverTolRel, C=1.0, wdist=0.0;
	floatmax_t rsum, sq_norm_W, sq_norm_Wdiff=0.0;
	uint32_t *I;
	uint8_t S=1;
	uint32_t nDim=model->get_dim();

	CTime ttime;
	float64_t tstart, tstop;

	bmrm_ll *CPList_head, *CPList_tail, *cp_ptr, *cp_ptr2, *cp_list=NULL;
	float64_t *A_1=NULL, *A_2=NULL;
	bool *map=NULL;


	tstart=ttime.cur_time_diff(false);

	BufSize=_BufSize;
	QPSolverTolRel=1e-9;

	H=NULL;
	b=NULL;
	beta=NULL;
	A=NULL;
	subgrad=NULL;
	diag_H=NULL;
	I=NULL;
	prevW=NULL;

	H= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));

	if (H==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	A= (float64_t*) LIBBMRM_CALLOC(nDim*BufSize, sizeof(float64_t));

	if (A==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	b= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));

	if (b==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	beta= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));

	if (beta==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	subgrad= (float64_t*) LIBBMRM_CALLOC(nDim, sizeof(float64_t));

	if (subgrad==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	diag_H= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));

	if (diag_H==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	I= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));

	if (I==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	ICP_stats icp_stats;
	icp_stats.maxCPs = BufSize;

	icp_stats.ICPcounter= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	if (icp_stats.ICPcounter==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	icp_stats.ICPs= (float64_t**) LIBBMRM_CALLOC(BufSize, sizeof(float64_t*));
	if (icp_stats.ICPs==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	icp_stats.ACPs= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
	if (icp_stats.ACPs==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	/* Temporary buffers for ICP removal */
	icp_stats.H_buff= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
	if (icp_stats.H_buff==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	map= (bool*) LIBBMRM_CALLOC(BufSize, sizeof(bool));

	if (map==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	memset( (bool*) map, true, BufSize);

	cp_list= (bmrm_ll*) LIBBMRM_CALLOC(1, sizeof(bmrm_ll));

	if (cp_list==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	prevW= (float64_t*) LIBBMRM_CALLOC(nDim, sizeof(float64_t));

	if (prevW==NULL)
	{
		bmrm.exitflag=-2;
		goto cleanup;
	}

	bmrm.hist_Fp = SGVector< float64_t >(BufSize);
	bmrm.hist_Fd = SGVector< float64_t >(BufSize);
	bmrm.hist_wdist = SGVector< float64_t >(BufSize);

	/* Iinitial solution */
	R=model->risk(subgrad, W);

	bmrm.nCP=0;
	bmrm.nIter=0;
	bmrm.exitflag=0;

	b[0]=-R;

	/* Cutting plane auxiliary double linked list */

	LIBBMRM_MEMCPY(A, subgrad, nDim*sizeof(float64_t));
	map[0]=false;
	cp_list->address=&A[0];
	cp_list->idx=0;
	cp_list->prev=NULL;
	cp_list->next=NULL;
	CPList_head=cp_list;
	CPList_tail=cp_list;

	/* Compute initial value of Fp, Fd, assuming that W is zero vector */

	sq_norm_W=0;
	bmrm.Fp=R+0.5*_lambda*sq_norm_W;
	bmrm.Fd=-LIBBMRM_PLUS_INF;

	tstop=ttime.cur_time_diff(false);

	/* Verbose output */

	if (verbose)
		SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf\n",
				bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, R);

	/* store Fp, Fd and wdist history */
	bmrm.hist_Fp[0]=bmrm.Fp;
	bmrm.hist_Fd[0]=bmrm.Fd;
	bmrm.hist_wdist[0]=0.0;

	/* main loop */

	while (bmrm.exitflag==0)
	{
		tstart=ttime.cur_time_diff(false);
		bmrm.nIter++;

		/* Update H */

		if (bmrm.nCP>0)
		{
			A_2=get_cutting_plane(CPList_tail);
			cp_ptr=CPList_head;

			for (uint32_t i=0; i<bmrm.nCP; ++i)
			{
				A_1=get_cutting_plane(cp_ptr);
				cp_ptr=cp_ptr->next;
				rsum= SGVector<float64_t>::dot(A_1, A_2, nDim);

				H[LIBBMRM_INDEX(bmrm.nCP, i, BufSize)]
					= H[LIBBMRM_INDEX(i, bmrm.nCP, BufSize)]
					= rsum/_lambda;
			}
		}

		A_2=get_cutting_plane(CPList_tail);
		rsum = SGVector<float64_t>::dot(A_2, A_2, nDim);

		H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)]=rsum/_lambda;

		diag_H[bmrm.nCP]=H[LIBBMRM_INDEX(bmrm.nCP, bmrm.nCP, BufSize)];
		I[bmrm.nCP]=1;

		bmrm.nCP++;
		beta[bmrm.nCP]=0.0; // [beta; 0]

#if 0
		/* TODO: scaling...*/
		float64_t scale = SGVector<float64_t>::max(diag_H, BufSize)/(1000.0*_lambda);
		SGVector<float64_t> sb(bmrm.nCP);
		sb.zero();
		sb.vec1_plus_scalar_times_vec2(sb.vector, 1/scale, b, bmrm.nCP);

		SGVector<float64_t> sh(bmrm.nCP);
		sh.zero();
		sb.vec1_plus_scalar_times_vec2(sh.vector, 1/scale, diag_H, bmrm.nCP);

		qp_exitflag =
			libqp_splx_solver(&get_col, sh.vector, sb.vector, &C, I, &S, beta,
				bmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
#else
		/* call QP solver */
		qp_exitflag=libqp_splx_solver(&get_col, diag_H, b, &C, I, &S, beta,
				bmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
#endif

		bmrm.qp_exitflag=qp_exitflag.exitflag;

		/* Update ICPcounter (add one to unused and reset used)
		 * + compute number of active CPs */
		bmrm.nzA=0;

		for (uint32_t aaa=0; aaa<bmrm.nCP; ++aaa)
		{
			if (beta[aaa]>epsilon)
			{
				++bmrm.nzA;
				icp_stats.ICPcounter[aaa]=0;
			}
			else
			{
				icp_stats.ICPcounter[aaa]+=1;
			}
		}

		/* W update */
		memset(W, 0, sizeof(float64_t)*nDim);
		cp_ptr=CPList_head;
		for (uint32_t j=0; j<bmrm.nCP; ++j)
		{
			A_1=get_cutting_plane(cp_ptr);
			cp_ptr=cp_ptr->next;
			SGVector<float64_t>::vec1_plus_scalar_times_vec2(W, -beta[j]/_lambda, A_1, nDim);
		}

		/* risk and subgradient computation */
		R = model->risk(subgrad, W);
		add_cutting_plane(&CPList_tail, map, A,
				find_free_idx(map, BufSize), subgrad, nDim);

		sq_norm_W=SGVector<float64_t>::dot(W, W, nDim);
		b[bmrm.nCP]=SGVector<float64_t>::dot(subgrad, W, nDim) - R;

		sq_norm_Wdiff=0.0;
		for (uint32_t j=0; j<nDim; ++j)
		{
			sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
		}

		bmrm.Fp=R+0.5*_lambda*sq_norm_W;
		bmrm.Fd=-qp_exitflag.QP;
		wdist=CMath::sqrt(sq_norm_Wdiff);

		/* Stopping conditions */

		if (bmrm.Fp - bmrm.Fd <= TolRel*LIBBMRM_ABS(bmrm.Fp))
			bmrm.exitflag=1;

		if (bmrm.Fp - bmrm.Fd <= TolAbs)
			bmrm.exitflag=2;

		if (bmrm.nCP >= BufSize)
			bmrm.exitflag=-1;

		tstop=ttime.cur_time_diff(false);

		/* Verbose output */

		if (verbose)
			SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d, QPexitflag=%d\n",
					bmrm.nIter, tstop-tstart, bmrm.Fp, bmrm.Fd, bmrm.Fp-bmrm.Fd,
					(bmrm.Fp-bmrm.Fd)/bmrm.Fp, R, bmrm.nCP, bmrm.nzA, qp_exitflag.exitflag);

		/* Keep Fp, Fd and w_dist history */
		bmrm.hist_Fp[bmrm.nIter]=bmrm.Fp;
		bmrm.hist_Fd[bmrm.nIter]=bmrm.Fd;
		bmrm.hist_wdist[bmrm.nIter]=wdist;

		/* Check size of Buffer */

		if (bmrm.nCP>=BufSize)
		{
			bmrm.exitflag=-2;
			SG_SERROR("Buffer exceeded.\n");
		}

		/* keep W (for wdist history track) */
		LIBBMRM_MEMCPY(prevW, W, nDim*sizeof(float64_t));

		/* Inactive Cutting Planes (ICP) removal */
		if (cleanICP)
		{
			clean_icp(&icp_stats, bmrm, &CPList_head, &CPList_tail, H, diag_H, beta, map, cleanAfter, b, I);
		}
	} /* end of main loop */

	bmrm.hist_Fp.resize_vector(bmrm.nIter);
	bmrm.hist_Fd.resize_vector(bmrm.nIter);
	bmrm.hist_wdist.resize_vector(bmrm.nIter);

	cp_ptr=CPList_head;

	while(cp_ptr!=NULL)
	{
		cp_ptr2=cp_ptr;
		cp_ptr=cp_ptr->next;
		LIBBMRM_FREE(cp_ptr2);
		cp_ptr2=NULL;
	}

	cp_list=NULL;

cleanup:

	LIBBMRM_FREE(H);
	LIBBMRM_FREE(b);
	LIBBMRM_FREE(beta);
	LIBBMRM_FREE(A);
	LIBBMRM_FREE(subgrad);
	LIBBMRM_FREE(diag_H);
	LIBBMRM_FREE(I);
	LIBBMRM_FREE(icp_stats.ICPcounter);
	LIBBMRM_FREE(icp_stats.ICPs);
	LIBBMRM_FREE(icp_stats.ACPs);
	LIBBMRM_FREE(icp_stats.H_buff);
	LIBBMRM_FREE(map);
	LIBBMRM_FREE(prevW);

	if (cp_list)
		LIBBMRM_FREE(cp_list);

	return(bmrm);
}
示例#11
0
complex128_t SGMatrix<complex128_t>::max_single()
{
	SG_SERROR("SGMatrix::max_single():: Not supported for complex128_t\n");
	return complex128_t(0.0);
}
示例#12
0
void SGSparseMatrix<complex64_t>::load(CFile* loader)
{
	SG_SERROR("SGSparseMatrix::load():: Not supported for complex64_t");
}
示例#13
0
template<class T> CRegressionLabels* SGSparseMatrix<T>::load_svmlight_file(char* fname,
		bool do_sort_features)
{
	CRegressionLabels* lab=NULL;

	size_t blocksize=1024*1024;
	size_t required_blocksize=blocksize;
	uint8_t* dummy=SG_MALLOC(uint8_t, blocksize);
	FILE* f=fopen(fname, "ro");

	if (f)
	{
		free_data();

		SG_SINFO("counting line numbers in file %s\n", fname)
		size_t sz=blocksize;
		size_t block_offs=0;
		size_t old_block_offs=0;
		fseek(f, 0, SEEK_END);
		size_t fsize=ftell(f);
		rewind(f);

		while (sz == blocksize)
		{
			sz=fread(dummy, sizeof(uint8_t), blocksize, f);
			for (size_t i=0; i<sz; i++)
			{
				block_offs++;
				if (dummy[i]=='\n' || (i==sz-1 && sz<blocksize))
				{
					num_vectors++;
					required_blocksize=CMath::max(required_blocksize, block_offs-old_block_offs+1);
					old_block_offs=block_offs;
				}
			}
			SG_SPROGRESS(block_offs, 0, fsize, 1, "COUNTING:\t")
		}

		SG_SINFO("found %d feature vectors\n", num_vectors)
		SG_FREE(dummy);
		blocksize=required_blocksize;
		dummy = SG_MALLOC(uint8_t, blocksize+1); //allow setting of '\0' at EOL

		lab=new CRegressionLabels(num_vectors);
		sparse_matrix=SG_MALLOC(SGSparseVector<T>, num_vectors);
		rewind(f);
		sz=blocksize;
		int32_t lines=0;
		while (sz == blocksize)
		{
			sz=fread(dummy, sizeof(uint8_t), blocksize, f);

			size_t old_sz=0;
			for (size_t i=0; i<sz; i++)
			{
				if (i==sz-1 && dummy[i]!='\n' && sz==blocksize)
				{
					size_t len=i-old_sz+1;
					uint8_t* data=&dummy[old_sz];

					for (size_t j=0; j<len; j++)
						dummy[j]=data[j];

					sz=fread(dummy+len, sizeof(uint8_t), blocksize-len, f);
					i=0;
					old_sz=0;
					sz+=len;
				}

				if (dummy[i]=='\n' || (i==sz-1 && sz<blocksize))
				{

					size_t len=i-old_sz;
					uint8_t* data=&dummy[old_sz];

					int32_t dims=0;
					for (size_t j=0; j<len; j++)
					{
						if (data[j]==':')
							dims++;
					}

					if (dims<=0)
					{
						SG_SERROR("Error in line %d - number of"
								" dimensions is %d line is %d characters"
								" long\n line_content:'%.*s'\n", lines,
								dims, len, len, (const char*) data);
					}

					SGSparseVectorEntry<T>* feat=SG_MALLOC(SGSparseVectorEntry<T>, dims);
					size_t j=0;
					for (; j<len; j++)
					{
						if (data[j]==' ')
						{
							data[j]='\0';

							lab->set_label(lines, atof((const char*) data));
							break;
						}
					}

					int32_t d=0;
					j++;
					uint8_t* start=&data[j];
					for (; j<len; j++)
					{
						if (data[j]==':')
						{
							data[j]='\0';

							feat[d].feat_index=(int32_t) atoi((const char*) start)-1;
							num_features=CMath::max(num_features, feat[d].feat_index+1);

							j++;
							start=&data[j];
							for (; j<len; j++)
							{
								if (data[j]==' ' || data[j]=='\n')
								{
									data[j]='\0';
									feat[d].entry=(T) atof((const char*) start);
									d++;
									break;
								}
							}

							if (j==len)
							{
								data[j]='\0';
								feat[dims-1].entry=(T) atof((const char*) start);
							}

							j++;
							start=&data[j];
						}
					}

					sparse_matrix[lines].num_feat_entries=dims;
					sparse_matrix[lines].features=feat;

					old_sz=i+1;
					lines++;
					SG_SPROGRESS(lines, 0, num_vectors, 1, "LOADING:\t")
				}
			}
		}
		SG_SINFO("file successfully read\n")
		fclose(f);
	}
示例#14
0
void SGSparseMatrix<complex64_t>::save(CFile* saver)
{
	SG_SERROR("SGSparseMatrix::save():: Not supported for complex64_t");
}
示例#15
0
SGVector<index_t> SGVector<complex64_t>::argsort()
{
	SG_SERROR("SGVector::argsort():: Not supported for complex64_t\n");
	SGVector<index_t> idx(vlen);
	return idx;
}
示例#16
0
void arpack_dsaupd(double* matrix, int n, int nev, const char* which,
                   int mode, bool pos, double shift, double* eigenvalues,
                   double* eigenvectors, int& status)
{
    // check if nev is greater than n
    if (nev>n)
        SG_SERROR("Number of required eigenpairs is greater than order of the matrix");

    // check specified mode
    if (mode!=1 && mode!=3)
        SG_SERROR("Unknown mode specified");

    // init ARPACK's reverse communication parameter
    // (should be zero initially)
    int ido = 0;

    // specify that non-general eigenproblem will be solved
    // (Ax=lGx, where G=I)
    char bmat[2] = "I";

    // init tolerance (zero means machine precision)
    double tol = 0.0;

    // allocate array to hold residuals
    double* resid = new double[n];

    // set number of Lanczos basis vectors to be used
    // (with max(4*nev,n) sufficient for most tasks)
    int ncv = nev*4>n ? n : nev*4;

    // allocate array 'v' for dsaupd routine usage
    int ldv = n;
    double* v = new double[ldv*ncv];

    // init array for i/o params for routine
    int* iparam = new int[11];
    // specify method for selecting implicit shifts (1 - exact shifts)
    iparam[0] = 1;
    // specify max number of iterations
    iparam[2] = 2*2*n;
    // set the computation mode (1 for regular or 3 for shift-inverse)
    iparam[6] = mode;

    // init array indicating locations of vectors for routine callback
    int* ipntr = new int[11];

    // allocate workaround arrays
    double* workd = new double[3*n];
    int lworkl = ncv*(ncv+8);
    double* workl = new double[lworkl];

    // init info holding status (should be zero at first call)
    int info = 0;

    // which eigenpairs to find
    char* which_ = strdup(which);
    // All
    char* all_ = strdup("A");

    // shift-invert mode
    if (mode==3)
    {
        for (int i=0; i<n; i++)
            matrix[i*n+i] -= shift;

        if (pos)
        {
            clapack_dpotrf(CblasColMajor,CblasUpper,n,matrix,n);
            clapack_dpotri(CblasColMajor,CblasUpper,n,matrix,n);
        }
        else
        {
            int* ipiv = new int[n];
            clapack_dgetrf(CblasColMajor,n,n,matrix,n,ipiv);
            clapack_dgetri(CblasColMajor,n,matrix,n,ipiv);
            delete[] ipiv;
        }
    }
    // main computation loop
    do
    {
        dsaupd_(&ido, bmat, &n, which_, &nev, &tol, resid,
                &ncv, v, &ldv, iparam, ipntr, workd, workl,
                &lworkl, &info);

        if ((ido==1)||(ido==-1))
        {
            cblas_dsymv(CblasColMajor,CblasUpper,
                        n,1.0,matrix,n,
                        (workd+ipntr[0]-1),1,
                        0.0,(workd+ipntr[1]-1),1);
        }
    } while ((ido==1)||(ido==-1));

    // check if DSAUPD failed
    if (info<0)
    {
        if ((info<=-1)&&(info>=-6))
            SG_SWARNING("DSAUPD failed. Wrong parameter passed.");
        else if (info==-7)
            SG_SWARNING("DSAUPD failed. Workaround array size is not sufficient.");
        else
            SG_SWARNING("DSAUPD failed. Error code: %d.", info);

        status = -1;
    }
    else
    {
        if (info==1)
            SG_SWARNING("Maximum number of iterations reached.\n");

        // allocate select for dseupd
        int* select = new int[ncv];
        // allocate d to hold eigenvalues
        double* d = new double[2*ncv];
        // sigma for dseupd
        double sigma = shift;

        // init ierr indicating dseupd possible errors
        int ierr = 0;

        // specify that eigenvectors to be computed too
        int rvec = 1;

        dseupd_(&rvec, all_, select, d, v, &ldv, &sigma, bmat,
                &n, which_, &nev, &tol, resid, &ncv, v, &ldv,
                iparam, ipntr, workd, workl, &lworkl, &ierr);

        if (ierr!=0)
        {
            SG_SWARNING("DSEUPD failed with status=%d", ierr);
            status = -1;
        }
        else
        {

            for (int i=0; i<nev; i++)
            {
                eigenvalues[i] = d[i];

                for (int j=0; j<n; j++)
                    eigenvectors[j*nev+i] = v[i*n+j];
            }
        }

        // cleanup
        delete[] select;
        delete[] d;
    }

    // cleanup
    delete[] all_;
    delete[] which_;
    delete[] resid;
    delete[] v;
    delete[] iparam;
    delete[] ipntr;
    delete[] workd;
    delete[] workl;
};