'm trying to solve a large number (50) of non-linear simultaneous equations in Julia. For the moment I'm just trying to make this work with 2 equations to get the syntax right etc. However, I've tried a variety of packages/tools - NLsolve, nsolve in SymPy and NLOpt in JuMP (where I ignore the objective function and just enter equality constraints)- without much luck. I guess I should probably focus on making it work in one. I'd appreciate any advice on choice of packages and if possible code.
Here's how I tried to do it in NLsolve (using it in mcpsolve mode so I can impose constraints on the variables I am solving for - x[1] and x[2] - which are unemployment rates and so bounded between zero and 1) :
using Distributions
using Devectorize
using Distances
using StatsBase
using NumericExtensions
using NLsolve
beta = 0.95
xmin= 0.73;
xmax = xmin+1;
sigma = 0.023;
eta = 0.3;
delta = 0.01;
gamma=0.5
kappa = 1
psi=0.5
prod=linspace(xmin,xmax,ns)
l1=0.7
l2=0.3
assets = linspace(0,amaximum,na);
wbar=1
r=((1/beta)-1-1e-6 +delta)
## Test code
function f!(x, fvec)
ps1= wbar + ((kappa*(1-beta*(1-sigma*((1-x[1])/x[1]))))/
(beta*((x[1]/(sigma*(1-x[1])))^(gamma/(1-gamma)))*(1/(2-x[1]))))
ps2= wbar + ((kappa*(1-beta*(1-sigma*((1-x[2])/x[1]))))/
(beta*((x[2]/(sigma*(1-x[2])))^(gamma/(1-gamma)))*(1/(2-x[2]))))
prod1=prod[1]
prod2=prod[50]
y1=(1-x[1])*l1
y2=(1-x[2])*l2
M=(((prod1*y1)^((psi-1)/psi))+((prod2*y2)^((psi-1)/psi)))^(psi/(psi-1))
K=((r/eta)^(1/(eta-1)))*M
pd1=(1-eta)*(K^eta)*(M^(-eta))*((((prod1*y1)^((psi-1)/psi))+
((prod2*y2)^((psi- 1)/psi)))^(1/(psi-1)))*
((prod1*y1)^(-1/psi))*prod1
pd2=(1-eta)*(K^eta)*(M^(-eta))*((((prod1*y1)^((psi-1)/psi))+
((prod2*y2)^((psi-1)/psi)))^(1/(psi-1)))*
((prod2*y2)^(-1/psi))*prod2
fvec[1]=pd1-ps1
fvec[2]=pd2-ps2
end
mcpsolve(f!,[0.0,0.0],[1.0,1.0], [ 0.3, 0.3])
However, I get this error

As I understand it, this occurs because I am trying to take the root of a negative number. However, the bounds on x[1] and x[2] should stop this happening. Any advice very welcome. I appreciate the formulas are pretty ugly so let me know if any further simplifications helpful (I have tried!)
David
using Distributionsusing Devectorizeusing Distancesusing StatsBaseusing NumericExtensionsusing NLsolvebeta = 0.95xmin= 0.73xmax = xmin+1sigma = 0.023eta = 0.3delta = 0.01gamma=0.5kappa = 1psi=0.5
ns=50prod=linspace(xmin,xmax,ns)l1=0.7l2=0.3
wbar=1r=((1/beta)-1-1e-6 +delta)## Test codefunction f!(x, fvec)
ps1= wbar + (kappa*(1-beta*(1-sigma*((1-x[1])/x[1]))))ps2= wbar + (kappa*(1-beta*(1-sigma*((1-x[2])/x[2]))))
prod1=prod[1]prod2=prod[50]y1=(1-x[1])*l1y2=(1-x[2])*l2M=(((prod1*y1)^((psi-1)/psi))+((prod2*y2)^((psi-1)/psi)))
K=((r/eta)^(1/(eta-1)))*Mpd1=(1-eta)*(K^eta)*(M^(-eta))*prod1pd2=(1-eta)*(K^eta)*(M^(-eta))*prod2
beta = 0.95; % Discount Factor(Krusell, Mukoyama, Sahin)lambda0 = .90; % Exog contact Rate @inbounds for unemployed to job (DZM)lambda1 = 0.05; % Exog job to job contact (DZM)tao = .5; % Proportion of job contacts resulting in move (JM Robin)mu = 2; % First shape parameter of beta productivity distribution (JM Robin)rho = 5.56; % Second shape parameter of beta productivity distribution (JM Robin)xmin= 0.73; % Lower bound @inbounds for beta human capital distribution (JM Robin)xmax = xmin+1; % Upper bound @inbounds for beta human capital distribution (JM Robin)z0 = 0.0; % parameter @inbounds for unemployed income (JM Robin)nu = 0.64; % parameter @inbounds for unemployed income (DZM)sigma = 0.023; % Job Destruction Rate (DZM)alpha = 2; % Coef of risk aversion in utility function (Krusell, Mukoyama, Sahin)TFP = 1; % TFP (Krusell, Mukoyama, Sahin)eta = 0.3; % Index of labour @inbounds for CD production function (Krusell, Mukoyama, Sahin)delta = 0.01; % Capital Depreciation Rate (Krusell, Mukoyama, Sahin)tol1=1e-5; % Tolerance parameter @inbounds for value function iterationtol2=1e-5; % Tolerance parameter @inbounds for eveything elsena=500; % Number of points on household assets gridns=50; % Number of points on human capital gridamaximum=500; % Max point on assets gridmaxiter1=10000;maxiter=20000; % Max number of iterationsbins=25; % Number of bins @inbounds for wage and income distributionszeta=0.97; % Damping parameter (=weight put on new guess when updating in algorithms)zeta1=0.6;zeta2=0.1;zeta3=0.01;mwruns=15;gamma=0.5; % Matching Function Parameterkappa = 1; % Vacancy Costpsi=0.5;prod=linspace(xmin,xmax,ns); % Human Capital Grid (Values)l1=0.7;l2=0.3;wbar=0.2;r=((1/beta)-1-1e-6 +delta);
syms x1 x2
ps1= wbar + ((kappa*(1-beta*(1-sigma*((1-x1)/x1))))/(beta*((x1/(sigma*(1-x1)))^(gamma/(1-gamma)))*(1/(2-x1))));ps2= wbar + ((kappa*(1-beta*(1-sigma*((1-x2)/x2))))/(beta*((x2/(sigma*(1-x2)))^(gamma/(1-gamma)))*(1/(2-x2))));
prod1=prod(1);prod2=prod(50);y1=(1-x1)*l1;y2=(1-x2)*l2;M=(((prod1*y1)^((psi-1)/psi))+((prod2*y2)^((psi-1)/psi)))^(psi/(psi-1));Mprime=(((prod1*y1)^((psi-1)/psi))+((prod2*y2)^((psi-1)/psi)))^(1/(psi-1));K=((r/eta)^(1/(eta-1)))*M;
pd1=(1-eta)*(K^eta)*(M^(-eta))*Mprime*((prod1*y1)^(-1/psi))*prod1;pd2=(1-eta)*(K^eta)*(M^(-eta))*Mprime*((prod2*y2)^(-1/psi))*prod2;
eqn1=pd1-ps1;eqn2=pd2-ps2;
sol=vpasolve([0==eqn1, 0==eqn2], [x1 x2],[0 1;0 1]);[sol.x1 sol.x2]julia> sol
2x1 Array{Float64,2}:
214.956
300.851
julia> subs(eqn1, (x1, sol[1]), (x2, sol[2]))
-1.11022302462516e-16
julia> subs(eqn2, (x1, sol[1]), (x2, sol[2]))
-2.77555756156289e-17
sol=SymPy.sympy_meth(:nsolve, [eqn1, eqn2], [x1,x2], tuple(x0...))
One way to get a decent initial guess would be to plot the functions. With PyPlot installed, the `plot_implicit` function shows roughly the location of your answer:
plot_implicit(eqn1 * eqn2, (x1, 0, 1), (x2,0,1))
The zeros of eqn1 and eqn2 seem to cross at (1,1) and your answer.