Improper index matrix reference in parfor matlab called from command line - matlab

I have this piece of MATLAB code:
path(path,'./Classes');
locationID = 'Z8Ksof1rzm';
poolobj = gcp('nocreate');
if isempty(poolobj)
parpool(4)
else
%do nothing. we already have parpool running
end
myFiles = dir(strcat('./exportParse/exportLocation_', locationID));
MachineData = cell(length(myFiles)-2,1);
disp(myFiles)
parfor iFile =3:length(myFiles)
jsonFile = myFiles(iFile).name;
MachineData{iFile-2} = loadjson(strcat('./exportParse/exportLocation_', locationID,'/',jsonFile));
end
The script runs pretty well from the MATLAB desktop. I see no errors and I get all 4 processors working on the json parsing. At the end, I get MachineData filled with the desired information. All good.
The problem occurs when I call
matlabPath="/Applications/MATLAB_R2014b.app/bin/matlab -nodesktop -nosplash -r"
$matlabPath "run myScript.m"
where myScript.m is the file containing the code above. The script won't run again, it says this:
10x1 struct array with fields:
name
date
bytes
isdir
datenum
Error using readDataAprocam (line 17)
Improper index matrix reference.
Error in run (line 63)
evalin('caller', [script ';']);
as you can see, the line dis(myFiles) returns a valid struct array of files.
Line 17 is the line of the parfor command.
Note that on the shell and in MATLAB I'm located on the same path. I also shut down the parpool on the matlab desktop so the script running from the shell can claim it. there is no problem here as well.
What does Improper index matrix reference means on this context? Why does it run from the matlab desktop and not from the shell?
I'm running Mac OS X 10.11.3 and MATLAB 2014b.

I'm not sure what I did, but I got rid of this error. My code looks like this now:
myScript.m:
%% settings
path(path,'./Classes');
locationID = 'Z8Ksof1rzm';
poolobj = gcp('nocreate');
if isempty(poolobj)
parpool(4)
else
%do nothing. we already have parpool running
end
%% get files
disp('ok. lets try it')
myFiles = dir(strcat('./exportParse/exportLocation_', locationID,'/export*'));
MachineData = cell(length(myFiles),1);
parfor iFile =1:length(myFiles)
data = importJSONFile(iFile,locationID,myFiles);
MachineData{iFile} =data;
end %looping over files
MachineData
Script importJSONFile:
function data = importJSONFile(fileIndex,locationID,myFiles)
jsonFile = myFiles(fileIndex).name;
filePath = strcat('./exportParse/exportLocation_', locationID,'/',jsonFile);
data = loadjson(filePath);
%data = struct;
end
The code runs from the shell ONLY if I change the parfor to for. if I leave the parfor it will trow the error
Error using myScript (line 16)
Conversion to char from cell is not possible.
Error in run (line 63)
evalin('caller', [script ';']);
Line 16 is the parfor line.
... but, I got rid of the error above.

Related

Try/Catch without skipping lines after the error (Matlab) [duplicate]

I'd like to run several lines of code, but I'm unsure if any line will throw an error. If an error occurs however, I'd like the script to ignore that line and continue on.
One choice would be to have a try-catch-end block, that skips over a block of code that may throw errors. However, as soon as an error occurs, the rest of the code after the error in the try-statement is not executed.
TL;TR: Do I have another choice than writing a try-catch-end block for every individual line in the following example code?
Example code:
try
disp('1st line');
disp('2nd line');
PRODUCE_ERROR; %throws an error, variable/function does not exist
disp('3rd line'); %%%%%
disp('4th line'); % these lines I would like to keep executing
disp('5th line'); %%%%%
catch
disp('something unexpected happened');
end
Output:
1st line
2nd line
something unexpected happened
Output that would be preferred:
1st line
2nd line
something unexpected happened
3rd line
4th line
5th line
related: Why should I not wrap every block in "try"-"catch"?
One option is to put each section of code in a function and iterate over a cell array of the function handles. Here's an example with a list of anonymous functions:
fcnList = {#() disp('1'); ...
#() disp('2'); ...
#() error(); ... % Third function throws an error
#() disp('4')};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}(); % Evaluate each function
catch
fprintf('Error with function %d.\n', fcnIndex); % Display when an error happens
end
end
And here's the output this generates, showing that functions are still evaluated even after one throws an error:
1
2
Error with function 3.
4
The above example works for the case when you have individual lines of code you want to evaluate sequentially, but you can't fit multiple lines into an anonymous function. In this case, I would go with nested functions if they have to access variables in the larger workspace or local functions if they can operate independently. Here's an example with nested functions:
function fcn1
b = a+1; % Increments a
fprintf('%d\n', b);
end
function fcn2
error(); % Errors
end
function fcn3
b = a.^2; % Squares a
fprintf('%d\n', b);
end
a = 2;
fcnList = {#fcn1 #fcn2 #fcn3};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}();
catch
fprintf('Error with function %d.\n', fcnIndex);
end
end
And the output:
3
Error with function 2.
4
A simpler approach involves reading the script file line by line and evaluating each line in turn. This assumes that the script you want to run does not include any multi-line statements (such as e.g. a for with the end on a different line, or a statement broken onto multiple lines using ...). This is a strong limitation, as it is common to e.g. initialize a matrix using multiple lines of text.
This is the function:
function execute_script(fname)
fid = fopen(fname,'rt');
n = 0;
while ~feof(fid)
cmd = fgetl(fid);
n = n+1;
if ~isempty(cmd)
try
evalin('caller',cmd);
catch exception
disp(['Error occurred executing line number ',num2str(n),': ',exception.message]);
end
end
end
It does exactly as I described above: it reads in a line, then uses evalin to evaluate that line in the caller's workspace. Any variable created is created in the caller's workspace. Any variable used is taken from the caller's workspace.
For example, I create the file testscript.m with the following contents:
A = 1;
B = 2+C; % This line needs a variable not defined in the script!
D = 5;
Next, at the MATLAB command prompt:
>> execute_script('testscript.m')
Error occurred executing line number 2: Undefined function or variable 'C'.
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
D 1x1 8 double
The variable A and D were created. If I define C:
>> C=0;
>> execute_script('testscript.m')
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
B 1x1 8 double
C 1x1 8 double
D 1x1 8 double
With a variable C defined, the script runs without error, and defines B also.

sequential try catch end block for matlab

I'd like to run several lines of code, but I'm unsure if any line will throw an error. If an error occurs however, I'd like the script to ignore that line and continue on.
One choice would be to have a try-catch-end block, that skips over a block of code that may throw errors. However, as soon as an error occurs, the rest of the code after the error in the try-statement is not executed.
TL;TR: Do I have another choice than writing a try-catch-end block for every individual line in the following example code?
Example code:
try
disp('1st line');
disp('2nd line');
PRODUCE_ERROR; %throws an error, variable/function does not exist
disp('3rd line'); %%%%%
disp('4th line'); % these lines I would like to keep executing
disp('5th line'); %%%%%
catch
disp('something unexpected happened');
end
Output:
1st line
2nd line
something unexpected happened
Output that would be preferred:
1st line
2nd line
something unexpected happened
3rd line
4th line
5th line
related: Why should I not wrap every block in "try"-"catch"?
One option is to put each section of code in a function and iterate over a cell array of the function handles. Here's an example with a list of anonymous functions:
fcnList = {#() disp('1'); ...
#() disp('2'); ...
#() error(); ... % Third function throws an error
#() disp('4')};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}(); % Evaluate each function
catch
fprintf('Error with function %d.\n', fcnIndex); % Display when an error happens
end
end
And here's the output this generates, showing that functions are still evaluated even after one throws an error:
1
2
Error with function 3.
4
The above example works for the case when you have individual lines of code you want to evaluate sequentially, but you can't fit multiple lines into an anonymous function. In this case, I would go with nested functions if they have to access variables in the larger workspace or local functions if they can operate independently. Here's an example with nested functions:
function fcn1
b = a+1; % Increments a
fprintf('%d\n', b);
end
function fcn2
error(); % Errors
end
function fcn3
b = a.^2; % Squares a
fprintf('%d\n', b);
end
a = 2;
fcnList = {#fcn1 #fcn2 #fcn3};
for fcnIndex = 1:numel(fcnList)
try
fcnList{fcnIndex}();
catch
fprintf('Error with function %d.\n', fcnIndex);
end
end
And the output:
3
Error with function 2.
4
A simpler approach involves reading the script file line by line and evaluating each line in turn. This assumes that the script you want to run does not include any multi-line statements (such as e.g. a for with the end on a different line, or a statement broken onto multiple lines using ...). This is a strong limitation, as it is common to e.g. initialize a matrix using multiple lines of text.
This is the function:
function execute_script(fname)
fid = fopen(fname,'rt');
n = 0;
while ~feof(fid)
cmd = fgetl(fid);
n = n+1;
if ~isempty(cmd)
try
evalin('caller',cmd);
catch exception
disp(['Error occurred executing line number ',num2str(n),': ',exception.message]);
end
end
end
It does exactly as I described above: it reads in a line, then uses evalin to evaluate that line in the caller's workspace. Any variable created is created in the caller's workspace. Any variable used is taken from the caller's workspace.
For example, I create the file testscript.m with the following contents:
A = 1;
B = 2+C; % This line needs a variable not defined in the script!
D = 5;
Next, at the MATLAB command prompt:
>> execute_script('testscript.m')
Error occurred executing line number 2: Undefined function or variable 'C'.
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
D 1x1 8 double
The variable A and D were created. If I define C:
>> C=0;
>> execute_script('testscript.m')
>> whos
Name Size Bytes Class Attributes
A 1x1 8 double
B 1x1 8 double
C 1x1 8 double
D 1x1 8 double
With a variable C defined, the script runs without error, and defines B also.

How can I execute my Thomas Algorithm function using Matlab?

I have created a function to execute the thomas algorithm. I'm trying to use my function to solve a system with the following arrays:
b = -4ε + 2αh^2
a = 2ε - h(1+α(n+1)h)
c = 2ε + h(1+αnh)
g = 4kπh^2sin(kπnh)
where α=1.2, k=2, ε=0.02, R=4
I've inserted my function (below), but I'm not completely sure how to enter in these parameters in the command window as I'm pretty new to Matlab. Any help would be much appreciated.
function y = ThomasAlgorithm(a,b,c,f)
% obtain values
m = length(f);
f(1) = f(1)/b(1);
% Forward Substitution
for j = 1:m-1
c(j) = c(j)/b(j);
b(j+1) = b(j+1) - a(j)*c(j);
f(j+1) = (f(j+1) - a(j)*f(j))/b(j+1);
end;
% Backwards Substitution
for k = m-1:-1:1
f(k) = f(k) - c(k)*f(k+1);
end;
% Output
y = f;
end
I tried to put this into the command window (below) but I got the error:
Error in ThomasAlgorithm (line 11)
b(j+1) = b(j+1) - a(j)*c(j);
I'm not really sure where I'm going wrong at the moment or how to solve it and I've kind of hit a wall.
>> m=10;
x0=0, xm=1;
y0=R, ym=0;
alpha=1.2;
k=2;
eps=0.02;
R=4;
h=xm-x0/m;
a=[2*eps-h*(1+alpha*((1:m-1)+1)*h)];
b=[-4*eps+2*alpha*h*h];
c=[2*eps+h*(1+(alpha*(1:m-1)*h))];
f=[4*k*pi*h*h*sin(k*pi*(1:m-1)*h)];
x=ThomasAlgorithm(a,b,c,f);
for ic=1:n
disp(x);
end
Put all of the stuff you've put in the command window into a separate script (.m file) instead, then run it. This allows you to get the actual full error message, and keeps the command window clutter free!
When running the script with your code in, you see the following error:
Undefined function or variable 'R'.
Error in myScript (line 3)
y0=R, ym=0;
Now your (first) problem is clear! You set y0=R when R doesn't exist.
It's good practise at times like this to run clear before you run your script, so your workspace is emptied and you know what you've not defined in the script.
So we add R = 1 or something to the start, then run it again. Now we have an indexing error!
Index exceeds matrix dimensions.
Error in ThomasAlgorithm (line 8)
b(j+1) = b(j+1) - a(j)*c(j);
This is because you defined b as
b=[-4*eps+2*alpha*h*h]; % a SCALAR not a vector!
Then passed it to ThomasAlgorithm and expected to be able to index it, when it isn't a vector.
Hopefully that points out the immediate problem, and how to better diagnose issues. Also when your code is in a script you can step through it to debug things.

Issue with parfor in Matlab; "UndefinedFunction error thrown to workers" and Matlab crashing

I've got some code that works perfectly fine in series, but I'm trying to speed it up by putting it in parallel, and it's giving me fits in multiple places. Here's my code:
parfor q = 1:num_ranges;
timenumber = squeeze(DATA(q,:,:));
timenumber_shift = circshift(timenumber, [0 1]);
for m = 1:total_working_channels;
timenumberm = timenumber(m,:);
for n = 1:total_working_channels;
R_P(m,n,q) = mean(timenumberm.*conj(timenumber(n,:)),2);
R_V(m,n,q) = mean(timenumberm.*conj(timenumber_shift(n,:)),2);
end
end
end
DATA is a complex double of size 1716x32x400. When I try running it like this, Matlab just crashes ("Matlab has encountered an internal problem and needs to close"). Is the array too big to be sent? I have a feeling that that's the issue, but I'm not sure.
To get around that, I've tried changing the location of the parfor command; here's attempt #2:
for q = 1:num_ranges;
timenumber = squeeze(DATA(q,:,:));
timenumber_shift = circshift(timenumber, [0 1]);
parfor m = 1:total_working_channels; %this is line 145!
timenumberm = timenumber(m,:);
for n = 1:total_working_channels;
R_P(m,n,q) = mean(timenumberm.*conj(timenumber(n,:)),2);
R_V(m,n,q) = mean(timenumberm.*conj(timenumber_shift(n,:)),2);
end
end
end
When I do this, Matlab doesn't crash. However, in the command line, it says "Analyzing and transferring files to workers...done.", followed by an error. Here's the error message:
Error using DBFCode12 (line 145). An UndefinedFunction error was thrown on the workers for ''. This might be because the file containing '' is not accessible on the
workers. Use addAttachedFiles(pool, files) to specify the required files to be attached. See the documentation for
'parallel.Pool/addAttachedFiles' for more details. Caused by: Undefined function or variable "".
I'm pretty well stumped on this one. Why is it saying there's an undefined function (with no name!) on the parfor line?
I'm using version R2014a.

save figure on multiple folders on matlab

I am new on matlab and I don't know many things at the moment.
I have a script which create more than 100 figures. I want to save those figures in 3 different folders. Here is my code until now:
pridir='C:\Users\tasos\Desktop\folder';
figtxt1='folder1';
figtxt2='folder2';
figtxt3='folder3';
yM = load('pathtomydata');
[n,m]=size(yM);
maxtau2 = 10;
alpha = 0.05;
zalpha = norminv(1-alpha/2);
p=6;
for i=1:m-1
for j=i+1:m
figure()
y1V=yM(:,i);
y2V=yM(:,j);
plot(y1V,'b')
hold on
plot(y2V,'r')
legend(sprintf('text= % d',i),sprintf('text= % d',j))
title('My Title')
printto = sprintf('%s%d\\text%d and %d.jpg',pridir,i,i,j);
print('-djpeg90',printto)
close(gcf)
end
end
If I left my code like this, all the figures created but they didn't save on folders. If I remove the "%" from the last two lines, I have the following error
Error using name (line 103)
Cannot create output file 'C:\Users\tasos\Desktop\folder1\text1 and 2.jpg'
Error in print (line 206)
pj = name( pj );
Error in test (line 25)
print('-djpeg90',printto)
P.S. I am using the R2012b version
Avoid eval()!
Define one generic print directory:
pridir = 'C:\Users\***\Desktop\fold';
Then inside the inner loop:
printto = sprintf('%s%d\\figuretext %d and %d.jpg',pridir,i,i,j);
print('-djpeg90',printto)
where printto will be something like:
C:\Users\***\Desktop\fold1\figuretext 1 and 3.jpg
Also, you might want to close the figure after the print: close(gcf).
NOTE: the directories where you're gonna save the files should already exist, otherwise create them with mkdir() before saving any pictures.
I think matlab changed the code for writing a folder with the 2013 version.
I changed 'XX\YY\ZZ.pjg'
To:
'XX/YY/ZZ.pjg'
And it worked for me, strangely.