27 CMosek::CMosek(int32_t num_con, int32_t num_var)
31 #if (MSK_VERSION_MAJOR == 6)
32 m_rescode = MSK_makeenv(&m_env, NULL, NULL, NULL, NULL);
33 #elif (MSK_VERSION_MAJOR == 7)
34 m_rescode = MSK_makeenv(&m_env, NULL);
36 #error "Unsupported Mosek version"
41 if ( m_rescode == MSK_RES_OK )
43 m_rescode = MSK_linkfunctoenvstream(m_env, MSK_STREAM_LOG,
49 if ( m_rescode == MSK_RES_OK )
51 m_rescode = MSK_initenv(m_env);
55 if ( m_rescode == MSK_RES_OK )
57 m_rescode = MSK_maketask(m_env, num_con, num_var, &m_task);
62 if ( m_rescode == MSK_RES_OK )
64 m_rescode = MSK_linkfunctotaskstream(m_task, MSK_STREAM_LOG,
80 MSKrescodee CMosek::init_sosvm(int32_t M, int32_t N,
81 int32_t num_aux, int32_t num_aux_con,
88 int32_t num_var = M+N+num_aux;
89 int32_t num_con = N*N+num_aux_con;
92 m_rescode = MSK_putmaxnumvar(m_task, num_var);
95 m_rescode = MSK_putmaxnumcon(m_task, num_con);
97 m_rescode = MSK_putmaxnumanz(m_task, (M+1)*N*N);
100 #if (MSK_VERSION_MAJOR == 6)
101 m_rescode = MSK_append(m_task, MSK_ACC_VAR, num_var);
102 #elif (MSK_VERSION_MAJOR == 7)
103 m_rescode = MSK_appendvars(m_task, num_var);
105 #error "Unsupported Mosek version"
108 #if (MSK_VERSION_MAJOR == 6)
109 m_rescode = MSK_append(m_task, MSK_ACC_CON, num_con);
110 #elif (MSK_VERSION_MAJOR == 7)
111 m_rescode = MSK_appendcons(m_task, num_con);
113 #error "Unsupported Mosek version"
116 m_rescode = MSK_putcfix(m_task, 0.0);
131 REQUIRE(lb.
vlen >= M,
"CMosek::init_sosvm(): lb.vlen < dimension of feature space.\n");
132 REQUIRE(ub.
vlen >= M,
"CMosek::init_sosvm(): ub.vlen < dimension of feature space.\n");
134 for ( int32_t j = 0 ; j < num_var && m_rescode == MSK_RES_OK ; ++j )
138 m_rescode = MSK_putcj(m_task, j, 0.0);
140 m_rescode = MSK_putcj(m_task, j, 1.0);
145 if (lb[j] > -MSK_INFINITY && ub[j] < +MSK_INFINITY && lb[j] != ub[j])
148 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
149 MSK_BK_RA, lb[j], ub[j]);
151 else if (lb[j] > -MSK_INFINITY && ub[j] < +MSK_INFINITY && lb[j] == ub[j])
154 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
155 MSK_BK_FX, lb[j], ub[j]);
157 else if (lb[j] <= -MSK_INFINITY && ub[j] < +MSK_INFINITY)
160 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
161 MSK_BK_UP, -MSK_INFINITY, ub[j]);
163 else if (lb[j] > -MSK_INFINITY && ub[j] >= +MSK_INFINITY)
166 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
167 MSK_BK_LO, lb[j], +MSK_INFINITY);
172 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
173 MSK_BK_FR, -MSK_INFINITY, +MSK_INFINITY);
180 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
181 MSK_BK_LO, 0.0, +MSK_INFINITY);
190 m_rescode = wrapper_putqobj(C);
193 m_rescode = wrapper_putaveclist(m_task, A);
194 m_rescode = wrapper_putboundlist(m_task, b);
196 REQUIRE(m_rescode == MSK_RES_OK,
"MOSEK Error in CMosek::init_sosvm(). "
197 "Enable DEBUG_MOSEK for details.\n");
202 MSKrescodee CMosek::add_constraint_sosvm(
218 for ( int32_t i = 0 ; i < dPsi.
vlen ; ++i )
230 asub[idx] = dPsi.vlen + num_aux + train_idx;
233 #if (MSK_VERSION_MAJOR == 6)
234 m_rescode = MSK_putavec(m_task, MSK_ACC_CON, con_idx, nnz+1,
235 asub.vector, aval.vector);
236 #elif (MSK_VERSION_MAJOR == 7)
237 m_rescode = MSK_putarow(m_task, con_idx, nnz+1, asub.vector, aval.vector);
239 #error "Unsupported Mosek version"
242 if ( m_rescode == MSK_RES_OK )
244 m_rescode = MSK_putbound(m_task, MSK_ACC_CON, con_idx,
245 MSK_BK_UP, -MSK_INFINITY, bi);
251 MSKrescodee CMosek::wrapper_putaveclist(
272 bool first_nnz_found =
false;
276 first_nnz_found =
false;
285 if ( !first_nnz_found )
288 first_nnz_found =
true;
298 if ( !first_nnz_found )
299 ptrb[i] = ( i ? ptrb[i-1] : 0 );
312 #if (MSK_VERSION_MAJOR == 6)
313 ret = MSK_putaveclist(task, MSK_ACC_CON, A.
num_rows, sub.vector,
314 ptrb.vector, ptre.vector,
315 asub.vector, aval.vector);
316 #elif (MSK_VERSION_MAJOR == 7)
317 ret = MSK_putarowlist(task, A.
num_rows, sub.vector, ptrb.vector, ptre.vector,
318 asub.vector, aval.vector);
320 #error "Unsupported Mosek version"
323 REQUIRE(ret == MSK_RES_OK,
"MOSEK Error in CMosek::wrapper_putaveclist(). "
324 "Enable DEBUG_MOSEK for details.\n");
338 MSKboundkeye* bk = SG_MALLOC(MSKboundkeye, b.
vlen);
343 bl[i] = -MSK_INFINITY;
346 MSKrescodee ret = MSK_putboundlist(task, MSK_ACC_CON, b.
vlen, sub.vector,
351 REQUIRE(ret == MSK_RES_OK,
"MOSEK Error in CMosek::wrapper_putboundlist(). "
352 "Enable DEBUG_MOSEK for details.\n");
366 for (
index_t i = 0 ; i < N ; ++i )
367 for (
index_t j = i ; j < M ; ++j )
368 nnz += ( Q0[j + i*M] ? 1 : 0 );
379 for (
index_t i = 0 ; i < N ; ++i )
380 for (
index_t j = i ; j < M ; ++j )
386 qoval[idx] = Q0[j + i*M];
392 return MSK_putqobj(m_task, nnz, qosubi.vector,
393 qosubj.vector, qoval.vector);
398 m_rescode = MSK_optimize(m_task);
402 MSK_solutionsummary(m_task, MSK_STREAM_LOG);
406 if ( m_rescode == MSK_RES_OK )
414 #if (MSK_VERSION_MAJOR == 6)
415 MSK_getsolutionstatus(m_task, MSK_SOL_ITR, NULL, &solsta);
416 #elif (MSK_VERSION_MAJOR == 7)
417 MSK_getsolsta(m_task, MSK_SOL_ITR, &solsta);
419 #error "Unsupported Mosek Version"
423 case MSK_SOL_STA_OPTIMAL:
424 case MSK_SOL_STA_NEAR_OPTIMAL:
425 MSK_getsolutionslice(m_task,
433 #ifdef DEBUG_SOLUTION
437 case MSK_SOL_STA_DUAL_INFEAS_CER:
438 case MSK_SOL_STA_PRIM_INFEAS_CER:
439 case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
440 case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
442 SG_PRINT(
"Primal or dual infeasibility "
443 "certificate found\n");
446 case MSK_SOL_STA_UNKNOWN:
448 SG_PRINT(
"Undetermined solution status\n")
461 if ( m_rescode != MSK_RES_OK )
463 char symname[MSK_MAX_STR_LEN];
464 char desc[MSK_MAX_STR_LEN];
466 MSK_getcodedesc(m_rescode, symname, desc);
468 SG_PRINT(
"An error occurred optimizing with MOSEK\n")
469 SG_PRINT("ERROR %s - '%s'\n", symname, desc)
475 void CMosek::delete_problem()
477 MSK_deletetask(&m_task);
478 MSK_deleteenv(&m_env);
481 void CMosek::display_problem()
483 int32_t num_var, num_con;
484 m_rescode = MSK_getnumvar(m_task, &num_var);
485 m_rescode = MSK_getnumcon(m_task, &num_con);
488 for ( int32_t i = 0 ; i < num_var ; ++i )
490 for ( int32_t j = 0 ; j < num_var ; ++j )
493 m_rescode = MSK_getqobjij(m_task, i, j, &qij);
495 SG_PRINT(
"(%d,%d)\t%.2f\n", i, j, qij)
502 m_rescode = MSK_getc(m_task, c.vector);
506 for ( int32_t i = 0 ; i < num_con ; ++i )
508 for ( int32_t j = 0 ; j < num_var ; ++j )
511 m_rescode = MSK_getaij(m_task, i, j, &aij);
513 SG_PRINT(
"(%d,%d)\t%.2f\n", i, j, aij)
518 SG_PRINT("\nConstraint Bounds, vector b:\n")
519 for ( int32_t i = 0 ; i < num_con ; ++i )
523 m_rescode = MSK_getbound(m_task, MSK_ACC_CON, i, &bk, &bl, &bu);
528 SG_PRINT(
"\nVariable Bounds, vectors lb and ub:\n")
529 for ( int32_t i = 0 ; i < num_var ; ++i )
533 m_rescode = MSK_getbound(m_task, MSK_ACC_VAR, i, &bk, &bl, &bu);
541 float64_t CMosek::get_primal_objective_value()
const
544 MSK_getprimalobj(m_task, MSK_SOL_ITR, &po);
static void fill_vector(T *vec, int32_t len, T value)
void print(int depth, node< P > &top_node)
void display_vector(const char *name="vector", const char *prefix="") const
Class SGObject is the base class of all shogun objects.
static int32_t get_num_nonzero(T *vec, int32_t len)
all of classes and functions are contained in the shogun namespace