-1

I am pretty new to programming so be patient with me lol. I am trying to convert an example code of matlab to python but I am having trouble with arrays in for loops and keep getting index errors.

Here is the given MatLab Code:

clear all
close all
clc
m=100; %kg 
k=1000; %N/m
c=25;
v0=0;
x0=0;
dt=0.0005;
F=1000; % N the mag of input force
f0=F/m;
w=2.5; %rad/sec input frequency 
t=0:dt:10;
wn=(k/m)^0.5;% rad/sec natural frequency 
ze=c/(2*(k*m)^0.5);
A=[0 1; -wn^2 -2*ze*wn];
X0=[x0;v0]; %intial conditions 
for i=1:length(t)
    X(:,i)=X0;
    Finput=[0;f0*cos(w*t(i))];
    X0=X0+A*X0*dt+dt*Finput;
end
figure,plot(t,X(1,:));
title('Displacement vs tiem')
xlabel('time (second)')
ylabel('Displacement')
grid on
figure,plot(t,X(2,:),'r');
xlabel('time (second)')
ylabel('Velocity')

My code

import numpy as np
import matplotlib.pyplot as plt
#constants
k=1000
m=100
v0=0.0
x0=0.0
f=1000
c=25

f0 = f/m
wn = np.sqrt(k/m)
w = wn*2
ze =c/(2*(k*m)**0.5)

A = np.array([[0.0,1.0],[-wn**2,-2*ze*wn]])
X0= np.array([x0,v0])
dt = 0.01
t = np.arange(0, 2.5, dt) #get values between -10 and 10 with 0.01 step and set to y

for i in range (len(t)):
             print(X0)
             X0[:,i]=X0 #error
             print(X0)
             Finput = np.array([0.0,(f0*np.cos(w*dt*i))])

             X0 = X0 + A*dt*X0+dt*Finput

plt.plot(t, X0[0,:])
plt.plot(t, X0[1,:])
plt.show()

I keep getting an "IndexError: too many indices for array" for the X0[:,i]=X0 part in my for loop and am struggling to figure out why.

Many Thanks in advance for the help!

2 Answers2

1

In Matlab code, X(:,i)=X0; assigns X0 to ith column of X. But your python X0[:,i]=X0 #error is assiging X0 to X0 ith column.

Eirene
  • 26
  • 3
1

The first time MATLAB runs the line

    X(:,i)=X0;

it creates a new variable X whose i'th column is equal to X0. In your code i is 1 when this happens but if i were > 1, MATLAB would initialise columns 1...i-1 with zeroes. After the loop is done, the code plots the data from the matrix X.

You have mistakenly translated this as X0[:,i]=X0 in your Python code, which gives an error because you're trying to assign to X0 as if it were a two-dimensional array when it's only one-dimensional.

Python and numpy don't automatically create and grow arrays when you assign to a subarray in the way that MATLAB does, so in Python you need to create the array X before the loop then either resize the array each time before you assign to the next column of it, or just initialise it with the right size when you create it - since you know how big it's going to be, i.e. len(t), do the latter - you can use np.zeros for this.

Also, in the Python code as you have posted it the line X0 = X0 + A*dt*X0+dt*Finput is outside the loop because the previous line has no indentation - Python should raise an IndentationError for this though. Conventionally you should use four spaces for each level of indentation.

After the loop in the Python code you want to plot the contents of X, not X0.

nekomatic
  • 5,988
  • 1
  • 20
  • 27