9 views (last 30 days)

The problem I'm having is related to looping a function over a grid of inputs. More specifically, I seem to be unable to create an initial matrix for preallocation such that the estimated output is stored properly. I'll provide a brief description before moving on to the actual code.

-- Description.

The goal is to loop a maximum likelihood function over a grid of three arrays. The underlying maximum likelihood function utilizes simulated annealing to numerically estimate thirteen parameters. This maximum likelihood function utilizes a kalman filter to decompose observables into unobservables; trend and cyclical terms. To overcome the identification issue related to having two error terms, I omit the error term parameters pertaining to the cyclical variables, and impose relative variances in the initial variance bounds restrictions.

Therfore, the goal is to loop the maximum likelihood function with three relative variances; such that all outputs (parameters and their associated likelihoods) are stored after every estimation (for every relative variance).

-- Code.

The idea is to loop the maximum likelihood function over a grid of three arrays. In this case, these are given by [g1, g2, g3]. For simplicity, these are (0.5:1:2.5).

1) The [P] output is a function of simulated annealing ("SIMANN") and a likelihood function ("likelihoodfunction"). The main concern here is not related to the codes within these functions, but to the storing of output values they create.

2) The "SIMANN" function only permits one input variable (theta), which is why I have chosen to loop this process multiple times, rather than modifying the "SIMANN" function directly. This isn't the most kosher way of doing this, but the underlying code in the "SIMANN" function isn't something I want to tinker with.

3) The "P" output array is 1x13, whereas "L" is 1x1.

4) In the segment below, I have tried to modify the answer from one of the threads here. This portion is only for the "L" portion of the problem at hand.

L = zeros(3,3,3)

fidx = zeros(3,3,3,3)

for g1=0.5:1:2.5

for g2=0.5:1:2.5

for g3=0.5:1:2.5

% 1. Initial (fictional) values. Not the full code, just an illustration of how the gamma values enter into theta.

theta=[1,2,3,4,5,6,7,8,9,10,g1,g2,g3]

% 2. "P" is a 1x13 array of estimated parameter values.

P=SIMANN('likelihoodfunction', theta);

% 3. The likelihood, L, is produced separately as L.

L=-likelihoodfunction(P);

fidx(g1,g2,g3,:) = [g1,g2,g3];

end

end

end

g1 = reshape(fidx(:,:,:,1), [], 1);

g2 = reshape(fidx(:,:,:,2), [], 1);

g3 = reshape(fidx(:,:,:,3), [], 1);

L = L(:);

results = table(g1, g2, g3, :);

To reiterate, the objective is to loop this segment of the code over a grid of three input arrays. The problem I'm having is how to properly define the preallocation matrix for parameters and the likelihood function, such that all estimated parameters and the associated likelihoods are properly aligned.

The code I receive, after producing "P", is as follows:

Index in position 1 is invalid. Array indices must be positive integers or

logical values.

P(theta)=theta;

-- Summary.

My problem is related to defining properly the matrix for "P" and "L" such that the loop saves the associated values into a proper matrix.

Best regards.

Stephen Cobeldick
on 9 Jan 2020

Edited: Stephen Cobeldick
on 9 Jan 2020

The very simple solution is to loop over indices, and not over data (like you are doing):

V1 = 0.5:1:2.5; % data!

V2 = 0.5:1:2.5; % data!

V3 = 0.5:1:2.5; % data!

N1 = numel(V1);

N2 = numel(V2);

N3 = numel(V3);

L = nan(N1,N2,N3);

for k1 = 1:N1 % indices!

for k1 = 1:N1 % indices!

for k3 = 1:N3 % indices!

% 1. Initial (fictional) values.

theta = [1,2,3,4,5,6,7,8,9,10,V1(k1),V2(k2),V3(k3)];

% 2. "P" is a 1x13 array of estimated parameter values.

P = SIMANN('likelihoodfunction', theta);

% 3. The likelihood, L, is produced separately as L.

L(k1,k2,k3) = -likelihoodfunction(P);

end

end

end

Stephen Cobeldick
on 10 Jan 2020

"The post-loop section of the code creates a table with indices rather than [g1,g2,g3] values"

Because that is exactly what you wrote your code to do:

fidx(k1,k2,k3,:) = [k1,k2,k3]; % store k1, k2, k3 index values.

If you want to store values from V1, V2, and V3, then that is what you need to do:

fidx(k1,k2,k3,:) = [V1(k1),V2(k2),V3(k3)]; % store data values.

"The second problem is associated with the "P" output component."

You are trying to put 13 values into one element, because your LHS indexing refers to only one element of P:

P(k1,k2,k3) = ... 1x13 array

%^^^^^^^^^ but this refers to just ONE element!

That will not work: one element of a numeric array contains one value, that is all. If you want to all put 13 values into an array then you will need to use indexing that refers to 13 elements of that array. For example:

P = nan(N1,N2,N3,13);

for k1 = 1:N1

for k2 = 1:N2

for k3 = 1:N3

...

P(k1,k2,k3,:) = SIMANN('likelihoodfunction', theta);

end

end

end

For consistency I made the first three dimensions those corresponding to V1, V2, and V3: MATLAB will automatically change the 1x13 array into a 1x1x1x13 array to fit into the location that the indexing refers to. If you really MUST keep the 1x13 orientation then do this:

P = nan(N1,13,N2,N3);

...

P(k1,:,k2,k3) = SIMANN('likelihoodfunction', theta);

Sign in to comment.

KALYAN ACHARJYA
on 9 Jan 2020

Edited: KALYAN ACHARJYA
on 9 Jan 2020

Please note that you are using invalid indexing, In MATLAB allows only positive real numbers for indexing

for loop g1=0.5:1:2.5

for g2=0.5:1:2.5

for g3=0.5:1:2.5

fidx(g1,g2,g3)=

end

end

Here fidx(0.5.0...) are not allowed

fidx(indexing Values must be real position number only)

fidx(0.5)>> Wrong

fidx(-2)>> Wrong

fidx(0)>> Wrong

fidx(2)>> Correct way ..

More Example

fidx(g1,g2,g3)=...... Here g1,g2,g3 must be position interger like, 1,2,3,4 only (Not 0, or 0.4,or -4)

Hope it helps to get the error sort out, please try you can.

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.