diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-22 12:37:48 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-22 12:37:48 +0000 |
commit | 26ee5089659da12e3c060edfefd056e2196b4363 (patch) | |
tree | 399784a877bc56b043e150dfb0ca96798c3e9398 | |
parent | 9dad240ddfbe770ddfc8e1556d77328696a6734c (diff) |
Implement scalar functions via a macro
-rw-r--r-- | array.c | 10 | ||||
-rw-r--r-- | functions.c | 215 |
2 files changed, 74 insertions, 151 deletions
@@ -138,6 +138,16 @@ commontype(Array *a, Array *b, Array **aa, Array **bb, int forcefloat) }else if(a->type == AtypeInt && b->type == AtypeFloat){ *aa = inttofloatarray(a); *bb = fnSame(b); + }else if(a->type == AtypeArray && b->type != AtypeArray){ + *aa = fnSame(a); + *bb = allocarray(AtypeArray, 0, 1); + (*bb)->arraydata[0] = b; + incref(b); + }else if(a->type != AtypeArray && b->type == AtypeArray){ + *aa = allocarray(AtypeArray, 0, 1); + (*aa)->arraydata[0] = a; + incref(a); + *bb = fnSame(b); }else return 0; return 1; diff --git a/functions.c b/functions.c index 3d62828..daff046 100644 --- a/functions.c +++ b/functions.c @@ -525,159 +525,72 @@ fnTranspose(Array *right) /* Dyadic functions */ -Array * -fnPlus(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++){ - if(res->type == AtypeFloat) - res->floatdata[i] += right->floatdata[i]; - else if(res->type == AtypeInt) - res->intdata[i] += right->intdata[i]; - } - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} - -Array * -fnMinus(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++){ - if(res->type == AtypeFloat) - res->floatdata[i] -= right->floatdata[i]; - else if(res->type == AtypeInt) - res->intdata[i] -= right->intdata[i]; - } - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} - -Array * -fnTimes(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++){ - if(res->type == AtypeFloat) - res->floatdata[i] *= right->floatdata[i]; - else if(res->type == AtypeInt) - res->intdata[i] *= right->intdata[i]; - } - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} - -Array * -fnDivide(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 1); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++) +/* macro to define dyadic scalar functions */ +#define SCALAR_FUNCTION_2(name, forcefloat, cases) \ +Array *name(Array *left, Array *right){\ + Array *leftarr, *rightarr;\ + if(!commontype(left, right, &leftarr, &rightarr, forcefloat)) throwerror(nil, EType);\ + if(!scalarextend(leftarr, rightarr, &left, &right)) throwerror(nil, ERank);\ + Array *res = duparray(left);\ + for(int i = 0; i < left->size; i++)\ + switch(res->type){\ + default: throwerror(nil, EType); break;\ + case AtypeArray:\ + freearray(res->arraydata[i]);\ + res->arraydata[i] = name(left->arraydata[i], right->arraydata[i]);\ + break;\ + cases\ + }\ + freearray(leftarr); freearray(rightarr); freearray(left); freearray(right);\ + return res;} + +SCALAR_FUNCTION_2(fnPlus, 0, + case AtypeFloat: + res->floatdata[i] += right->floatdata[i]; + break; + case AtypeInt: + res->intdata[i] += right->intdata[i]; + break; +) + +SCALAR_FUNCTION_2(fnMinus, 0, + case AtypeFloat: + res->floatdata[i] -= right->floatdata[i]; + break; + case AtypeInt: + res->intdata[i] -= right->intdata[i]; + break; +) + +SCALAR_FUNCTION_2(fnTimes, 0, + case AtypeFloat: + res->floatdata[i] *= right->floatdata[i]; + break; + case AtypeInt: + res->intdata[i] *= right->intdata[i]; + break; +) + +SCALAR_FUNCTION_2(fnDivide, 1, + case AtypeFloat: res->floatdata[i] /= right->floatdata[i]; - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} - -Array * -fnPower(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 0); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++){ - if(res->type == AtypeFloat) - res->floatdata[i] = pow(res->floatdata[i], right->floatdata[i]); - else if(res->type == AtypeInt) - res->intdata[i] = pow(res->intdata[i], right->intdata[i]); - } - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} - -Array * -fnLogarithm(Array *left, Array *right) -{ - Array *leftarr; - Array *rightarr; - int rankok = scalarextend(left, right, &leftarr, &rightarr); - if(!rankok) - throwerror(nil, ERank); - - int typeok = commontype(leftarr, rightarr, &left, &right, 1); - if(!typeok) - throwerror(nil, EType); - - Array *res = duparray(left); - for(int i = 0; i < left->size; i++) + break; +) + +SCALAR_FUNCTION_2(fnPower, 0, + case AtypeFloat: + res->floatdata[i] = pow(res->floatdata[i], right->floatdata[i]); + break; + case AtypeInt: + res->intdata[i] = pow(res->intdata[i], right->intdata[i]); + break; +) + +SCALAR_FUNCTION_2(fnLogarithm, 1, + case AtypeFloat: res->floatdata[i] = log(right->floatdata[i])/log(res->floatdata[i]); - freearray(leftarr); - freearray(rightarr); - freearray(left); - freearray(right); - return res; -} + break; +) Array * fnLeft(Array *left, Array *right) |