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

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

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.