How can I create or change polynomial coefficients - python

I have this code and I want to edit it to do something else:
def pol(poly, n, x):
result = poly[0]
#Using Horner's method
for i in range(1, n):
result = result * x + poly[i]
return result
#Let us evaluate value of
#ax^3 - bx^2 - x - 10 for x = 1
poly = [5, 9, -1, -10]
x = 1
n = len(poly)
print("Value of polynomial is: ", pol(poly, n, x))
I wonder how can I can change the coefficients of the polynomial. And this code just calculates:
x^3 and x^2
How can I make this code calculate for example this polynomial:
p(x) = 5x^10 + 9x - 7x - 10
or any polynomial in Python?

Your code should work, you just need to present the correct input. For
p(x) = 5x^10 + 9x - 7x - 10
you should provide:
poly2 = [5, 0, 0, 0, 0, 0, 0, 0, 0, 9-7, 10]
Alternate pol - implementation:
def pol(poly, x):
n = len(poly) # no need to provide it at call
rp = poly[::-1] # [-10, -1, 9, 5] so they correlate with range(n) as power
print("Poly:",poly, "for x =",x)
result = 0
for i in range(n):
val = rp[i] * x**i
print(rp[i],' * x^', i, ' = ', val, sep='') # debug output
result += val
return result
x = 2 # 1 is a bad test candidate - no differences for 1**10 vs 1**2
# 5x^3 + 9x^2 - x - 10 for x = 1
poly = [5, 9, -1, -10]
print("Value of polynomial is: ", pol(poly, x))
# p(x) = 5x^10 + 9x - 7x - 10
poly2 = [5, 0, 0, 0, 0, 0, 0, 0, 0, 9-7, 10]
print("Value of polynomial is: ", pol(poly2, x))
Output:
Poly: [5, 9, -1, -10] for x = 2
-10 * x^0 = -10
-1 * x^1 = -2
9 * x^2 = 36
5 * x^3 = 40
Value of polynomial is: 64
Poly: [5, 0, 0, 0, 0, 0, 0, 0, 0, 2, -10] for x = 2
-10 * x^0 = -10
2 * x^1 = 4
0 * x^2 = 0
0 * x^3 = 0
0 * x^4 = 0
0 * x^5 = 0
0 * x^6 = 0
0 * x^7 = 0
0 * x^8 = 0
0 * x^9 = 0
5 * x^10 = 5120
Value of polynomial is: 5114

Related

Finding the coordinates of max sum path in matrix

I have this method which returns the max sum of the path from top left to bottom right (can move only to the right or bottom).
def max_path(grid):
N = len(grid)
M = len(grid[0])
sum = [[0 for i in range(M + 1)] for i in range(N + 1)]
for i in range(1, N + 1):
for j in range(1, M + 1):
sum[i][j] = (max(sum[i - 1][j], sum[i][j - 1]) + grid[i - 1][j - 1])
return sum[N][M]
matrix = [[1, 2, 3], [3, 4, 5]]
print(max_path(matrix))
output : 1 + 3 + 4 + 5 = 13
But what I want to get is also the coordinates of the points of the path:
[(0,0) (1,0) (1,1) (1,2)]
You can try the below code to get your job done.
from itertools import permutations, product
def get_max_sum(table):
height, width = len(table), len(table[0])
sum_, *pos = max((sum(table[x][y] for x, y in zip(*pairs)), *zip(*pairs))
for pairs in product(
permutations(range(height)),
([*range(i, width), *range(i)] for i in range(width))))
return (sum_, *sorted(pos))
sum_, *pos = get_max_sum(
[[1, 2, 3],
[2, 3, 5],
[4, 9, 16]]
)
Output:
20 #maximum sum
(0, 1) (1, 0) (2, 2) #co -ordinates
The variable sum after the nested-for loops (as written in your code) is
[0, 0, 0, 0],
[0, 1, 3, 6],
[0, 4, 8, 13]
You can work out the coordinates of the max sum by having a initial "pointer" at the bottom right corner (i=1, j =2, ignoring the zeros), and comparing the values that is on the top (i=0, i=2) and on the left (i=1, j=1). Since 8 is larger than 6, we move the "pointer" to the left, and now i=1, j=1.
4 is larger than 3, so we move the pointer to 4 (i=1, j=0)
1 is larger than 0, so we move the pointer to 1 (i=0, j=0)
A basic (untested) implementation of the algorithm is as follows:
def max_path(grid):
N = len(grid)
M = len(grid[0])
sum = [[0 for i in range(M + 1)] for i in range(N + 1)]
for i in range(1, N + 1):
for j in range(1, M + 1):
sum[i][j] = (max(sum[i - 1][j], sum[i][j - 1]) + grid[i - 1][j - 1])
j = M
i = N
path = []
while i > 0 and j > 0:
path.append((i-1,j-1))
if sum[i-1][j] <= sum[i][j-1]:
j -= 1
else:
i -= 1
path.reverse()
return sum[N][M],path
matrix = [[1, 2, 3], [3, 4, 5]]
print(max_path(matrix))

Unable to access float object in a 2D array in Python

I need to return the vector solution x of Ux = b for an upper triangular matrix U and vector b using back substitution, but I'm unable to actually access an element of the matrix U.
def BackSub(U, b):
n = len(U)
x = [0 for i in range(n)]
for i in range(n - 1, -1, -1):
s = 0
for j in range(n - 1, i, -1):
s += (U[i][j])*b[j]
b[i] = (b[i] - s)/(U[i][i])
return b
b = [5, 6, 3, 2]
U = [[ 1, 2, 1, 0],
[ 0, 3, -5, 9],
[ 0, 0, 0.5, 1],
[ 0, 0, 0, 7]]
N = GaussElim(U, b)
x = BackSub(N, b)
It returns
TypeError: 'float' object is not subscriptable for U[i][i]
The GaussElim function is this
import numpy as np
def GaussElim(A, b):
n = len(b) #n is matrix size
#Elimination phase
for k in range(0 , n - 1): #k is matrix row
for i in range(k + 1, n): #i is matrix col
if A[i][k] != 0:
factor = A[i][k]/ A[k][k]
A[i][k + 1 : n] = A[i][k + 1 : n] - np.multiply(factor, A[k][k + 1 : n])
b[i] = b[i] - np.multiply(factor, b[k])
#Back substitution
for k in range(n - 1, -1, -1):
b[k] = (b[k] - dot(A[k][k + 1 : n], b[k + 1 : n]))/A[k][k]
return b

Gauss Siedel not converging

I have written this code, which is not converging and runs more iterations than I expect. I expect it to run 17 iterations and it does 24. I am not able to figure out the reason!
import numpy as np
from numpy import *
A = [[10, -1, 2, 0],
[ -1, 11, -1, 3 ],
[ 2, -1, 10, -1 ],
[ 0, 3, -1, 8 ] ]
b = [6, 25, -11, 15]
def GaussSiedelAccelerated(A, b, e, x, w):
e = float(e)
iterations = 0
Epsilon = float()
n = len(A)
condition = True
while condition:
for i in range(n):
s1 = 0
s2 = 0
tempx = x.copy() # Record answer of the previous iteration
for j in range(1,i,1):
s1 = s1 + x[j]*A[i][j]
for k in range(i+1,n,1):
s2 = s2 + tempx[k]*A[i][k]
x[i] = x[i]*(1-w) + w*(b[i] - s1 - s2)/A[i][i]
iterations = iterations +1
Epsilon = max(abs(x-tempx))/max(abs(x))
print("Output vector for the run no.", iterations, "is:", x)
print("Error for the run no.", iterations, "is: \t", Epsilon)
condition = Epsilon > e
return x, Epsilon, iterations
x0 = np.zeros(len(A))
x, Epsilon, iterations = GaussSiedelAccelerated(A,b,0.0001,x0, 1.1)

What cause this weird bug in my selfplaying tetris written in Python 3? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
What happen is that at certain point when a piece is put to its place suddenly the a whole column became solid. Putting breakpoint on line 236 one can debug this and see that in the value assignment:
gameSpace[current_y + x][current_x + y] = current_piece + 1
Suddenly not just one field of the gameSpace is changing, but a whole column and its just does not make sense for me. (I'm extremely beginner in Python, written my tetris originally in C on an MCU board and now trying to port to PC to be able find the best parameters for the fitness function.) The indices into the 2D game space are also valid so that could not cause it.
The code:
from tkinter import *
from random import seed
from random import randint
import time
# seed random number generator
seed(1)
# constants
PX_WIDTH = 480
PX_HEIGHT = 640
BLOCK_SIZE = PX_HEIGHT / 20
HEIGHT = int(PX_HEIGHT / BLOCK_SIZE)
WIDTH = int(HEIGHT / 2)
TICK_CNT = 1
current_piece = randint(0, 6)
current_x = 3
current_y = 0
current_rotation = 0
scores = 0
ticks = 0
colors = ["black", "blue", "orange", "green", "yellow", "red", "purple", "brown"]
gameSpaceBOT = [0] * HEIGHT
for i in range(HEIGHT):
gameSpaceBOT[i] = [0] * WIDTH
tetrominos = [
[[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, 0]],
[[0, 0, 1, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]],
[[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]],
[[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]]
]
def rotatedIndex(rotation, index):
if rotation == 0:
return index
if rotation == 1:
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 12 8 4 0 13 9 5 1 14 10 6 2 15 11 7 3
return int(12 - ((index % 4) * 4) + int(index / 4))
if rotation == 2:
return 15 - index
if rotation == 3:
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# 3 7 11 15 2 6 10 14 1 5 9 13 0 4 8 12
return int(15 - int(index / 4) - ((3 - (index % 4)) * 4))
def doesItFit(piece, rota, in_x, in_y, gameSpace):
piece_x = in_y
piece_y = in_x
idx = 0
for x in range(4):
for y in range(4):
idx = rotatedIndex(rota, x * 4 + y)
gs_x = piece_x + x
gs_y = piece_y + y
if tetrominos[piece][int(idx / 4)][idx % 4] != 0:
if gs_x >= 0 and gs_x < HEIGHT and gs_y >= 0 and gs_y < WIDTH:
if gameSpace[gs_x][gs_y] != 0:
return 0
else:
return 0
return 1
# print for debug
def printGamespace(gameSpace):
for x in range(HEIGHT):
for y in range(WIDTH):
print(gameSpace[x][y], end=" ")
print()
# drawing the gamespace
def drawGamespace(C, squares_list, gameSpace):
### print("in drawGamespace")
#gameSpace[randint(0, HEIGHT-1)][randint(0, WIDTH-1)] = 1
for y in range(HEIGHT):
for x in range(WIDTH):
C.itemconfig(squares_list[y * WIDTH + x], fill=colors[gameSpace[y][x]])
#draw current piece
for x in range(4):
for y in range(4):
idx = rotatedIndex(current_rotation, x * 4 + y)
if tetrominos[current_piece][int(idx / 4)][idx % 4] != 0:
C.itemconfig(squares_list[(current_y + x) * WIDTH + (current_x + y)], fill="white")
def spawnNewPiece(gameSpace):
### print("in spawnNewPiece")
global current_x
current_x = 3
global current_y
current_y = 0
global current_rotation
current_rotation = randint(0, 3)
global current_piece
current_piece = randint(0, 6)
return doesItFit(current_piece, current_rotation, current_x, current_y, gameSpace)
def calculateFitness(gameSpace):
lineFillednessFactor = 0
lineSolved = 0
for x in range(HEIGHT):
currentRowFilledness = 0
for y in range(WIDTH):
if gameSpace[x][y] != 0:
currentRowFilledness = currentRowFilledness + 1
if currentRowFilledness == WIDTH:
lineSolved += 1
lineFillednessFactor += currentRowFilledness * (x + 1)
return lineFillednessFactor + 10000 * lineSolved
def bot(gameSpace):
global gameSpaceBOT
global current_rotation
global current_x
local_y = current_y
target_x = current_x
target_rot = current_rotation
bestFitness = -1
for x in range(HEIGHT):
for y in range(WIDTH):
gameSpaceBOT[x][y] = gameSpace[x][y]
for rot in range(4):
for x in range(WIDTH + 3):
if doesItFit(current_piece, rot, x - 3 , local_y, gameSpace) == 1:
# moving down until it stucks
while doesItFit(current_piece, rot, x - 3 , local_y + 1, gameSpace) == 1:
local_y = local_y + 1
# fitting the piece into the BOTs gameSpace
for px in range(4):
for py in range(4):
idx = rotatedIndex(rot, px * 4 + py)
if tetrominos[current_piece][int(idx / 4)][idx % 4] == 1:
gameSpaceBOT[local_y + px][x - 3 + py] = current_piece + 1
# if the resulting gamespace fitness is better then the current best one
# then change the target coordinates for the best solution to the current one
if calculateFitness(gameSpaceBOT) > bestFitness:
bestFitness = calculateFitness(gameSpaceBOT)
target_x = x - 3
target_rot = rot
# removing the piece for the next iteration
for px in range(4):
for py in range(4):
idx = rotatedIndex(rot, px * 4 + py)
if tetrominos[current_piece][int(idx / 4)][idx % 4] == 1:
gameSpaceBOT[local_y + px][x - 3 + py] = 0
# depending on our current position move the current piece towards the target
# first do the rotation
### print('target_rot={:d}, target_x={:d}'.format(target_rot, target_x))
if target_rot != current_rotation:
if target_rot > current_rotation:
current_rotation = current_rotation + 1
else:
current_rotation = current_rotation - 1
# if rotation is correct than move it horrizontally
elif target_x != current_x:
if target_x > current_x:
current_x = current_x + 1
else:
current_x = current_x - 1
def checkAndRemoveFilledLines(gameSpace):
global scores
first_found_line_y_coord = 0
found_lines = 0
for x in range(HEIGHT):
num_of_blocks_in_row = 0
for y in range(WIDTH):
if gameSpace[x][y] != 0:
num_of_blocks_in_row = num_of_blocks_in_row + 1
if num_of_blocks_in_row == WIDTH:
found_lines = found_lines + 1
if first_found_line_y_coord == 0:
first_found_line_y_coord = x
# if there was filled lines then add to score and erase the lines
if found_lines != 0:
scores += 10
for x in range(first_found_line_y_coord + found_lines - 1, 0, -1):
### print("x is {:d}".format(x))
gameSpace[x] = gameSpace[x - found_lines]
def update(C, squares_list, gameSpace):
global ticks
ticks = (ticks + 1) % TICK_CNT
global current_y
global scores
bot(gameSpace)
if ticks == 0:
# if it able to move down than move it down
if doesItFit(current_piece, current_rotation, current_x, current_y + 1, gameSpace) == 1:
current_y = current_y + 1
else:
if current_y == 8 and current_piece == 5 and current_x == 5:
print("hey")
scores += 1
for x in range(4):
for y in range(4):
idx = rotatedIndex(current_rotation, x * 4 + y)
if tetrominos[current_piece][int(idx / 4)][idx % 4] != 0:
gameSpace[current_y + x][current_x + y] = current_piece + 1
checkAndRemoveFilledLines(gameSpace)
if not spawnNewPiece(gameSpace):
return 0
drawGamespace(C, squares_list, gameSpace)
C.after(1, update, C, squares_list, gameSpace)
def main():
# canvasd
root = Tk()
C = Canvas(root, bg="black", height=PX_HEIGHT, width=PX_WIDTH)
C.pack()
# for storing the rectangles
squares_list = []
# init
# creating and initializing the game space 2d array
gameSpace = [0] * HEIGHT
for i in range(HEIGHT):
gameSpace[i] = [0] * WIDTH
for y in range(HEIGHT):
for x in range(WIDTH):
squares_list.append(C.create_rectangle(x * BLOCK_SIZE,
y * BLOCK_SIZE,
(x + 1) * BLOCK_SIZE,
(y + 1) * BLOCK_SIZE,
fill=colors[gameSpace[y][x]]))
update(C, squares_list, gameSpace)
root.mainloop()
if __name__ == "__main__":
main()
As it was pointed out by stovfl the problem was indeed that the gameSpace was copied by reference and not by value. Using deepcopy solved it.

Solving "Knapsack" using DP

Here's my code:
def knapsack_dynamic(ws, vs, W):
n = len(ws)
K = [[0] * (W+1)] * (n+1)
for i in range(n+1):
for w in range(W+1):
if i == 0 or w == 0: # knapsack is empty or no more weight to carry
K[i][w] = 0
else:
if ws[i-1] > w:
K[i][w] = K[i-1][w]
else:
K[i][w] = max(vs[i-1] + K[i-1][w-ws[i-1]], K[i-1][w])
return K[n][W]
Here's how to test it:
maxw = 50
ws = [10, 20, 30]
vs = [60, 100, 120]
print(knapsack_dynamic(ws, vs, maxw)) # should print 220
I'm not sure why I'm getting 300 instead of 220.
Can you help me figuring it out please?
The error is made during the matrix initialization:
Replace
K = [[0] * (W+1)] * (n+1)
by
K = [[0] * (W+1) for i in range(n+1)]
or by
K = [[0 for w in range(W+1)] for i in range(n+1)]
When applying the repeat operator * on nested lists, only the reference is repeated not the values.
Try this simple example:
m = [[0] * 4] * 3
print(m) # --> [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
m[0][0] = 5
print(m) # --> [[5, 0, 0, 0], [5, 0, 0, 0], [5, 0, 0, 0]]

Categories