20 using namespace shogun;
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);
118 for ( int32_t j = 0 ; j < num_var && m_rescode == MSK_RES_OK ; ++j )
122 m_rescode = MSK_putcj(m_task, j, 0.0);
124 m_rescode = MSK_putcj(m_task, j, 1.0);
130 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
131 MSK_BK_FR, -MSK_INFINITY, +MSK_INFINITY);
137 m_rescode = MSK_putbound(m_task, MSK_ACC_VAR, j,
138 MSK_BK_LO, 0.0, +MSK_INFINITY);
147 m_rescode = wrapper_putqobj(C);
150 m_rescode = wrapper_putaveclist(m_task, A);
151 m_rescode = wrapper_putboundlist(m_task, b);
153 REQUIRE(m_rescode == MSK_RES_OK,
"MOSEK Error in CMosek::init_sosvm(). "
154 "Enable DEBUG_MOSEK for details.\n");
159 MSKrescodee CMosek::add_constraint_sosvm(
167 int32_t nnz = CMath::get_num_nonzero(dPsi.
vector, dPsi.
vlen);
175 for ( int32_t i = 0 ; i < dPsi.
vlen ; ++i )
187 asub[idx] = dPsi.vlen + num_aux + train_idx;
190 #if (MSK_VERSION_MAJOR == 6)
191 m_rescode = MSK_putavec(m_task, MSK_ACC_CON, con_idx, nnz+1,
192 asub.vector, aval.vector);
193 #elif (MSK_VERSION_MAJOR == 7)
194 m_rescode = MSK_putarow(m_task, con_idx, nnz+1, asub.vector, aval.vector);
196 #error "Unsupported Mosek version"
199 if ( m_rescode == MSK_RES_OK )
201 m_rescode = MSK_putbound(m_task, MSK_ACC_CON, con_idx,
202 MSK_BK_UP, -MSK_INFINITY, bi);
208 MSKrescodee CMosek::wrapper_putaveclist(
229 bool first_nnz_found =
false;
233 first_nnz_found =
false;
242 if ( !first_nnz_found )
245 first_nnz_found =
true;
255 if ( !first_nnz_found )
256 ptrb[i] = ( i ? ptrb[i-1] : 0 );
269 #if (MSK_VERSION_MAJOR == 6)
270 ret = MSK_putaveclist(task, MSK_ACC_CON, A.
num_rows, sub.vector,
271 ptrb.vector, ptre.vector,
272 asub.vector, aval.vector);
273 #elif (MSK_VERSION_MAJOR == 7)
274 ret = MSK_putarowlist(task, A.
num_rows, sub.vector, ptrb.vector, ptre.vector,
275 asub.vector, aval.vector);
277 #error "Unsupported Mosek version"
280 REQUIRE(ret == MSK_RES_OK,
"MOSEK Error in CMosek::wrapper_putaveclist(). "
281 "Enable DEBUG_MOSEK for details.\n");
295 MSKboundkeye* bk = SG_MALLOC(MSKboundkeye, b.
vlen);
300 bl[i] = -MSK_INFINITY;
303 MSKrescodee ret = MSK_putboundlist(task, MSK_ACC_CON, b.
vlen, sub.vector,
308 REQUIRE(ret == MSK_RES_OK,
"MOSEK Error in CMosek::wrapper_putboundlist(). "
309 "Enable DEBUG_MOSEK for details.\n");
323 for (
index_t i = 0 ; i < N ; ++i )
324 for (
index_t j = i ; j < M ; ++j )
325 nnz += ( Q0[j + i*M] ? 1 : 0 );
336 for (
index_t i = 0 ; i < N ; ++i )
337 for (
index_t j = i ; j < M ; ++j )
343 qoval[idx] = Q0[j + i*M];
349 return MSK_putqobj(m_task, nnz, qosubi.vector,
350 qosubj.vector, qoval.vector);
355 m_rescode = MSK_optimize(m_task);
359 MSK_solutionsummary(m_task, MSK_STREAM_LOG);
363 if ( m_rescode == MSK_RES_OK )
371 #if (MSK_VERSION_MAJOR == 6)
372 MSK_getsolutionstatus(m_task, MSK_SOL_ITR, NULL, &solsta);
373 #elif (MSK_VERSION_MAJOR == 7)
374 MSK_getsolsta(m_task, MSK_SOL_ITR, &solsta);
376 #error "Unsupported Mosek Version"
380 case MSK_SOL_STA_OPTIMAL:
381 case MSK_SOL_STA_NEAR_OPTIMAL:
382 MSK_getsolutionslice(m_task,
390 #ifdef DEBUG_SOLUTION
394 case MSK_SOL_STA_DUAL_INFEAS_CER:
395 case MSK_SOL_STA_PRIM_INFEAS_CER:
396 case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
397 case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
399 SG_PRINT(
"Primal or dual infeasibility "
400 "certificate found\n");
403 case MSK_SOL_STA_UNKNOWN:
405 SG_PRINT(
"Undetermined solution status\n")
418 if ( m_rescode != MSK_RES_OK )
420 char symname[MSK_MAX_STR_LEN];
421 char desc[MSK_MAX_STR_LEN];
423 MSK_getcodedesc(m_rescode, symname, desc);
425 SG_PRINT(
"An error occurred optimizing with MOSEK\n")
426 SG_PRINT("ERROR %s - '%s'\n", symname, desc)
432 void CMosek::delete_problem()
434 MSK_deletetask(&m_task);
435 MSK_deleteenv(&m_env);
438 void CMosek::display_problem()
440 int32_t num_var, num_con;
441 m_rescode = MSK_getnumvar(m_task, &num_var);
442 m_rescode = MSK_getnumcon(m_task, &num_con);
445 for ( int32_t i = 0 ; i < num_var ; ++i )
447 for ( int32_t j = 0 ; j < num_var ; ++j )
450 m_rescode = MSK_getqobjij(m_task, i, j, &qij);
452 SG_PRINT(
"(%d,%d)\t%.2f\n", i, j, qij)
459 m_rescode = MSK_getc(m_task, c.vector);
463 for ( int32_t i = 0 ; i < num_con ; ++i )
465 for ( int32_t j = 0 ; j < num_var ; ++j )
468 m_rescode = MSK_getaij(m_task, i, j, &aij);
470 SG_PRINT(
"(%d,%d)\t%.2f\n", i, j, aij)
475 SG_PRINT("\nConstraint Bounds, vector b:\n")
476 for ( int32_t i = 0 ; i < num_con ; ++i )
480 m_rescode = MSK_getbound(m_task, MSK_ACC_CON, i, &bk, &bl, &bu);
485 SG_PRINT(
"\nVariable Bounds, vectors lb and ub:\n")
486 for ( int32_t i = 0 ; i < num_var ; ++i )
490 m_rescode = MSK_getbound(m_task, MSK_ACC_VAR, i, &bk, &bl, &bu);
498 float64_t CMosek::get_primal_objective_value()
const
501 MSK_getprimalobj(m_task, MSK_SOL_ITR, &po);