Index exceeds array bounds at position 3

3 views (last 30 days)
Owen
Owen on 12 Nov 2024
Commented: Voss on 14 Nov 2024
The variable i on line 86 plot(vsine(begin(FREQ):begin(FREQ)+cycle(FREQ)-1,k),nsd(n,k,i,j)) is said to exceed array bounds once the variable indexes to 5. I am assuming this may be related to an issue at line 43 vsine(n,counter)=ampl(5-i)*sin(2*pi*freq(FREQ)*0.001*ptime(n))+vmean(j); since any value larger than 5 here would return a 0 or negative position variable for ampl. However, if I initialize i at line 79 as for i=1:4:16 then i should be able to index to 16. Is there a logic error I'm missing? Thank you!
freq=[100 250 500 1000];
cycle=[200 80 40 20];
begin=[753 785 795 739];
cnum=[2 4 8 16];
%tth must be accounted for in ZHAD
vhold=-90;
vr=-75;
%all the above are just initial values, trial stands for which model trial
%data was used
%gives us time(ptime)
step=0.05;
ptime=0:step:1199*step;
%This gets sintrace value which is not needed. Left in just in case
for FREQ=1:4
SNUM=16;
for i=1:SNUM
%sweepnamestr=sprintf('%s%s%s', 'Trace_',int2str(9),'_',int2str(i),'_1_1'); %9 used to be 10-FREQ
sweepnamestr=sprintf('%s%s%s', 'Trace_',int2str(10-FREQ),'_',int2str(i),'_1_1');
tracetemp=eval(sweepnamestr);
trace(:,i)=tracetemp(:,2)*10^9; %store sweeps in nA
sintrace(:,i)=trace(301:1500,i);
end
init=14.175;
inipt=285;
finpt=1501;
% to get the voltage amounts (vsine)
ampl=[15 30 45 60];
vmean=[0 -15 -30 -45];
counter=1;
for j=1:length(vmean)
for i=1:length(ampl)
for n=1:1200
vsine(n,counter)=ampl(5-i)*sin(2*pi*freq(FREQ)*0.001*ptime(n))+vmean(j);
end
counter=counter+1;
end
end
%generate current from parameters
cycle=[200 80 40 20];
ta=AM(trial,:);
tb=BM(trial,:);
tg=GM(trial,:);
init=[1;0;0;0;0];
for t=1:length(ptime);
vv=vsine(t);
coeff=[-0.000000000001456 0.000000000012566 0.000000013391643 -0.000000133240032 -0.000033555887315 0.000473197916512 0.038026092731197];
m=aldamtrx(ta,tb,vv);
p0=expm(m*50)*init;
%ppd=p0;
pgval=polyval(coeff,vv);
%ppd = expm(m*step)*ppd;
ppd = expm(m*step)*p0;
nsd(n,k,i,j) = (ppd(5))*(vv-vr)*pgval;
end
%plot the voltage vs current
%see sinavgplot for the use of the values in the first 2 loops
for i=1:4:16
%for i=1:4
ii=(i-1)/4+1;
%ii = (i-1)+1;
for j=1:4
k=i+j;
plot(vsine(begin(FREQ):begin(FREQ)+cycle(FREQ)-1,k),nsd(n,k,i,j))
hold on
end
%pause
hold off
title([num2str(freq(FREQ)),'Hz, ','Mean V=',num2str(vmean(ii)),'V'])
axis([-100 100 -.5 1,])
end
pause
end
Error using eval
Unrecognized function or variable 'Trace_9_1_1_1'.
  5 Comments
Owen
Owen on 13 Nov 2024
Edited: Owen on 13 Nov 2024
No. Variable n should be indexing through as well at 1:1200. Adding another for loop accounting for n after i and j where vsine is being plotted never fully runs to completion and I have to terminate the script.
for i=1:4:16
%for i=1:4
ii=(i-1)/4+1;
%ii=(i-1)+1;
for j=1:4
k=i+j;
for n=1:1200;
plot(vsine(begin(FREQ):begin(FREQ)+cycle(FREQ)-1,k),nsd(n,k,i,j))
hold on
end
end
Voss
Voss on 14 Nov 2024
A couple of pointers:
1. This
sweepnamestr=sprintf('%s%s%s', 'Trace_',int2str(10-FREQ),'_',int2str(i),'_1_1');
would be better written like
sweepnamestr=sprintf('Trace_%d_%d_1_1',10-FREQ,i);
Example to show they are the same:
FREQ = 3;
i = 5;
sweepnamestr=sprintf('%s%s%s', 'Trace_',int2str(10-FREQ),'_',int2str(i),'_1_1')
sweepnamestr = 'Trace_7_5_1_1'
sweepnamestr=sprintf('Trace_%d_%d_1_1',10-FREQ,i)
sweepnamestr = 'Trace_7_5_1_1'
2. You can avoid using eval() by loading the Traces mat file into a structure (rather than loading all its variables directly into the workspace), and then using a dynamic field name to reference the relevant field of the structure. Example:
S = load('hyster_20140721_001sin100.mat');
% ...
tracetemp = S.(sweepnamestr);

Sign in to comment.

Accepted Answer

Voss
Voss on 12 Nov 2024
plot(vsine(begin(FREQ):begin(FREQ)+cycle(FREQ)-1,k),nsd(n,k,i,j))
Indexing nsd is the error, not indexing vsine. (nsd is the only variable indexed on that line using at least 3 subscripts.)
Looking at how nsd is defined:
for t=1:length(ptime)
% ...
nsd(n,k,i,j) = (ppd(5))*(vv-vr)*pgval;
end
At that point in the code, j is length(vmean), i is length(ampl), and n is 1200, because the previous j/i/n nested for loops have all completed (and the loop iteration variables maintain their values after the loops). And k is undefined. (There's no telling what value of k you had in your workspace when you ran the script.) But k is not the problem (not right now, anyway), i is.
So i is length(ampl), which is 4 (and j is also 4). Which means size(nsd) is 1200-by-k-by-4-by-4 (at least - it could be larger because nsd could've been defined by some previously run code before this script was run). Thus, attempting to index nsd in the third dimension with anything greater than 4 will produce the error you got (assuming nsd was not previously defined to be larger than we see here). Indeed you see the error when i is 5.
What's the solution?
  1. Define variables before you use them, in particular k.
  2. Preallocate your variables to the correct size before defining them using indexing in loops.
  3. Consider using clearvars at the top of the script to clear old variables left over from previously run code (i.e., start with a clean workspace).
  4. Also, the definition of nsd is likely incorrect; assigning to nsd(n,k,i,j) suggests that that assignment should take place inside 4 nested loops (over i, j, k, and n) not one loop over t where the variable k is not previously defined in this script and i, j, and n happen to have values left over from previous loops. Maybe that's really what you want, but it doesn't seem likely.
  6 Comments
Owen
Owen on 14 Nov 2024
While this does present figures that are closer to what I am looking for, nsd must be dependent on voltage (vv and thus, vsine) directly because the current values (nsd) should be generated in response to the changing voltage values at each time interval. The figures to be produced should exhibit hysteretic behavior, not linear behavior. Could it could potentially be linear since the for loop at:
for n=1:1200
vsine(n,counter)=ampl(5-i)*sin(2*pi*freq(FREQ)*0.001*ptime(n))+vmean(j);
would be set at 1200 instead of indexing through the array? Thus, only the vsine value taken at ptime = 1200 would be retained.
Voss
Voss on 14 Nov 2024
I think this is probably what you were going for with the nsd calculation:
nsd = zeros(size(vsine)); % pre-allocate nsd
init=[1;0;0;0;0];
coeff = [-0.000000000001456 0.000000000012566 0.000000013391643 -0.000000133240032 -0.000033555887315 0.000473197916512 0.038026092731197];
for t=1:length(ptime)
vv=vsine(t); % same as vsine(t,1)
m=aldamtrx(ta,tb,vv);
p0=expm(m*50)*init;
ppd=p0;
pgval=polyval(coeff,vv);
ppd = expm(m*step)*ppd;
nsd(t,:) = ppd(5)*(vsine(t,:)-vr)*pgval; % calculate one row of nsd from one row of vsine
end
Making that change (see attached untitled_modified_modified.m) gives plots that may be close to being correct. E.g.:

Sign in to comment.

More Answers (0)

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!