Index in position 1 exceeds array bounds (must not exceed 1). Error in pij (line 14) pmat(k,n) = pis(k,1) .* tau(k,n); Error in pfij (line 18)
Mostrar comentarios más antiguos
Please my code is not running when I run the main script GE_fsolve. I can attached my main codes upon request. At the moment I inserted copies of all functions that I am using. Please kindly help me with this. Thanks!!!!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create output price function
function [Pis] = pis(wis)
global Ais beta IOcoef Nsec Ncoun
% reformat IOcoef to (NS,S) instead of the initial (NS,NS)
IOmat_cs_s = nan(Ncoun*Nsec,Nsec); %cs-s
for t = 1:1:Nsec
IOmat_cs_s(:,t) = sum(IOcoef(:,((t-1)*Ncoun+1):Ncoun*t),2); %cs-s
end
IOmat_cs = sum(IOmat_cs_s,2); %change IOcoef to (NS,1) instead of (NS,S)
% create matrix
pimat = zeros(Nsec*Ncoun,1);
% compute pis(NS,1)
for i = 1:1:Nsec*Ncoun
pimat(i) = ((beta(i)).^(-beta(i)) .* (1-beta(i)).^(-1+beta(i)))...
.*(wis(i).^beta(i) .* (IOmat_cs(i).*PMis(pij(pis(i)))).^(1-beta(i)))./Ais(i);
end
Pis = pimat; %(NS,1)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create pirce of output function
function [Pij] = pij(pis)
global tau Nsec Ncoun
% create matrix
pmat = zeros(Nsec*Ncoun,Ncoun);
% solve for price of output(n,k)
for k = 1:1:Nsec*Ncoun
for n = 1:1:Ncoun
pmat(k,n) = pis(k) .* tau(k,n);
end
end
Pij = pmat; %(NS,N)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create CES final demand function
function [Fij] = fij(pis,wis,mij)
global alpha sigma Nsec Ncoun
% PFis = PFis(pij,sigma,Ncoun,Nsec)
% reformat sigma to (N*S,1) instead of initial (S,1)
for s = 1:1:Nsec
idx = 1+(s-1)*Ncoun:1:Ncoun*s; %for every s what is idx
SG(idx,1) = ones(Ncoun,1)*sigma(s); %for every s use the respective idx as row and multiply the actual s value by col vector
end
% create matrices
fmat = zeros(Nsec*Ncoun,Ncoun);
for i = 1:1:Nsec*Ncoun
for j = 1:1:Ncoun
fmat(:,:) = alpha(i,j) .* (pij(pis(i,1))).^(-(SG*ones(1,Ncoun)))...
.*(PFis(pij(pis(i,1)))).^((SG*ones(1,Ncoun))-1) .* Yis(wis,pis,mij);
end
end
Fij = fmat; %(NS,N)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create CES intermediate demand function
function [Mij] = mij(pis,mij)
global gama rho Nsec Ncoun
% reformat rho to (N*S,1) instead of initial (S,1)
for s = 1:1:Nsec
idx = 1+(s-1)*Ncoun:1:Ncoun*s; %for every s what is idx
SG(idx,1) = ones(Ncoun,1)*rho(s); %for every s use the respective idx as row and multiply the actual s value by col vector
end
% create matrices
mmat = zeros(Nsec*Ncoun,Nsec*Ncoun);
for i = 1:1:Nsec*Ncoun
for j = 1:1:Ncoun
mmat(i,j) = gama(i,j) .* (pij(pis(i,1))).^(-(SG*ones(1,Ncoun)))...
.* (PMis(pij(pis(i,1)))).^((SG*ones(1,Ncoun))-1) .* IMis(pis,mij); %(NS,N)
end
end
Mij = mmat; %(NS*N)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create final demand total value of imports
function [Pfij] = pfij(pis,wis,mij)
global alpha sigma Nsec Ncoun
% reformat sigma to (N*S,1) instead of initial (S,1)
for s = 1:1:Nsec
idx = 1+(s-1)*Ncoun:1:Ncoun*s; %for every s what is idx
SG(idx,1) = ones(Ncoun,1)*sigma(s); %for every s use the respective idx as row and multiply the actual s value by col vector
end
% create matrices
pfmat = zeros(Nsec*Ncoun,Ncoun);
for i = 1:1:Nsec*Ncoun
for j = 1:1:Ncoun
pfmat(:,:) = alpha(i,j) .* (pij(pis(i,1))).^(1-(SG*ones(1,Ncoun)))...
.*(PFis(pij(pis(i,1)))).^(1-(SG*ones(1,Ncoun))) .* Yis(wis,pis,mij);
end
end
Pfij = pfmat; %(NS,N)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create intermediate demand total value of imports
function [Pmij] = pmij(pis,mij)
global gama rho Nsec Ncoun
% reformat rho to (N*S,1) instead of initial (S,1)
for s = 1:1:Nsec
idx = 1+(s-1)*Ncoun:1:Ncoun*s; %for every s what is idx
SG(idx,1) = ones(Ncoun,1)*rho(s); %for every s use the respective idx as row and multiply the actual s value by col vector
end
% create matrices
pmmat = zeros(Nsec*Ncoun,Nsec*Ncoun);
for i = 1:1:Nsec*Ncoun
for j = 1:1:Ncoun
pmmat(i,j) = gama(i,j) .* (pij(pis(i,1))).^(1-(SG*ones(1,Ncoun)))...
.* (PMis(pij(pis(i,1)))).^(1-(SG*ones(1,Ncoun))) .* IMis(pis,mij); %(NS,N)
end
end
Pmij = pmmat; %(NS,N)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solve GE Model
function syseqn = GEsol(x)
global Ais Lis beta IOmat_cs Ncoun
% Define unknown variables x
% Break x into 4 separate variables
% System x=( mij, fij, pis, wi )
% (N*S,N*S) (N*S,N) (N*S,1) (NS,1)
mij = x(:,1:Ncoun);
fij = x(:,Ncoun+1:end-2);
pis = x(:,end-1);
wis = x(:,end);
% Safeguard restrictions
tol = 1e-10; %Tolerance, use to keep certain variables away from zero
mij = max(mij, tol);
fij = max(fij, tol);
pis = max(pis, tol);
wis = max(wis, tol);
% Equations to be solve simultaneously
eq1 = pij(pis).*fij - pfij(pis,wis,mij); %final demand import
eq2 = pij(pis).*mij - pmij(pis,wis,mij); %intermeditate demand import
eq3 = pis - (beta.^(-beta).*(1-beta).^(-1+beta))...
.* (wis.^beta .* (IOmat_cs.*PMis(pij(pis))).^(1-beta))./Ais; %output price equation
eq4 = Lis - (((sum(fij,2) + sum(mij,2)))./Ais) * ((beta.*PMis(pij(pis)))./...
((1-beta)*wis)).^(1-beta); %labor market clearing condition
syseqn = [eq1, eq2, eq3, eq4];
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Main Script PrograM
% ***********************************
close all;
clear;
clc;
tic;
global alpha gama sigma rho tau Ais Lis beta IOcoef IOmat_cs Nsec Ncoun
%******************************************
% Define country-sector inputs %
%******************************************
Nsec = 2;
Ncoun = 4;
%******************************************
% Define parameters %
%******************************************
sigma = 5*ones(Nsec,1); %elasticity of substitution for households
rho = 5*ones(Nsec,1); %elasticity of substitution for firm
beta = 0.6*ones(Nsec*Ncoun,1); %value-added share
Lis = 1*ones(Nsec*Ncoun,1); %labor (supply) endowment
Ais = 1*ones(Nsec*Ncoun,1); %TFP
tau = 1.5*ones(Nsec*Ncoun,Ncoun); %tariff
alpha = 0.6*ones(Nsec*Ncoun,Ncoun); %sector share of expenditure for final demand
gama = 0.4*ones(Nsec*Ncoun,Ncoun); %sector share of expenditure for intermediate demand
IOcoef = importdata('IOcoef.txt');
% reformat IOcoef to (NS,S) instead of the initial (NS,NS)
IOmat_cs_s = nan(Ncoun*Nsec,Nsec); %cs-s
for t = 1:1:Ncoun
IOmat_cs_s(:,t) = sum(IOcoef(:,((t-1)*Nsec+1):Nsec*t),2); %cs-s
end
IOmat_cs = sum(IOmat_cs_s,2); %change IOcoef to (NS,1) instead of (NS,S)
% % parameters put in a vector to enable easy passing to the function
% P = [beta,Lis,Ais,IOcoef];
%******************************************
% Solve non-linear equations(fsolve) %
%******************************************
options = optimset('Display', 'iter', 'MaxFunEvals', 20000, 'MaxIter', 20000, 'TolFun', 1e-10, 'TolX', 1e-10);
% initial guess vakues for x matrix
x0 = 0.5.*ones(8,10);
% call output of equation function under initial guess
% syseqn = GEsol(x0,P);
% syseqn = GEsol(x0,P,Nsec,Ncoun);
syseqn = GEsol(x0);
% fsolve solves the function by looking for matrix x0 using initial guess
% x = fsolve('GEsol', x0, options,P);
x = fsolve('GEsol', x0, options);
% solution of the model in terms of x
mij = x(:,1:Ncoun);
fij = x(:,Ncoun+1:end-2);
pis = x(:,end-1);
wis = x(:,end);
55 comentarios
Mathieu NOE
el 3 de Sept. de 2021
hello
I had some trouble to run your code
- first issue : error here : IOcoef = importdata('IOcoef.txt'); : the file IOcoef.txt is not provided
- second issues : you have variable names like fij , pis and alike , which are the same as some of your subfunctions names :
% solution of the model in terms of x
mij = x(:,1:Ncoun);
fij = x(:,Ncoun+1:end-2);
pis = x(:,end-1);
wis = x(:,end);
conflict with subfunctions names , like :
function [Pis] = pis(wis)
this is not good and you should create subfunctions which names are not same as variables
for example i simply added "my" to the function names , like here :
function [Pis] = mypis(wis)
- last but not least , where are all those subfunctions used in your main code ? are you sure you posted the entire code ?
all the best
Celestine Siameh
el 3 de Sept. de 2021
Editada: Celestine Siameh
el 3 de Sept. de 2021
Celestine Siameh
el 4 de Sept. de 2021
Celestine Siameh
el 5 de Sept. de 2021
Walter Roberson
el 5 de Sept. de 2021
Look in mypfij
for i = 1:1:Nsec*Ncoun
for j = 1:1:Ncoun
pfmat(:,:) = alpha(i,j) .* (mypij(mypis(i,1))).^(1-(SG*ones(1,Ncoun)))...
i is a scalar, so mypis(i,1) is a scalar, so you are passing a scalar to mypij . But mypij does
for k = 1:1:Nsec*Ncoun
for n = 1:1:Ncoun
pmat(k,n) = mypis(k) .* tau(k,n);
end
end
so it is expecting a vector of values to be passed in.
Both mypfij and mypij are expecting to process the entire vector; you need to change that so that only one of them processes the entire vector.
Celestine Siameh
el 5 de Sept. de 2021
Walter Roberson
el 6 de Sept. de 2021
Sorry, not enough documentation to be able to tell what needs to be changed.
Celestine Siameh
el 6 de Sept. de 2021
Mathieu NOE
el 6 de Sept. de 2021
hello
your code is not very easy to debugg , but I could see already a couple of issues :
probably the most annoying one - as far as I understand how you constructed the whole thing :
- so we start with the main code (GE_fsolve.m) , and first subfunction called is GEsol.m
- in GEsol.m , there are these lines
% Equations to be solve simultaneously
eq1 = mypij(wis).*fij - mypfij(wis,mij); %final demand import
eq2 = mypij(wis).*mij - mypmij(wis,mij); %intermeditate demand import
eq3 = pis - (beta.^(-beta).*(1-beta).^(-1+beta))...
.* (wis.^beta .* (IOmat_cs.*myPMis(mypij(wis))).^(1-beta))./Ais; %output price equation
eq4 = Lis - (((sum(fij,2) + sum(mij,2)))./Ais) * ((beta.*PMis(pij(wis)))./...
((1-beta)*wis)).^(1-beta); %labor market clearing condition
where we call the subfunction mypij.m , (not only) and this function calls mypis.m
(BTW why the index k is no more used in the computation ? )
% solve for price of output(k,n)
for k = 1:1:Nsec*Ncoun
for n = 1:1:Ncoun
pmat(:,n) = mypis(wis(:,1)) .* tau(:,n);
end
end
and mypis.m then use again mypij.m .... this cannot work !
% compute pis(NS,1)
for i = 1:1:Nsec*Ncoun
pimat(:,1) = ((beta(:,1)).^(-beta(:,1)) .* (1-beta(:,1)).^(-1+beta(:,1)))...
.*(wis(:,1).^beta(:,1) .* (IOmat_cs(:,1).*myPMis(mypij(wis(:,1))))...
.^(1-beta(:,1)))./Ais(:,1);
end
so we have a problem here; a subfunction cannot call herself even through another (intermediate) subfunction
this could be the root cause of your infinite loop - or - matlab is stucked in this impossible scenario;
Celestine Siameh
el 6 de Sept. de 2021
Walter Roberson
el 6 de Sept. de 2021
Editada: Walter Roberson
el 6 de Sept. de 2021
mypis:
% compute pis(NS,1)
for i = 1:1:Nsec*Ncoun
pimat(:,1) = ((beta(:,1)).^(-beta(:,1)) .* (1-beta(:,1)).^(-1+beta(:,1)))...
.*(wis(:,1).^beta(:,1) .* (IOmat_cs(:,1).*myPMis(mypij(wis(:,1))))...
.^(1-beta(:,1)))./Ais(:,1);
end
Notice the call to mypij in the first of the continuation lines
Meanwhile, mypij has
for k = 1:1:Nsec*Ncoun
for n = 1:1:Ncoun
pmat(:,n) = mypis(wis(:,1)) .* tau(:,n);
end
end
Notice the call to mypis() .
So to compute mypis the code needs to call mypij, but to compute mypij you need to call mypis, which needs to call mypij which needs to call mypis, which ... etc.
In some cases it is possible to write routines that depend upon each other -- but in such cases you need to be able to prove that each one of them will eventually terminate, such as if each iteration the array size becomes smaller than the time before.
Walter Roberson
el 6 de Sept. de 2021
@Mathieu NOE's reply was not present when I wrote mine... not sure why it did not show up.
An example of something that does not work:
function C = A(x)
C = B(x-1);
end
function D = B(x)
D = A(x-1);
end
In order to execute A, you need to finish executing a call to B. In order to finish executing a call to B, you need to finish executing a call to A -- but in order to finish that call to A, you need to call B to call A to call B to ... it never ends until MATLAB says you are out of memory or you have made too many calls.
An example of something that does work
function C = A(x)
C = B(x-1);
end
function D = B(x)
if all(isinf(x) | x < 0)
D = max(-2, x);
else
D = A(x-1);
end
end
For example, call A([2 4]) then that calls B([1 3]) . In B, no values of [1 3] are infinite or negative, so you take the else and call A([0 2]) . A then calls B([-1 1]) . None of the elements of [-1 1] are infinite, and at least one of the values is not < 0, so the else is taken and A([-2 0]) is called. A then calls B([-3 -1]) . None of the elements of [-3 -1] are infinite, but all of the values of [-3 -1] are < 0, so the if is taken. max(-2, [-3 -1]) is [-2 -1] and that is the output, so that call to B with [-3 -1] finishes, and returns to A, which finishes and returns to the B instance processing [-1 1], which finishes and returns to A, which finishes and returns to the B that is processing [1 3], which returns to the A that is processing [2 4], which finishes -- and the final output is [-2 -1] .
So the problem is not having one function calling another and the other calling the first: the problem is that you have to hae some condition in at least one of the function under which the calls terminate. Each cycle of calls must, in some sense, be reducing the amount of remaining work, and then at some point the calls have to detect that there is no remaining work and return back values.
However... as outsiders we have to ask whether mypis() really depends upon mypij() and mypij() really depends upon mypis() . Sorry, but at the moment as an outsider I get the impression that you are flailing around trying things without thinking through questions about which routine needs to process vectors and which routines need to process invididual elements.
We cannot make any recommendations for you because there is not enough documentation about what the code is intended to do, or why you have those multiple layers of calls.
Mathieu NOE
el 6 de Sept. de 2021
hello again
I don't know what the code is supposed to do (as most of the time when you are not expert in the specific topic)
but if I were you I would first make a graph to show how should the data flow be organized - and avoid this situation.
Try to make the whole process simpler like :
- one main function call one or several subfunctions , that can work in parallel but are not dependent one each other
- if you really needs several hierarchical levels , a subfunction of level -1 can call a subfunction of level -2 , which can also call a subfunction of level -3 , etc... but the problem that we see in your code is that you create a kind of algebraic loop that cannot be solved : a first subfunction call a second subfunction that call itself the first subfunction. That is simply not good coding practice ...
If I had a lot of free time , I could try rewritte your program , but I need to see how the data flow is / should be organized, where we start, what we need to compute (some infos about the whole process would be needed), etc...
so this can be a lot of work and even if I am also keen to give a hand within the possibilities of my skills and agenda, I will not promise to solve all issues for tomorrow !
Celestine Siameh
el 6 de Sept. de 2021
Celestine Siameh
el 7 de Sept. de 2021
Mathieu NOE
el 7 de Sept. de 2021
hello Celestine
wish I could help you, but once I started to read your manuscript I got terrible headaches... this is not simple as I am absolute rookie in economic science.... maybe it would be easier if you could rewritte it with some simpler variable names instead of these cryptic anotations with ij everywhere
also could try to make a graphic to show the work flow of your data vs a time axis ?
Celestine Siameh
el 7 de Sept. de 2021
Mathieu NOE
el 7 de Sept. de 2021
well , I meant , some very high level desription of the tasks and how they interact , especially if there are recurrence
it can be as simple as a pseudo code first like :
- initialization
- C = A + B
- D = D + C (update D)
- A = A + 1 (update A)
- B = B/2 (update B)
- jump back to step 1 and do it until tbd condition (will be a for or while loop or I don't know...)
Celestine Siameh
el 7 de Sept. de 2021
Celestine Siameh
el 8 de Sept. de 2021
Mathieu NOE
el 8 de Sept. de 2021
hello Celestine
I will have a look and try further help you , but I am also in a busy period - I cannot make any promises about my chances of success and when I will be able to show some progress. Do my best I can
Celestine Siameh
el 8 de Sept. de 2021
Mathieu NOE
el 8 de Sept. de 2021
hello Celestine
I started to read your memo , but it's by no way an easy task - at least for me, especially the relationships in this economic matter aren't very familiar to my ears.
I don't know if Walter could start doing something ?
Walter Roberson
el 8 de Sept. de 2021
Editada: Walter Roberson
el 8 de Sept. de 2021
I have no economics experience, and those are too many equations for me to get through.
Celestine Siameh
el 8 de Sept. de 2021
Mathieu NOE
el 8 de Sept. de 2021
hello again
well it's not so easy - because IMHO we have today a code that does not work because of this "algebraic" loop where one function calls a subfunction which itself call the first one function (already explained above)
I doubt that this important issue can be solved simply by "checking" a few functions - it can be that the entire logic must be reviewed and corrected and you probably don't know how hard it can be to dig into someone else code , especially when it's so complex and not in a matter you master (so you also don't know what should be obtained as well )
I really hate to say that I am not in a position to help , it's not a question of ego , but when I start something I like to succeed (as anyone) ---- but believe me , this task is really not easy at all... I could spend hours and hours on it , but this time I simply don't have now. Really sorry
Walter Roberson
el 8 de Sept. de 2021
I checked the functions and how they are called and I already reported back that your code won't work and pointed to the lines that are the problem.
Your code needs to be redesigned, so at this point having me look at it means that I would have to study the equations and the design outline that you posted and figure out what would have to be done.
Celestine Siameh
el 9 de Sept. de 2021
Walter Roberson
el 9 de Sept. de 2021
Sorry, I do not have the resources to engage in a redesign.
Celestine Siameh
el 9 de Sept. de 2021
Editada: Celestine Siameh
el 9 de Sept. de 2021
Celestine Siameh
el 13 de Sept. de 2021
Celestine Siameh
el 14 de Sept. de 2021
Mathieu NOE
el 15 de Sept. de 2021
hello Celestine
about the first bullet - this is just a basic coding practice , when you hav a complex task you try to split it in small pieces (simpler); applied to coding, this means you try to split your complex task into a main code that contains mostly :
- initialising data / structures
- call subfunctions ( that do the hard work )
- put together the results of the subfunctions - the way you want it
- eventually plot and export the results
that "main" code is supposed to be simple and easy to create , read and debugg. Even a non specialist should be able to follow the logic even if the maths or operations may not be his cup of tea.
now what is in the subfunctions depends of what has to be done. usually we put there what is complex or repetitive (so you can call the same subfunction multiple times , for example in a for loop).
to come back to the main issue in your code is that if I had two subfunctions , you have to avoid a situation where the first one calls the second which itself depends on the first one . This kind of situation usually lead to impredictable errors or matlab will simply "freeze" as this is not resolvable.
that 's why in one of my previous answer I say that if yiu are in trouble with this situation you should start to think how the data flow must be organized to avoid such kind of "algebraic" loop; once this is clear for you, then the code implementation should be easier to do and to debug;
hope this general statements can help
Walter Roberson
el 15 de Sept. de 2021
you have to avoid a situation where the first one calls the second which itself depends on the first one .
Not exactly -- but if you do have your code work that way, then each time you go through the sequence, there has to be some way in which you are getting closer to finishing, and the code must test for that completion.
When I glanced at the information earlier, it looked to me as if you should perhaps be working with iteration:
- initialize first matrix
- loop:
- use current version of first matrix to generate second matrix
- use second matrix to propose a modified version of the first matrix
- if the proposed modified version of the first matrix is "close enough" to the current version of the first matrix, then say that the iteration is done and leave the loop
- otherwise, make the proposed modified version of the first matrix into the current version of the first matrix
- loop back
- end of loop
- the current version of the first matrix is the one you work with for whatever calculations
This does not use recursion, it uses looping, and it has an endpoint (provided that generation of the new matrices does not diverge.)
Celestine Siameh
el 15 de Sept. de 2021
Mathieu NOE
el 15 de Sept. de 2021
hello
sorry , I cannot help regarding fsolve (I don't use the Optimization Toolbox)
Celestine Siameh
el 15 de Sept. de 2021
Walter Roberson
el 16 de Sept. de 2021
Change
options = optimset('Display', 'iter', 'MaxFunEvals', 20000, 'MaxIter', 20000, 'TolFun', 1e-10, 'TolX', 1e-10);
to increae the MaxFunEvals and MaxIter options
Celestine Siameh
el 16 de Sept. de 2021
Walter Roberson
el 16 de Sept. de 2021
Increase them more -- 10 million was not enough.
Or look at your output to get an idea of how close you are to a solution, and modify your tolerances so that you would accept something it came up with.
The portion of the output you posted does not, however, appear to be coming up with any good solution.
Walter Roberson
el 16 de Sept. de 2021
Question: does your code involve any random number generation? If it does, it might not converge.
Celestine Siameh
el 16 de Sept. de 2021
Celestine Siameh
el 16 de Sept. de 2021
Walter Roberson
el 17 de Sept. de 2021
https://www.mathworks.com/help/optim/ug/first-order-optimality-measure.html
Your function appears to evaluate to about 1e-8 but the optimality is about 1e+5. That means that the gradient is about that at its worst. You could set the optimality goal as (say) 1e-7, but be sure to estimate the gradient there to see how much the position can be trusted.
Celestine Siameh
el 17 de Sept. de 2021
Celestine Siameh
el 18 de Sept. de 2021
Celestine Siameh
el 18 de Sept. de 2021
Walter Roberson
el 18 de Sept. de 2021
can you explain what gradient is
Given a function F with N inputs,
then you can construct
This is the Gradient function.
Then for any particular set of inputs,
you can evaluate the gradient function G at
to get the list of numeric derivatives, g, at that location.
You can then take
the 2-norm of g, which would be sqrt(sum(g(:).^2)) (but just use norm(), it is shorter). This gives you an approximate idea of how "big" the norm components are -- the length of a vector with those components. This is what fsolve() calls the "first level optimality" .
fsolve() does not, however, have access to the actual function in order to be able to take derivatives. Instead, it evaluates the function N times with slightly different inputs, and uses that to estimate the "slope" along each direction. Does a change of 1e-5 in the 4th variable result in a much larger function value but a change of 1e-5 in the 2nd variable hardly changes anything? Given a particular point, you can estimate how much the function curves with respect to each of the variables -- and that estimate is the numeric gradient.
So, at the end of the search, when fsolve() has returned a list of values, X, then evaluate
Fx = reshape(Gesolve(X), 1, []);
Nx = length(X);
g = zeros(Nx, length(Fx));
for K = 1 : Nx
testX = X; testX(K) = testX(K) + 1e-5;
g(K, :) = GEsolve(testX);
end
differences = abs(g - Fx);
reldifferences = differences ./Fx;
was0 = Fx == 0;
if any(was0)
reldifferences(:,was0) = differences(:,was0);
fprintf('Warning: absolute difference used for variable(s) #%s\n', mat2str(find(was0)));
end
maxreldifference = max(reldifferences(:))
at this point, reldifferences is a measure of relative differences of the nearby points -- relative so that a change of 1/10 in a large number is not as significant as a change of 1/10 in a small number. maxreldifference is the worst case relative difference over the whole system. If it is "small" then the end location is pretty good; if it is "large" then you should examine the entire reldifferences matrix to see which variable (row number) and which equation (column number) is giving trouble.
Walter Roberson
el 18 de Sept. de 2021
Tested code to go at the end of your current code:
X = x;
Fx = reshape(GEsolve(X), 1, []);
Nx = length(X);
g = zeros(Nx, length(Fx));
for K = 1 : Nx
testX = X; testX(K) = testX(K) + 1e-5;
g(K, :) = reshape(GEsolve(testX), 1, []);
end
differences = abs(g - Fx);
reldifferences = differences ./Fx;
was0 = Fx == 0;
if any(was0)
reldifferences(:,was0) = differences(:,was0);
fprintf('Warning: absolute difference used for variable(s) #%s\n', mat2str(find(was0)));
end
maxreldifference = max(abs(reldifferences(:)))
Walter Roberson
el 18 de Sept. de 2021
After 1e6 iterations, maxreldifference was 1.13662450079165 which is Not Good At All.
Walter Roberson
el 18 de Sept. de 2021
It turned out that the 1e-5 that I was using to move by was a significant change for one particular variable. I am working on figuring out better values and better calculations.
Celestine Siameh
el 18 de Sept. de 2021
Walter Roberson
el 18 de Sept. de 2021
I got significant movement of variables between 1e6 function calls and 1e7 function calls even though norm of the estimated gradients did not look too bad at 1e6. norm() of the result of calling the function on the last position (optimality) decreased from 800's to 200's.
I am running 1e8 now (oh darn, just noticed that I did not increase maximum iterations to match.)
You are working with 76 variables and a notable number of outputs (will need to verify the number later.) There might be clever approaches, but I think you might possibly need 3^76 tests to verify that you are at minima.
Celestine Siameh
el 19 de Sept. de 2021
Celestine Siameh
el 19 de Sept. de 2021
Respuesta aceptada
Más respuestas (0)
Categorías
Más información sobre Matrix Indexing en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!