123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- #include <stdio.h>
- #include "osqp.h"
- #include "minunit.h"
- #include "lin_alg/data.h"
- static const char* 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);
- return 0;
- }
- static const char* 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);
- return 0;
- }
- static const char* 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);
- return 0;
- }
- static const char* 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);
- return 0;
- }
- static const char* 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);
- return 0;
- }
- static const char* 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);
- return 0;
- }
- static const char* test_lin_alg()
- {
- mu_run_test(test_constr_sparse_mat);
- mu_run_test(test_vec_operations);
- mu_run_test(test_mat_operations);
- mu_run_test(test_mat_vec_multiplication);
- mu_run_test(test_extract_upper_triangular);
- mu_run_test(test_quad_form_upper_triang);
- return 0;
- }
|