I want to solve a complex matrix differential equation y' = Ay.
import numpy as np
from scipy.integrate import solve_ivp
def deriv(y, t, A):
return np.dot(A, y)
A = np.array([[-0.25 + 0.14j, 0, 0.33 + 0.44j],
[ 0.25 + 0.58j, -0.2 + 0.14j, 0],
[ 0, 0.2 + 0.4j, -0.1 + 0.97j]])
time = np.linspace(0, 25, 101)
y0 = np.array([[2, 3, 4], [5, 6 , 7], [9, 34, 78]])
result = solve_ivp(deriv, y0, time, args=(A,))
There already seems to be an answer in case of 'odeint'.
https://stackoverflow.com/a/45970853/7952027
https://stackoverflow.com/a/26320130/7952027
https://stackoverflow.com/a/26747232/7952027
https://stackoverflow.com/a/26582411/7952027
I am curious as to whether it can be done with any of the new API of Scipy?
I have updated your snippet, have a look below. You should carefully check the doc as, I believe, everything is well detailed there.
import numpy as np
from scipy.integrate import solve_ivp
def deriv_vec(t, y):
return A # y
def deriv_mat(t, y):
return (A # y.reshape(3, 3)).flatten()
A = np.array([[-0.25 + 0.14j, 0, 0.33 + 0.44j],
[0.25 + 0.58j, -0.2 + 0.14j, 0],
[0, 0.2 + 0.4j, -0.1 + 0.97j]])
result = solve_ivp(deriv_vec, [0, 25], np.array([10 + 0j, 20 + 0j, 30 + 0j]),
t_eval=np.linspace(0, 25, 101))
print(result.y[:, 0])
# [10.+0.j 20.+0.j 30.+0.j]
print(result.y[:, -1])
# [18.46+45.25j 10.01+36.23j -4.98+80.07j]
y0 = np.array([[2 + 0j, 3 + 0j, 4 + 0j],
[5 + 0j, 6 + 0j, 7 + 0j],
[9 + 0j, 34 + 0j, 78 + 0j]])
result = solve_ivp(deriv_mat, [0, 25], y0.flatten(),
t_eval=np.linspace(0, 25, 101))
print(result.y[:, 0].reshape(3, 3))
# [[ 2.+0.j 3.+0.j 4.+0.j]
# [ 5.+0.j 6.+0.j 7.+0.j]
# [ 9.+0.j 34.+0.j 78.+0.j]]
print(result.y[:, -1].reshape(3, 3))
# [[ 5.67+12.07j 17.28+31.03j 37.83+63.25j]
# [ 3.39+11.82j 21.32+44.88j 53.17+103.80j]
# [ -2.26+22.19j -15.12+70.191j -38.34+153.29j]]
Related
I have a function. I need to minimize the MSE to 0.75 or less. I was able to get to 6 and don't know what to do next.
def print_points_ands_function1(sympy_function):
def function(x_): return float(sympy_function.subs(x, x_))
points_X = np.array([-2, -1, 0, 1, 2, 3, 3.5, 4, 4.5, 5])
points_Y = np.array([3, 1, -0.5, 1.2, 2.5, 0.8, -2, -3.5, -3, -5])
plt.xlim(-10, 10)
plt.ylim(-5, 5)
plt.scatter(points_X, points_Y, c='r')
x_range = np.linspace(plt.xlim()[0], plt.xlim()[1], num=100)
function_Y = [function(x_) for x_ in x_range]
plt.plot(x_range, function_Y, 'b')
plt.show()
MSE = sum([(points_Y[i] - function(points_X[i]))**2 for i in range(len(points_Y))]) / len(points_Y)
print(f'MSE = {MSE}')
f1 = 2 * x * sin(2 * x + 5) + 5 * sin(2 * x + 5) + 2
print(f1)
print_points_ands_function1(f1)
f1_1 = expand(f1.subs(x, x / 1.4))
print(f1_1)
print_points_ands_function1(f1_1)
f1_2 = expand(f1_1.subs(x, -x))
print(f1_2)
print_points_ands_function1(f1_2)
f1_3 = expand(f1_2.subs(x, x + 2.6))
print(f1_3)
print_points_ands_function1(f1_3)
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)
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
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]]
So this is my code to plot a Bézier curve:
def bezier(a):
n = np.shape(a)[0]-1
# initialise arrays
B = np.zeros([101, 2])
terms = np.zeros([n+1, 2])
# create an array of values for t from 0 to 1 in 101 steps
t = np.linspace(0, 1, 101)
# loop through all t values
for i in range(0, 101):
#calculate terms inside sum in equation 13
for j in range(0, n + 1):
# YOUR CODE HERE
terms[j,:] = ((1 - t[i]) ** 3 * a[0,:] \
+ 3 * t[i] * (1-t[i]) ** 2 * a[1,:] \
+ 3 * t[i] ** 2 * (1-t[i]) * a[2,:]
+ t[i] ** 3 * a[3,:])
#sum terms to find Bezier curve
B[i, :] = sum(terms, 0)
# plot Bezier
pl.plot(B[:, 0], B[:, 1])
# plot control points
pl.plot(a[:, 0], a[:, 1],'ko')
# plot control polygon
pl.plot(a[:, 0], a[:, 1],'k')
return B
And when I try to pass it some control points:
a = np.array([[0, 0], [0.5, 1], [1, 0]])
B = bezier(a)
I receive this IndexError:
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-16-fce87c9f1c04> in <module>()
1 a = np.array([[0, 0], [0.5, 1], [1, 0]])
----> 2 B = bezier(a)
<ipython-input-13-3bb3bb02cc87> in bezier(a)
11 for j in range(0, n + 1):
12 # YOUR CODE HERE
---> 13 terms[j,:] = ((1 - t[i]) ** 3 * a[0,:] + 3 * t[i] * (1-t[i]) ** 2 * a[1,:] + 3 * t[i] ** 2 * (1-t[i]) * a[2,:] + t[i] ** 3 * a[3,:])
14 #sum terms to find Bezier curve
15 B[i, :] = sum(terms, 0)
IndexError: index 3 is out of bounds for axis 0 with size 3
So I figure it is trying to access something outside the container but I can't see where it is I need to change the code.
You array a = np.array([[0, 0], [0.5, 1], [1, 0]] does not have element with index 3. Add another point to the array. You need four points for a Bezier curve, anyway.