Skip to content

Commit

Permalink
change printing for Matlab and R
Browse files Browse the repository at this point in the history
  • Loading branch information
RSchwan committed Jul 20, 2023
1 parent 6af7087 commit b718307
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 95 deletions.
12 changes: 12 additions & 0 deletions include/piqp/fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,16 @@

#define PIQP_INF 1e30

#ifdef MATLAB
#define c_print mexPrintf
#define c_eprint mexPrintf
#elif defined R_LANG
#include <R_ext/Print.h>
#define c_print Rprintf
#define c_eprint REprintf
#else
#define c_print printf
#define c_eprint(...) fprintf(stderr, __VA_ARGS__)
#endif

#endif //PIQP_FWD_HPP
137 changes: 70 additions & 67 deletions include/piqp/solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "piqp/sparse/data.hpp"
#include "piqp/sparse/preconditioner.hpp"
#include "piqp/sparse/kkt.hpp"
#include "piqp/utils.hpp"
#include "piqp/utils/optional.hpp"

namespace piqp
Expand Down Expand Up @@ -90,27 +89,27 @@ class SolverBase
{
if (m_settings.verbose)
{
printf("----------------------------------------------------------\n");
printf(" PIQP \n");
printf(" (c) Roland Schwan \n");
printf(" Ecole Polytechnique Federale de Lausanne (EPFL) 2023 \n");
printf("----------------------------------------------------------\n");
c_print("----------------------------------------------------------\n");
c_print(" PIQP \n");
c_print(" (c) Roland Schwan \n");
c_print(" Ecole Polytechnique Federale de Lausanne (EPFL) 2023 \n");
c_print("----------------------------------------------------------\n");
if (MatrixType == PIQP_DENSE)
{
printf("variables n = %zd\n", m_data.n);
printf("equality constraints p = %zd\n", m_data.p);
printf("inequality constraints m = %zd\n", m_data.m);
c_print("variables n = %zd\n", m_data.n);
c_print("equality constraints p = %zd\n", m_data.p);
c_print("inequality constraints m = %zd\n", m_data.m);
}
else
{
printf("variables n = %zd, nzz(P upper triangular) = %zd\n", m_data.n, m_data.non_zeros_P_utri());
printf("equality constraints p = %zd, nnz(A) = %zd\n", m_data.p, m_data.non_zeros_A());
printf("inequality constraints m = %zd, nnz(G) = %zd\n", m_data.m, m_data.non_zeros_G());
c_print("variables n = %zd, nzz(P upper triangular) = %zd\n", m_data.n, m_data.non_zeros_P_utri());
c_print("equality constraints p = %zd, nnz(A) = %zd\n", m_data.p, m_data.non_zeros_A());
c_print("inequality constraints m = %zd, nnz(G) = %zd\n", m_data.m, m_data.non_zeros_G());
}
printf("variable lower bounds n_lb = %zd\n", m_data.n_lb);
printf("variable upper bounds n_ub = %zd\n", m_data.n_ub);
printf("\n");
printf("iter prim_obj dual_obj duality_gap prim_inf dual_inf rho delta mu p_step d_step\n");
c_print("variable lower bounds n_lb = %zd\n", m_data.n_lb);
c_print("variable upper bounds n_ub = %zd\n", m_data.n_ub);
c_print("\n");
c_print("iter prim_obj dual_obj duality_gap prim_inf dual_inf rho delta mu p_step d_step\n");
}

if (m_settings.compute_timings)
Expand All @@ -132,16 +131,16 @@ class SolverBase

if (m_settings.verbose)
{
printf("\n");
printf("status: %s\n", status_to_string(status));
printf("number of iterations: %zd\n", m_result.info.iter);
printf("objective: %.5e\n", m_result.info.primal_obj);
c_print("\n");
c_print("status: %s\n", status_to_string(status));
c_print("number of iterations: %zd\n", m_result.info.iter);
c_print("objective: %.5e\n", m_result.info.primal_obj);
if (m_settings.compute_timings)
{
printf("total run time: %.3es\n", m_result.info.run_time);
printf(" setup time: %.3es\n", m_result.info.setup_time);
printf(" update time: %.3es\n", m_result.info.update_time);
printf(" solve time: %.3es\n", m_result.info.solve_time);
c_print("total run time: %.3es\n", m_result.info.run_time);
c_print(" setup time: %.3es\n", m_result.info.setup_time);
c_print(" update time: %.3es\n", m_result.info.update_time);
c_print(" solve time: %.3es\n", m_result.info.solve_time);
}
}

Expand All @@ -168,14 +167,14 @@ class SolverBase
m_data.p = A.rows();
m_data.m = G.rows();

assert_exit(P.rows() == m_data.n && P.cols() == m_data.n, "P must be square");
assert_exit(A.rows() == m_data.p && A.cols() == m_data.n, "A must have correct dimensions");
assert_exit(G.rows() == m_data.m && G.cols() == m_data.n, "G must have correct dimensions");
assert_exit(c.size() == m_data.n, "c must have correct dimensions");
assert_exit(b.size() == m_data.p, "b must have correct dimensions");
assert_exit(h.size() == m_data.m, "h must have correct dimensions");
if (x_lb.has_value()) { assert_exit(x_lb->size() == m_data.n, "x_lb must have correct dimensions"); }
if (x_ub.has_value()) { assert_exit(x_ub->size() == m_data.n, "x_ub must have correct dimensions"); }
if (P.rows() != m_data.n || P.cols() != m_data.n) { c_eprint("P must be square"); return; }
if (A.rows() != m_data.p || A.cols() != m_data.n) { c_eprint("A must have correct dimensions"); return; }
if (G.rows() != m_data.m || G.cols() != m_data.n) { c_eprint("G must have correct dimensions"); return; }
if (c.size() != m_data.n) { c_eprint("c must have correct dimensions"); return; }
if (b.size() != m_data.p) { c_eprint("b must have correct dimensions"); return; }
if (h.size() != m_data.m) { c_eprint("h must have correct dimensions"); return; }
if (x_lb.has_value() && x_lb->size() != m_data.n) { c_eprint("x_lb must have correct dimensions"); return; }
if (x_ub.has_value() && x_ub->size() != m_data.n) { c_eprint("x_ub must have correct dimensions"); return; }

m_data.P_utri = P.template triangularView<Eigen::Upper>();
m_data.AT = A.transpose();
Expand Down Expand Up @@ -319,7 +318,9 @@ class SolverBase

if (!m_setup_done)
{
assert_exit(false, "Solver not setup yet");
c_eprint("Solver not setup yet");
m_result.info.status = Status::PIQP_UNSOLVED;
return m_result.info.status;
}

if (!m_settings.verify_settings())
Expand Down Expand Up @@ -451,18 +452,18 @@ class SolverBase

if (m_settings.verbose)
{
printf("%3zd % .5e % .5e %.5e %.5e %.5e %.3e %.3e %.3e %.4f %.4f\n",
m_result.info.iter,
m_result.info.primal_obj,
m_result.info.dual_obj,
m_result.info.duality_gap,
m_result.info.primal_inf,
m_result.info.dual_inf,
m_result.info.rho,
m_result.info.delta,
m_result.info.mu,
m_result.info.primal_step,
m_result.info.dual_step);
c_print("%3zd % .5e % .5e %.5e %.5e %.5e %.3e %.3e %.3e %.4f %.4f\n",
m_result.info.iter,
m_result.info.primal_obj,
m_result.info.dual_obj,
m_result.info.duality_gap,
m_result.info.primal_inf,
m_result.info.dual_inf,
m_result.info.rho,
m_result.info.delta,
m_result.info.mu,
m_result.info.primal_step,
m_result.info.dual_step);
}

if (m_result.info.primal_inf < m_settings.eps_abs + m_settings.eps_rel * m_result.info.primal_rel_inf &&
Expand Down Expand Up @@ -921,7 +922,8 @@ class DenseSolver : public SolverBase<DenseSolver<T, Preconditioner>, T, int, Pr
{
if (!this->m_setup_done)
{
assert_exit(false, "Solver not setup yet");
c_eprint("Solver not setup yet");
return;
}

if (this->m_settings.compute_timings)
Expand All @@ -935,48 +937,48 @@ class DenseSolver : public SolverBase<DenseSolver<T, Preconditioner>, T, int, Pr

if (P.has_value())
{
assert_exit(P->rows() == this->m_data.n && P->cols() == this->m_data.n, "P has wrong dimensions");
if (P->rows() != this->m_data.n || P->cols() != this->m_data.n) { c_eprint("P has wrong dimensions"); return; }
this->m_data.P_utri = P->template triangularView<Eigen::Upper>();

update_options |= KKTUpdateOptions::KKT_UPDATE_P;
}

if (A.has_value())
{
assert_exit(A->rows() == this->m_data.p && A->cols() == this->m_data.n, "A has wrong dimensions");
if (A->rows() != this->m_data.p || A->cols() != this->m_data.n) { c_eprint("A has wrong dimensions"); return; }
this->m_data.AT = A->transpose();

update_options |= KKTUpdateOptions::KKT_UPDATE_A;
}

if (G.has_value())
{
assert_exit(G->rows() == this->m_data.m && G->cols() == this->m_data.n, "G has wrong dimensions");
if (G->rows() != this->m_data.m || G->cols() != this->m_data.n) { c_eprint("G has wrong dimensions"); return; }
this->m_data.GT = G->transpose();

update_options |= KKTUpdateOptions::KKT_UPDATE_G;
}

if (c.has_value())
{
assert_exit(c->size() == this->m_data.n, "c has wrong dimensions");
if (c->size() != this->m_data.n) { c_eprint("c has wrong dimensions"); return; }
this->m_data.c = *c;
}

if (b.has_value())
{
assert_exit(b->size() == this->m_data.p, "b has wrong dimensions");
if (b->size() != this->m_data.p) { c_eprint("b has wrong dimensions"); return; }
this->m_data.b = *b;
}

if (h.has_value())
{
assert_exit(h->size() == this->m_data.m, "h has wrong dimensions");
if (h->size() != this->m_data.m) { c_eprint("h has wrong dimensions"); return; }
this->m_data.h = (*h).cwiseMin(PIQP_INF).cwiseMax(-PIQP_INF);
}

if (x_lb.has_value()) { assert_exit(x_lb->size() == this->m_data.n, "x_lb has wrong dimensions"); }
if (x_ub.has_value()) { assert_exit(x_ub->size() == this->m_data.n, "x_ub has wrong dimensions"); }
if (x_lb.has_value() && x_lb->size() != this->m_data.n) { c_eprint("x_lb has wrong dimensions"); return; }
if (x_ub.has_value() && x_ub->size() != this->m_data.n) { c_eprint("x_ub has wrong dimensions"); return; }
if (x_lb.has_value()) { this->setup_lb_data(x_lb); }
if (x_ub.has_value()) { this->setup_ub_data(x_ub); }

Expand Down Expand Up @@ -1024,7 +1026,8 @@ class SparseSolver : public SolverBase<SparseSolver<T, I, Mode, Preconditioner>,
{
if (!this->m_setup_done)
{
assert_exit(false, "Solver not setup yet");
c_eprint("Solver not setup yet");
return;
}

if (this->m_settings.compute_timings)
Expand All @@ -1038,13 +1041,13 @@ class SparseSolver : public SolverBase<SparseSolver<T, I, Mode, Preconditioner>,

if (P.has_value())
{
assert_exit(P->rows() == this->m_data.n && P->cols() == this->m_data.n, "P has wrong dimensions");
if (P->rows() != this->m_data.n || P->cols() != this->m_data.n) { c_eprint("P has wrong dimensions"); return; }
isize n = P->outerSize();
for (isize j = 0; j < n; j++)
{
PIQP_MAYBE_UNUSED isize P_col_nnz = P->outerIndexPtr()[j + 1] - P->outerIndexPtr()[j];
isize P_col_nnz = P->outerIndexPtr()[j + 1] - P->outerIndexPtr()[j];
isize P_utri_col_nnz = this->m_data.P_utri.outerIndexPtr()[j + 1] - this->m_data.P_utri.outerIndexPtr()[j];
assert_exit(P_col_nnz >= P_utri_col_nnz, "P nonzeros missmatch");
if (P_col_nnz < P_utri_col_nnz) { c_eprint("P nonzeros missmatch"); return; }
Eigen::Map<Vec<T>>(this->m_data.P_utri.valuePtr() + this->m_data.P_utri.outerIndexPtr()[j], P_utri_col_nnz) = Eigen::Map<const Vec<T>>(P->valuePtr() + P->outerIndexPtr()[j], P_utri_col_nnz);
}

Expand All @@ -1053,42 +1056,42 @@ class SparseSolver : public SolverBase<SparseSolver<T, I, Mode, Preconditioner>,

if (A.has_value())
{
assert_exit(A->rows() == this->m_data.p && A->cols() == this->m_data.n, "A has wrong dimensions");
assert_exit(A->nonZeros() == this->m_data.AT.nonZeros(), "A nonzeros missmatch");
if (A->rows() != this->m_data.p || A->cols() != this->m_data.n) { c_eprint("A has wrong dimensions"); return; }
if (A->nonZeros() != this->m_data.AT.nonZeros()) { c_eprint("A nonzeros missmatch"); return; }
sparse::transpose_no_allocation(*A, this->m_data.AT);

update_options |= KKTUpdateOptions::KKT_UPDATE_A;
}

if (G.has_value())
{
assert_exit(G->rows() == this->m_data.m && G->cols() == this->m_data.n, "G has wrong dimensions");
assert_exit(G->nonZeros() == this->m_data.GT.nonZeros(), "G nonzeros missmatch");
if (G->rows() != this->m_data.m || G->cols() != this->m_data.n) { c_eprint("G has wrong dimensions"); return; }
if (G->nonZeros() != this->m_data.GT.nonZeros()) { c_eprint("G nonzeros missmatch"); return; }
sparse::transpose_no_allocation(*G, this->m_data.GT);

update_options |= KKTUpdateOptions::KKT_UPDATE_G;
}

if (c.has_value())
{
assert_exit(c->size() == this->m_data.n, "c has wrong dimensions");
if (c->size() != this->m_data.n) { c_eprint("c has wrong dimensions"); return; }
this->m_data.c = *c;
}

if (b.has_value())
{
assert_exit(b->size() == this->m_data.p, "b has wrong dimensions");
if (b->size() != this->m_data.p) { c_eprint("b has wrong dimensions"); return; }
this->m_data.b = *b;
}

if (h.has_value())
{
assert_exit(h->size() == this->m_data.m, "h has wrong dimensions");
if (h->size() != this->m_data.m) { c_eprint("h has wrong dimensions"); return; }
this->m_data.h = (*h).cwiseMin(PIQP_INF).cwiseMax(-PIQP_INF);
}

if (x_lb.has_value()) { assert_exit(x_lb->size() == this->m_data.n, "x_lb has wrong dimensions"); }
if (x_ub.has_value()) { assert_exit(x_ub->size() == this->m_data.n, "x_ub has wrong dimensions"); }
if (x_lb.has_value() && x_lb->size() != this->m_data.n) { c_eprint("x_lb has wrong dimensions"); return; }
if (x_ub.has_value() && x_ub->size() != this->m_data.n) { c_eprint("x_ub has wrong dimensions"); return; }
if (x_lb.has_value()) { this->setup_lb_data(x_lb); }
if (x_ub.has_value()) { this->setup_ub_data(x_ub); }

Expand Down
28 changes: 0 additions & 28 deletions include/piqp/utils.hpp

This file was deleted.

0 comments on commit b718307

Please sign in to comment.