//------------------------------------------------------------------------------ // SPEX/MATLAB/SPEX_mex_get_A_and_b.c: convert A&b to SPEX matrices //------------------------------------------------------------------------------ // SPEX: (c) 2022-2024, Christopher Lourenco, Jinhao Chen, // Lorena Mejia Domenzain, Erick Moreno-Centeno, and Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0-or-later or LGPL-3.0-or-later //------------------------------------------------------------------------------ /* Purpose: This function reads in the A matrix and right hand side vectors. */ #include "SPEX_mex.h" void spex_mex_get_A_and_b ( SPEX_matrix *A_handle, // Internal SPEX Mat stored in CSC SPEX_matrix *b_handle, // mpz matrix used internally const mxArray* pargin[], // The input A matrix and options SPEX_options option ) { //-------------------------------------------------------------------------- // check inputs //-------------------------------------------------------------------------- if (!A_handle || !pargin) { spex_mex_error (SPEX_INCORRECT_INPUT, ""); } (*A_handle) = NULL ; //-------------------------------------------------------------------------- // Declare variables //-------------------------------------------------------------------------- SPEX_info status; int64_t nA, mA, nb, mb, Anz, k, j; int64_t *Ap, *Ai; double *Ax, *bx; //-------------------------------------------------------------------------- // Read in A //-------------------------------------------------------------------------- // Read in Ap, Ai, Ax Ap = (int64_t *) mxGetJc (pargin[0]); Ai = (int64_t *) mxGetIr (pargin[0]); Ax = mxGetDoubles (pargin[0]); if (!Ai || !Ap || !Ax) { spex_mex_error (SPEX_INCORRECT_INPUT, ""); } // Get info about A nA = (int64_t) mxGetN (pargin[0]); mA = (int64_t) mxGetM (pargin[0]); Anz = Ap[nA]; if (nA != mA) { spex_mex_error (1, "A must be square"); } // check the values of A bool A_has_int64_values = spex_mex_check_for_inf (Ax, Anz); SPEX_matrix A = NULL; SPEX_matrix A_matlab = NULL; if (A_has_int64_values) { // All entries in A can be typecast to int64_t without change in value. int64_t *Ax_int64 = (int64_t*) SPEX_malloc (Anz* sizeof (int64_t)); if (!Ax_int64) { spex_mex_error (SPEX_OUT_OF_MEMORY, ""); } for (k = 0; k < Anz; k++) { // typecast the double Ax into the int64_t Ax_int64 Ax_int64[k] = (int64_t) Ax[k]; } // Create A_matlab (->x starts as shallow) SPEX_matrix_allocate (&A_matlab, SPEX_CSC, SPEX_INT64, mA, nA, Anz, true, false, option); // transplant A_matlab->x, which is no longer shallow A_matlab->x.int64 = Ax_int64; A_matlab->x_shallow = false ; } else { // Entries in A cannot be typecast to int64_t without changing them. // Create A_matlab (->x is shallow) SPEX_matrix_allocate (&A_matlab, SPEX_CSC, SPEX_FP64, mA, nA, Anz, true, false, option); A_matlab->x.fp64 = Ax; } // the pattern of A_matlab is always shallow A_matlab->p = Ap ; A_matlab->i = Ai ; // scale A and convert to MPZ SPEX_MEX_OK (SPEX_matrix_copy(&A, SPEX_CSC, SPEX_MPZ, A_matlab, option)); // free the shallow copy of A SPEX_MEX_OK (SPEX_matrix_free (&A_matlab, option)); //-------------------------------------------------------------------------- // Read in b //-------------------------------------------------------------------------- SPEX_matrix b = NULL; SPEX_matrix b_matlab = NULL; bx = mxGetDoubles (pargin[1]); if (!bx) { spex_mex_error (SPEX_INCORRECT_INPUT, ""); } // Get info about RHS vector (s) nb = mxGetN (pargin[1]); mb = mxGetM (pargin[1]); if (mb != mA) { spex_mex_error (1, "dimension mismatch"); } int64_t count = 0; // check the values of b bool b_has_int64_values = spex_mex_check_for_inf (bx, nb*mb); if (b_has_int64_values) { // Create b_matlab (which is shallow) SPEX_matrix_allocate(&b_matlab, SPEX_DENSE, SPEX_INT64, mb, nb, mb*nb, true, false, option); b_matlab->x.int64 = SPEX_calloc(nb*mb, sizeof(int64_t)); for (int64_t j = 0; j < mb*nb; j++) { // typecast b from double to int64 b_matlab->x.int64[j] = (int64_t) bx[j]; } } else { // Create b_matlab (which is shallow) SPEX_matrix_allocate(&b_matlab, SPEX_DENSE, SPEX_FP64, mb, nb, mb*nb, true, false, option); b_matlab->x.fp64 = bx; } // scale b and convert to MPZ SPEX_MEX_OK (SPEX_matrix_copy(&b, SPEX_DENSE, SPEX_MPZ, b_matlab, option)); // free the shallow copy of b SPEX_MEX_OK (SPEX_matrix_free (&b_matlab, option)); (*A_handle) = A; (*b_handle) = b; }