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; }
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; }
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; }
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(); }
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."); } }
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; }
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(); }
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); }
complex128_t SGMatrix<complex128_t>::max_single() { SG_SERROR("SGMatrix::max_single():: Not supported for complex128_t\n"); return complex128_t(0.0); }
void SGSparseMatrix<complex64_t>::load(CFile* loader) { SG_SERROR("SGSparseMatrix::load():: Not supported for complex64_t"); }
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); }
void SGSparseMatrix<complex64_t>::save(CFile* saver) { SG_SERROR("SGSparseMatrix::save():: Not supported for complex64_t"); }
SGVector<index_t> SGVector<complex64_t>::argsort() { SG_SERROR("SGVector::argsort():: Not supported for complex64_t\n"); SGVector<index_t> idx(vlen); return idx; }
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; };