MATLAB Answers

A problem with using generalized code

1 view (last 30 days)
UPDATE:
I think I found what is the cause of this problem in fact in the last code that I wrote to this question, in this line
Cnew{r,m}=cell2table(C{r,m}.station_name); % input names under the "station_name" variable of your old tables into the new cell array based on their indexed locations
It gets Cnew based on station_name. station_name in C was different names but in Cgrid all station_names are same each other. So I think this line should modify but I don't know-how.
----------------------------------------------------------------------------------------------------------------------------------------------
Hello all,
I have a problem, I checked everything but I can't find whats wrong. I want to use the function that writes for me in my previous question for new input (Cgrid) against C (in the previous question). The function gave me the right answer when I run it using C (previous question attached file) but it gives me repeated answers when I try to run it using Cgrid as input. I write my issue here and I write my codes too:
I wanted to run this code ( I call it N_SPI in the rest of this question) below for each precip in the tables that stored in Cgrid and save the results in another cell named CgridSPI.
% The name of this code is N_SPI
% Source code: https://www.mathworks.com/matlabcentral/fileexchange/51080-nonparametric-standardized-precipitation-index-spi
% this code calculates SPI 1, 3, 6, 12, 24, 48 months for a given station.
td = Cgrid{1,1}.rrr24; % get rrr24 of first station_name I want do it for all station_name's rrr24
Date = Cgrid{1,1}.date % date is constant for all station_name
sc_vect=[1 3 6 12 24 48]; % a set including all values for iterations
% sc: scale of the index (>1, e.g., 3-month SPI or SSI)
n=length(td);
SI=zeros(n,numel(sc_vect)); % columns correspond to values in sc_vect
% iterate over sc_vect
for p=1:numel(sc_vect)
sc = sc_vect(p);
%For some grid, no observation exist.
if length(td(td>=0))/length(td)~=1
SI(n,p)=nan;
else
% Obtain the prcp and smc for the specified time scale and
% compute the standarized drought index (for SPI and SSI)
SI(1:sc-1,p)=nan;
A1=[];
for i=1:sc,
A1=[A1,td(i:length(td)-sc+i)];
end
Y=sum(A1,2);
% Compute the SPI or SSI
nn=length(Y);
SI1=zeros(nn,1);
for k=1:12
d=Y(k:12:nn);
%compute the empirical probability
nnn=length(d);
bp=zeros(nnn,1);
for i=1:nnn
bp(i,1)=sum(d(:,1)<=d(i,1));
end
y=(bp-0.44)./(nnn+0.12);
SI1(k:12:nn,1)=y;
end
SI1(:,1)=norminv(SI1(:,1));
%output
SI(sc:end,p)=SI1;
end
end
CgridSPI = array2table(SI);
CgridSPI.Properties.VariableNames = {'SPI_1month' 'SPI_3month' 'SPI_6month'...
'SPI_12month' 'SPI_24month' 'SPI_48month'};
So thanks to helping by fred ssemwogerere in this question I used this function below to use the above code for all my tables in Cgrid.
function SI = myfunction(Cn,rnum,colnum,tcol) % save this as a functionfile with filename: "myfunction.m"
%Summary of "myfunction"
% SI = output
% Cn = Cell array storing all tables
% rnum = row index of table in cell array
% colnum = column index of table in cell array
% tcol = column number of table variable ("rrr24") on which you are doing the computations
td = table2array(Cn{rnum, colnum}(:,tcol)); % example for C{1, 1}
n=numel(td);
sc_set= [3,6,12,24];
SI=zeros(n,length(sc_set));
for q = 1:length(sc_set)
sc = sc_set(q); % I have replaced "k" with "q" on this line
if numel(td(td>=0))/numel(td)~=1
SI(n,q)=nan;
else
SI(1:sc-1,q)=nan;
A1=[];
for i=1:sc
A1=[A1,td(i:numel(td)-sc+i)]; %#ok<AGROW>
end
Y=sum(A1,2);
nn=numel(Y);
SI1=zeros(nn,1);
for k=1:12
d=Y(k:12:nn);
nnn=numel(d);
bp=zeros(nnn,1);
for i=1:nnn
bp(i,1)=sum(d(:,1)<=d(i,1));
end
y=(bp-0.44)./(nnn+0.12);
SI1(k:12:nn,1)=y;
end
SI1(:,1)=norminv(SI1(:,1));
%output
SI(sc:end,q)=SI1;
end
end
end
So then I used this below to achieve my outputs:
Cnew=cell(1,size(Cgrid,2)); % pre-allocating your new array
for r=1:size(Cgrid,1)
for m=1:size(Cgrid,2)
SI{r,m}= myfunction(Cgrid,r,m,4);% On this line, "4" is the column index of "precip" (your table variable)
Cnew{r,m}=cell2table(Cgrid{r,m}.model_name); % input names under the "station_name" variable of your old tables into the new cell array based on their indexed locations
Cnew{r,m}.Output=SI{r,m}; % Add column variable, "Output" holding computed values to each table in the new cell array based on their indexed positions
Cnew{r,m}.Properties.VariableNames{1}='model_name'; % variable name for first column of each table
end
end
This code gives me correct answers when I run it using my previous question attached data but when here I want to run it with Cgrid, I saw that all results for all tables are the same (repeated, all is 2.02).
To check that issue I run N_SPI code manually for some cell in Cgrid and saw that everything is okay and I haven't any similar results in CgridSPI , I don't know why I get the same answer for all tables when I use Cgrid.
Thank you in advance

  0 Comments

Sign in to comment.

Accepted Answer

fred  ssemwogerere
fred ssemwogerere on 10 Feb 2020
Hello, the problem stems from the value of your column index; "4". You should be indexing column "5" instead on line 4 of the last code above. Column index "4" is for position (latitude). Additionally, please edit the function file "myfunction" on line 4 (without counting commented lines) to:
sc_set= [1,3,6,12,24,48];
% this includes additional inputs for periods that you are making the computations

  1 Comment

Behzad Navidi
Behzad Navidi on 10 Feb 2020
Thank you so much. My problem fixed.

Sign in to comment.

More Answers (0)

Sign in to answer this question.

Products


Release

R2018b