How to use different columns for for loop iteration - python

So i want to do an iteration a vairable amount of times (a)
I have an excel sheet where that iteration is already programmed and i want to do the same now in python 3 spyder.
I decided to calculate the first row externally. The iteration should now look like this:
da,air core diameter (2,1) is has the input t_new (1,5), delta p, spray pressure (2,2) has input da,air core diameter (2,1), t_new (2,5) has the input delta p, spray pressure (2,2) and so on for a given number of iterations.
My code looks as follows up until now (everything else is defined properly beforehand):
a = [b for b in range(14)] # number of iterations -1
arr = np.array([[da_iter], [ps_iter], [t_mod_iter]]).reshape(1,3) # external calculated values first row
arr_zeros = np.zeros([len(a), 3]) # filling array with 0's based on iteration number
arr_iter = np.vstack((arr, arr_zeros)) #iteration array with 1st row calculated values
i = 0 #row index
j = 0 #column index
for i in range(len(arr_iter)):
np.append(arr_iter, do_in-2*arr_iter[i,j+2]) #calculating new da out of t_mod
np.append(arr_iter, ml**2*gs*0.5*pl*((dsc/(2*pl*(hsc*din*arr_iter[i+1,j]/2)))**2+(1/(pl*(ao-np.pi/4*arr_iter[i+1,j]**2)))**2)) #calculating new ps out of new da
np.append(arr_iter, k*(1738.7*ul**2-79.898*ul+2.0122)*((do_in*ml*ul)/(pl*arr_iter[i+1,j+1]))**0.25) #calculation new t_new out of spray pressure
i = i+1
print(arr_iter)
But that doesnt seem to work properly since i only get out arr_iter as it was before. Unfortunatley i also didnt found sth usefull how to iterate over changing rows using a for loop.
Does somebody have a better idea how to do it or sees my mistake in the loop?
Thank you very much in advance

First thing, you don't need i=i+1 as for loop already doing the same.
Secondly, I think you want to replace zeros in arr_iter so in for loop, you should write something like
np.append(arr_iter[i, j], 2nd_variable)
Alternatively you can simply do the following to update arr_iter matrix, rather than append.
arr_iter[i][j] = new_variable

Related

How to get inner for-loop to run all the way through before moving onto next increment of outer loop?

I am making a program i wrote for a uni project more expansive, and before i was working with a 3x3 matrix, but now its a 15 by 15 matrix, and i want to make a for loop to fill the values, rather than what i have currently. Ive made this sample code a bit smaller, but this is what i want to put into a for loop:
distance_matrix=
[array1[0]-array2[0], array1[1]-array2[0], array1[2]-array2[0], array1[3]-array2[0],array1[4]-array2[0]],
[array1[0]-array2[1], array1[1]-array2[1], array1[2]-array2[1], array1[3]-array2[1],array1[4]-array2[1]],
[array1[0]-array2[2], array1[1]-array2[2], array1[2]-array2[2], array1[3]-array2[2],array1[4]-array2[2]],
[array1[0]-array2[3], array1[1]-array2[3], array1[2]-array2[3], array1[3]-array2[3],array1[4]-array2[3]],
[array1[0]-array2[4], array1[1]-array2[4], array1[2]-array2[4], array1[3]-array2[4],array1[4]-array2[4]]
So this is a 5x5 matrix. As you can see, the values for each entry are the difference between values in the 2 arrays. My first thought to loop this was a 2 layer nested for loop, but that only generated a 5x1 matrix, with the values on the diagonal, the (i,i) values. it looked like this:
distance_matrix=[[0 for x in range(0,5)] for y in range(0,5)]
for i range(0,5):
for j in range(0,5):
distance_matrix[i][j]=array1[i]-array2[j]
then i tried with an if statement, just a list that i could then reshape, and setting the value that stays constant over the rows in the outer loop,but this generated again a list of length 5 (and i cant really figure out why):
distance_matrix_list=[]
for col_val in range(0,5):
first_value=array1[col_val]
for row_val in range(0,5)):
if row_val<5):
distance_matrix_list.append([first_value-array2[row_val]])
distance_matrix=np.array(distance_matrix_list)
distance_matrix.reshape((5,5))
this must be really obvious and im quite frustrated that im missing this. Please help!
Your first code snippet, apart from some typos should work just fine. You do however need to switch i and j, when assigning the indicies. This works fine for me:
distance_matrix=[[0 for x in range(5)] for y in range(5)]
for i in range(5):
for j in range(5):
distance_matrix[i][j] = array1[j] - array2[i]

Coding an iterated sum of sums in python

For alpha and k fixed integers with i < k also fixed, I am trying to encode a sum of the form
where all the x and y variables are known beforehand. (this is essentially the alpha coordinate of a big iterated matrix-vector multiplication)
For a normal sum varying over one index I usually create a 1d array A and set A[i] equal to the i indexed entry of the sum then use sum(A), but in the above instance the entries of the innermost sum depend on the indices in the previous sum, which in turn depend on the indices in the sum before that, all the way back out to the first sum which prevents me using this tact in a straightforward manner.
I tried making a 2D array B of appropriate length and width and setting the 0 row to be the entries in the innermost sum, then the 1 row as the entries in the next sum times sum(np.transpose(B),0) and so on, but the value of the first sum (of row 0) needs to vary with each entry in row 1 since that sum still has indices dependent on our position in row 1, so on and so forth all the way up to sum k-i.
A sum which allows for a 'variable' filled in by each position of the array it's summing through would thusly do the trick, but I can't find anything along these lines in numpy and my attempts to hack one together have thus far failed -- my intuition says there is a solution that involves summing along the axes of a k-i dimensional array, but I haven't been able to make this precise yet. Any assistance is greatly appreciated.
One simple attempt to hard-code something like this would be:
for j0 in range(0,n0):
for j1 in range(0,n1):
....
Edit: (a vectorized version)
You could do something like this: (I didn't test it)
temp = np.ones(n[k-i])
for j in range(0,k-i):
temp = x[:n[k-i-1-j],:n[k-i-j]].T#(y[:n[k-i-j]]*temp)
result = x[alpha,:n[0]]#(y[:n[0]]*temp)
The basic idea is that you try to press it into a matrix-vector form. (note that this is python3 syntax)
Edit: You should note that you need to change the "k-1" to where the innermost sum is (I just did it for all sums up to index k-i)
This is 95% identical to #sehigle's answer, but includes a generic N vector:
def nested_sum(XX, Y, N, alpha):
intermediate = np.ones(N[-1], dtype=XX.dtype)
for n1, n2 in zip(N[-2::-1], N[:0:-1]):
intermediate = np.sum(XX[:n1, :n2] * Y[:n2] * intermediate, axis=1)
return np.sum(XX[alpha, :N[0]] * Y[:N[0]] * intermediate)
Similarly, I have no knowledge of the expression, so I'm not sure how to build appropriate tests. But it runs :\

for loop iteration-population conflict

I am new in python and I am trying to learn it by myself. I am currently working on a code, which gives me index error because somehow for loop does not populate my data. I am supposed to iterate a value and with it, I depend on the previous value to produce the new value. Normally this was easy with matlab, only with x(:,k) but python does not work the same way and I will really be grateful for any help that does not judge my level of knowledge in python. Here how it goes:
x = np.matrix([[1.2],[.2]]) # prior knowledge
A = np.matrix([[1, 1], [0, 1]])
B = np.matrix([[.5], [1]])
U = -9
t1 = range(1,100,1)
for k, val in enumerate(t1):
x[:,k] = A*x[:,k-1] + B*U
To my understanding, the error 'IndexError: index 1 is out of bounds for axis 1 with size 1' pops up because the for loop does not populate the data 'x' and therefore, there is no value for neither 'k-1' nor 'k'.
What I should do is to iterate and store 'x' values and pick the relevant previous value each time to obtain new value with given equation till the end of loop. As you can see, I have a column matrix and I should have a column matrix each time. I hope I could make myself clear.
Thank you
The first line is the initial value of x, the second, third, fourth and fifth lines are the values that are used in for loop to calculate iterations for x.
What I am trying to implement is code for kaman filter in general. In this system, the current value x(k) is calculated with previous value x(k-1) with given equation x(k) = Ax(k-1) + BU. Each x(k) value becomes x(k-1) in next iteration until loop is executed. Here, I am expecting to have (2,k) matrix after every loop because record of values are essential for other calculations. And to use the previous value in current value, I need to access to (k-1)th value.
The question was solved by juanpa.arrivillaga (https://stackoverflow.com/users/5014455/juanpa-arrivillaga) Thank you.

Making histogram out of matrix entries?

Today my task is to make a histogram to represent the operation of A^n where A is a matrix, but only for specific entries in the matrix.
For example, say I have a matrix where the rows sum to one. The first entry is some specific decimal number. However, if I raise that matrix to the 2nd power, that first entry becomes something else, and if I raise that matrix to the 3rd power, it changes again, etc - ad nauseum, and that's what I need to plot.
Right now my attempt is to create an empty list, and then use a for loop to add the entries that result from matrix multiplication to the list. However, all that it does is print the result from the final matrix multiplication into the list, rather than printing its value at each iteration.
Here's the specific bit of code that I'm talking about:
print("The intial probability matrix.")
print(tabulate(matrix))
baseprob = []
for i in range(1000):
matrix_n = numpy.linalg.matrix_power(matrix, s)
baseprob.append(matrix_n.item(0))
print(baseprob)
print("The final probability matrix.")
print(tabulate(matrix_n))
Here is the full code, as well as the output I got.
http://pastebin.com/EkfQX2Hu
Of course it only prints the final value, you are doing the same operation, matrix^s, 1000 times. You need to have s change each of those 1000 times.
If you want to calculate all values in location matrix(0) for matrix^i where i is each value from 1 to s (your final power) do:
baseprob = []
for i in range(1,s): #changed to do a range 1-s instead of 1000
#must use the loop variable here, not s (s is always the same)
matrix_n = numpy.linalg.matrix_power(matrix, i)
baseprob.append(matrix_n.item(0))
Then baseprob will hold matrix(0) for matrix^1, matrix^2, etc. all the way to matrix^s.

Project Euler #82 (Python)

First of all this is the problem : https://projecteuler.net/problem=82 .
This is my code :
# https://projecteuler.net/problem=82
matrice = open('matrix3.txt','r').read().split('\n')
m = []
for el in matrice:
if el=='':
continue
tmp = el.split(',')
m.append(tmp)
matrix = [[0 for i in range(80)]for j in range(80)]
x,y = 0,0
while(True):
matrix[x][y]=int(m[x][y])
y+=1
if y==80:
y=0
x+=1
if x==80:
break
tmp = [0]*80
x,y = 0,78
while(True):
if x==0:
tmp[x]=min(matrix[x][y+1],matrix[x+1][y]+matrix[x+1][y+1])
if x==79:
tmp[x]=min(matrix[x][y+1],matrix[x-1][y]+matrix[x-1][y+1])
else:
tmp[x]=min(matrix[x][y+1],matrix[x-1][y]+matrix[x-1][y+1],matrix[x+1][y]+matrix[x+1][y+1])
x+=1
if x==80:
for e in range(80):
matrix[e][y]+=tmp[e]
tmp = [0]*80
x=0
y+=-1
if y<0:
break
minimo = 10**9
for e in range(80):
if matrix[e][0]<minimo:
minimo=matrix[e][0]
print(minimo)
The idea behind this code is the following:
I start from the 79th column(78th if you start counting from 0) and I calculate the best(the minimal) way to get from any given entry in that column to the column to the right.
When the column is over I replace it with the minimal results I found and I start doing the same with the column to the left.
Is anyone able to help me understand why I get the wrong answer?(I get 262716)
The same code works for the matrix in the example(It works if you change the indeces of course).
If I understand the question, your code, and your algorithm correctly, it looks like you aren't actually calculating the best way to get from one column to the next because you're only considering a couple of the possible ways to get to the next column. For example, consider the first iteration (when y=78). Then I think what you want is tmp[0] to hold the minimum sum for getting from matrix[0][78] to anywhere in the 79th column, but you only consider two possibilities: go right, or go down and then go right. What if the best way to get from matrix[0][78] to the next column is to go down 6 entries and then go right? Your code will never consider that possibility.
Your code probably works on the small example because it so happens that the minimum path only goes up or down a single time in each column. But I think that's a coincidence (also possibly a poorly chosen example).
One way to solve this problem is using the following approach. When the input is a NxN matrix, define a NxN array min_path. We're going to want to fill in min_path so that min_path[x][y] is the minimum path sum starting in any entry in the first column of the input matrix and ending at [x][y]. We fill in one column of min_path at a time, starting at the leftmost column. To compute min_path[i][j], we look at all entries in the (j-1)th column of min_path, and the cost of getting from each of those entries to (i, j). Here is some Python code showing this solution: https://gist.github.com/estark37/5216851. This is an O(N^4) solution but it can probably be made faster! (maybe by precomputing the results of the sum_to calls?)

Categories

Resources