I'm new to numpy, and trying to implement the following equation.
The equation has two parts, and should give a final value called Sigma.
the equation is taken from the paper as below image:
image of the equation to provide the result of Sigma
I tried to implement it as below, but when running the code, the value c is giving nan
c = np.sqrt(np.log(2 / np.sqrt( 16 * delta + 1 ) -1 ))
sigma = (c + np.sqrt(np.square(c) + epsilon) ) * s / (epsilon * np.sqrt(2))
appreciate if you can advise on how to implement it in numpy
You missed a bracket in your code
c = np.sqrt(np.log(2 / (np.sqrt( 16 * delta + 1 ) -1 )))
sigma = (c + np.sqrt(np.square(c) + epsilon) ) * s / (epsilon * np.sqrt(2))
To get a valid c value, you should input delta like 0 < delta < 0.5.
You are missing a parenthesis. This is the correct formula:
c = np.sqrt(np.log(2/(np.sqrt(16*delta + 1) -1)))
Also, keep in mind that (as the paper states) this is defined only for .
Related
How can I convert this equation to Python code
enter image description here
You can need to learn about operator precedence and associativity in Programming Languages. That way you can strengthen your understanding of how to perform complex calculations in Python.
Apart from that try to break the problem into smaller subproblems and combine the smaller subproblems to generate solution for the larger problem.
[0.38C(1-g/C)2] = (0.38 * C) * (1 - (g/C) * 2)
[1-(g/C)(X)] = (1 - (g/C) * X)
173X2 = 173 * 2
[(X-1)+[(X-1)2 + (16X/C)]1/2] = ((X-1)+((X-1)*2 + (16*X/C))* 1/2)
Now put all values in the equation:
"d=[0.38C(1-g/C)2]/[1-(g/C)(X)]+173X2[(X-1)+[(X-1)2 + (16X/C)]1/2]"
d = (((0.38 * C)*(1 - (g/c)) * 2 ) / (1 - (g/C) * X)) + 172 * 2 *((X-1) +((X-1)+((X-1)*2 + (16*X/C))* 1/2)
Let (0,0) and (Xo,Yo) be two points on a Cartesian plane. We want to determine the parabolic curve, Y = AX^2 + BX + C, which passes from these two points and has a given arc length equal to S. Obviously, S > sqrt(Xo^2 + Yo^2). As the curve must pass from (0,0), it should be C=0. Hence, the curve equation reduces to: Y = AX^2 + BX. How can I determine {A,B} knowing {Xo,Yo,S}? There are two solutions, I want the one with A>0.
I have an analytical solution (complex) that gives S for a given set of {A,B,Xo,Yo}, though here the problem is inverted... I can proceed by solving numerically a complex system of equations... but perhaps there is a numerical routine out there that does exactly this?
Any useful Python library? Other ideas?
Thanks a lot :-)
Note that the arc length (line integral) of the quadratic a*x0^2 + b*x0 is given by the integral of sqrt(1 + (2ax + b)^2) from x = 0 to x = x0. On solving the integral, the value of the integral is obtained as 0.5 * (I(u) - I(l)) / a, where u = 2ax0 + b; l = b; and I(t) = 0.5 * (t * sqrt(1 + t^2) + log(t + sqrt(1 + t^2)), the integral of sqrt(1 + t^2).
Since y0 = a * x0^2 + b * x0, b = y0/x0 - a*x0. Substituting the value of b in u and l, u = y0/x0 + a*x0, l = y0/x0 - a*x0. Substituting u and l in the solution of the line integral (arc length), we get the arc length as a function of a:
s(a) = 0.5 * (I(y0/x0 + a*x0) - I(y0/x0 - a*x0)) / a
Now that we have the arc length as a function of a, we simply need to find the value of a for which s(a) = S. This is where my favorite root-finding algorithm, the Newton-Raphson method, comes into play yet again.
The working algorithm for the Newton-Raphson method of finding roots is as follows:
For a function f(x) whose root is to be obtained, if x(i) is the ith guess for the root,
x(i+1) = x(i) - f(x(i)) / f'(x(i))
Where f'(x) is the derivative of f(x). This process is continued till the difference between two consecutive guesses is very small.
In our case, f(a) = s(a) - S and f'(a) = s'(a). By simple application of the chain rule and the quotient rule,
s'(a) = 0.5 * (a*x0 * (I'(u) + I'(l)) + I(l) - I(u)) / (a^2)
Where I'(t) = sqrt(1 + t^2).
The only problem that remains is calculating a good initial guess. Due to the nature of the graph of s(a), the function is an excellent candidate for the Newton-Raphson method, and an initial guess of y0 / x0 converges to the solution in about 5-6 iterations for a tolerance/epsilon of 1e-10.
Once the value of a is found, b is simply y0/x0 - a*x0.
Putting this into code:
def find_coeff(x0, y0, s0):
def dI(t):
return sqrt(1 + t*t)
def I(t):
rt = sqrt(1 + t*t)
return 0.5 * (t * rt + log(t + rt))
def s(a):
u = y0/x0 + a*x0
l = y0/x0 - a*x0
return 0.5 * (I(u) - I(l)) / a
def ds(a):
u = y0/x0 + a*x0
l = y0/x0 - a*x0
return 0.5 * (a*x0 * (dI(u) + dI(l)) + I(l) - I(u)) / (a*a)
N = 1000
EPSILON = 1e-10
guess = y0 / x0
for i in range(N):
dguess = (s(guess) - s0) / ds(guess)
guess -= dguess
if abs(dguess) <= EPSILON:
print("Break:", abs((s(guess) - s0)))
break
print(i+1, ":", guess)
a = guess
b = y0/x0 - a*x0
print(a, b, s(a))
Run the example on CodeSkulptor.
Note that due to the rational approximation of the arc lengths given as input to the function in the examples, the coefficients obtained may ever so slightly differ from the expected values.
Make a program to find the roots of a quadratic equation using the Bhaskara formule:
for to calculate the square root using the formula: number ** 0.5
I can put the a,b and c, but when I run the program does't show the result of the roots x1 and x2 ...
This is my code so far:
a = int(input("a "))
b = int(input("b "))
c = int(input("c "))
delta = b * b - 4 * a * c
if (delta >= 0):
x1 = (-b + delta ** 0.5) / 2 * a
x2 = (-b - (delta) ** 0.5) / 2 * a
print("x1: ", x1)
print("x2: ", x2)
All a, b, and c real values have two roots (except in the case where the delta is 0)—but sometimes the roots are complex numbers, not real numbers.
In particular, if I remember correctly:
If delta > 0, there are two real roots.
If delta == 0, there is only one root, the real number -b/(2*a).
If delta < 0, there are two complex roots (which are always conjugates).
If you do your math with complex numbers, you can use the same formula, (-b +/- delta**0.5) / 2a, for all three cases, and you'll get two real numbers, or 0 twice, or two complex numbers, as appropriate.
There are also ways to calculate the real and imaginary parts of the third case without doing complex math, but since Python makes complex math easy, why bother unless you're specifically trying to learn about those ways?
So, if you always want to print 2 roots, all you have to do is remove that if delta >= 0: line (and dedent the next few lines). Raising a negative float to the 0.5 power will give you a complex automatically, and that will make the rest of the expression complex. Like this:
delta = b * b - 4 * a * c
x1 = (-b + delta ** 0.5) / 2 * a
x2 = (-b - (delta) ** 0.5) / 2 * a
print("x1: ", x1)
print("x2: ", x2)
If you only want 0-2 real roots, your code is already correct as-is. You might want to add a check for delta == 0, or just for x1 == x2, so you don't print the same value twice. Like this:
delta = b * b - 4 * a * c
if delta >= 0:
x1 = (-b + delta ** 0.5) / 2 * a
x2 = (-b - (delta) ** 0.5) / 2 * a
print("x1: ", x1)
if x1 != x2:
print("x2: ", x2)
If you want some kind of error message, all you need to do is add an else clause. Something like this:
delta = b * b - 4 * a * c
if delta >= 0:
x1 = (-b + delta ** 0.5) / 2 * a
x2 = (-b - (delta) ** 0.5) / 2 * a
print("x1: ", x1)
print("x2: ", x2)
else:
print('No real solutions because of negative delta: ", delta)
Which one do you want? I have no idea. That's a question for you to answer. Once you decide what output you want for, say, 3, 4, and 5, you can pick the version that gives you that output.
I am using Python 2 and the fairly simple method given in Wikipedia's article "Cubic function". This could also be a problem with the cube root function I have to define in order to create the function mentioned in the title.
# Cube root and cubic equation solver
#
# Copyright (c) 2013 user2330618
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://www.mozilla.org/MPL/2.0/.
from __future__ import division
import cmath
from cmath import log, sqrt
def cbrt(x):
"""Computes the cube root of a number."""
if x.imag != 0:
return cmath.exp(log(x) / 3)
else:
if x < 0:
d = (-x) ** (1 / 3)
return -d
elif x >= 0:
return x ** (1 / 3)
def cubic(a, b, c, d):
"""Returns the real roots to cubic equations in expanded form."""
# Define the discriminants
D = (18 * a * b * c * d) - (4 * (b ** 3) * d) + ((b ** 2) * (c ** 2)) - \
(4 * a * (c ** 3)) - (27 * (a ** 2) * d ** 2)
D0 = (b ** 2) - (3 * a * c)
i = 1j # Because I prefer i over j
# Test for some special cases
if D == 0 and D0 == 0:
return -(b / (3 * a))
elif D == 0 and D0 != 0:
return [((b * c) - (9 * a * d)) / (-2 * D0), ((b ** 3) - (4 * a * b * c)
+ (9 * (a ** 2) * d)) / (-a * D0)]
else:
D1 = (2 * (b ** 3)) - (9 * a * b * c) + (27 * (a ** 2) * d)
# More special cases
if D != 0 and D0 == 0 and D1 < 0:
C = cbrt((D1 - sqrt((D1 ** 2) - (4 * (D0 ** 3)))) / 2)
else:
C = cbrt((D1 + sqrt((D1 ** 2) - (4 * (D0 ** 3)))) / 2)
u_2 = (-1 + (i * sqrt(3))) / 2
u_3 = (-1 - (i * sqrt(3))) / 2
x_1 = (-(b + C + (D0 / C))) / (3 * a)
x_2 = (-(b + (u_2 * C) + (D0 / (u_2 * C)))) / (3 * a)
x_3 = (-(b + (u_3 * C) + (D0 / (u_3 * C)))) / (3 * a)
if D > 0:
return [x_1, x_2, x_3]
else:
return x_1
I've found that this function is capable of solving some simple cubic equations:
print cubic(1, 3, 3, 1)
-1.0
And a while ago I had gotten it to a point where it could solve equations with two roots. I've just done a rewrite and now it's gone haywire. For example, these coefficients are the expanded form of (2x - 4)(x + 4)(x + 2) and it should return [4.0, -4.0, -2.0] or something similar:
print cubic(2, 8, -8, -32)
[(-4+1.4802973661668753e-16j), (2+2.9605947323337506e-16j), (-2.0000000000000004-1.1842378929335002e-15j)]
Is this more a mathematical or a programming mistake I'm making?
Update: Thank you, everyone, for your answers, but there are more problems with this function than I've iterated so far. For example, I often get an error relating to the cube root function:
print cubic(1, 2, 3, 4) # Correct solution: about -1.65
...
if x > 0:
TypeError: no ordering relation is defined for complex numbers
print cubic(1, -3, -3, -1) # Correct solution: about 3.8473
if x > 0:
TypeError: no ordering relation is defined for complex numbers
Wolfram Alpha confirms that the roots to your last cubic are indeed
(-4, -2, 2)
and not as you say
... it should return [4.0, -4.0, -2.0]
Not withstanding that (I presume) typo, your program gives
[(-4+1.4802973661668753e-16j), (2+2.9605947323337506e-16j), (-2.0000000000000004-1.1842378929335002e-15j)]
Which to accuracy of 10**(-15) are the exact same roots as the correct solution. The tiny imaginary part is probably due, as others have said, to rounding.
Note that you'll have to use exact arithmetic to always correctly cancel if you are using a solution like Cardano's. This one of the reasons why programs like MAPLE or Mathematica exist, there is often a disconnect from the formula to the implementation.
To get only the real portion of a number in pure python you call .real. Example:
a = 3.0+4.0j
print a.real
>> 3.0
Hooked's answer is the way to go if you want to do this numerically. You can also do it symbolically using sympy:
>>> from sympy import roots
>>> roots('2*x**3 + 8*x**2 - 8*x - 32')
{2: 1, -4: 1, -2: 1}
This gives you the roots and their multiplicity.
You are using integer values - which are not automatically converted to floats by Python.
The more generic solution will be to write coefficients in the function as float numbers - 18.0 instead of 18, etc. That will do the trick
An illustration - from the code:
>>> 2**(1/3)
1
>>> 2**(1/3.)
1.2599210498948732
>>>
I have the following set of equations, and I want to solve them simultaneously for X and Y. I've been advised that I could use numpy to solve these as a system of linear equations. Is that the best option, or is there a better way?
a = (((f * X) + (f2 * X3 )) / (1 + (f * X) + (f2 * X3 ))) * i
b = ((f2 * X3 ) / (1 + (f * X) + (f2 * X3))) * i
c = ((f * X) / (1 + (j * X) + (k * Y))) * i
d = ((k * Y) / (1 + (j * X) + (k * Y))) * i
f = 0.0001
i = 0.001
j = 0.0001
k = 0.001
e = 0 = X + a + b + c
g = 0.0001 = Y + d
h = i - a
As noted by Joe, this is actually a system of nonlinear equations. You are going to need more firepower than numpy alone provides.
Solution of nonlinear equations is tricky, and the typical approach is to define an objective function
F(z) = sum( e[n]^2, n=1...13 )
where z is a vector containing a value for each of your 13 variables a,b,c,d,e,f,g,h,i,X,Y and e[n] is the amount by which each of your 13 equations is violated. For example
e[3] = (d - ((k * Y) / (1 + (j * X) + (k * Y))) * i )
Once you have that objective function, then you can apply a nonlinear solver to try to find a z for which F(z)=0. That of course corresponds to a solution to your equations.
Commonly used solvers include:
The Solver in Microsoft Excel
The python library scipy.optimize
Fitting routines in the Gnu Scientific Library
Matlab's optimization toolbox
Note that all of them will work far better if you first alter your set of equations to eliminate as many variables as practical before trying to run the solver (e.g. by substituting for k wherever it is found). The reduced dimensionality makes a big difference.