Multi Parameter Function Replacement with Sympy - python-3.x

I've got a math equation that I want to visually record the substitution of.
The equation is y = h * f(t + h, h + f(t, h)), where f(x, y) = x + y - 1
I want to substitute f into y, such that I get:
y = h * f(t + h, h + (t + h - 1))
y = h * (t + h + h + (t + h - 1) - 1)
I've had issues with replace not allowing me to do multi-parameter substitution
I don't have much code, since I'm not sure how to implement it
from sympy import *
f = Function('f')(x, y)
eqn = h * f(t + h, h + f(t, h))
Thanks

sympy.Function is used for declaring undefined functions but in your case the function is known.
The following code seems to work fine over here
from sympy import *
x,y,t,h = symbols('x y t h')
def f(x,y):
return x + y - 1
y = h * f(t+h,h+f(t,h))
y = expand(y)
display(y)
The role of the expand function was to work out the outer multiplication by h in the definition of y.
You can run it in a Jupyter notebook or as an alternative use the print or display function, I get the following result:

Extending average's answer -- Their solution works perfectly if the function is known.
To make it work for a function that's input from the user, you need to do this:
function = input()
def f(x, y, evaluate = False):
eqn = sympify(function)
if evaluate:
eqn = eqn.subs([("x", x), ("y", y)])
return eqn
y = h + f(h, t, True)
This way, if the user inputs "x ** y" for f, y will expand to h + h ** t

Related

Looking for simplification of Elliptic curve multiplication calculator

I am looking for a reduced way of this code. I had to do the division separately because of the multiplicative inverse condition.
"""This code calculates the multiplication Elliptic curves over Zp"""
#Initial values for testing
yq = 3
yp = 3
xq = 8
xp = 8
a = 1
p = 11
#Calculate the Euclid greatest common divisor
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return g, x - (b // a) * y, y
#Calculate the multiplicate inverse
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('Mod inverse does not exist')
else:
return x % m
#veces = Number of times for the multiplication
veces = 7
print(f"The next results are the multiplication of {veces}*({xp},{yp})")
z = 1
while z <= (veces - 1):
if xp == xq and yp == yq:
numerador = (3 * pow(xp, 2) + a) % p
denominador = ((2 * yp) % p)
inver = modinv(denominador, p)
landa = (inver * numerador) % p
else:
numerador = (yq - yp) % p
denominador = (xq - xp) % p
inver = modinv(denominador, p)
landa = (inver * numerador) % p
xr = (pow(landa, 2) - xp - xq) % p
yr = (landa * (xp - xr) - yp) % p
z += 1
xp, yp = xr, yr
print(f"The result is ({xp},{yp})")
#Any way to simplify this code? I had to do the division separately but I think we can a reducted code for the division.

Weird behavior of (^) in Haskell

Why does GHCi give incorrect answer below?
GHCi
λ> ((-20.24373193905347)^12)^2 - ((-20.24373193905347)^24)
4.503599627370496e15
Python3
>>> ((-20.24373193905347)**12)**2 - ((-20.24373193905347)**24)
0.0
UPDATE
I would implement Haskell's (^) function as follows.
powerXY :: Double -> Int -> Double
powerXY x 0 = 1
powerXY x y
| y < 0 = powerXY (1/x) (-y)
| otherwise =
let z = powerXY x (y `div` 2)
in if odd y then z*z*x else z*z
main = do
let x = -20.24373193905347
print $ powerXY (powerXY x 12) 2 - powerXY x 24 -- 0
print $ ((x^12)^2) - (x ^ 24) -- 4.503599627370496e15
Although my version doesn't appear any more correct than the one provided below by #WillemVanOnsem, it strangely gives the correct answer for this particular case at least.
Python is similar.
def pw(x, y):
if y < 0:
return pw(1/x, -y)
if y == 0:
return 1
z = pw(x, y//2)
if y % 2 == 1:
return z*z*x
else:
return z*z
# prints 0.0
print(pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24))
Short answer: there is a difference between (^) :: (Num a, Integral b) => a -> b -> a and (**) :: Floating a => a -> a -> a.
The (^) function works only on integral exponents. It will normally make use of an iterative algorithm that will each time check if the power is divisible by two, and divide the power by two (and if non-divisible multiply the result with x). This thus means that for 12, it will perform a total of six multiplications. If a multiplication has a certain rounding-off error, that error can "explode". As we can see in the source code, the (^) function is implemented as:
(^) :: (Num a, Integral b) => a -> b -> a
x0 ^ y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0 ^ y0 = x ^ y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) (y `quot` 2) x -- See Note [Half of y - 1]
-- g : x0 ^ y0 = (x ^ y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) (y `quot` 2) (x * z) -- See Note [Half of y - 1]
The (**) function is, at least for Floats and Doubles implemented to work on the floating point unit. Indeed, if we take a look at the implementation of (**), we see:
instance Floating Float where
-- …
(**) x y = powerFloat x y
-- …
This thus redirect to the powerFloat# :: Float# -> Float# -> Float# function, which will, normally be linked to the corresponding FPU operation(s) by the compiler.
If we use (**) instead, we obtain zero as well for a 64-bit floating point unit:
Prelude> (a**12)**2 - a**24
0.0
We can for example implement the iterative algorithm in Python:
def pw(x0, y0):
if y0 < 0:
raise Error()
if y0 == 0:
return 1
return f(x0, y0)
def f(x, y):
if (y % 2 == 0):
return f(x*x, y//2)
if y == 1:
return x
return g(x*x, y // 2, x)
def g(x, y, z):
if (y % 2 == 0):
return g(x*x, y//2, z)
if y == 1:
return x*z
return g(x*x, y//2, x*z)
If we then perform the same operation, I get locally:
>>> pw(pw(-20.24373193905347, 12), 2) - pw(-20.24373193905347, 24)
4503599627370496.0
Which is the same value as what we get for (^) in GHCi.

Why do I get the "Type-declaration character does not match declared data type" in my VBA code?

I wrote a program which calculates the integral of the probability density function of the lognormal distribution.
I want it to be able to calculate the nth moments of the pdf too. But if I modify my code I get this error. It works properly before I add *(x^(M))
Function riemanint(n, a, b)
Dim h, i, x
h = (b - a) / n
x = a - h / 2
For i = 1 To n
x = x + h
s = s + f(x, ev, var, PI, M) * h
Next
riemanint = s
End Function
Function f(x, ev, var, PI, M)
PI = Application.WorksheetFunction.PI()
ev = Range("D2")
var = Range("E2")
M = Range("F2")
f = (((1 / (x * ((2 * PI) ^ 0.5) * var)) * Exp((-(Log(x) - ev) ^ 2) / (2 * var * var)))) * (x^(M))
End Function

How to numerically calculate value of complex function given derivative of this function in Haskell?

Given:
Haskell
Complex-valued function df/dz defined on complex plane U (let's say z is a Complex Double).
Point z1 from the U on which df/dz is defined.
Question:
How to get value of function f(z) for which df/dz is a derivative, in point z1?
I. e. how to restore value of original function given only it's derivative, assuming complex plane?
This question is somewhat related to my previous question about calculating integrals of complex functions, but they are about different things. Here I am interested not in calculating some scalar value, but in finding the origin function given it's derivative. It's essentially calculating the indefinite integral of this derivative.
(Runge–Kutta in Haskell)
You can use some numeric solver like Runge-Kutta
-- define 4th order Runge-Kutta map (RK4)
rk4 :: Floating a => (a -> a) -> a -> a -> a
rk4 f h x = x + (1/6) * (k1 + 2*k2 + 2*k3 + k4)
where k1 = h * f (x)
k2 = h * f (x + 0.5*k1)
k3 = h * f (x + 0.5*k2)
k4 = h * f (x + k3)
in that case function signature is Floating but you can use RealFloat instead (you can use runge-kutta in complex).
Complete example:
Prelude> import Data.Complex
Prelude Data.Complex> let rk4 f h x = x + (1/6) * (k1 + 2*k2 + 2*k3 + k4) where {k1 = h * f(x);k2 = h * f (x + 0.5*k1);k3 = h * f (x + 0.5*k2);k4 = h * f (x + k3)}
Prelude Data.Complex> let f z = 2 * z
Prelude Data.Complex> rk4 f (0.1 :+ 0.2) (0.3 :+ 1.2)
(-0.2334199999999999) :+ 1.4925599999999999
Prelude Data.Complex>
On the other hand, #leftaroundabout suggest extend that behavior to VectorSpace (great! of course! :D )

Equation for Sliding Collision of LineSegments

I need an equation to find point F.
Point A, B, and D are known. Point F is unknown. Point F is on line AB. Line AB is perpendicular to line DF. What is the equation for F?
I'm assuming you want something computationally fast, since you mention 'collision', and this is Stack Overflow. First, a diagram:
We want to calculate the components of AF, which we'll label f = qi + pj. AFD forms a triangle, so we can get the length of f from AD, which we'll label d. Let's mark lengths in italics versus vectors in bold:
f = d cos(θ).
But trig is computationally expensive. So let's use the fact that the vector dot product between b (AB) and d is:
b · d = b d cos(θ)
The angle is the same because AF and AB are on the same line. Substituting in for dcos(θ):
b · d = b f
f = (b · d) / b
Now we have f, but we want its components p and q. Calling the angle to the horizontal φ:
q = f cos(φ)
p = f sin(φ)
But again we're avoiding trig. We know that f is along b, so f = kb, and in fact using the unit vector in the direction of b:
f = f (b/b)
Substituting our expression for f:
f = [(b · d) / b ] (b/b)
= [(b/ b) · d ] (b/b)
= [b · d] b / (b2)
Defining a factor k which is common to both components:
k = (bx dx + by dy) /b2
By keeping the b2 separate, we can avoid a square root operation to get the unit vector along b
Our components, then:
q = k bx
p = k by
Finally, add back in the offset of point A.
Fx = Ax + q
Fy = Ay + p
So, the pseudo code:
var vbx = Bx - Ax; //vector b x component
var vby = By - Ay; //vector b y component
var dot = vbx*(Dx-Ax) + vby*(Dy-Ay); // dot product of b and d
var k = dot/(vbx*vbx + vby*vby); // inverse of square of vector b length
var fx = Ax + k*vbx
var fy = Ay + k*vby
No square root calls, no trig, 8 additions/subtractions, 6 multiplications, 1 division. The only instabilities I can see are: divide by zero when A and B are at the same position, possible overflow calculating dot if AB is large and AD is large.
First, find the slope of line AB with the point-slope formula using A and B's coordinates:
Point Slope Formula
You can then find b to finished the equation for line AB:
y = mx + b where m is the slope you already found and b is the y-intercept that you just found.
The slope of line DF would be the negative reciprocal of the slope of line AB. Plug this into the equation:
y = mx + b where m is the negative reciprocal of the slope of line AB and b comes later.
Now, solve for b using the x and y values of point D, and plug that into the equation.
You should now have an equation for line DF and another equation for line AB. Now solve for the intercept of the two equations by setting them equal to one another and solving for x first and then plugging in x and finding y.
Here's an example.
A = (1, 2). B = (4, 8). D = (2, 5).
Line AB:
(y - y1) = m*(x - x1)
(1 - 4) = m*(2 - 8)
-3 = m*(-6)
0.5 = m
y = (0.5)*x + b
2 = (0.5)*1 + b
2 = (0.5) + b
1.5 = b
y = 0.5*x + 1.5
Line DF:
m = -(1/mAB)
m = -(1/0.5)
m = -2
y = -2*x + b
5 = -2*2 + b
5 = -4 + b
9 = b
y = -2*x + 9
Intersection of AB and DF (i.e. coordinates of point F)
Line DF: y = -2*x + 9
Line AB: y = 0.5*x + 1.5
-2*x + 9 = 0.5*x + 1.5
9 = 2.5*x + 1.5
7.5 = 2.5*x
x = 3
y = -2*x + 9
y = -2*3 + 9
y = -6 + 9
y = 3
F = (3, 3)
You haven't specified exactly where point F is along line DF, so there's no single answer. If you're just trying to find SOME point along a line perpendicular to line AB, from point D, then
F.x = D.x + (B.y - A.y)
F.y = D.y + (B.x - A.x)
will work.

Resources