1 /* 2 * Copyright 2011 Sven Verdoolaege 3 * Copyright 2012-2013 Ecole Normale Superieure 4 * 5 * Use of this software is governed by the MIT license 6 * 7 * Written by Sven Verdoolaege, 8 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France 9 */ 10 11 #include <isl/space.h> 12 #include <isl_val_private.h> 13 14 #include <isl_multi_macro.h> 15 16 /* Add "multi2" to "multi1" and return the result. 17 */ 18 __isl_give MULTI(BASE) *FN(MULTI(BASE),add)(__isl_take MULTI(BASE) *multi1, 19 __isl_take MULTI(BASE) *multi2) 20 { 21 return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,add)); 22 } 23 24 /* Subtract "multi2" from "multi1" and return the result. 25 */ 26 __isl_give MULTI(BASE) *FN(MULTI(BASE),sub)(__isl_take MULTI(BASE) *multi1, 27 __isl_take MULTI(BASE) *multi2) 28 { 29 return FN(MULTI(BASE),bin_op)(multi1, multi2, &FN(EL,sub)); 30 } 31 32 /* Depending on "fn", multiply or divide the elements of "multi" by "v" and 33 * return the result. 34 */ 35 static __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val_fn)( 36 __isl_take MULTI(BASE) *multi, __isl_take isl_val *v, 37 __isl_give EL *(*fn)(__isl_take EL *el, __isl_take isl_val *v)) 38 { 39 if (!multi || !v) 40 goto error; 41 42 if (isl_val_is_one(v)) { 43 isl_val_free(v); 44 return multi; 45 } 46 47 if (!isl_val_is_rat(v)) 48 isl_die(isl_val_get_ctx(v), isl_error_invalid, 49 "expecting rational factor", goto error); 50 51 return FN(MULTI(BASE),fn_val)(multi, fn, v); 52 error: 53 isl_val_free(v); 54 return FN(MULTI(BASE),free)(multi); 55 } 56 57 /* Multiply the elements of "multi" by "v" and return the result. 58 */ 59 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_val)(__isl_take MULTI(BASE) *multi, 60 __isl_take isl_val *v) 61 { 62 return FN(MULTI(BASE),scale_val_fn)(multi, v, &FN(EL,scale_val)); 63 } 64 65 /* Divide the elements of "multi" by "v" and return the result. 66 */ 67 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_val)( 68 __isl_take MULTI(BASE) *multi, __isl_take isl_val *v) 69 { 70 if (!v) 71 goto error; 72 if (isl_val_is_zero(v)) 73 isl_die(isl_val_get_ctx(v), isl_error_invalid, 74 "cannot scale down by zero", goto error); 75 return FN(MULTI(BASE),scale_val_fn)(multi, v, &FN(EL,scale_down_val)); 76 error: 77 isl_val_free(v); 78 return FN(MULTI(BASE),free)(multi); 79 } 80 81 /* Multiply the elements of "multi" by the corresponding element of "mv" 82 * and return the result. 83 */ 84 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_multi_val)( 85 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) 86 { 87 return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,scale_val), mv); 88 } 89 90 /* Divide the elements of "multi" by the corresponding element of "mv" 91 * and return the result. 92 */ 93 __isl_give MULTI(BASE) *FN(MULTI(BASE),scale_down_multi_val)( 94 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) 95 { 96 return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,scale_down_val), mv); 97 } 98 99 /* Compute the residues of the elements of "multi" modulo 100 * the corresponding element of "mv" and return the result. 101 */ 102 __isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)( 103 __isl_take MULTI(BASE) *multi, __isl_take isl_multi_val *mv) 104 { 105 return FN(MULTI(BASE),fn_multi_val)(multi, &FN(EL,mod_val), mv); 106 } 107 108 /* Return the opposite of "multi". 109 */ 110 __isl_give MULTI(BASE) *FN(MULTI(BASE),neg)(__isl_take MULTI(BASE) *multi) 111 { 112 S(MULTI(BASE),un_op_control) control = { .fn_el = &FN(EL,neg) }; 113 return FN(MULTI(BASE),un_op)(multi, &control); 114 } 115