# How to differentiate a function constructed through FindRoot?

I am trying to maximize a function which has as a variable another function that was solved numerically using FindRoot. My code is below.I start by defining some parameters

alpha = .2;
beta = .1;
n2 = n - n1 ;
sigma = 5;
d = 1.25;
eta = .1
n = 100;
F = 1;
theta = .6;
delta = .8;
Phi = -((alpha + beta)/(sigma - 1) + eta (1 - delta) - theta);
A2 = 1;
T1 = b1^(sigma - 1) (1 + t1)^(-sigma);
T2 = b2^(sigma - 1) (1 + t2)^(-sigma);
phi1 = (b2/d)^(sigma - 1);
phi2 = (b1/d)^(sigma - 1);


I then define two functions.

Function 1:

v1lim[tau1_, t1_, tau2_, t2_, b1_, b2_, A1_, n1_] =
A1 (tau1 + alpha t1 (1 - tau1)/(1 + t1) +
t1 beta T1 ((1 - tau1) T2 (1 +
t2) - (T2 - phi2)/(T1 - phi1) phi1 (1 - tau2) n2/
n1)/(T1 (1 + t1) T2 (1 + t2) - phi1 phi2))^
eta ((1 - tau1)^(sigma - (1 - alpha - beta))/(1 +
t1)^(alpha sigma))^(1/(sigma - 1)) ((T1 T2 - phi1 phi2)/(T2 -
phi2))^(beta/(sigma - 1)) n1^(-Phi);


Function 2:

v2lim[tau1_, t1_, tau2_, t2_, b1_, b2_, A1_, n1_] =
A2 (tau2 + alpha t2 (1 - tau2)/(1 + t2) +
t2 beta T2 ((1 - tau2) T1 (1 +
t1) - (T1 - phi1)/(T2 - phi2) phi1 (1 - tau1) n1/
n2)/(T1 (1 + t1) T2 (1 + t2) - phi1 phi2))^
eta ((1 - tau2)^(sigma - (1 - alpha - beta))/(1 +
t2)^(alpha sigma))^(1/(sigma - 1)) ((T1 T2 - phi1 phi2)/(T1 -
phi1))^(beta/(sigma - 1)) n2^(-Phi);


I equate these functions to solve for the variable "nilim"below

nilim[tau1_?NumericQ, t1_?NumericQ, tau2_?NumericQ, t2_?NumericQ,
b1_?NumericQ, b2_?NumericQ, A1_?NumericQ] :=
n1 /. FindRoot[
v1lim[tau1, t1, tau2, t2, b1, b2, A1, n1] -
v2lim[tau1, t1, tau2, t2, b1, b2, A1, n1] == 0, {n1, 50}]


I then want to insert that value back into function 1 and maximize the function numerically for "t1,tau1,t2,tau2".

I have used the following method

 FindRoot[Grad[
v1lim[tau1, t1, tau2, t2, 1, 1, 1,
nilim[tau1?Numericq, t1?Numericq, tau2?Numericq, t2?Numericq, 1, 1, 1]], {tau1, t1, tau2, t2}] == {0,
0, 0, 0}, {{tau1, .1}, {t1, -.1}, {tau2, .1}, {t2, -.1}}]


But I get the following errors

FindRoot::nlnum: The function value {0.138682 ((-0.167772+Power[<<2>>] Power[<<1>>])/(-0.4096+Power[<<2>>]))^0.025 ((1. +<<1>>)^4.3/(1. +t1)^1.)^(1/4) ((0.2 t1 (1. +Times[<<2>>]))/Plus[<<2>>]+tau1+(0.1 t1 (Times[<<2>>]+Times[<<4>>]))/(Plus[<<2>>]^5 Plus[<<2>>]))^0.1-0.138682 (<<1>>/<<1>>)^0.025 (<<1>>/<<1>>)^(1/4) (<<1>>/(<<1>>^5 <<1>>)+<<1>>/<<1>>+tau2)^0.1} is not a list of numbers with dimensions {1} at {n1} = {50.}.

General::stop: Further output of FindRoot::nlnum will be suppressed during this calculation.

FindRoot::vloc: The variable #2 cannot be localized so that it can be assigned to numerical values.

FindRoot::vloc: The variable #2 cannot be localized so that it can be assigned to numerical values.

FindRoot::vloc: The variable #2 cannot be localized so that it can be assigned to numerical values.

General::stop: Further output of FindRoot::vloc will be suppressed during this calculation.

FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances.

FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances.

FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances.


There is probably a simpler way of doing this. I would appreciate any suggestions.

All that I am getting as a result is my initial code again.

   FindRoot[Grad[
v1lim[tau1, t1, tau2, t2, 1, 1, 1,
nilim[tau1, t1, tau2, t2, 1, 1, 1]],{tau1, t1, tau2, t2}] == {0,
0, 0, 0}, {{tau1, 0.1}, {t1, -0.1}, {tau2, 0.1}, {t2, -0.1}}]

• It would make it easier to read if you explicitly identified the two functions mentioned in the first sentence. -- Second, why are there two definitions of nilim? Try commenting out the first one. – Michael E2 Jun 26 '19 at 19:22
• (1) Do the parameters alpha etc. have numerical values? If not, FindRoot cannot be used. You'd need a symbolic solver. (2) Omit the four instances of ?Numericq in the final FindRoot. The pattern test ? is for defining functions (and replacement rules). – Michael E2 Jun 26 '19 at 21:45
• Yes, all parameters in the equations are given numerical values in the beginning of the notebook so the only variables are "tau1, tau2, t1, t2" which are the variables I am trying to simulate. – jcl Jun 26 '19 at 22:11
• Well it "works" for me if I remove ?Numericq, but it works poorly because I have given it bad (I assume) parameter values. Can you post your actual values? – Michael E2 Jun 26 '19 at 22:16
• I have taken ?Numericq  out of my initial code but I do not get a result. All I get back is my initial code FindRoot[Grad[ v1lim[tau1, t1, tau2, t2, 1, 1, 1, nilim[tau1, t1, tau2, t2, 1, 1, 1]],{tau1, t1, tau2, t2}] == {0, 0, 0, 0}, {{tau1, 0.1}, {t1, -0.1}, {tau2, 0.1}, {t2, -0.1}}]` – jcl Jun 26 '19 at 22:33