Exemplo n.º 1
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);
}
Exemplo n.º 2
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);
}
Exemplo n.º 3
0
/* -------------------------------------------------------------
  MEX main function.
------------------------------------------------------------- */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
  int verb;          
  uint32_t MaxIter;
  uint32_t *vec_I; 
  uint32_t nConstr; 
  uint8_t *vec_S;
  double *vec_x;         
  double TolRel;     
  double TolAbs;     
  double QP_TH;
  double *vec_x0;        
  double *vec_f;         
  double *vec_b;
  double *diag_H;    
  long i ;           
  libqp_state_T state;
  double *tmp;

  /*------------------------------------------------------------------- 
     Get input arguments
   ------------------------------------------------------------------- */
  if( nrhs != 12) mexErrMsgTxt("Incorrect number of input arguments.");
  
  mat_H = (mxArray*)prhs[0];
  nVar = mxGetM(prhs[0]);

  diag_H = mxGetPr(prhs[1]);

  vec_f = mxGetPr(prhs[2]);
  vec_b = (double*)mxGetPr(prhs[3]);
  vec_I = (uint32_t*)mxGetPr(prhs[4]);
  vec_S = (uint8_t*)mxGetPr(prhs[5]);

  nConstr = LIBQP_MAX(mxGetN(prhs[3]),mxGetM(prhs[3]));

  vec_x0 = mxGetPr(prhs[6]);
  MaxIter = mxIsInf( mxGetScalar(prhs[7])) ? 0xFFFFFFFF : (uint32_t)mxGetScalar(prhs[7]);
  TolAbs = mxGetScalar(prhs[8]);   
  TolRel = mxGetScalar(prhs[9]);   
  QP_TH = mxGetScalar(prhs[10]);   
  verb = (int)mxGetScalar(prhs[11]);  

  /* print input setting if required */  
  if( verb > 0 ) {
    mexPrintf("Settings of LIBQP_SSVM solver:\n");
    mexPrintf("MaxIter  : %u\n", MaxIter );
    mexPrintf("TolAbs   : %f\n", TolAbs );
    mexPrintf("TolRel   : %f\n", TolRel );
    mexPrintf("QP_TH    : %f\n", QP_TH );
    mexPrintf("nVar     : %u\n", nVar );
    mexPrintf("nConstr  : %u\n", nConstr );
  }     
  
  /*------------------------------------------------------------------- 
     Inicialization                                                     
   ------------------------------------------------------------------- */

  /* create solution vector x [nVar x 1] */
  plhs[0] = mxCreateDoubleMatrix(nVar,1,mxREAL);
  vec_x = mxGetPr(plhs[0]);
  memcpy( vec_x, vec_x0, sizeof(double)*nVar );
  
  /*------------------------------------------------------------------- 
   Call the QP solver.
   -------------------------------------------------------------------*/

  if( mxIsSparse(mat_H)== true )
  {
    col_buf0 = mxCalloc(nVar,sizeof(double));
    if( col_buf0 == NULL)
      mexErrMsgTxt("Cannot allocate memory for col_buf0.");      

    col_buf1 = mxCalloc(nVar,sizeof(double));
    if( col_buf1 == NULL)
      mexErrMsgTxt("Cannot allocate memory for col_buf1.");      

    /*    tmp = get_col_sparse(nVar-1);
    for(i=0; i<nVar; i++)
    {
    mexPrintf("%d: %f\n",i,tmp[i]);
      vec_x[i] = tmp[i];
    }
*/
    
    state = libqp_splx_solver(&get_col_sparse, diag_H, vec_f, vec_b, vec_I, vec_S, vec_x, nVar, 
           MaxIter, TolAbs, TolRel, QP_TH, NULL);

    mxFree(col_buf0);
    mxFree(col_buf1);
    
  }
  else
  {

    /*    tmp = get_col(nVar-1);
    for(i=0; i<nVar; i++)
    {
       mexPrintf("%d: %f\n",i,tmp[i]);
      vec_x[i] = tmp[i];
    }
    */
   
    state = libqp_splx_solver(&get_col, diag_H, vec_f, vec_b, vec_I, vec_S, vec_x, nVar, 
                              MaxIter, TolAbs, TolRel, QP_TH, NULL);
   
  }
  
  /*------------------------------------------------------------------- 
    Set output arguments                                                   
    [x,QP,QD,exitflag,nIter] = libqp_splx_mex(...)
  ------------------------------------------------------------------- */

  plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
  *(mxGetPr(plhs[1])) = (double)state.QP;

  plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL);
  *(mxGetPr(plhs[2])) = (double)state.QD;

  plhs[3] = mxCreateDoubleMatrix(1,1,mxREAL);
  *(mxGetPr(plhs[3])) = (double)state.exitflag;

  plhs[4] = mxCreateDoubleMatrix(1,1,mxREAL);
  *(mxGetPr(plhs[4])) = (double)state.nIter;

  
  return; 
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
  FILE *input_fid = NULL;
  FILE *output_fid = NULL;
  char *input_fname;  
  char *output_fname; 
  int nMatrices;
  int i, j, idx;
  mtf_matrix_t *matrix_array = NULL;
  uint32_t nConstr;
  double *diag_H = NULL;
  double *vec_f = NULL;
  double *vec_b = NULL;
  uint32_t *vec_I = NULL;
  uint8_t *vec_S = NULL;
  double *vec_x = NULL;
  libqp_state_T exitflag;
  uint32_t MaxIter = 0xFFFFFFFF;
  double TolAbs = 0.0;                  
  double TolRel = 1e-9;
  double QP_TH = -LIBQP_PLUS_INF;
  double load_time = 0;
  double solver_time = 0;
  double total_time = get_time();

  if(argc != 3)
  {
    fprintf(stderr,"Usage: qpsplx input_file output_file\n");
    return(0);
  }
    
  input_fname = argv[1];
  output_fname = argv[2];

  fprintf(stdout,"Input file: %s\n", input_fname);
  fprintf(stdout,"Output file: %s\n", output_fname);

  input_fid = fopen(input_fname, "r");
  if(input_fid == NULL) 
  {
    perror("fopen error: ");
    fprintf(stderr,"Cannot open input file.");
    return(0);
  }

  load_time = get_time();
  nMatrices = mtf_read_file(input_fid, &matrix_array);
  load_time = get_time()-load_time;

  if(nMatrices < 1) 
  {
    fprintf(stderr,"Error when reading matrices from file.\n");
    mtf_print_error( nMatrices );
    goto cleanup;
  }

  if(nMatrices != 5)
  {
    fprintf(stderr,"Input file must contain five matrices/vectors.");
    goto cleanup_free_matrices;
  }

  /*  fprintf(stdout,"Number of loaded matrices: %d\n", nMatrices);
  for(i=0; i < nMatrices; i++ )
  {    
    fprintf(stdout,"name: %s  nRows: %d  nCols: %d\n", 
            matrix_array[i].name, matrix_array[i].nRows, matrix_array[i].nCols);
  }
  */

  /*--------------------------------------------------*/
  /* Get input matrices and vectors                   */
  /*--------------------------------------------------*/
  idx = mtf_get_index("H",matrix_array,nMatrices);
  if(idx < 0 )
  {
    fprintf(stderr,"Matrix H not found.\n");
    goto cleanup_free_matrices;    
  }
  mat_H = matrix_array[idx].value;
  nVars = matrix_array[idx].nCols;

  idx = mtf_get_index("f",matrix_array,nMatrices);
  if(idx < 0 )
  {
    fprintf(stderr,"Vector f not found.\n");
    goto cleanup_free_matrices;    
  }
  vec_f = matrix_array[idx].value;
  
  idx = mtf_get_index("b",matrix_array,nMatrices);
  if(idx < 0 )
  {
    fprintf(stderr,"Vector b not found.\n");
    goto cleanup_free_matrices;    
  }
  vec_b = matrix_array[idx].value;      
  nConstr = LIBQP_MAX(matrix_array[idx].nCols,matrix_array[idx].nRows);
  
  idx = mtf_get_index("I",matrix_array,nMatrices);
  if(idx < 0 )
  {
    fprintf(stderr,"Vector I not found.\n");
    goto cleanup_free_matrices;    
  }
  vec_I = calloc(nVars,sizeof(uint32_t));
  if(vec_I == NULL) {
    fprintf(stderr,"Not enough memory.\n");
    goto cleanup_free_matrices;
  }
  for(i=0; i < nVars; i++)
    vec_I[i] = (uint32_t)matrix_array[idx].value[i];


  idx = mtf_get_index("S",matrix_array,nMatrices);
  if(idx < 0 )
  {
    fprintf(stderr,"Vector S not found.\n");
    goto cleanup_free_matrices;    
  }
  vec_S = calloc(nConstr,sizeof(uint8_t));      
  if(vec_S == NULL) {
    fprintf(stderr,"Not enough memory.\n");
    goto cleanup_free_matrices;
  }
  for(i=0; i < nConstr; i++)
    vec_S[i] = (uint8_t)matrix_array[idx].value[i];


  diag_H = calloc(nVars,sizeof(double));
  if(diag_H == NULL) {
    fprintf(stderr,"Not enough memory.\n");
    goto cleanup_free_matrices;
  }

  for(i=0; i < nVars; i++)
    diag_H[i] = mat_H[LIBQP_INDEX(i,i,nVars)];


  /*--------------------------------------------------*/
  /* Create initial feasible solution                 */
  /*--------------------------------------------------*/
  vec_x = calloc(nVars, sizeof(double)); 
  if( vec_x == NULL )
  {
    fprintf(stderr,"Not enough memory.\n");
    goto cleanup_free_matrices;
  }
  for(i=0; i < nVars; i++)
    vec_x[i] = 0.0;

  for(i=0; i < nConstr; i++ )
  {
    if(vec_S[i] == 0)
    {
      for(j=0; j < nVars; j++)
      {
        if(vec_I[j] == i+1)
        {
          vec_x[j] = vec_b[i];
          break;
        }
      }
    }
  }

  printf("nVar: %d  nConstr: %d\n", nVars, nConstr);

  /*--------------------------------------------------*/
  /* Call the QP solver and print results             */
  /*--------------------------------------------------*/

  printf("Solving QP..."); fflush(stdout); 
  solver_time = get_time();

  exitflag = libqp_splx_solver(get_col_of_mat_H, diag_H, vec_f, vec_b,
                               vec_I, vec_S, vec_x, nVars, MaxIter,
                               TolAbs, TolRel, QP_TH, NULL);

  solver_time = get_time()-solver_time;
  printf("done.\n");

  total_time= get_time() - total_time;

  printf("QP: %f\n", exitflag.QP);
  printf("QD: %f\n", exitflag.QD);
  printf("nIter: %d\n", exitflag.nIter);
  printf("exitflag: %d\n", exitflag.exitflag);
  printf("load_time: %f\n", load_time);
  printf("solver_time: %f\n", solver_time);
  printf("total_time: %f\n", total_time);

  /*--------------------------------------------------*/
  /* Write result to file                             */
  /*--------------------------------------------------*/

  output_fid = fopen(output_fname, "w+");
  if(output_fid == NULL) 
  {
    perror("fopen error: ");
    fprintf(stderr,"Cannot open input file.");
    goto cleanup_free_matrices;
  }

  fprintf(output_fid,"6\n");
  fprintf(output_fid,"QP 1 1\n");
  fprintf(output_fid,"%.12f\n",exitflag.QP);

  fprintf(output_fid,"QD 1 1\n");
  fprintf(output_fid,"%.12f\n",exitflag.QD);

  fprintf(output_fid,"nIter 1 1\n");
  fprintf(output_fid,"%d\n",exitflag.nIter);

  fprintf(output_fid,"exitflag 1 1\n");
  fprintf(output_fid,"%d\n",exitflag.exitflag);

  fprintf(output_fid,"solver_time 1 1\n");
  fprintf(output_fid,"%.12f\n",solver_time);

  fprintf(output_fid,"x %d 1\n", nVars);
  for(i=0; i < nVars; i++ )
    fprintf(output_fid,"%.12f\n", vec_x[i]);

  fclose(output_fid); 

cleanup_free_matrices: 

  free(diag_H);
  free(vec_I); 
  free(vec_S); 
  free(vec_x); 

  for(i=0; i < nMatrices; i++ )  
    free(matrix_array[i].value); 
  
cleanup:  
  fclose(input_fid); 

  return(0); 
}