/* K M Briggs 2004 Sep 02
   This file defines macros (or possibly functions) for the required
   scalar operations on power series terms.
   I have defined them here in terms of gmp's mpq_t type.
   This could conceivably be replaced by a floating point type.
*/

typedef mpq_t scalar;

/* scalar initializations */
#define scalar_init(Z) mpq_init(Z);
#define scalar_set(Z,X) mpq_set(Z,X);
#define scalar_set_zonz(Z,X,Y) mpz_set(mpq_numref(Z),X); mpz_set(mpq_denref(Z),Y); mpq_canonicalize(Z);
#define scalar_set_ui(Z,X,Y) mpq_set_ui(Z,X,Y); // mpq_canonicalize(Z);
#define scalar_set_si(Z,X,Y) mpq_set_si(Z,X,Y);
#define scalar_init_set_ui(Z,X,Y) mpq_init(Z); mpq_set_ui(Z,X,Y);
#define scalar_init_set_zero(Z) mpq_init(Z); mpq_set_ui(Z,0,1);
#define scalar_init_set_one(Z) mpq_init(Z); mpq_set_ui(Z,1,1);
#define scalar_set_zero(Z) mpq_set_ui(Z,0,1);
#define scalar_set_one(Z) mpq_set_ui(Z,1,1);
#define scalar_clear(Z) mpq_clear(Z);

/* scalar comparisons */
#define scalar_cmp_zero(Z) mpq_cmp_ui(Z,0,1)
#define scalar_cmp_one(Z) mpq_cmp_ui(Z,1,1)

/* scalar unary operations */
#define scalar_neg(Z,X) mpq_neg(Z,X);

/* scalar binary operations */
#define scalar_add(Z,X,Y) mpq_add(Z,X,Y);
#define scalar_sub(Z,X,Y) mpq_sub(Z,X,Y);
#define scalar_mul(Z,X,Y) mpq_mul(Z,X,Y);
#define scalar_div(Z,X,Y) mpq_div(Z,X,Y);
#define scalar_divexact_ui(Z,X,Y) mpz_divexact_ui(mpq_numref(Z),mpq_numref(X),Y);

/* scalar mixed binary operations */
#define scalar_div_ui(Z,X,Y) mpq_set(Z,X); mpz_mul_ui(mpq_denref(Z),mpq_denref(Z),Y); mpq_canonicalize(Z);
#define scalar_div_si(Z,X,Y) mpq_set(Z,X); mpz_mul_si(mpq_denref(Z),mpq_denref(Z),Y); mpq_canonicalize(Z);

/* scalar mixed binary in-place operations */
#define scalar_mulby_ui(Z,X) mpz_mul_ui(mpq_numref(Z),mpq_numref(Z),X); mpq_canonicalize(Z);
#define scalar_mulby_si(Z,X) mpz_mul_si(mpq_numref(Z),mpq_numref(Z),X); mpq_canonicalize(Z);
#define scalar_divby_ui(Z,X) mpz_mul_ui(mpq_denref(Z),mpq_denref(Z),X); mpq_canonicalize(Z);
#define scalar_pp(X) mpz_addmul_ui(mpq_numref(X),mpq_denref(X),1UL); mpq_canonicalize(X);
#define scalar_inc_ui(X,Y) mpz_addmul_ui(mpq_numref(X),mpq_denref(X),Y); mpq_canonicalize(X);

/* from http://www.swox.com/gmp/manual/Efficiency.html#Efficiency */
/* mpq increment */
//mpz_add (mpq_numref(q), mpq_numref(q), mpq_denref(q));
/* mpq += unsigned long */
//mpz_addmul_ui (mpq_numref(q), mpq_denref(q), 123UL);
/* mpq -= mpz */
//mpz_submul (mpq_numref(q), mpq_denref(q), z);
          
/* scalar output */
#define scalar_out_str(F,X) mpq_out_str(F,10,X); 
