#define NATIVE_MODULE "$math" #include <math.h> #include "ext_math.h" #include "list.h" module_t ext_math_module = {NO, NULL, NO, NULL}; static int check_one_vector(cList *l1, Int *len_ret) { Int i,len; len=list_length(l1); for (i=0; i<len; i++) { if (list_elem(l1,i)->type != FLOAT) THROW((type_id, "Arguments must be lists of floats.")) } *len_ret=len; RETURN_TRUE; } static int check_vectors(cList *l1, cList *l2, Int *len_ret) { Int i,len; len=list_length(l1); if (list_length(l2)!=len) THROW((range_id, "Arguments are not of the same length.")) for (i=0; i<len; i++) { if (list_elem(l1,i)->type != FLOAT) THROW((type_id, "Arguments must be lists of floats.")) if (list_elem(l2,i)->type != FLOAT) THROW((type_id, "Arguments must be lists of floats.")) } *len_ret=len; RETURN_TRUE; } NATIVE_METHOD(minor) { Int i,len; cList *l,*l1,*l2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; l=list_new(len); l->len=len; for (i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; list_elem(l,i)->type=FLOAT; list_elem(l,i)->u.fval=p<q ? p : q; } CLEAN_RETURN_LIST(l); } NATIVE_METHOD(major) { Int i,len; cList *l,*l1,*l2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; l=list_new(len); l->len=len; for (i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; list_elem(l,i)->type=FLOAT; list_elem(l,i)->u.fval=p>q ? p : q; } CLEAN_RETURN_LIST(l); } NATIVE_METHOD(add) { Int i,len; cList *l,*l1,*l2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; l=list_new(len); l->len=len; for (i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; list_elem(l,i)->type=FLOAT; list_elem(l,i)->u.fval=p+q; } CLEAN_RETURN_LIST(l); } NATIVE_METHOD(sub) { Int i,len; cList *l,*l1,*l2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; l=list_new(len); l->len=len; for (i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; list_elem(l,i)->type=FLOAT; list_elem(l,i)->u.fval=p-q; } CLEAN_RETURN_LIST(l); } NATIVE_METHOD(dot) { Int i,len; cList *l1,*l2; Float s; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; for (s=0.0,i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; s+=p*q; } CLEAN_RETURN_FLOAT(s); } NATIVE_METHOD(distance) { Int i,len; cList *l1,*l2; Float s; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; for (s=0.0,i=0; i<len; i++) { Float p,q,d; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; d=p-q; s+=d*d; } CLEAN_RETURN_FLOAT(sqrt(s)); } NATIVE_METHOD(cross) { Int len; cList *l,*l1,*l2; cData *f,*f1,*f2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; if (len!=3) THROW((range_id,"The vectors are not of length 3.")) l=list_new(len); l->len=len; f=list_elem(l,0); f1=list_elem(l1,0); f2=list_elem(l2,0); f[0].type=f[1].type=f[2].type=FLOAT; f[0].u.fval=f1[1].u.fval*f2[2].u.fval-f1[2].u.fval*f2[1].u.fval; f[1].u.fval=f1[2].u.fval*f2[0].u.fval-f1[0].u.fval*f2[2].u.fval; f[2].u.fval=f1[0].u.fval*f2[1].u.fval-f1[1].u.fval*f2[0].u.fval; CLEAN_RETURN_LIST(l); } NATIVE_METHOD(scale) { Int i,len; cList *l,*l1; Float f; INIT_2_ARGS(FLOAT,LIST); l1=LIST2; f=FLOAT1; if (!check_one_vector (l1,&len)) RETURN_FALSE; l=list_new(len); l->len=len; for (i=0; i<len; i++) { Float p; p=list_elem(l1,i)->u.fval; list_elem(l,i)->type=FLOAT; list_elem(l,i)->u.fval=p*f; } CLEAN_RETURN_LIST(l); } NATIVE_METHOD(is_lower) { Int i,len; cList *l1,*l2; INIT_2_ARGS(LIST,LIST); l1=LIST1; l2=LIST2; if (!check_vectors (l1,l2,&len)) RETURN_FALSE; for (i=0; i<len; i++) { Float p,q; p=list_elem(l1,i)->u.fval; q=list_elem(l2,i)->u.fval; if (p>=q) { CLEAN_RETURN_INTEGER(0); } } CLEAN_RETURN_INTEGER(1); } NATIVE_METHOD(transpose) { Int i,len,len1; cList *l,*l1; cData *e,*o; INIT_1_ARG(LIST); l1=LIST1; len=list_length(l1); if (!len) { l1=list_dup(l1); CLEAN_RETURN_LIST(l1); } e=list_elem(l1,0); for (i=0; i<len; i++) { if (e[i].type!=LIST) THROW((type_id,"The argument must be a list of lists.")) } len1=list_length(e[0].u.list); if (!len1) { l1=list_dup(e[0].u.list); CLEAN_RETURN_LIST(l1); } for (i=1; i<len; i++) { if (list_length(e[i].u.list)!=len1) THROW((range_id,"All sublists must be of the same length")) } l=list_new(len1); l->len=len1; o=list_elem(l,0); for (i=0; i<len1; i++) { cList *l2; cData *k; Int j; l2=list_new(len); l2->len=len; o[i].type=LIST; o[i].u.list=l2; k=list_elem(l2,0); for (j=0; j<len; j++) data_dup(&k[j],list_elem(e[j].u.list,i)); } CLEAN_RETURN_LIST(l); }