Cubic Equations in Python - python

Using the formula from https://engineersfield.com/cubic-equation-formula/:
class CubicEquation():
def __init__(self,a,b,c,d):
'''initialize constants and formula'''
q = (3*c - b**2) / 9
r = -27*d + b*(9*c - 2*b**2)
discriminant = q**3 + r**2
s = r + sqrt(discriminant)
t = r - sqrt(discriminant)
term1 = sqrt(3 * ((-t + s) / 2))
r13 = 2 * sqrt(q)
self.cubic_equation = [\
'-term1 + r13*cos(q**3 / 3)',\
'-term1 + r13*cos(q**3 + (2 * pi)/3)',\
'-term1 + r13*cos(q**3 + (4 * pi)/3)'\
]
def solve(self):
*--snip--*
and then later calling it with answer = eval(self.cubic_equation[index])
when calling this formula with args (1,1,1,1), I receive the solution:
-6.803217085397121, -8.226355957420402, -8.208435953185608
and yes I have triple-checked my formulas with those on the site.
What is the correct code for this function, and what went wrong with my current program?

Related

Invalid index to scalar variable error when trying to use scipy.optimize.curve_fit

I have a function with different parameters that I want to optimize to fit some existing data.
The function runs fine on its own, but when I try to pass it through the scipy.optimize.curve_fit function, I get this error :
IndexError: invalid index to scalar variable.
I don't understand why the function would work on its own, and I would not get any errors.
What can I do ?
The original function used dictionnaries and I thought that might be the problem but I modified it and it still doesn't work.
This is the function I'm using :
def function_test(xy,X1,X2,X3,X4):
precip = xy\[0\]
potential_evap = xy\[1\]
nUH1 = int(math.ceil(X4))
nUH2 = int(math.ceil(2.0*X4))
uh1_ordinates = [0] * nUH1
uh2_ordinates = [0] * nUH2
UH1 = [0] * nUH1
UH2 = [0] * nUH2
for t in range(1, nUH1 + 1):
uh1_ordinates[t - 1] = s_curves1(t, X4) - s_curves1(t-1, X4)
for t in range(1, nUH2 + 1):
uh2_ordinates[t - 1] = s_curves2(t, X4) - s_curves2(t-1, X4)
production_store = X1*0.60# S
routing_store = X3*0.70# R
qsim = []
for j in range(2191):
if precip[j] > potential_evap[j]:
net_evap = 0
scaled_net_precip = (precip[j] - potential_evap[j])/X1
if scaled_net_precip > 13:
scaled_net_precip = 13.
tanh_scaled_net_precip = tanh(scaled_net_precip)
reservoir_production = (X1 * (1 - (production_store/X1)**2) * tanh_scaled_net_precip) / (1 + production_store/X1 * tanh_scaled_net_precip)
routing_pattern = precip[j]-potential_evap[j]-reservoir_production
else:
scaled_net_evap = (potential_evap[j] - precip[j])/X1
if scaled_net_evap > 13:
scaled_net_evap = 13.
tanh_scaled_net_evap = tanh(scaled_net_evap)
ps_div_x1 = (2 - production_store/X1) * tanh_scaled_net_evap
net_evap = production_store * (ps_div_x1) / \
(1 + (1 - production_store/X1) * tanh_scaled_net_evap)
reservoir_production = 0
routing_pattern = 0
production_store = production_store - net_evap + reservoir_production
percolation = production_store / (1 + (production_store/2.25/X1)**4)**0.25
routing_pattern = routing_pattern + (production_store-percolation)
production_store = percolation
for i in range(0, len(UH1) - 1):
UH1[i] = UH1[i+1] + uh1_ordinates[i]*routing_pattern
UH1[-1] = uh1_ordinates[-1] * routing_pattern
for j in range(0, len(UH2) - 1):
UH2[j] = UH2[j+1] + uh2_ordinates[j]*routing_pattern
UH2[-1] = uh2_ordinates[-1] * routing_pattern
groundwater_exchange = X2 * (routing_store / X3)**3.5
routing_store = max(0, routing_store + UH1[0] * 0.9 + groundwater_exchange)
R2 = routing_store / (1 + (routing_store / X3)**4)**0.25
QR = routing_store - R2
routing_store = R2
QD = max(0, UH2[0]*0.1+groundwater_exchange)
Q = QR + QD
qsim.append(Q)
return qsim

Scipy minimization one variable while keeping some variables constant - args defining problem

I have a function where I need to minimize c_init to make totalF output zero. the problem is that I have some constants over this function which are Es, f_slong and f_c. I need to repeat this whole minimization for 30 different cases meaning that I have 30 different constant variables and 30 different c_init initial values. Then, my aim is to obtain what the values for c_init will be at the end of the algorithm. However, those constant variables give me trouble. I do not have any inequality (I am not sure if I have to define it anyway), I strongly feel that my problem is to define the location and inputs of *args, I've tested out many different scenarios but they all failed. Could anyone help me out? Those constant variables should be coming from their list of array in every iteration and sending through the minimization function.
def c_neutral_un(c_init, Es, f_slong, f_c):
eps_s = e_cu_un * (d - c_init) / c_init
eps_s_prime = e_cu_un * (c_init - d_prime) / c_init
if Es * eps_s > f_slong:
f_s = f_slong
else:
f_s = Es * eps_s
if Es * eps_s_prime > f_slong:
f_s_prime = f_slong
else:
f_s_prime = Es * eps_s_prime
T = As * f_s
Cs_prime = As_prime * (f_s_prime - alfa1 * f_c)
Cc_conc = alfa1 * f_c * b * beta1 * c_init
totalF = Cc_conc + Cs_prime - T
return totalF
c = []
for i in range(31)
bnd = ([0, 200])
x0 = c_init[i]
Es = Es[i]
f_slong = f_slong[i]
f_c = f_c[i]
res = minimize(c_neutral_un, x0, args=([Es, f_slong, f_c], True) method = "SLSQP", bounds = bnd)
c.append(res.x)
THere is an error for constant assignment like Es = Es[i]
def c_neutral_un(c_init, Es, f_slong, f_c):
eps_s = e_cu_un * (d - c_init) / c_init
eps_s_prime = e_cu_un * (c_init - d_prime) / c_init
if Es * eps_s > f_slong:
f_s = f_slong
else:
f_s = Es * eps_s
if Es * eps_s_prime > f_slong:
f_s_prime = f_slong
else:
f_s_prime = Es * eps_s_prime
T = As * f_s
Cs_prime = As_prime * (f_s_prime - alfa1 * f_c)
Cc_conc = alfa1 * f_c * b * beta1 * c_init
totalF = Cc_conc + Cs_prime - T
return totalF
c = []
for i in range(31):
bnd = ([0, 200])
x0 = c_init[i]
Es2 = Es[i]
f_slong2 = f_slong[i]
f_c2 = f_c[i]
res = minimize(c_neutral_un, x0, args=([Es2, f_slong2, f_c2], True),method = "SLSQP", bounds = bnd)
c.append(res.x)

Understanding the implementation of ConvLSTM in tensorflow

In the tensorflow implementation of convLSTM cell the following lines of code are written as:
x_i = self.input_conv(inputs_i, kernel_i, bias_i, padding=self.padding)
x_f = self.input_conv(inputs_f, kernel_f, bias_f, padding=self.padding)
x_c = self.input_conv(inputs_c, kernel_c, bias_c, padding=self.padding)
x_o = self.input_conv(inputs_o, kernel_o, bias_o, padding=self.padding)
h_i = self.recurrent_conv(h_tm1_i, recurrent_kernel_i)
h_f = self.recurrent_conv(h_tm1_f, recurrent_kernel_f)
h_c = self.recurrent_conv(h_tm1_c, recurrent_kernel_c)
h_o = self.recurrent_conv(h_tm1_o, recurrent_kernel_o)
i = self.recurrent_activation(x_i + h_i)
f = self.recurrent_activation(x_f + h_f)
c = f * c_tm1 + i * self.activation(x_c + h_c)
o = self.recurrent_activation(x_o + h_o)
h = o * self.activation(c)
The corresponding equations as described in the paper are:
I am not able to see how W_ci, W_cf, W_co C_{t-1}, C_t is used in the input, forget and output gates. Where does it being used in computing the 4 gates?
Of course you cannot find those in that implementation of ConvLSTM cell, because it not using peephole:
Peephole connections allow the gates to utilize the previous internal
state as well as the previous hidden state (which is what LSTMCell is
limited to)
The tf.keras.experimental.PeepholeLSTMCell follow the equations you post above, as you can see in it source code:
x_i, x_f, x_c, x_o = x
h_tm1_i, h_tm1_f, h_tm1_c, h_tm1_o = h_tm1
i = self.recurrent_activation(
x_i + K.dot(h_tm1_i, self.recurrent_kernel[:, :self.units]) +
self.input_gate_peephole_weights * c_tm1)
f = self.recurrent_activation(x_f + K.dot(
h_tm1_f, self.recurrent_kernel[:, self.units:self.units * 2]) +
self.forget_gate_peephole_weights * c_tm1)
c = f * c_tm1 + i * self.activation(x_c + K.dot(
h_tm1_c, self.recurrent_kernel[:, self.units * 2:self.units * 3]))
o = self.recurrent_activation(
x_o + K.dot(h_tm1_o, self.recurrent_kernel[:, self.units * 3:]) +
self.output_gate_peephole_weights * c)
Or more clear, if you look at source code of tf.compat.v1.nn.rnn_cell.LSTMCell:
if self._use_peepholes:
c = (
sigmoid(f + self._forget_bias + self._w_f_diag * c_prev) * c_prev +
sigmoid(i + self._w_i_diag * c_prev) * self._activation(j))
else:
c = (
sigmoid(f + self._forget_bias) * c_prev +
sigmoid(i) * self._activation(j))

ray caster, cast_ray function incorrectly accounts for obscured light

I am getting an error that says I am not accounting for obscured light and that my specular is getting added when the light is obscured. This is what the specular part that is being added onto is with x representing r, g, orb of my Color class: light.color.x * s.finish.specular * specIntense
def in_shadow (sphere_list, sphere, ray_to_light, light):
new_list = list()
for s in sphere_list:
if sphere != s:
new_list.append(s)
for s in new_list:
if sphere_intersection_point(ray_to_light, s):
x1 = ray_to_light.pt.x - light.pt.x
y1 = ray_to_light.pt.y - light.pt.y
z1 = ray_to_light.pt.z - light.pt.z
dist1 = math.sqrt(x1 + y1 + z1)
x2 = ray_to_light.pt.x - s.center.x
y2 = ray_to_light.pt.y - s.center.y
z2 = ray_to_light.pt.z - s.center.z
dist2 = math.sqrt(x2 + y2 + z2)
# distance to light, distance to sphere
# check if distance to sphere < distance to light
# if so return 0
if dist2 < dist1:
return 0
return 1
def cast_ray(ray, sphere_list, color, light, point):
# count = 0
dist = -1
cp = Color(1.0, 1.0, 1.0)
for s in sphere_list:
if sphere_intersection_point(ray, s):
# count += 1
p = sphere_intersection_point(ray, s)
vec = vector_from_to(s.center, p)
N = normalize_vector(vec)
norm_scaled = scale_vector(N, 0.01)
pe = translate_point(p, norm_scaled)
l = vector_from_to(pe, light.pt)
l_dir = normalize_vector(l)
dot = dot_vector(N, l_dir)
r = Ray(pe, l_dir)
dotNScaled = dot * 2
reflecVec = difference_vector(l_dir, scale_vector(N, dotNScaled))
V = vector_from_to(point, pe)
Vdir = normalize_vector(V)
spec = dot_vector(reflecVec, Vdir)
m = in_shadow(sphere_list, s, r, light)
if (dot <= 0):
m = 0
x = (ray.pt.x - p.x) ** 2
y = (ray.pt.y - p.y) ** 2
z = (ray.pt.z - p.z) ** 2
curdist = math.sqrt(x + y + z)
# print curdist
if (dist < 0) or (dist > curdist):
dist = curdist
if (spec <= 0 ):
r = ( s.color.r * s.finish.ambient * color.r ) \
+ ( light.color.r * s.finish.diffuse * dot * s.color.r * m )
g = ( s.color.g * s.finish.ambient * color.g ) \
+ (light.color.g * s.finish.diffuse * dot * s.color.g * m )
b = ( s.color.b * s.finish.ambient * color.b ) \
+ (light.color.b * s.finish.diffuse * dot * s.color.b * m )
cp = Color(r, g, b)
if ( spec >= 0 ):
specIntense = spec ** (1/s.finish.roughness)
print type(s.finish.diffuse)
r = (s.color.r * s.finish.ambient * color.r) \
+ (light.color.r * s.finish.diffuse * dot * s.color.r * m) \
+ (light.color.r * s.finish.specular * specIntense)
g = (s.color.g * s.finish.ambient * color.g) \
+ (light.color.g * s.finish.diffuse * dot * s.color.g * m) \
+ (light.color.g * s.finish.specular * specIntense)
b = (s.color.b * s.finish.ambient * color.b) \
+ (light.color.b * s.finish.diffuse * dot * s.color.b * m) \
+ (light.color.b * s.finish.specular * specIntense)
cp = Color(r, g, b)
# if count > 1:
# print 'intersects two!'
return cp
I think somewhere I am not accounting for the case where the sphere has another one in front of it therefore the specular part is being added to it when it shouldn't, creating this weird white light behind the first sphere that isn't supposed to be there. I'm sure there is a bug in this code somewhere but I cannot find it.

How to write mathematic formula in python

I try to write these formulas in python but with no luck
I have no errors in code but I know that calculation gives incorrect result so I guess I have something wrong in implementation of formulas.
import math
lat = 54.5917455423
lon = 17.2078876198
B = math.radians(lat)
L = math.radians(lon)
h = 55.889
pi = math.pi
a = 6378137
b = 6356752.3141
f = 1/298.257222101
ba = 1 - f# should be b/a = 1 - f
e = 0.006694380036
Da = 108
Df = - 4.80812 * 10 **-7
m = 0.000004848#one second in radians
dX = -23.74
dY = +123.83
dZ = +81.81
sin = math.sin
cos = math.cos
Rn = a/ math.sqrt(1-e**2 * math.sin(B)**2)
Rm = a*(1-e**2)/(1-e**2 * sin(B)**2)**(3/2)
vc = (Rm+h)*sin(m)
dB = (-dX*sin(B)*cos(L) - dY*sin(L) + dZ*cos(B) + Da*(Rn * e**2*sin(B)*cos(B)/a+Df)*(Rm*(a/b)+Rn*ba)*sin(B)*cos(B))*vc**-1
dL = (-dX * sin(L) + dY * cos(L) ) * ((Rn + h) * cos(B) * sin(m))**-1
a = dB * 180/pi + B
b = dL *180/pi + L
print a
print b
This isn't Python:
b/a = 1 - f
This formula has errors in it:
dB = (-dX*sin(B)*cos(L) - dY*sin(L) + dZ*cos(B)
+ Da*(Rn * e**2*sin(B)*cos(B)/a+Df)*(Rm*(a/b)+Rn*ba)*sin(B)*cos(B))*vc**-1
It should be:
dB = ( -dX*sin(B)*cos(L) - dY*sin(B)*sin(L) + dZ*cos(B)
+ Da*(Rn * e**2*sin(B)*cos(B)/a)
+ Df*(Rm*(a/b)+Rn*b/a)*sin(B)*cos(B) )*vc**-1

Categories