summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--array.c10
-rw-r--r--functions.c215
2 files changed, 74 insertions, 151 deletions
diff --git a/array.c b/array.c
index 2e0e71e..bf75a1b 100644
--- a/array.c
+++ b/array.c
@@ -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)