MATLAB Answers

0

ODE Error: "Array indices must be positive integers or logical values"

Asked by Tom Keaton on 21 Aug 2019
Latest activity Commented on by Star Strider
on 21 Aug 2019
Alright I managed to simplify this down to the most basic I can. I am getting an error in my ode set:
Index in position 1 is invalid. Array indices must be positive integers or logical values: .
Error in bdipuniodefun (line 10)
bdip = [s(4); s(5); s(6); (Ex(s(1),s(2),s(3))); (Ey(s(1),s(2),s(3))); (Ez(s(1),s(2),s(3)))];
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode15s (line 150)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in EFieldTest (line 46)
[T,S] = ode15s(@bdipuniodefun, tspan, icv);
What does this mean? My code:
%TSTEP MUST BE ABLE TO GO INTO TFIN AN ODD AMOUNT OF TIMES (Because simulation includes tstep @ 0 so it ends up being even)
tstep = 1; %Defining time step
tfin = 11; %Defining final time
%Create zeros matrices to populate later
intspan = [0:tstep:tfin]; %Total time span
[introw,intcol] = size(intspan);
%Generate matrix that will be populated by positions and velocities (Each matrix within structure "posandvelmat" should be of size 2*introw-1 by 6)
posandvelmat = zeros(2*intcol-1,6);
spart(1) = 0;
spart(2) = 0;
spart(3) = 0;
vpart(1) = 0;
vpart(2) = 0;
vpart(3) = 0;
tic
for t = 0:1:intcol-2 %complete time interval and time step
%Defining relative position and velocity
x = spart(1);
y = spart(2);
z = spart(3);
vx = vpart(1);
vy = vpart(2);
vz = vpart(3);
%Coupled differential equation solver for trajectory within current time step
icv = [x; y; z; vx; vy; vz]; %Initial conditions
tspan = [intspan(t+1) ((intspan(t+2)-intspan(t+1))/2)+intspan(t+1) intspan(t+2)]; %Time span
%Trajectory solver
[T,S] = ode15s(@bdipuniodefun, tspan, icv);
posandvelmat((1+2*t):(3+2*t),(1:6)) = S;
%Redfine the velocity and position components to reference on next if-loop run
spart(1) = posandvelmat((3+2*t),1);
spart(2) = posandvelmat((3+2*t),2);
spart(3) = posandvelmat((3+2*t),3);
vpart(1) = posandvelmat((3+2*t),4);
vpart(2) = posandvelmat((3+2*t),5);
vpart(3) = posandvelmat((3+2*t),6);
end
bdipuniodefun script:
function bdip = bdipuniodefun(t,s)
persistent Ex Ey Ez
if isempty(Ex)
[Ex, Ey, Ez] = E_field_c();
end
bdip = [s(4); s(5); s(6); (Ex(s(1),s(2),s(3))); (Ey(s(1),s(2),s(3))); (Ez(s(1),s(2),s(3)))];
end
E_field_c script:
function [Ex, Ey, Ez] = E_field_c()
syms x y z
E = -2000.*z;
Ex = matlabFunction(E(1));
Ey = matlabFunction(E(2));
Ez = matlabFunction(E(3));
end

  3 Comments

It appears that ‘Ex’ and the others are values, not arrays or functions, so you need an operator between them and the values that follow. Note that even with that change:
Ex*(s(1),s(2),s(3))
this is not valid MATLAB syntax.
This is valid:
Ex*[s(1),s(2),s(3)]
however it may not be what you want to do (since that is not at all obvious).
The Ex, Ey and Ez all are supposed to be functions depedent on s(1), s(2) and s(3). It is not a constant multiplied against the S's. I thought that putting them in parenthases in this way would make them so.
Edit - Sorry I forgot to add these important lines to the "E_field_c" function. However, it still does not fix the error.
Ex = matlabFunction(E(1));
Ey = matlabFunction(E(2));
Ez = matlabFunction(E(3));
That still lacks significant clarity.
Note that:
Ex = matlabFunction(E(1));
Ey = matlabFunction(E(2));
Ez = matlabFunction(E(3));
assumes ‘E’ as a vector. It isn’t.
Consider:
syms v x y z
E(v) = -2000.*v;
Ex = matlabFunction(E(1));
Ey = matlabFunction(E(2));
Ez = matlabFunction(E(3));
That at least makes some sense, although ‘Ex’ and the rest are functions without input arguments.
Note that in my version of the code (that has the advantage of at least having the correct syntax):
Ex =
function_handle with value:
@()-2.0e+3
so ‘Ex’ and the rest have no idea what to do with the arguments you give them. Passing them any arguments at all wil throw:
Error using symengine>@()-2.0e+3
Too many input arguments.
Please spend some time with the documentation.

Sign in to comment.

Tags

1 Answer

Ted Shultz 님의 답변 21 Aug 2019

You are calling bdipuniodefun(t,s) with s having values of 0 (values from icv). Your program then attempts to index to the "0" element of Ex (using s as the index). In MATLAB there is no 0 index, thus the error.

  2 Comments

Even when I changed the initial conditions to all equal 1 and the indexing to 1 for the for loop I still get the same error. Also, shouldn't the ode solver be able to use 0 as an initial condition when solving?
0 is the not the inital condition, but an invalid index.
when you write
Ey(s(1),s(2),s(3))
Matlab things that you are saying that Ey is a three dimentional variable, and that you want the value definded by the location dim1 = s(1), dim2 = s(2) and dim3 = s(3).
I don't belive that is what you are trying to do. I think your notation could be tweaked.

Sign in to comment.