Hi I make some derivative Program on Python, but the result isn't same as what i expected,
This is the result as what i want to be :
f(x) = x^2 - 8x + 25
f'(x) = 2x -8
0 = 2x - 8
8 = 2x
4 = x
x = 4
i want x to be equal to 4
and here's the code :
import sympy as sp
from sympy import *
p = 8
m = 25
f = x**2 - p*x + m
f_prime = f.diff(x)
f = lambdify(x, f)
f_prime = lambdify(x, f_prime)
f_prime(2)
the result is -4
how to solve this problem?
Thankyou
You have to define x as a symbolic variable (otherwise code will not compile), lambdify f_prime and solve the equation f_prime(x) = 0
from sympy import *
p = 8
m = 25
x = symbols('x')
f = x**2 - p*x + m
f_prime = f.diff(x)
print (f_prime)
f_prime = lambdify(x, f_prime)
print(solve(f_prime(x))[0])
2*x - 8
4
Related
I am trying to write a program about Simpson's Law.What I am trying to do is use as error as shown in this picture:
.
In the code i write the Ih is my f1 and Ih/2 is my f2.If the error doesnt happen then the steps get halved.
However I get this error
Traceback (most recent call last):
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\example.py", line 22, in <module>
sim2 = simps(f2, x2)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 436, in simps
return simpson(y, x=x, dx=dx, axis=axis, even=even)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 542, in simpson
last_dx = x[slice1] - x[slice2]
IndexError: index -1 is out of bounds for axis 0 with size 0
Process finished with exit code 1
My code is
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, int(N/2))
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = int(N/2)
print(sim1)
I wasnt expecting any error,and basically expecting to calculate correctly.
When you reduce the grid step by half h -> h/2, the number of grid steps in turn grows N -> 2 * N, so you have to make two changes in your code:
Define x2 to have twice as many elements as x1
x2 = np.linspace(a, b, 2 * N)
Update N to be twice it was on the previous iteration
N = 2 * N
The resulting code would be
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, 2 * N)
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = 2 * N
print(sim1)
And this prints the value
87.9765411043221
with error consistent with the threshold
abs(sim1 - sim2) = 4.66441463231604e-9
#DmitriChubarov's solution is correct. However, your implementation is very inefficient: it does double the work it needs to. Also, simps is deprecated, you should be using proper exponential notation, and your function expression can be simplified. For an equivalent error-free algorithm that still doubles the input array length on each iteration but doesn't throw away the intermediate result,
import numpy as np
from scipy.integrate import simpson
a = 0
b = 2*np.pi
N = 100
ra = 0.1 # ρα
R = 0.05
fa = np.radians(35) # φα
za = 0.4
aa = np.linalg.norm((ra, R, za))
error = 5e-9
sim1 = np.nan
while True:
x = np.linspace(a, b, N)
f = (aa**2 - 2*ra*R*np.cos(x - fa))**-1.5
sim2 = simpson(f, x)
if np.abs(sim1 - sim2) < error:
break
sim1 = sim2
N *= 2
print(sim1)
When I modified your code by adding two lines to print(len(x1), len(f1)) and print(len(x2), len(f2)), I got these results:
Output:
length of x1 and f1: 100 100
length of x2 and f2: 50 50
length of x1 and f1: 50 50
length of x2 and f2: 25 25
length of x1 and f1: 25 25
length of x2 and f2: 12 12
length of x1 and f1: 12 12
length of x2 and f2: 6 6
length of x1 and f1: 6 6
length of x2 and f2: 3 3
length of x1 and f1: 3 3
length of x2 and f2: 1 1
length of x1 and f1: 1 1
length of x2 and f2: 0 0
as you can see the length decreases each loop because N decreases and ends with an empty list length of x2 and f2: 0 0 and this causes the error you have had. To fix the issue of 'the empty list' I suggest that you duplicate N; this means using N*2 instead of N/2.
Here is the current extended euclidean algorithm I found online :
def euclideEtendu(bNombre, aModulo):
""" Algorithme d'Euclide étendu, permettant de connaître:
PGCD
Coefficients de Bézout (u, v)
Inverse modulaire de B modulo A ---> B * B^-1 mod A = 1
"""
modulo = aModulo
x = 0
y = 1
u = 1
v = 0
while bNombre != 0:
q = aModulo // bNombre
r = aModulo % bNombre
m = x - u * q
n = y - v * q
aModulo = bNombre
bNombre = r
x = u
y = v
u = m
v = n
' retourne (pgcd, u, v, inverse modulaire '
return (aModulo, x, y, x % modulo)
Here is an example :
>>> euclideEtendu(17, 13)
(1, -3, 4, 10)
And here is what I want it to return :
>>> euclideEtendu(17, 13)
1 = 13 - 3 * 4
1 = 13 - 3 * (17 - 1 * 13)
1 = 4 * 13 - 3 * 17
17x + 13y = 1
17 * -3 + 13 * 4 = 1
So adding all the "steps".
Thanks in advance.
Getting wrong output for this equation. Can someone review my code?
from math import cos
from math import sin
from math import pi
a0 = int(input("a0:"))
b0 = int(input("b0:"))
N = int(input("N:"))
L = int(input("L:"))
X = int(input("X:"))
n = 0
an = a0
bn = b0
y=0
for i in range(N):
an = an + 10 # since our first value would An = A0 +10 , we could just loop the values by adding 10 to it
bn = bn * 10
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
print(y)
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
There's never any change in the n variable! Given that n starts (and remains) at 0, you always calculate
an * cos(0) + bn * sin(0) == an * 1 + bn * 0 == an
Furthermore you need to add the result to the y variable, not just assign it. And you need to prime the y variable with a0.
an = a0
bn = b0
c = 0
d = pi * X / L # precalculating for efficiency
y = a0
for i in range(N):
an = an + 10
bn = bn * 10
c = c + d
y = y + an * cos(c) + bn * sin(c)
print(y)
Maybe I don't want machine learning and I might just be looking for a term to find some working examples, Basically, I have 'x' values and I want to figure out what formula(s) have a greater than 75% success rate overall the values given.
Let's say, for example, I have these values
1 2 3 6
7 9 1 63
10 1 2 20
9 3 3 33
What I'm trying to develop is an algorithm that will basically permiuntate all values in [0],[1],[2] by all basic math functions ( + / * - ) and end up with [3]. So I know if the first 3 values are multiplied [0][1][2] = [3] and since [3] fails it has hit my 75% rate.
This actually feels like a rare reasonable use for eval:
from itertools import product
from statistics import mean
from typing import Sequence
def build_expression(ops: Sequence[str], values: Sequence[int]) -> str:
return " ".join(
c for t in zip(map(str, values), ops) for c in t
) + " " + str(values[-1])
def apply_ops(ops: Sequence[str], values: Sequence[int]) -> int:
"""apply_ops(['+', '-'], [1, 2, 3]) == 1 + 2 - 3"""
assert len(ops) + 1 == len(values)
return eval(build_expression(ops, values))
def score_op_accuracy(
ops: Sequence[str],
data: Sequence[Sequence[int]]
) -> float:
assert all(len(ops) + 2 == len(values) for values in data)
return mean(
100.0
if apply_ops(ops, values[:-1]) == values[-1] else
0.0
for values in data
)
data = [
[1, 2, 3, 6],
[7, 9, 1, 63],
[10, 1, 2, 20],
[9, 3, 3, 33],
]
possible_ops = list(product(*([list("+-*/%")] * 2)))
valid_ops = [
ops for ops in possible_ops if score_op_accuracy(ops, data) >= 75.0
]
for ops in valid_ops:
for values in data:
left = values[:-1]
right = values[-1]
result = apply_ops(ops, left)
equals = "==" if right == result else "!="
print(f"{build_expression(ops, left)} {equals} {result}")
print("-" * 20)
prints:
1 * 2 * 3 == 6
7 * 9 * 1 == 63
10 * 1 * 2 == 20
9 * 3 * 3 != 81
--------------------
def plus(x,y):
return x+y
def minus(x,y):
return x-y
def times_by(x,y):
return x*y
def divided_by(x,y):
return x/y
def find_solution(l):
x,y,z,targ = l
for func1 in [plus, minus, times_by, divided_by]:
for func2 in [plus, minus, times_by, divided_by]:
if func2(func1(x,y), z) == targ :
print(f'({x} {func1.__name__} {y}) {func2.__name__} {z} = {targ}')
if func1(x, func2(y,z)) == targ:
print(f'{x} {func1.__name__} ({y} {func2.__name__} {z}) = {targ}')
find_solution([7, 9, 1, 63])
output:
(7 times_by 9) times_by 1 = 63
7 times_by (9 times_by 1) = 63
(7 times_by 9) divided_by 1 = 63
7 times_by (9 divided_by 1) = 63
I'll leave some edge cases and errors (dividing by zero, notably) to you
I'm not 100% sure if this is what you want to do, but here's what I came up with
df
0 1 2 3
0 1 2 3 6
1 7 9 1 63
2 10 1 2 20
3 9 3 3 33
Code
from itertools import permutations
for index, data in df.iterrows():
t = []
for p in permutations(data[0:3]):
t.extend([
p[0] + p[1] + p[2],
p[0] - p[1] - p[2],
p[0] / p[1] / p[2],
p[0] * p[1] * p[2]])
if np.mean([x==data[3] for x in t[0::4]]) >=.75:
print(data.values, 'sum')
elif np.mean([x==data[3] for x in t[1::4]]) >=.75:
print(data.values, 'subtract')
elif np.mean([x==data[3] for x in t[2::4]]) >=.75:
print(data.values, 'divide')
elif np.mean([x==data[3] for x in t[4::4]]) >=.75:
print(data.values, 'multiply')
Output
[1 2 3 6] sum
It's maybe a linear regression problem. Through linear regression, you can get a formula similar to the following:
y = a * x1 + b * x2 + c * x3 + d
a, b, c and d are the parameters that need to be learned.
First, copy your data to test.txt:
Then, read and train:
# Import libraries
import pandas as pd
from sklearn.linear_model import LinearRegression
# Read data to a DataFrame
df = pd.read_csv('test.txt', header=None, sep=' ')
df.columns = list('ABCD')
# Train a linear regression model
reg = LinearRegression()
reg.fit(df[['A', 'B', 'C']], df['D'])
# Get score, i.e. accuracy
print(reg.score(df[['A', 'B', 'C']], df['D'])) # 1.0
# Get model's prediction
print(reg.predict(df[['A', 'B', 'C']])) # [ 6. 63. 20. 33.]
# Get parameters
print(reg.coef_, reg.intercept_) # [2.54761905 6.61904762 2.30952381] -16.71428571428573
So, the final formula is:
y = 2.54761905 * x1 + 6.61904762 * x2 + 2.30952381 * x3 - 16.71428571428573
If you have more data, this model will be more generalized.
I'd like to implement a geometric progression using Python / Pandas / Numpy.
Here is what I did:
N = 10
n0 = 0
n_array = np.arange(n0, n0 + N, 1)
u = pd.Series(index = n_array)
un0 = 1
u[n0] = un0
for n in u.index[1::]:
#u[n] = u[n-1] + 1.2 # arithmetic progression
u[n] = u[n-1] * 1.2 # geometric progression
print(u)
I get:
0 1.000000
1 1.200000
2 1.440000
3 1.728000
4 2.073600
5 2.488320
6 2.985984
7 3.583181
8 4.299817
9 5.159780
dtype: float64
I wonder how I could avoid to use this for loop.
I had a look at
https://fr.wikipedia.org/wiki/Suite_g%C3%A9om%C3%A9trique
and found that u_n can be expressed as: u_n = u_{n_0} * q^{n-n_0}
So I did that
n0 = 0
N = 10
n_array = np.arange(n0, n0 + N, 1)
un0 = 1
q = 1.2
u = pd.Series(map(lambda n: un0 * q ** (n - n0), n_array), index = n_array)
That's ok... but I'm looking for a way to define it in a recurrent way like
u_n0 = 1
u_n = u_{n-1} * 1.2
But I don't see how to do it using Python / Pandas / Numpy... I wonder if it's possible.
Another possibility, that is probably more computationally efficient than using exponentiation:
>>> N, un0, q = 10, 1, 1.2
>>> u = np.empty((N,))
>>> u[0] = un0
>>> u[1:] = q
>>> np.cumprod(u)
array([ 1. , 1.2 , 1.44 , 1.728 , 2.0736 ,
2.48832 , 2.985984 , 3.5831808 , 4.29981696, 5.15978035])
Use numpy.logspace
>>> import numpy
>>> N=10
>>> u=numpy.logspace(0,N,num=N, base=1.2, endpoint=False)
>>> print u
[ 1. 1.2 1.44 1.728 2.0736 2.48832
2.985984 3.5831808 4.29981696 5.15978035]
Here is how it works for me in a Pandas series:
N = 10
n0 = 0
n_array = np.arange(n0, n0 + N, 1)
u = pd.Series(index = n_array)
u[n0] = 1
q = 1.2
# option 1:
u = pd.Series(u[n0]*q**(u.index.values - n0), index = n_array)
# or option 2 with cumprod
u[1:] = q
u = u.cumprod()
Just defining u(u0, q, n) function should work:
def u(u0, q, n):
return u0 if n==0 else q*u(u0, q, n-1)
Itertools helps:
from itertools import accumulate
import operator
import pandas as pd
d, f, n = 1.2, 1, 10 # degree, first element, number
pd.Series([* accumulate([f]+[d] * (n-1), func = operator.mul)])
result is:
0 1.000000
1 1.510000
2 2.280100
3 3.442951
4 5.198856
5 7.850273
6 11.853912
7 17.899406
8 27.028104
9 40.812437
dtype: float64
I think #Ashish's solution with np.cumprod is the simplest but if you are willing to define a generator somewhere then this is probably the most computationally efficient solution:
def geometric_series_generator(x, r, n):
"""Generate a geometric series of length n, starting
at x and increasing by the ratio r.
"""
for i in range(n):
yield x
x = x*r
N = 10
u0 = 1
r = 1.2
gen = geometric_series_generator(u0, r, N)
geom_series = np.fromiter(gen, float, count=N)
print(pd.Series(geom_series, index=np.arange(0, N, 1)))
Output:
0 1.000000
1 1.200000
2 1.440000
3 1.728000
4 2.073600
5 2.488320
6 2.985984
7 3.583181
8 4.299817
9 5.159780
dtype: float64