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; }
char *ft_itoa(int n) { int tmp; int len; char *str; int min; tmp = n; if (n == 0 || n == -2147483648) return (func_zero(n)); len = (n < 0) ? ft_ilong(tmp) + 1 : ft_ilong(tmp); str = ft_strnew((size_t)len + 1); if (str == NULL) return (NULL); min = (n < 0) ? 1 : 0; signe(&n, str); while (len >= min) { tmp = n % 10; str[len] = '0' + tmp; n /= 10; len--; } return (str); }
func_t *func_diff_eval(func_t *g) { int var; func_t *fx=NULL,*f=NULL,*x=NULL; if(g==NULL || !func_is(g,"diff") || func_asize(g)!=2){ FUNC_ERROR_ARG1("func_diff_eval",g); } f=func_aget(g,0); x=func_aget(g,1); if(f==NULL || x==NULL || !func_is_1var(x)){ FUNC_ERROR_ARG2("func_diff_eval",f,x); } var=func_var_num(x,0); if (func_is_zero(f)) { fx=func_zero(); } else if(func_is_one(f)) { fx=func_zero(); } else if(func_is_bigint(f)) { fx=func_zero(); } else if(func_is_real(f)) { fx=func_zero(); } else if(func_is_complex(f)) { fx=func_zero(); } else if(func_is_var(f)) { fx=func_diff_var(FR(f),var); } else if(func_is(f,"pow")) { fx=func_diff_pow(FR(f),var); } else if(func_is_list(f)) { fx=func_diff_list(FR(f),var); } else if(func_is(f,"rvec")) { fx=func_list_zeros(func_rvec_size(f)); } else if(func_is(f,"cvec")) { fx=func_list_zeros(func_cvec_size(f)); } else if(func_is(f,"rmat")) { fx=func_list_zeros2(func_rmat_rows(f),func_rmat_cols(f)); } else if(func_is(f,"cmat")) { fx=func_list_zeros2(func_cmat_rows(f),func_cmat_cols(f)); } else if(func_is_add(f) && func_power(f)==1){ fx=func_diff_add_pow1(FR(f),var); } // (add)^1 else if(func_is_mul(f) && func_power(f)==1){ fx=func_diff_mul_pow1(FR(f),var); } // (mul)^1 else if(func_is(f,"sqrt") && func_power(f)==1){ fx=func_diff_sqrt_pow1(FR(f),var); } // sqrt^1 else if(func_is(f,"exp") && func_power(f)==1){ fx=func_diff_exp_pow1(FR(f),var); } // exp^1 else if(func_is(f,"log") && func_power(f)==1){ fx=func_diff_log_pow1(FR(f),var); } // log^1 else if(func_is(f,"sin") && func_power(f)==1){ fx=func_diff_sin_pow1(FR(f),var); } // sin^1 else if(func_is(f,"cos") && func_power(f)==1){ fx=func_diff_cos_pow1(FR(f),var); } // cos^1 else if(func_is(f,"tan") && func_power(f)==1){ fx=func_diff_tan_pow1(FR(f),var); } // tan^1 else if(func_is(f,"sinh") && func_power(f)==1){ fx=func_diff_sinh_pow1(FR(f),var); } // sinh^1 else if(func_is(f,"cosh") && func_power(f)==1){ fx=func_diff_cosh_pow1(FR(f),var); } // cosh^1 else if(func_is(f,"tanh") && func_power(f)==1){ fx=func_diff_tanh_pow1(FR(f),var); } // tanh^1 else if(func_is(f,"asin") && func_power(f)==1){ fx=func_diff_asin_pow1(FR(f),var); } // asin^1 else if(func_is(f,"acos") && func_power(f)==1){ fx=func_diff_acos_pow1(FR(f),var); } // acos^1 else if(func_is(f,"atan") && func_power(f)==1){ fx=func_diff_atan_pow1(FR(f),var); } // atan^1 else if(func_is(f,"asinh") && func_power(f)==1){ fx=func_diff_asinh_pow1(FR(f),var); } // asinh^1 else if(func_is(f,"acosh") && func_power(f)==1){ fx=func_diff_acosh_pow1(FR(f),var); } // acosh^1 else if(func_is(f,"atanh") && func_power(f)==1){ fx=func_diff_atanh_pow1(FR(f),var); } // atanh^1 else if(func_has_power(f) && func_power(f)!=1) { fx=func_diff_pow_n(FR(f),var); } // (???)^p with p!=1 else { fx=FR(g); } // otherwise g=func_del(g); return fx; }
func_t *func_poly_clone_coeff_ntarm(func_t *f,int n) { func_t *a; if(!func_is_poly(f)){ return NULL; } a=func_poly_get_mono_ntarm(f,n); if(a==NULL){ return func_zero(); } if(func_is_number(a)){ return func_clone(FR(a)); } a=func_mono_get_coeff(a); if(a==NULL){ return func_one(); } return func_clone(FR(a)); }
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_expand_add_pow1(func_t *f) { int i; func_t *g=NULL; if(func_is_add(f) && func_power(f)==1){ g=func_zero(); for(i=0; i<func_asize(f); i++){ g=func_add(g,func_expand(FR(f->a[i]))); } }else{ FUNC_ERROR_ARG1("func_expand_add_pow1",f); } f=func_del(f); return g; }
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; }
func_t *func_diff_var(func_t *f, int var) { int n,m; func_t *fx=NULL; if(!func_is_var(f)){ FUNC_ERROR_ARG1("func_diff_var",f); } n=ivec_first_index_if(func_var_size(f),f->p.var->num,var); if(n<0) { fx=func_zero(); } else{ fx=func_clone(FR(f)); m=fx->p.var->pow[n]; fx->p.var->pow[n]--; fx=func_var_check_mul(fx); fx=func_mul(func_bigint_int(m,1),fx); } f=func_del(f); return fx; }
func_t *func_add_eval(func_t *f) { func_t *g; if(!func_is_add(f)){ FUNC_ERROR_ARG1("func_add_eval",f); } f=func_flatten(f,__func_add); func_add_args(f,func_is_complex,func_is_number); func_add_args(f,func_is_real,func_is_number); func_add_args(f,func_in_bigint,func_in_bigint); func_add_args_collect(f,func_in_complex); func_add_args_collect(f,func_is_number); func_a_rm_op(f,func_is_zero); func_args_sort(f); func_args_reverse(f); if (func_asize(f)<=0){ f=func_del(f); return func_zero(); } else if(func_asize(f)==1){ g=func_pow(FR(func_aget(f,0)),func_bigint_int(func_power(f),1)); f=func_del(f); return g; } else { return f; } }
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; }
// q=f/g, where f=g*q+r func_t *func_poly_div_q(func_t *f, func_t *g) { func_t *r=NULL,*neg=NULL,*q=NULL,*a; if(func_is_poly(f) && func_is_poly(g)){ neg=func_bigint_int(-1,1); r=FR(f); // r=f q=func_zero(); 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) q=func_add(q,FR(a)); // q+=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); r=func_del(r); return q; }
func_t *func_poly_list_div_r(func_t *f, func_t *g) { int i,flag; func_t *p=NULL,*r=NULL,*neg=NULL,*a=NULL; if(!(func_is_poly(f) && func_is_poly_list(g))){ FUNC_ERROR_ARG2("func_poly_list_div_r",f,g); } neg=func_bigint_int(-1,1); p=func_clone(FR(f)); r=func_zero(); while(!func_is_zero(p)){ i=0; flag=0; while(i<func_asize(g) && flag==0){ if(func_poly_can_div(p,g->a[i])){ a=func_div(FR(func_poly_get_lt(p)),FR(func_poly_get_lt(g->a[i]))); // a:=LT(p)/LT(g[i]) a=func_mul(FR(neg),a); // a:=-LT(p)/LT(g[i]) a=func_expand(func_mul(a,func_poly_rm_lt(FR(g->a[i])))); // a:=expand((-LT(p)/LT(g[i]))*(g[i]-LT(g[i]))) p=func_poly_rm_lt(p); // p:=p-LT(p) p=func_add(p,FR(a)); // p:=(p-LT(p))-(LT(p)/LT(g[i]))*(g[i]-LT(g[i])))=p-(LT(p)/LT(g[i]))*g[i] a=func_del(a); flag=1; }else{ i=i+1; } } if(flag==0){ r=func_add(r,FR(func_poly_get_lt(p))); p=func_poly_rm_lt(p); } } p=func_del(p); f=func_del(f); g=func_del(g); neg=func_del(neg); a=func_del(a); return r; }