Squashed 'third_party/osqp/' content from commit 33454b3e23
Change-Id: I056df0582ca06664e86554c341a94c47ab932001
git-subtree-dir: third_party/osqp
git-subtree-split: 33454b3e236f1f44193bfbbb6b8c8e71f8f04e9a
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/tests/lin_alg/test_lin_alg.h b/tests/lin_alg/test_lin_alg.h
new file mode 100644
index 0000000..735216e
--- /dev/null
+++ b/tests/lin_alg/test_lin_alg.h
@@ -0,0 +1,292 @@
+#include <stdio.h>
+#include "osqp.h"
+#include "osqp_tester.h"
+
+#include "lin_alg/data.h"
+
+void test_constr_sparse_mat() {
+ c_float *Adns; // Conversion to dense matrix
+
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+ // Convert sparse to dense
+ Adns = csc_to_dns(data->test_sp_matrix_A);
+
+ // Compute norm of the elementwise difference with
+ mu_assert("Linear algebra tests: error in constructing sparse/dense matrix!",
+ vec_norm_inf_diff(Adns, data->test_sp_matrix_Adns,
+ data->test_sp_matrix_A->m *
+ data->test_sp_matrix_A->n) < TESTS_TOL);
+
+ // Free memory
+ c_free(Adns); // because of vars from file matrices.h
+ clean_problem_lin_alg_sols_data(data);
+
+}
+
+void test_vec_operations() {
+ c_float norm_inf, vecprod; // normInf;
+ c_float *ew_reciprocal;
+ c_float *add_scaled;
+ c_float *vec_ew_max_vec_test, *vec_ew_min_vec_test;
+
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+
+ // Add scaled
+ add_scaled = vec_copy(data->test_vec_ops_v1, data->test_vec_ops_n);
+ vec_add_scaled(add_scaled,
+ add_scaled,
+ data->test_vec_ops_v2,
+ data->test_vec_ops_n,
+ data->test_vec_ops_sc);
+ mu_assert(
+ "Linear algebra tests: error in vector operation, adding scaled vector",
+ vec_norm_inf_diff(add_scaled, data->test_vec_ops_add_scaled,
+ data->test_vec_ops_n) < TESTS_TOL);
+
+ // Norm_inf of the difference
+ mu_assert(
+ "Linear algebra tests: error in vector operation, norm_inf of difference",
+ c_absval(vec_norm_inf_diff(data->test_vec_ops_v1,
+ data->test_vec_ops_v2,
+ data->test_vec_ops_n) -
+ data->test_vec_ops_norm_inf_diff) <
+ TESTS_TOL);
+
+ // norm_inf
+ norm_inf = vec_norm_inf(data->test_vec_ops_v1, data->test_vec_ops_n);
+ mu_assert("Linear algebra tests: error in vector operation, norm_inf",
+ c_absval(norm_inf - data->test_vec_ops_norm_inf) < TESTS_TOL);
+
+ // Elementwise reciprocal
+ ew_reciprocal = (c_float *)c_malloc(data->test_vec_ops_n * sizeof(c_float));
+ vec_ew_recipr(data->test_vec_ops_v1, ew_reciprocal, data->test_vec_ops_n);
+ mu_assert(
+ "Linear algebra tests: error in vector operation, elementwise reciprocal",
+ vec_norm_inf_diff(ew_reciprocal, data->test_vec_ops_ew_reciprocal,
+ data->test_vec_ops_n) < TESTS_TOL);
+
+
+ // Vector product
+ vecprod = vec_prod(data->test_vec_ops_v1,
+ data->test_vec_ops_v2,
+ data->test_vec_ops_n);
+ mu_assert("Linear algebra tests: error in vector operation, vector product",
+ c_absval(vecprod - data->test_vec_ops_vec_prod) < TESTS_TOL);
+
+ // Elementwise maximum between two vectors
+ vec_ew_max_vec_test =
+ (c_float *)c_malloc(data->test_vec_ops_n * sizeof(c_float));
+ vec_ew_max_vec(data->test_vec_ops_v1,
+ data->test_vec_ops_v2,
+ vec_ew_max_vec_test,
+ data->test_vec_ops_n);
+ mu_assert(
+ "Linear algebra tests: error in vector operation, elementwise maximum between vectors",
+ vec_norm_inf_diff(vec_ew_max_vec_test, data->test_vec_ops_ew_max_vec,
+ data
+ ->test_vec_ops_n) < TESTS_TOL);
+
+ // Elementwise minimum between two vectors
+ vec_ew_min_vec_test =
+ (c_float *)c_malloc(data->test_vec_ops_n * sizeof(c_float));
+ vec_ew_min_vec(data->test_vec_ops_v1,
+ data->test_vec_ops_v2,
+ vec_ew_min_vec_test,
+ data->test_vec_ops_n);
+ mu_assert(
+ "Linear algebra tests: error in vector operation, elementwise minimum between vectors",
+ vec_norm_inf_diff(vec_ew_min_vec_test, data->test_vec_ops_ew_min_vec,
+ data
+ ->test_vec_ops_n) < TESTS_TOL);
+
+ // cleanup
+ c_free(add_scaled);
+ c_free(ew_reciprocal);
+ c_free(vec_ew_min_vec_test);
+ c_free(vec_ew_max_vec_test);
+ clean_problem_lin_alg_sols_data(data);
+}
+
+void test_mat_operations() {
+ csc *Ad, *dA; // Matrices used for tests
+ // csc *A_ewsq, *A_ewabs; // Matrices used for tests
+ c_int exitflag = 0;
+
+ // c_float trace, fro_sq;
+ c_float *inf_norm_cols_rows_test;
+
+
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+
+ // Copy matrices
+ Ad = copy_csc_mat(data->test_mat_ops_A);
+ dA = copy_csc_mat(data->test_mat_ops_A);
+
+
+ // Premultiply matrix A
+ mat_premult_diag(dA, data->test_mat_ops_d);
+ mu_assert(
+ "Linear algebra tests: error in matrix operation, premultiply diagonal",
+ is_eq_csc(dA, data->test_mat_ops_prem_diag, TESTS_TOL));
+
+
+ // Postmultiply matrix A
+ mat_postmult_diag(Ad, data->test_mat_ops_d);
+ mu_assert(
+ "Linear algebra tests: error in matrix operation, postmultiply diagonal",
+ is_eq_csc(Ad, data->test_mat_ops_postm_diag, TESTS_TOL));
+
+ // Maximum norm over columns
+ inf_norm_cols_rows_test =
+ (c_float *)c_malloc(data->test_mat_ops_n * sizeof(c_float));
+ mat_inf_norm_cols(data->test_mat_ops_A, inf_norm_cols_rows_test);
+ mu_assert(
+ "Linear algebra tests: error in matrix operation, max norm over columns",
+ vec_norm_inf_diff(inf_norm_cols_rows_test, data->test_mat_ops_inf_norm_cols,
+ data
+ ->test_mat_ops_n) < TESTS_TOL);
+
+ // Maximum norm over rows
+ mat_inf_norm_rows(data->test_mat_ops_A, inf_norm_cols_rows_test);
+ mu_assert("Linear algebra tests: error in matrix operation, max norm over rows",
+ vec_norm_inf_diff(inf_norm_cols_rows_test,
+ data->test_mat_ops_inf_norm_rows,
+ data
+ ->test_mat_ops_n) < TESTS_TOL);
+
+
+ // cleanup
+ c_free(inf_norm_cols_rows_test);
+ csc_spfree(Ad);
+ csc_spfree(dA);
+ clean_problem_lin_alg_sols_data(data);
+}
+
+void test_mat_vec_multiplication() {
+ c_float *Ax, *ATy, *Px, *Ax_cum, *ATy_cum, *Px_cum;
+
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+
+ // Allocate vectors
+ Ax = (c_float *)c_malloc(data->test_mat_vec_m * sizeof(c_float));
+ ATy = (c_float *)c_malloc(data->test_mat_vec_n * sizeof(c_float));
+ Px = (c_float *)c_malloc(data->test_mat_vec_n * sizeof(c_float));
+
+
+ // Matrix-vector multiplication: y = Ax
+ mat_vec(data->test_mat_vec_A, data->test_mat_vec_x, Ax, 0);
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, matrix-vector multiplication",
+ vec_norm_inf_diff(Ax, data->test_mat_vec_Ax,
+ data->test_mat_vec_m) < TESTS_TOL);
+
+ // Cumulative matrix-vector multiplication: y += Ax
+ Ax_cum = vec_copy(data->test_mat_vec_y, data->test_mat_vec_m);
+ mat_vec(data->test_mat_vec_A, data->test_mat_vec_x, Ax_cum, 1);
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, cumulative matrix-vector multiplication",
+ vec_norm_inf_diff(Ax_cum, data->test_mat_vec_Ax_cum,
+ data->test_mat_vec_m) < TESTS_TOL);
+
+ // Matrix-transpose-vector multiplication: x = A'*y
+ mat_tpose_vec(data->test_mat_vec_A, data->test_mat_vec_y, ATy, 0, 0);
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, matrix-transpose-vector multiplication",
+ vec_norm_inf_diff(ATy, data->test_mat_vec_ATy,
+ data->test_mat_vec_n) < TESTS_TOL);
+
+ // Cumulative matrix-transpose-vector multiplication: x += A'*y
+ ATy_cum = vec_copy(data->test_mat_vec_x, data->test_mat_vec_n);
+ mat_tpose_vec(data->test_mat_vec_A, data->test_mat_vec_y, ATy_cum, 1, 0);
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, cumulative matrix-transpose-vector multiplication",
+ vec_norm_inf_diff(ATy_cum, data->test_mat_vec_ATy_cum,
+ data->test_mat_vec_n) < TESTS_TOL);
+
+ // Symmetric-matrix-vector multiplication (only upper part is stored)
+ mat_vec(data->test_mat_vec_Pu, data->test_mat_vec_x, Px, 0); // upper
+ // traingular
+ // part
+ mat_tpose_vec(data->test_mat_vec_Pu, data->test_mat_vec_x, Px, 1, 1); // lower
+ // traingular
+ // part
+ // (without
+ // diagonal)
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, symmetric matrix-vector multiplication",
+ vec_norm_inf_diff(Px, data->test_mat_vec_Px,
+ data->test_mat_vec_n) < TESTS_TOL);
+
+
+ // Cumulative symmetric-matrix-vector multiplication
+ Px_cum = vec_copy(data->test_mat_vec_x, data->test_mat_vec_n);
+ mat_vec(data->test_mat_vec_Pu, data->test_mat_vec_x, Px_cum, 1); // upper
+ // traingular
+ // part
+ mat_tpose_vec(data->test_mat_vec_Pu, data->test_mat_vec_x, Px_cum, 1, 1); // lower
+ // traingular
+ // part
+ // (without
+ // diagonal)
+ mu_assert(
+ "Linear algebra tests: error in matrix-vector operation, cumulative symmetric matrix-vector multiplication",
+ vec_norm_inf_diff(Px_cum, data->test_mat_vec_Px_cum,
+ data->test_mat_vec_n) < TESTS_TOL);
+
+
+ // cleanup
+ c_free(Ax);
+ c_free(ATy);
+ c_free(Px);
+ c_free(Ax_cum);
+ c_free(ATy_cum);
+ c_free(Px_cum);
+ clean_problem_lin_alg_sols_data(data);
+}
+
+void test_extract_upper_triangular() {
+ c_float *inf_norm_cols_test;
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+ // Extract upper triangular part
+ csc *Ptriu = csc_to_triu(data->test_mat_extr_triu_P);
+
+ mu_assert("Linear algebra tests: error in forming upper triangular matrix!",
+ is_eq_csc(data->test_mat_extr_triu_Pu, Ptriu, TESTS_TOL));
+
+ // Compute infinity norm over columns of the original matrix by using the
+ // upper triangular part only
+ inf_norm_cols_test = (c_float *)c_malloc(data->test_mat_extr_triu_n
+ * sizeof(c_float));
+ mat_inf_norm_cols_sym_triu(Ptriu, inf_norm_cols_test);
+ mu_assert(
+ "Linear algebra tests: error in forming upper triangular matrix, infinity norm over columns",
+ vec_norm_inf_diff(inf_norm_cols_test,
+ data->test_mat_extr_triu_P_inf_norm_cols,
+ data->test_mat_extr_triu_n) < TESTS_TOL);
+
+ // Cleanup
+ c_free(inf_norm_cols_test);
+ csc_spfree(Ptriu);
+ clean_problem_lin_alg_sols_data(data);
+}
+
+void test_quad_form_upper_triang() {
+ c_float quad_form_t;
+
+ lin_alg_sols_data *data = generate_problem_lin_alg_sols_data();
+
+ // Compute quadratic form
+ quad_form_t = quad_form(data->test_qpform_Pu, data->test_qpform_x);
+
+ mu_assert(
+ "Linear algebra tests: error in computing quadratic form using upper triangular matrix!",
+ (c_absval(quad_form_t - data->test_qpform_value) < TESTS_TOL));
+
+ // cleanup
+ clean_problem_lin_alg_sols_data(data);
+}
\ No newline at end of file