1 //------------------------------------------------------------------------------
2 // SLIP_LU/slip_expand_mpq_array: convert mpq array to mpz
3 //------------------------------------------------------------------------------
4 
5 // SLIP_LU: (c) 2019-2020, Chris Lourenco, Jinhao Chen, Erick Moreno-Centeno,
6 // Timothy A. Davis, Texas A&M University.  All Rights Reserved.  See
7 // SLIP_LU/License for the license.
8 
9 //------------------------------------------------------------------------------
10 
11 /* Purpose: This function converts a mpq array of size n into an appropriate
12  * mpz array of size n. To do this, the lcm of the denominators is found as a
13  * scaling factor. This function allows mpq arrays to be used in SLIP LU.
14  */
15 
16 #define SLIP_FREE_ALL               \
17     SLIP_MPZ_CLEAR(temp);           \
18     SLIP_matrix_free(&x3, NULL);    \
19     SLIP_matrix_free(&x4, NULL);
20 
21 #include "slip_internal.h"
22 
slip_expand_mpq_array(mpz_t * x_out,mpq_t * x,mpq_t scale,int64_t n,const SLIP_options * option)23 SLIP_info slip_expand_mpq_array
24 (
25     mpz_t* x_out,        // mpz array, on output x_out = x*scale
26     mpq_t* x,            // mpq array that needs to be converted
27     mpq_t scale,         // scaling factor. x_out = scale*x
28     int64_t n,           // size of x
29     const SLIP_options* option // Command options
30 )
31 {
32 
33     //--------------------------------------------------------------------------
34     // check inputs
35     //--------------------------------------------------------------------------
36     // inputs have checked in the only caller slip_cast_array
37 
38     SLIP_info info ;
39 
40     //--------------------------------------------------------------------------
41 
42     mpz_t temp;
43     SLIP_matrix *x3 = NULL;
44     SLIP_matrix *x4 = NULL;;
45     SLIP_MPZ_SET_NULL(temp);
46     SLIP_CHECK (SLIP_mpz_init(temp)) ;
47 
48     SLIP_CHECK (SLIP_matrix_allocate(&x3, SLIP_DENSE, SLIP_MPZ, n, 1, n,
49         false, true, option));
50     SLIP_CHECK (SLIP_matrix_allocate(&x4, SLIP_DENSE, SLIP_MPQ, n, 1, n,
51         false, true, option));
52 
53     for (int64_t i = 0; i < n; i++)                  // x3 = denominators of x
54     {
55         SLIP_CHECK(SLIP_mpq_get_den(x3->x.mpz[i], x[i]));
56     }
57 
58     // Find LCM of denominators of x
59     SLIP_CHECK(SLIP_mpz_set(temp,x3->x.mpz[0]));
60     for (int64_t i = 1; i < n; i++)
61     {
62         SLIP_CHECK(SLIP_mpz_lcm(temp, x3->x.mpz[i], temp));
63     }
64     SLIP_CHECK(SLIP_mpq_set_z(scale,temp));
65 
66     for (int64_t i = 0; i < n; i++)
67     {
68         // x4[i] = x[i]*temp
69         SLIP_CHECK(SLIP_mpq_mul(x4->x.mpq[i], x[i], scale));
70 
71         // x_out[i] = x4[i]
72         SLIP_CHECK(SLIP_mpz_set_q(x_out[i], x4->x.mpq[i]));
73     }
74     SLIP_FREE_ALL;
75     return SLIP_OK;
76 }
77 
78