Hi,
I am trying to vary one of the parameters of my system. Then, I would like to input this value into the ode45 function, and determine the maximum displacement of my system, such that it is recorded in a variable, max_displ. I would like to iterate for many different values of my parameter, k_l, so I thought to use a for loop.
dk=1;
k_l=[1:dk:2]; %0 to 2 is just a test
for ii=1:dk:numel(k_l) %will iterate for all the values of the k_l from 0 up to 2
k_l=k_l(ii)
[t,z] = ode45(@(t, z) f(t,z,k_l,disp_data,vel_data,t_data),T,IC);
disp_data_int=interp1(t_data,disp_data,t,'spline'); %extracting the displacement data from the earthquake
displ=(z(:,8)); %extracting the displacement data for a particular stiffness value
disp_a=abs(disp_data_int-displ); %finding absolute value of diffence between displacment of earthquake and building
max_displ(ii)=max(disp_a) %finding the maximumm displacement for a particular stiffness value
end
figure;
hold on
plot(k_l,max_displ);
MATLAB indicates this error 'Index exceeds the number of array elements (1)', for this line of code,
k_l=k_l(ii)
Any suggestions would be greatly appreciated.
Thanks,
Kostas

 Respuesta aceptada

Star Strider
Star Strider el 31 de Mzo. de 2022

0 votos

Put the reference in the ‘f’ argument list:
[t,z] = ode45(@(t, z) f(t,z,k_l(ii),disp_data,vel_data,t_data),T,IC);
↑ ← HERE
and the loop indexing should be defined simply as:
for ii=1:numel(k_l)
.

7 comentarios

Kostas Kalabokas
Kostas Kalabokas el 31 de Mzo. de 2022
Thank you very much, that makes a lot more sense now.
K
Star Strider
Star Strider el 31 de Mzo. de 2022
As always, my pleasure!
If I wanted to extend this to vary another parameter, lets say c_l, would I use a nested for loop, definining
for ii=1:numel(k_l) %will iterate for all the values of the k_l from 0 up to 2
for jj=1:numel(c_l)
k_lii=k_l(ii)
c_ljj=c_l(jj)
[t,z] = ode45(@(t, z) f(t,z,k_l(ii),c_l(jj),disp_data,vel_data,t_data),T,IC);
disp_data_int=interp1(t_data,disp_data,t,'spline'); %extracting the displacement data from the earthquake
displ=(z(:,8)); %extracting the displacement data for a particular stiffness value
disp_a=abs(disp_data_int-displ); %finding absolute value of diffence between displacment of earthquake and building
max_displ(ii,jj)=max(disp_a) %finding the maximumm displacement for a particular stiffness value
end
end
Star Strider
Star Strider el 31 de Mzo. de 2022
Yes.
On a slightly different topic, I am not certain what you are doing with the interp1 call. If you want to have the results presented at specific time values, create ‘tspan’ (that appears to be ‘T’ here) as a vector of specific time instants, rather than a two-element range from minimum to maximum simulation times. The numerical solvers will then do that interpolation internally and present the results only at the indicated times.
Kostas Kalabokas
Kostas Kalabokas el 31 de Mzo. de 2022
The interpolation function has been used to ensure that the two vectors t, and t_data are of the same size for the disp_a to be computed. It isn't a matter of specific time instants, but instead, the t_data has an interval of 0.01 seconds (over a 30 second time span). The interp1 fucntion is used to make sure that the vectors match.
If you think I can improve this further, then I would be very grateful of any recommendations. :)
K
Torsten
Torsten el 31 de Mzo. de 2022
As said, if you specify T = t_data in the call to ode45, you don't need interp1. The returned t vector from the solver will match your t_data.
Look at what happens when you specify a vector with more than 2 elements as the tspan input to ode45.
tspan = 0:0.25:5;
[t, y] = ode45(@(t, y) y, tspan, [0; 1]);
wereTspanValuesUsed = isequal(tspan.', t) % true
wereTspanValuesUsed = logical
1
Alternately you could call ode45 with one output and use deval to evaluate the solution at the desired times.
sol = ode45(@(t, y) y, [0 5], [0; 1]);
norm(y - deval(sol, tspan).')
ans = 1.5993e-14
That's a pretty small difference.

Iniciar sesión para comentar.

Más respuestas (1)

Torsten
Torsten el 31 de Mzo. de 2022
Look at what your loop does with the array k_l.
k_l is set to [1 2] before the loop.
For ii=1, the command
k_l = k_l(1)
sets k_l to a scalar, namely k_l(1) = 1.
For ii=1,
k_l = k_l(2)
tries to access the 2nd element from k_l.
But k_l is a scalar, thus has no second element. That's why MATLAB errors.
Workaround:
Replace
k_l = k_l(ii)
by
k_lii = k_l(ii)

1 comentario

Kostas Kalabokas
Kostas Kalabokas el 31 de Mzo. de 2022
Thank you, that makes much more sense now.
Kostas

Iniciar sesión para comentar.

Productos

Versión

R2019b

Preguntada:

el 31 de Mzo. de 2022

Comentada:

el 31 de Mzo. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by