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; }
func_t *func_diff_pow(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*h=NULL,*gx=NULL,*hx=NULL; if(!func_is(f,"pow")){ FUNC_ERROR_ARG1("func_diff_pow",f); } g=f->a[0]; h=f->a[1]; gx=func_diff(FR(g),func_var1(var,1)); hx=func_diff(FR(h),func_var1(var,1)); hx=func_mul(hx,func_log(FR(g))); gx=func_mul(gx,FR(h)); gx=func_div(gx,FR(g)); gx=func_add(gx,hx); fx=func_mul(FR(f),gx); f=func_del(f); return fx; }
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_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; }
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; }
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_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_diff_list(func_t *f, int var) { int i; func_t *fx=NULL; if(!func_is_list(f)){ FUNC_ERROR_ARG1("func_diff_list",f); } fx=func_list(func_asize(f)); for(i=0; i<func_asize(f); i++){ fx->a[i]=func_diff(FR(f->a[i]),func_var1(var,1)); } f=func_del(f); return fx; }
func_t *func_diff_atanh_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL,*h=NULL; if(!func_is(f,"atanh") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_atanh",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); h=func_pow_n(FR(g),2); h=func_sub(func_one(),h); fx=func_div(gx,h); f=func_del(f); return fx; }
func_t *func_diff_acosh_pow1(func_t *f, int var) { func_t *fx=NULL,*g=NULL,*gx=NULL,*h=NULL; if(!func_is(f,"acosh") || func_power(f)!=1){ FUNC_ERROR_ARG1("func_diff_acosh",f); } g=f->a[0]; gx=func_diff(FR(g),func_var1(var,1)); h=func_pow_n(FR(g),2); h=func_add(h,func_bigint_int(-1,1)); h=func_sqrt(h); fx=func_div(gx,h); f=func_del(f); return fx; }
func_t *func_diff_pow_n(func_t *f, int var) { func_t *fx=NULL,*g=NULL; if(!func_has_power(f) || func_power(f)==1){ FUNC_ERROR_ARG1("func_diff_pow_n",f); } g=func_clone(FR(f)); func_set_power(g,1); g=func_diff(g,func_var1(var,1)); fx=func_clone(FR(f)); func_set_power(fx,func_power(fx)-1); fx=func_mul(func_bigint_int(func_power(f),1),fx); fx=func_mul(fx,g); f=func_del(f); return fx; }
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; }
std::unique_ptr<FunctionDeclDiff> DiffWrapper<FunctionDecl, FunctionDeclDiff>::Get() { std::unique_ptr<FunctionDeclDiff> func_diff(new FunctionDeclDiff()); google::protobuf::RepeatedPtrField<ParamDeclDiff> *pdiffs = func_diff->mutable_param_diffs(); assert(func_diff->mutable_return_type_diffs() != nullptr); func_diff->set_name(oldp_->basic_abi().linker_set_key()); if (DiffBasicNamedAndTypedDecl( func_diff->mutable_return_type_diffs()->mutable_old(), func_diff->mutable_return_type_diffs()->mutable_new_(), oldp_->basic_abi(), newp_->basic_abi()) || GetElementDiffs(pdiffs, oldp_->parameters(), newp_->parameters())) { return func_diff; } return nullptr; }