Error in my simple code, 3d matrix issue

1 view (last 30 days)
Robert
Robert on 14 Apr 2015
Commented: Image Analyst on 15 Apr 2015
Here is my code. Basically I am trying to load in 31 matrices then produce one new matrix that is the element by element average of all 31 (So in the new matrix 1:1,1:1 will be the average of the 31 1:1,1:1 values). There is an error somewhere, I think where I make the 2D matrices into 1 3D matrix. The code runs but result is wrong (the matrix that is compiled does not represent the 31 original matrices)
clear all
%Load the Data
S = dir('*.txt');
N = {S.name};
k = 1:numel(S)
A = load(N{k});
Days=zeros(35,43,31);
for k=1:31
Days(:,:,k)=rand(35,43);
end
%Find the Average
Janmean = mean(Days, 3);
%Export the Data
dlmwrite('200301.txt',Janmean)
Thank you in advance for any alterations/help
  1 Comment
Guillaume
Guillaume on 15 Apr 2015
A note on a part of your code that made me pause:
N = somecellarray
k = 1:numel(N); %you use S but N is the same szie
N{k}
is the same as
N = somecellarray
N{:}
The latter shows your intent a lot better

Sign in to comment.

Answers (3)

Jan
Jan on 14 Apr 2015
Edited: Jan on 14 Apr 2015
When you omit the evil clear all you can use the debugger to examine your code line by line. The debugger is such useful and required for serious programming, that dleteing all breakpoints is an extremely bad side effect of clear all.
With the debugger you would see, that the load does not do, what you expect. In the loop the values are set to random matrices by the rand command and the loaded data are simply ignored.
Days = zeros(35,43,31);
for k = 1:31
Data = load(N{k});
Days(:,:,k) = Data.Value; % Replace "Value" according to you files
end
  4 Comments
Robert
Robert on 15 Apr 2015
Thanks, but still stumped, if I only put one variable name in the code won't it just use the same one every loop? I have altered the code but still having trouble...
%This code is to calculate the monthly average from daily values in each
%pixel
clear all
%Load the Data
S = dir('*.txt');
N = {S.name};
k = 1:numel(S)
Days = zeros(35,43,31);
for k = 1:31
Data = load(N{k});
Days(:,:,k) = (Data.???);
end
%Find the Average
Janmean = mean(Days, 3);
%Export the Data
dlmwrite('200301.txt',Janmean)
Image Analyst
Image Analyst on 15 Apr 2015
Did you see the FAQ I gave in my answer? It doesn't use the same filename on each iteration.

Sign in to comment.


Image Analyst
Image Analyst on 15 Apr 2015
Attach one of your text files. If they are not .mat format files then you should probably use some other function instead of load(), like csvread(), importdata(), readtable(), textscan() or something like that.
And see the FAQ for how to read a sequence of files: http://matlab.wikia.com/wiki/FAQ#How_can_I_process_a_sequence_of_files.3F
  3 Comments
Image Analyst
Image Analyst on 15 Apr 2015
What a mess. Does load() read that in correctly?????
Robert
Robert on 15 Apr 2015
Absolutely, each file loads as a 35x43 matrix. This is the way the data is provided to me

Sign in to comment.


Guillaume
Guillaume on 15 Apr 2015
Edited: Guillaume on 15 Apr 2015
Your original code would never work because when you write
load(N{k})
you're passing all the filenames to load at once. load can only open one file at a time. Therefore as per Jan's example your load needs to be inside a loop.
Secondly, I believe that Jan and Image Analyst missed the fact that your load is loading a text file instead of a mat file (or like me assumed it behaved the same for text as for mat, I had to look up the doc). With mat files, load creates a structure whose field names are the variable names stored in the files (hence the replace "Value" according to your file comment). With text files, load just load the data as a matrix.
You were actually nearly there, you'd just need to move the load inside loop and get rid of the rand stuff (what is that about anyway):
%Load the Data
S = dir('*.txt');
numdays = numel(S);
%no need to convert the structure into a cell array
Days=zeros(35,43, numdays); %this is more flexible than hard coding the number of days, particularly if you never check that you actually have 31 files.
for day = 1:numdays %again avoid hardcoding constants, also use better variable names
daydata = load(S(day).name);
%When dealing with user input / data loaded from files, always check that it conforms to your expectations:
assert(isequal(size(daydata), [35 43]), 'File %s is not a 35x43 matrix', S(day).name);
Days(:, :, day) = datdata;
end
%Find the Average
Janmean = mean(Days, 3);
%Export the Data
dlmwrite('200301.txt',Janmean)
As per my comments in the code, you're dealing with external input (in this case files) which may not actually be what you expect. For example there may be 32 text files in the directory, or one of the file may not be a 35 x 43 matrix. When you deal with external input, it's always a good idea to check that it conforms to your expectation or not hard code these expectations.

Tags

Community Treasure Hunt

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

Start Hunting!