Looping a function with different inputs and storing multiple outputs.

45 ビュー (過去 30 日間)
Memek
Memek 2020 年 1 月 9 日
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.

採用された回答

Stephen23
Stephen23 2020 年 1 月 9 日
編集済み: Stephen23 2020 年 1 月 9 日
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
  4 件のコメント
Memek
Memek 2020 年 1 月 10 日
These extensions work perfectly! I should have asked these questions three days ago, thank you. Maybe one day I'll get a hang of these (seemingly) minor nuisances.
Nurul Ain Basirah Zakaria
Nurul Ain Basirah Zakaria 2021 年 12 月 21 日
Hi. How about if I have this function works well on 420x1 data but not 58x69x420 data.
s = spei(t,P,pevap);
It works well with
t=420x1
P=420x1
pevap=420x1
But, how can I make it works on;
t=1x1x420
P=65x98x420
pevap=65x98x420
Can I do this?

サインインしてコメントする。

その他の回答 (1 件)

KALYAN ACHARJYA
KALYAN ACHARJYA 2020 年 1 月 9 日
編集済み: KALYAN ACHARJYA 2020 年 1 月 9 日
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.

カテゴリ

Help Center および File ExchangeCorrelation and Convolution についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by