summaryrefslogtreecommitdiff
path: root/functions.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-22 12:37:48 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-22 12:37:48 +0000
commit26ee5089659da12e3c060edfefd056e2196b4363 (patch)
tree399784a877bc56b043e150dfb0ca96798c3e9398 /functions.c
parent9dad240ddfbe770ddfc8e1556d77328696a6734c (diff)
Implement scalar functions via a macro
Diffstat (limited to 'functions.c')
-rw-r--r--functions.c215
1 files changed, 64 insertions, 151 deletions
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)