//変数の個数を数える int func_poly_n_var(func_t *f) { int i,j,k,a,b,count=0; func_t *g=NULL,*h=NULL; if(func_is_mono(f)) return func_mono_n_var(f); if(!func_is_poly(f)) return -1; for(i=0;i<func_asize(f);i++){ a=func_mono_n_var(f->a[i]); count=count+a; } for(i=0;i<func_asize(f)-1;i++){ g=func_mono_get_var(f->a[i]); h=func_mono_get_var(f->a[i+1]); if(g!=NULL && h!=NULL){ for(j=0;j<func_var_size(g); j++){ a=g->p.var->num[j]; for(k=0;k<func_var_size(h); k++){ b=h->p.var->num[k]; if(a==b) count=count-1; } } } g=NULL; h=NULL; } g=func_del(g); h=func_del(h); return count; }
func_t *func_expand_mul1_add1(func_t *f) { int i,j,k; func_t *h=NULL,*g=NULL; if(func_is_mul(f) && func_power(f)==1 && func_a_has_op_pow1(f,func_is_add)){ // get terms without (add)^1 g=func_clone(FR(f)); func_args_rm_add_pow1(g); func_a_rm_null(g); g=func_mul_eval(g); // loop for(i=0; i<func_asize(f); i++){ if(func_is_add(f->a[i]) && func_power(f->a[i])==1){ if(func_is_add(g) && func_power(g)==1){ h=func_zero(); for(k=0; k<func_asize(g); k++){ for(j=0; j<func_asize(f->a[i]); j++){ h=func_add(h,func_expand(func_mul(FR(g->a[k]),FR(f->a[i]->a[j])))); } } }else{ h=func_zero(); for(j=0; j<func_asize(f->a[i]); j++){ h=func_add(h,func_expand(func_mul(FR(g),FR(f->a[i]->a[j])))); } } g=func_del(g); g=h; h=NULL; } } }else{ FUNC_ERROR_ARG1("func_expand_mul1_add1",f); } f=func_del(f); return g; }
void func_add_args_collect(func_t *f, func_is_t *fis) { int i,j; func_t *g=NULL; if(!func_is_add(f)){ FUNC_ERROR_ARG1("func_add_args_collect",f); } // convert args to split list for(i=0; i<func_asize(f); i++){ g=func_mul_split_list(FR(func_aget(f,i)),fis); func_aset(f,i,FR(g)); g=func_del(g); } // add a arg to same arg for(i=0; i<func_asize(f); i++){ for(j=i+1; func_aget(f,i)!=NULL && !func_is_one(func_aget(func_aget(f,i),1)) && j<func_asize(f); j++){ if(func_aget(f,j)!=NULL && func_cmp(func_aget(func_aget(f,i),1),func_aget(func_aget(f,j),1))==0){ g=func_list(2); func_aset(g,0,func_add(FR(func_aget(func_aget(f,i),0)),FR(func_aget(func_aget(f,j),0)))); func_aset(g,1,FR(func_aget(func_aget(f,i),1))); func_aset(f,i,FR(g)); func_adel(f,j); g=func_del(g); } } } // convert list to mul for(i=0; i<func_asize(f); i++){ if(func_aget(f,i)!=NULL){ g=func_mul(FR(func_aget(func_aget(f,i),0)),FR(func_aget(func_aget(f,i),1))); func_aset(f,i,FR(g)); g=func_del(g); } } func_a_rm_null(f); }
func_t *func_grad_eval(func_t *h) { int j,n=0; func_t *g=NULL,*f=NULL,*x=NULL; if(h==NULL || !func_is(h,"grad") || func_asize(h)<1 || func_asize(h)>2){ FUNC_ERROR_ARG1("func_grad_eval",h); } f=func_aget(h,0); if(func_asize(h)<2 && func_is_list(f)){ x=func_bigint_int(func_asize(f),1); } else if(func_asize(h)>1) { x=FR(func_aget(h,1)); } if (func_is_list(x)) { n=func_asize(x); } else if(func_bigint_is_integer(x)) { n=func_bigint_get_si(x); } else { FUNC_ERROR_ARG2("func_grad",f,x); } if(func_is_list(f)){ g=func_list(func_asize(f)); for(j=0; j<func_asize(f); j++){ func_aset(g,j,func_grad(FR(f->a[j]),FR(x))); } }else{ g=func_list(n); for(j=0; j<n; j++){ if(func_is_list(x)){ func_aset(g,j,func_diff(FR(f),FR(func_aget(x,j)))); } else { func_aset(g,j,func_diff(FR(f),func_var1(j,1))); } } } x=func_del(x); h=func_del(h); return g; }
//h={q,r} func_t *func_poly_div_r_and_q(func_t *f, func_t *g) { func_t *h=NULL; h=func_list(2); h->a[0]=func_poly_div_q(FR(f),FR(g)); h->a[1]=func_poly_div_r(FR(f),FR(g)); f=func_del(f); g=func_del(g); return h; }
func_t *func_poly_rm_lt(func_t *f) { func_t *g=NULL; if(func_is_poly(f)){ if(func_is_add(f) && func_power(f)==1 && func_asize(f)>=2){ g=func_clone(FR(f)); g->a[0]=func_del(g->a[0]); g=func_add_eval(g); }else{ g=func_zero(); } } f=func_del(f); return g; }
func_t *func_diff_mul_pow1(func_t *f, int var) { int i; func_t *fx=NULL,*g=NULL; if(!func_is_mul(f) || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_mul",f); } fx=func_zero(); for(i=0; i<func_asize(f); i++){ g=func_clone(FR(f)); g->a[i]=func_del(g->a[i]); g=func_mul_eval(g); fx=func_add(fx,func_mul(g,func_diff(FR(f->a[i]),func_var1(var,1)))); } f=func_del(f); return fx; }
void func_aset(func_t *f, int i, func_t *g) { if(f==NULL){ FUNC_ERROR_ARG2("func_aset",f,g); } if(i<0 || i>=func_asize(f)){ printf("Error in func_aset(%s,%d,%s)\n",func_op(f),i,func_op(g)); exit(0); } f->a[i]=func_del(f->a[i]); f->a[i]=g; }
func_t *func_add(func_t *f1, func_t *f2) { if (f1==NULL || f2==NULL) { FUNC_ERROR_ARG2("func_add",f1,f2); } else if(func_is_zero(f1)) { f1=func_del(f1); return f2; } else if(func_is_zero(f2)) { f2=func_del(f2); return f1; } else if(func_in_bigint(f1) && func_in_bigint(f2)) { return func_bigint_add(f1,f2); } else if(func_in_real(f1) && func_in_real(f2)) { return func_real_add(f1,f2); } else if(func_in_complex(f1) && func_in_complex(f2)){ return func_complex_add(f1,f2); } else if(func_is_real(f1) && func_is_number(f2)) { return func_add(f1,func_evalf(f2)); } else if(func_is_complex(f1) && func_is_number(f2)) { return func_add(f1,func_evalf(f2)); } else if(func_is_number(f1) && func_is_real(f2)) { return func_add(func_evalf(f1),f2); } else if(func_is_number(f1) && func_is_complex(f2)){ return func_add(func_evalf(f1),f2); } else if(func_in_vec(f1) && func_in_vec(f2)) { return func_vec_add(f1,f2); } else if(func_in_mat(f1) && func_in_mat(f2)) { return func_mat_add(f1,f2); } else { return func_add_eval(func_arg2_new(__func_add,f1,f2)); } }
func_t *func_set_script(func_t *f) { strings *a=NULL,*b=NULL,*vlist=NULL; func_t *g=NULL; if(func_is_strings(f) && func_strings_size(f)==1){ if(str_match(func_strings_at(f,0),"=",BLK0,BLK1)){ a=strings_split(func_strings_at(f,0),"=",BLK0,BLK1,SPC); if(strings_size(a)==2 && str_match(strings_at(a,0),"^%A%I*$",BLK0,BLK1)){ g=func_set(func_def(strings_at(a,0),func_script(strings_at(a,1)),0,FUNC_NOLIMIT)); }else if(strings_size(a)==2 && str_match(strings_at(a,0),"^%A%I*(%m*)$",BLK0,BLK1)){ b=strings_split_mask(strings_at(a,0),BLK0,BLK1,SPC); if(strings_size(b)==1){ g=func_set(func_def(strings_at(b,0),func_script(strings_at(a,1)),0,0)); }else if(strings_size(b)>1){ vlist=strings_split(strings_at(b,1),",",BLK0,BLK1,SPC); func_scope_begin(func_strings_strings(vlist)); g=func_set(func_def(strings_at(b,0),func_eval(func_script(strings_at(a,1))),strings_size(vlist),strings_size(vlist))); func_scope_end(); } } } } if(g==NULL){ g=f; }else{ f=func_del(f); } a=strings_del(a); b=strings_del(b); vlist=strings_del(vlist); return g; }
void funcmethods(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { int job = getInt(prhs[1]); int nn; double* ptr = 0; // constructor if (job == 0) { int type = getInt(prhs[2]); int n = getInt(prhs[3]); if (type < 20) { ptr = mxGetPr(prhs[4]); size_t msize = mxGetM(prhs[4]); size_t nsize = mxGetN(prhs[4]); size_t lenp = msize*nsize; nn = func_new(type, n, lenp, ptr); } else if (type < 45) { int m = getInt(prhs[4]); nn = func_new(type, n, m, ptr); } else { ptr = mxGetPr(prhs[4]); nn = func_new(type, n, 0, ptr); } plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); double* h = mxGetPr(plhs[0]); *h = double(nn); if (nn < 0) { reportError(); } return; } else { int nn = 0; double t; double v = 0.0; int i = getInt(prhs[2]); if (job == 1) { nn = func_del(i); if (nn < 0) { reportError(); } v = double(nn); } else if (job == 2) { t = getDouble(prhs[3]); v = func_value(i, t); if (v == Undef) { reportError(); } } else { mexErrMsgTxt("unknown job parameter"); } plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL); double* h = mxGetPr(plhs[0]); *h = v; return; } }
func_t *func_end_eval(func_t *f) { func_init(); if(f==NULL || !func_is(f,"end") || func_asize(f)!=0){ FUNC_ERROR_ARG1("func_end_eval",f); } func_scope_end(); f=func_del(f); return NULL; }
func_t *func_def_any_eval(func_t *f) { int i; func_t *g=NULL,*x=NULL; g=func_scope_find(0,func_op(f)); if(func_is_def(g) && func_aget(g,0)!=NULL){ g=FR(func_aget(g,0)); if(func_asize(f)>0){ x=func_list(func_asize(f)); for(i=0; i<func_asize(f); i++){ func_aset(x,i,FR(func_aget(f,i))); } g=func_maps(g,0,FR(x)); } f=func_del(f); }else{ g=f; } x=func_del(x); return g; }
func_t *func_set_eval(func_t *f) { func_init(); if(f==NULL || !func_is(f,"set") || func_asize(f)!=1){ FUNC_ERROR_ARG1("func_set_eval",f); } func_scope_set(0,FR(func_aget(f,0))); f=func_del(f); return f; }
func_t *func_poly_lm_lcm(func_t *f, func_t *g) { func_t *lcm=NULL,*f_lm=NULL,*g_lm=NULL; if(func_is_poly(f) && func_is_poly(g)){ f_lm=func_poly_get_lm(f); g_lm=func_poly_get_lm(g); if (f_lm!=NULL && g_lm!=NULL) { lcm=func_var_lcm(FR(f_lm),FR(g_lm)); } else if(f_lm==NULL && g_lm!=NULL) { lcm=FR(g_lm); } else if(f_lm!=NULL && g_lm==NULL) { lcm=FR(f_lm); } else { lcm=func_one(); } } f_lm=NULL; g_lm=NULL; f=func_del(f); g=func_del(g); return lcm; }
// r=mod(f,g), where f=g*q+r func_t *func_poly_div_r(func_t *f, func_t *g) { func_t *r=NULL,*neg=NULL,*a; if(func_is_poly(f) && func_is_poly(g)){ neg=func_bigint_int(-1,1); r=FR(f); // r=f while(func_is_poly(r) && func_poly_can_div(r,g)) { a=func_div(FR(func_poly_get_lt(r)), FR(func_poly_get_lt(g))); // a=LT(r)/LT(g) a=func_mul(FR(neg),a); // a=(-1)*LT(r)/LT(g) a=func_expand(func_mul(a,FR(g))); // a=((-1)*LT(r)/LT(g))*g r=func_add(r,a); // r-=(LT(r)/LT(g))*g } } f=func_del(f); g=func_del(g); neg=func_del(neg); return r; }
void func_args_rm_add_pow1(func_t *f) { int i; if(f==NULL) return; for(i=0; i<func_asize(f); i++){ if(func_is_add(f->a[i]) && func_power(f->a[i])==1){ f->a[i]=func_del(f->a[i]); } } }
func_t *func_diff_sqrt_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL; if(!func_is(f,"sqrt") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_sqrt",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); fx=func_mul(func_div(gx,func_sqrt(FR(g))),func_bigint_int(1,2)); f=func_del(f); return fx; }
func_t *func_diff_log_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL; if(!func_is(f,"log") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_log",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); fx=func_div(gx,FR(g)); f=func_del(f); return fx; }
func_t *func_diff_cos_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL; if(!func_is(f,"cos") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_cos",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); fx=func_mul(func_mul(func_sin(FR(g)),func_bigint_int(-1,1)),gx); f=func_del(f); return fx; }
void func_a_del(func_t *f) { int i; if(f==NULL) return; if(f->a==NULL) return; for(i=0; i<f->n; i++){ f->a[i]=func_del(f->a[i]); } free(f->a); f->a=NULL; f->n=0; }
func_t *func_diff_tanh_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL; if(!func_is(f,"tanh") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_tanh",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); fx=func_mul(func_pow_n(func_cosh(FR(g)),-2),gx); f=func_del(f); return fx; }
void func_rvec_set(func_t *f, int i, func_t *g) { func_t *a=NULL; if(f==NULL || func_ptype(f)!=FUNC_P_RVEC || f->p.rvec==NULL || i<0 || i>=f->p.rvec->n){ FUNC_ERROR_ARG2("func_rvec_set",f,g); } a=func_evalf(FR(g)); if (func_is_real(a)) { rcopy(func_rvec_at(f,i),func_real_p(a)); } else if(func_is(a,"rvec") && func_rvec_size(a)==1){ rcopy(func_rvec_at(f,i),func_rvec_at(a,0)); } else{ FUNC_ERROR_ARG2("func_rvec_set",f,g); } a=func_del(a); }
void func_sparse_del(func_sparse_p func_sparse) { int n , i = func_sparse->summands*func_sparse->dimension; for (n = 0; n < i; n++) { func_del(func_sparse->factors[n]); } free(func_sparse->factors); free(func_sparse); }
void func_cvec_set(func_t *f, int i, func_t *g) { func_t *a=NULL; if(f==NULL || func_ptype(f)!=FUNC_P_CVEC || f->p.rvec==NULL || i<0 || i>=f->p.rvec->n){ FUNC_ERROR_ARG2("func_cvec_set",f,g); } a=func_evalf(FR(g)); if(func_is_real(a)) { ccopy_r(func_cvec_at(f,i),func_real_p(a)); } else if(func_is_complex(a)){ ccopy (func_cvec_at(f,i),func_complex_p(a)); } else { FUNC_ERROR_ARG2("func_cvec_set",f,g); } a=func_del(a); }
func_t *func_expand_add_pow_n(func_t *f) { int i,j,k; func_t *g=NULL,*h=NULL; if(func_is_add(f) && func_power(f)>=2){ g=func_clone(FR(f)); func_set_power(g,1); for(k=1; k<func_power(f); k++){ h=func_zero(); for(i=0; i<func_asize(g); i++){ for(j=0; j<func_asize(f); j++){ h=func_add(h,func_expand(func_mul(FR(g->a[i]),FR(f->a[j])))); } } g=func_del(g); g=h; h=NULL; } }else{ FUNC_ERROR_ARG1("func_expand_add_pow_n",f); } f=func_del(f); return g; }
func_t *func_null_script(func_t *f) { func_t *g=NULL; if(func_is_strings(f) && func_strings_size(f)==1 && str_match(func_strings_at(f,0),"^NULL$",BLK0,BLK1)) { g=NULL; f=func_del(f); } else { g=f; } return g; }
void func_args_rm_op(func_t *f, const char *op) { int i; if(f==NULL) return; for(i=0; i<func_asize(f); i++){ if(func_is(f->a[i],op)){ f->a[i]=func_del(f->a[i]); } } func_a_rm_null(f); }
func_t *func_diff_add_pow1(func_t *f, int var) { int i; func_t *fx=NULL; if(!func_is_add(f) || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_add",f); } fx=func_zero(); for(i=0; i<func_asize(f); i++){ fx=func_add(fx,func_diff(FR(f->a[i]),func_var1(var,1))); } f=func_del(f); return fx; }
func_t *func_poly_list_monic(func_t *f) { int i; func_t *g=NULL; if(!(func_is_poly_list(f))){ FUNC_ERROR_ARG1("func_poly_list_monic",f); } g=func_clone(FR(f)); for(i=0; i<func_asize(g); i++){ func_aset(g,i,func_poly_monic(FR(g->a[i]))); } f=func_del(f); return g; }