I'm trying to implement a very basic Bi-Cubic algo to use it for image scaling. I used other questions on stack overflow and tried to just translate the code into the Python.
It executes correctly w/o any errors, I've checked the math a couple of times but I cant find the reason of that kind of problem seems like everything should be running smooth but as a result I get this:
Any help appreciated.
Here's the source:
def getBicPixelChannel(img,x,y,channel):
if x < img.shape[1] & y < img.shape[0]:
return img[y,x,channel]
return 0
def Bicubic(img, rate):
new_w = int(math.ceil(float(img.shape[1]) * rate))
new_h = int(math.ceil(float(img.shape[0]) * rate))
new_img = np.zeros((new_w, new_h, 3))
x_rate = float(img.shape[1]) / new_img.shape[1]
y_rate = float(img.shape[0]) / new_img.shape[0]
C = np.zeros(5)
for hi in range(new_img.shape[0]):
for wi in range(new_img.shape[1]):
x_int = int(wi * x_rate)
y_int = int(hi * y_rate)
dx = x_rate * wi - x_int
dy = y_rate * hi - y_int
for channel in range(new_img.shape[2]):
for jj in range(0,4):
o_y = y_int - 1 + jj
a0 = getBicPixelChannel(img,x_int,o_y, channel)
d0 = getBicPixelChannel(img,x_int - 1,o_y, channel) - a0
d2 = getBicPixelChannel(img,x_int + 1,o_y, channel) - a0
d3 = getBicPixelChannel(img,x_int + 2,o_y, channel) - a0
a1 = -1./3 * d0 + d2 - 1./6 * d3
a2 = 1./2 * d0 + 1./2 * d2
a3 = -1./6 * d0 - 1./2 * d2 + 1./6 * d3
C[jj] = a0 + a1 * dx + a2 * dx * dx + a3 * dx * dx * dx
d0 = C[0] - C[1]
d2 = C[2] - C[1]
d3 = C[3] - C[1]
a0 = C[1]
a1 = -1. / 3 * d0 + d2 - 1. / 6 * d3
a2 = 1. / 2 * d0 + 1. / 2 * d2
a3 = -1. / 6 * d0 - 1. / 2 * d2 + 1. / 6 * d3
new_img[hi, wi, channel] = a0 + a1 * dy + a2 * dy * dy + a3 * dy * dy * dy
return new_img
I think your problem is in this line of code:
if x < img.shape[1] & y < img.shape[0]:
From what I gather, & is the bit-wise AND operator in Python, and it has a higher precedence than <. Thus what you are computing is:
if x < ( img.shape[1] & y ) < img.shape[0]:
(whatever that means...)
Instead, try this:
if (x < img.shape[1]) and (y < img.shape[0]):
and is Python's boolean AND operator.
Related
I have this function for solve_ivp, which solves a series of differential equations.
For every time step, the variable position [Pos] should be updated depending on a probability of it jumping. However, solve_ivp is not remembering the previous variable.
def jump_fun(t, Y, P, flux = 670):
global Pos_list
k1, k2 , k3, k4, k5, k6 , k , kay, q , K1, c5_tot, c6_tot, phi, Nc, V, qs, Cx, Ks, F, Cs0, flux, Pos, Pos_list = P
c1, c2, c3, c4, c5 ,c6, c4ex1, c4ex2, Cs1, Cs2= Y.reshape([10,-1])
#print(c1, c2, c3, c4, c5 ,c6, c4ex, Cs, Pos)
print(f'Pos: {Pos}')
# function heterogeneous_environment
prob = heterogeneous_environment(Nc, flux, V, 10, 10)
print(f'prob: {prob}')
#These arrays keep track of where the cells are
R1 = np.where(Pos == 1, 1, 0 )
R2 = np.where(Pos == 2, 1, 0 )
# We need to know the external concentrations of each reactor
rs1 = (Cx*qs*Cs1/ (Ks+Cs1))
dCs1 = F/V + flux*Cs2/V - flux*Cs1/V - rs1 # Position of cell is reactor 1, C1 = Cs
rs2 = (Cx*qs*Cs2/ (Ks+Cs2))
dCs2 = flux*Cs1/V - flux*Cs2/V - rs2 # Position of cell is reactor 2, C2 = Cs
j0 = rs1*R1 + rs2*R2
jm1 = kay * (c4 - c4ex1)*R1
jm2 = kay * (c4 - c4ex2)*R2
dc1= j0 - (k1 * c1 * c6 * (1/( 1 + ((c6/K1 )**q))))
dc2 = 2* k1 * c1 * c6 * (1/( 1 + ((c6/K1 )**q))) - k2 * c2 * (c5_tot - c5) - k6 *c2 *c5
dc3 = k2 * c2 * (c5_tot - c5) - k3 * c3* (c6_tot - c6)
dc4 = k3 * c3* (c6_tot - c6) - k4 * c4 *c5 - (jm1*R1 + jm2*R2)
dc5= k2 * c2 * (c5_tot - c5) - k4 * c4 *c5 - k6 *c2 *c5
dc6 = -2 * k1 * c1 * c6 * (1/( 1 + ((c6/K1 )**q))) + 2 * k3 * c3* (c6_tot - c6) - k5 * c6
cell1 = np.count_nonzero(R1 == 1)
cell2 = np.count_nonzero(R2 == 1)
dc4ex1= - k * c4ex1 + (phi / cell1) * np.sum(jm1) - (flux*c4ex1)/V + (flux*c4ex2)/V
dc4ex2= - k * c4ex2 + (phi / cell2) * np.sum(jm2) + (flux*c4ex1)/V - (flux*c4ex2)/V
#print('1')
#print(Pos)
#print('2')
Pos = Pos + prob*R1
Pos = Pos - prob*R2
#print(Pos)
Pos_list.append(Pos)
#iterate through the Pos vector, if Pos =1 do the balances for reactor 1 and then if the probability says to change
#reactor, change the position of the cell. Same for POS=2
#UPDATE THE MASS BALANCE FOR EACH REACTOR
return dc1, dc2, dc3, dc4, dc5 , dc6, dc4ex1, dc4ex2, dCs1, dCs2
I tried passing Pos as a return of the function, but it also didn't seem to work. Please help.
I want to simulate the laser power along a silica fiber. The ODEs and the used parameters can be found in the paper linked below. Note that I converted all units to SI units in my code. The authors of this paper named the shooting method as a way to numerically solve this equations.
The paper I am referring to can be found here: https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-21-17-20090&id=260516
I tried it in python but I did not manage to implement the root-finding. I used scypi.integrate_ivp to integrate the ODEs with a first guess. If I use a small value (~500m) at fiberlength I get a result but at a higher value in the range of km the solver does not manage to finish without an error. Can somebody please tell me how I can implement the shooting method here and also how I get the same solution as in the paper?
My code:
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from scipy.integrate import solve_ivp
from scipy.integrate import solve_bvp
from scipy.optimize import fsolve
#%% ODEs und Parameter
#constants
alpha = 10**(-0.25/10)/1000 #fiber loss [1/m]
a0= alpha
a1= alpha
a2= alpha
a3= alpha
g = 0.53e-3 #RamanGain [1/(W*m)]
g1= g
g2= g*0.8
g3= g*0.6
epsilon0 = 1e-4*1e-3 #Rayleigh-scattering [1/m] REFERENZ: Paper: Third order random lasing via Raman gain and Rayleigh backscattering
epsilon1 = 5e-5*1e-3
epsilon2 = 2e-5*1e-3
epsilon3 = 1e-5*1e-3
wl_start = 1365e-9
RamanShift= 13.2e12
f0=3e8/wl_start
f1= f0 - RamanShift
f2= f1 - RamanShift
f3= f2 - RamanShift
#R_L1 = 0.99 # Reflexionskoeffizienten (Fasereingang FBG)
#R_L2 = 5e-3 # Reflexionskoeffizienten (Fasereingang)
#R_R1 = 4e-5 # Reflexionskoeffizienten (Faserausgang)
#R_R2 = 4e-5 # Reflexionskoeffizienten (Faserausgang)
R=0.6 # reflectivity
# G[i] = 4*h*f[i]*df[i]*(1+1/(np.exp((h*(f[i-1]-f[i]))/(K*T))-1))
h=6.63e-34 #Placksches Wirkungsquantum [Js]
K=1.38e-23 #Bolzmannkonstante [J/K]
T=300 #Temperature [K]
#df1= 0.18e12 #Bandbreite [Hz] REFERENZ: Paper: Third order random lasing via Raman gain and Rayleigh backscattering
#df2= 0.25e12
#df3= 0.25e12
#bandwidth
df1= 0.18e12
df2= 0.25e12
df3= 0.25e12
Gamma1= 4*h*f1*df1*(1+(1/(np.exp(h*(f0-f1)/(K*T))-1)))
Gamma2= 4*h*f2*df2*(1+(1/(np.exp(h*(f1-f2)/(K*T))-1)))
Gamma3= 4*h*f3*df3*(1+(1/(np.exp(h*(f2-f3)/(K*T))-1)))
#start conditions
Pin = 2.7 #W
fiberlength = 90000 #m
points = fiberlength*100
P0 = [Pin, 0, 0, 0, 0, 0, 0, 0 ]
def odes2 (z, P):
Pump_forward = P[0]
Pump_backward = P[1]
Stokes1_forward = P[2]
Stokes1_backward = P[3]
Stokes2_forward = P[4]
Stokes2_backward = P[5]
Stokes3_forward = P[6]
Stokes3_backward = P[7]
dPump_forwarddz = - a0 * Pump_forward - g1 * f0/f1 * Pump_forward * (Stokes1_forward + Stokes1_backward + Gamma1) + epsilon0 * Pump_backward
dPump_backwarddz = + a0 * Pump_backward + g1 * f0/f1 * Pump_backward * (Stokes1_forward + Stokes1_backward + Gamma1) - epsilon0 * Pump_forward
dStokes1_forwarddz = - a1 * Stokes1_forward - g2 * f1/f2 * Stokes1_forward * (Stokes2_forward + Stokes2_backward + Gamma2) + g1 * (Stokes1_forward + 0.5 * Gamma1) * (Pump_forward + Pump_backward) + epsilon1 * Stokes1_backward
dStokes1_backwardz = + a1 * Stokes1_backward + g2 * f1/f2 * Stokes1_backward * (Stokes2_forward + Stokes2_backward + Gamma2) - g1 * (Stokes1_backward + 0.5 * Gamma1) * (Pump_forward + Pump_backward) - epsilon1 * Stokes1_forward
dStokes2_forwarddz = - a2 * Stokes2_forward - g3 * f2/f3 * Stokes2_forward * (Stokes3_forward + Stokes3_backward + Gamma3) + g2 * (Stokes2_forward + 0.5 * Gamma2) * (Stokes1_forward + Stokes1_backward) + epsilon2 * Stokes2_backward
dStokes2_backwardz = + a2 * Stokes2_backward + g3 * f2/f3 * Stokes2_backward * (Stokes3_forward + Stokes3_backward + Gamma3) - g2 * (Stokes2_backward + 0.5 * Gamma2) * (Stokes1_forward + Stokes1_backward) - epsilon2 * Stokes2_forward
dStokes3_forwarddz = - a3 * Stokes3_forward + g3 * (Stokes3_forward + 0.5 * Gamma3) * (Stokes2_forward + Stokes2_backward) + epsilon3 * Stokes3_backward
dStokes3_backwardz = + a3 * Stokes3_backward - g3 * (Stokes3_backward + 0.5 * Gamma3) * (Stokes2_forward + Stokes2_backward) - epsilon3 * Stokes3_forward
return [dPump_forwarddz, dPump_backwarddz, dStokes1_forwarddz, dStokes1_backwardz, dStokes2_forwarddz, dStokes2_backwardz, dStokes3_forwarddz, dStokes3_backwardz]
sol = solve_ivp(odes2, (0, fiberlength), P0, t_eval=np.linspace(0, fiberlength, points))
Pump_f, Pump_b, Stokes1_f, Stokes1_b, Stokes2_f, Stokes2_b, Stokes3_f, Stokes3_b = sol.y
x=sol.t
plt.figure(1)
plt.title('backwards')
plt.plot(x, Pump_b, label='pump')
plt.plot(x, Stokes1_b, label='stokes#1')
plt.plot(x, Stokes2_b, label='stokes#2')
plt.plot(x, Stokes3_b, label='stokes#3')
plt.legend(loc=1, fontsize='xx-small')
plt.grid(True)
plt.figure(2)
plt.title('forwards')
plt.plot(x, Pump_f, label='pump')
plt.plot(x, Stokes1_f, label='stokes#1')
plt.plot(x, Stokes2_f, label='stokes#2')
plt.plot(x, Stokes3_f, label='stokes#3')
plt.legend(loc=1, fontsize='xx-small')
plt.grid(True)
I also tried the solve_bvp but it wasn't successfull.
I have wrote a code for Runge-Kutta 4th order, which works perfectly fine for a system of differential equations:
import numpy as np
import matplotlib.pyplot as plt
import numba
import time
start_time = time.clock()
#numba.jit()
def V(u,t):
x1,dx1, x2, dx2=u
ddx1=-w**2 * x1 -b * dx1
ddx2=-(w+0.5)**2 * x2 -(b+0.1) * dx2
return np.array([dx1,ddx1,dx2,ddx2])
#numba.jit()
def rk4(f, u0, t0, tf , n):
t = np.linspace(t0, tf, n+1)
u = np.array((n+1)*[u0])
h = t[1]-t[0]
for i in range(n):
k1 = h * f(u[i], t[i])
k2 = h * f(u[i] + 0.5 * k1, t[i] + 0.5*h)
k3 = h * f(u[i] + 0.5 * k2, t[i] + 0.5*h)
k4 = h * f(u[i] + k3, t[i] + h)
u[i+1] = u[i] + (k1 + 2*(k2 + k3) + k4) / 6
return u, t
u, t = rk4(V,np.array([0,0.2,0,0.3]) ,0,100, 20000)
print("Execution time:",time.clock() - start_time, "seconds")
x1,dx1,x2,dx2 = u.T
plt.plot(x1,x2)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
The above code, returns the desired result:
And thanks to Numba JIT, this code works really fast. However, this method doesn't use adaptive step size and hence, it is not very suitable for a system of stiff differential equations. Runge Kutta Fehlberg method, solves this problem by using a straight forward algorithm. Based on the algorithm (https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta%E2%80%93Fehlberg_method) I wrote this code which works for only one differential equation :
import numpy as np
def rkf( f, a, b, x0, tol, hmax, hmin ):
a2 = 2.500000000000000e-01 # 1/4
a3 = 3.750000000000000e-01 # 3/8
a4 = 9.230769230769231e-01 # 12/13
a5 = 1.000000000000000e+00 # 1
a6 = 5.000000000000000e-01 # 1/2
b21 = 2.500000000000000e-01 # 1/4
b31 = 9.375000000000000e-02 # 3/32
b32 = 2.812500000000000e-01 # 9/32
b41 = 8.793809740555303e-01 # 1932/2197
b42 = -3.277196176604461e+00 # -7200/2197
b43 = 3.320892125625853e+00 # 7296/2197
b51 = 2.032407407407407e+00 # 439/216
b52 = -8.000000000000000e+00 # -8
b53 = 7.173489278752436e+00 # 3680/513
b54 = -2.058966861598441e-01 # -845/4104
b61 = -2.962962962962963e-01 # -8/27
b62 = 2.000000000000000e+00 # 2
b63 = -1.381676413255361e+00 # -3544/2565
b64 = 4.529727095516569e-01 # 1859/4104
b65 = -2.750000000000000e-01 # -11/40
r1 = 2.777777777777778e-03 # 1/360
r3 = -2.994152046783626e-02 # -128/4275
r4 = -2.919989367357789e-02 # -2197/75240
r5 = 2.000000000000000e-02 # 1/50
r6 = 3.636363636363636e-02 # 2/55
c1 = 1.157407407407407e-01 # 25/216
c3 = 5.489278752436647e-01 # 1408/2565
c4 = 5.353313840155945e-01 # 2197/4104
c5 = -2.000000000000000e-01 # -1/5
t = a
x = np.array(x0)
h = hmax
T = np.array( [t] )
X = np.array( [x] )
while t < b:
if t + h > b:
h = b - t
k1 = h * f( x, t )
k2 = h * f( x + b21 * k1, t + a2 * h )
k3 = h * f( x + b31 * k1 + b32 * k2, t + a3 * h )
k4 = h * f( x + b41 * k1 + b42 * k2 + b43 * k3, t + a4 * h )
k5 = h * f( x + b51 * k1 + b52 * k2 + b53 * k3 + b54 * k4, t + a5 * h )
k6 = h * f( x + b61 * k1 + b62 * k2 + b63 * k3 + b64 * k4 + b65 * k5, \
t + a6 * h )
r = abs( r1 * k1 + r3 * k3 + r4 * k4 + r5 * k5 + r6 * k6 ) / h
if len( np.shape( r ) ) > 0:
r = max( r )
if r <= tol:
t = t + h
x = x + c1 * k1 + c3 * k3 + c4 * k4 + c5 * k5
T = np.append( T, t )
X = np.append( X, [x], 0 )
h = h * min( max( 0.84 * ( tol / r )**0.25, 0.1 ), 4.0 )
if h > hmax:
h = hmax
elif h < hmin:
raise RuntimeError("Error: Could not converge to the required tolerance %e with minimum stepsize %e." % (tol,hmin))
break
return ( T, X )
but I'm struggling to convert it to a function like the first code, where I can input a system of differential equations. The most confusing part for me, is how can I vectorize everything in the second code without messing things up. In other words, I cannot reproduce the first result using the RKF algorithm. Can anyone point me in the right direction?
I'm not really sure where your problem lies. Setting the not given parameters to w=1; b=0.1 and calling, without changing anything
T, X = rkf( f=V, a=0, b=100, x0=[0,0.2,0,0.3], tol=1e-6, hmax=1e1, hmin=1e-16 )
gives the phase plot
The step sizes grow as the system slows down as
which is the expected behavior for an unfiltered step size controller.
I've tried to solve the system of equations of neutronic kinetic with two feedbacks (the fuel temperature feedback and the coolant temperature feedback) using RADAU method in python.
import numpy as np
from scipy.integrate import Radau
def kin(x, t):
beta = []
lam = []
lam = [0.001334, 0.032739, 0.12078, 0.30278, 0.84949, 2.853]
beta = [0.000256, 0.00146, 0.001306, 0.002843, 0.000937, 0.000202]
lifetime = 0.000015
betasum = sum(beta)
alfa_ttop = -0.000018
alfa_ttn = -0.00026
po0 = -1.0 * betasum
n0 = 35.2 * 1000000
Ttop0 = 377
mtop = 1469.71
ctop = 300
kt = 11000
Tvh = 271
Gtn = 179.9
ctn = 5500
gamv = 900
mtn = 500
n = x[0]
c1 = x[1]
c2 = x[2]
c3 = x[3]
c4 = x[4]
c5 = x[5]
c6 = x[6]
Ttop = x[7]
Ttn = x[8]
dndt = (po0 + alfa_ttop * (Ttop - Ttop0) + alfa_ttn * (Ttn - Tvh) - betasum) / lifetime * n + lam[0] * c1 + lam[1] * c2 + lam[2] * c3 + lam[3] * c4 + lam[4] * c5 + lam[5] * c6
dc1dt = beta[0] / lifetime * n - lam[0] * c1
dc2dt = beta[1] / lifetime * n - lam[1] * c2
dc3dt = beta[2] / lifetime * n - lam[2] * c3
dc4dt = beta[3] / lifetime * n - lam[3] * c4
dc5dt = beta[4] / lifetime * n - lam[4] * c5
dc6dt = beta[5] / lifetime * n - lam[5] * c6
dTtopdt = 1.0 / (mtop * ctop) * (n - kt * (Ttop - Ttn))
dTtndt = 1.0 / (mtn * ctn) * (kt * (Ttop - Ttn) - gamv * ctn * Gtn * (Ttn - Tvh))
return (dndt, dc1dt, dc2dt, dc3dt, dc4dt, dc5dt, dc6dt, dTtopdt, dTtndt)
n0 = 35.2 * 1000000
beta = []
lam = []
lam = [0.001334, 0.032739, 0.12078, 0.30278, 0.84949, 2.853]
beta = [0.000256, 0.00146, 0.001306, 0.002843, 0.000937, 0.000202]
lifetime = 0.000015
Tvh = 271
Ttop0 = 377
x0 = np.array(
[n0, beta[0] * n0 / (lifetime * lam[0]), beta[1] * n0 / (lifetime * lam[1]), beta[2] * n0 / (lifetime * lam[2]),
beta[3] * n0 / (lifetime * lam[3]), beta[4] * n0 / (lifetime * lam[4]), beta[5] * n0 / (lifetime * lam[5]), Ttop0,
Tvh])
t = np.linspace(0, 350, 700)
t_bound = 700
x = Radau(kin, t, x0, t_bound)
n = x[:, 0]
for i in range(0, len(n)):
print(t[i], n[i] / 1000000)
And i received the next mistakes:
Traceback (most recent call last):
File "D:/Apps/untitled2/Scripts/RADAU.py", line 62, in <module>
x = Radau(kin, t, x0, t_bound)
File "D:\Apps\lib\site-packages\scipy\integrate\_ivp\radau.py", line 288, in __init__
super(Radau, self).__init__(fun, t0, y0, t_bound, vectorized)
File "D:\Apps\lib\site-packages\scipy\integrate\_ivp\base.py", line 145, in __init__
self.direction = np.sign(t_bound - t0) if t_bound != t0 else 1
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
What should i do in order to fix this mistakes?
P.S. First I've solved it using odeint in python, and it worked, but i found out that for this system of equations the odeint is not appropriate, because it is the stiff system of differential equations.
It is not explicitly said in the documentation, but Radau is just the stepper class for the method, the return of a successful call to this constructor is a stepper object. To get a result similar to odeint use the general interface method
sol = solve_ivp(kin, (t[0],t[-1]), x0, t_eval=t, max_step=max_step, method='Radau', atol=atol, rtol=rtol)
x = sol.y
kin has the argument order t,x,
max_step has to take the role of t_bound to limit how far into the future the ODE is evaluated, compatible with your values would be max_step=350,
it is my recommendation to always explicitly control the tolerances, especially to adapt the absolute tolerance to the expected scale of the state vector,
the output is also transpose to the output of odeint, sol.y[j,k] is component j at time index k.
Here in my code i want to compute the variation of Q with respect to the variation of l and d but I am getting an error of TypeError: bad operand type for unary -: 'tuple' how to fix this issue
import numpy as np
import matplotlib.pyplot as plt
def plot_with_variating_D ():
l = np.arange(1, 1.5, 0.01)
d = np.arange(0.005, 0.015, 0.0002)
zero=np.zeros(50)
one=np.ones(50)
Eb1 = 3543.75
A1 = 1
A2 = np.pi * (d / 2)
A3 = np.pi
F11 = 0
F21 = 2 * (np.arctan(0.5 / l) * (180 / np.pi)) / 360
F12 = (d * np.pi * F21)
F12p = (((4 / l ** 2) + 4) ** 0.5 - 2) * (l / 2)
F13 = F12p - F12
F14 = 1 - F12 - F13
F23 = 0.5
F24 = 1 - F21 - F23
F34 = F14 / np.pi
rho = 0.7
k = 0.04
pr = 0.7
cp = 1005
myu = 2.4 * 10 ** -5
alpha = 5.68 * 10 ** -5
beta = 1 / 500
Ra = (rho * 9.81 * beta * (500 - 293) * l) / (myu * alpha)
Nu = 0.68 + (0.67 * Ra ** 0.25) / (1 + (0.429 / pr) ** (9 / 16)) ** (4 / 9)
h = Nu * k
J1 = 3543.75 + 0.42 * h * (500 - 295)
a = np.array([[F12,F13, zero], [A2*F23,-(A2*F23+F13,zero)], [-(4*A2+F12+A2*F23),A2*F23,4*A2]])
b = np.array([7*(J1-Eb1)/3 +F12*J1+F13*J1,-F13*J1,-F12*J1])
x = np.linalg.solve(np.moveaxis(a, -1, 0), np.moveaxis(b,-1,0))
x = x.T
J2 = -x[0]
J3 = x[1]
Eb2 = -x[2]
qrad = (Eb2 - J2)*(0.8 * A2) / 0.2
print(Eb2)
return qrad
plot_with_variating_D()
The following line causes it:
a = np.array([[F12,F13, zero], [A2*F23,-(A2*F23+F13,zero)], [-(4*A2+F12+A2*F23),A2*F23,4*A2]])
More specifically: [A2*F23,-(A2*F23+F13,zero)] is invalid.
I'm guessing you meant [A2*F23,-(A2*F23+F13),zero]