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