How to let the user define the function - Python - Bisection Method - python

I have written the following code to find the roots of an equation using the bisection method.
def f(x):
return x**3-5
#computes f(x) intercept with the bisection method
#err - a small floating number that tells you your accuracy
def bisection(low, high, err):
mid = (high+low)/2
while(abs(f(mid)) > err):
print ('low =', low, 'high =', high, 'mid= ', mid)
if f(mid) > 0:
high = mid
elif f(mid) < 0:
low = mid
mid = (high + low)/2
return mid
print (bisection(0, 100, 0.001))
The code executes the method without a problem. However, I would like to find a way to prompt the user to input their own equations to solve rather than it already pre-programmed.
I appreciate any input you have.
Thank you very much for your help!

from sympy import *
eqn=sympify(input('Eqn'))
f=lambda x:eqn.subs({'x':x})

You can prompt the user for coefficients for a polynomial:
print('a x^3 + b x^2 + c x + d')
a = input('>a')
b = input('>b')
c = input('>c')
d = input('>d')
and then you input this into the function:
def f(x, a, b, c, d):
return a*x**3 + b*x**2 + c * x + d
A better way (continuing from #SmartManoj 's answer):
from sympy import *
equation = input('Your equation > ')
eqn=sympify(equation)
f=lambda x:eqn.subs({'x':x})
If you're using python 2, use raw_input('Your equation > ') instead.

There is no need for Sympy, eval is native.
def f(expr, x)
return eval(expr)
for i in range(10):
print f("x * x", i)

Related

Equation solving using bisection method using python

I wrote a python code to find root of 2*x-4 using bisection method
def func(x):
return 2*x-4
def bisection(a,b):
if (func(a) * func(b) >= 0):
print("You have not assumed right a and b\n")
return
c = a
while ((b-a) >= 0.01):
c = (a+b)/2
if (func(c) == 0.0):
break
if (func(c)*func(a) < 0):
b = c
else:
a = c
print("The value of root is : ","%.0f"%c)
a =-2
b = 4
bisection(a, b)
Now i want that the function input should be given by the user in the form of mx+n where m and n are integers. Can anyone help how can i do that ?
m, n = list(map(int, input("Please enter the value of [m] [n] for f(x) = mx +n: ").split()))
def Input():
a, b = list(map(int, input("Enter values of [a] [b]: ").split()))
if f(a)*f(b)<0:
Bisection(a, b)
else:
print("Oops! The root of function doesn't belong to the above domain\nPlease try to again:")
Input()
def f(x):
return m*x + n
def Bisection(a, b):
c = (a+b)/2
if f(c)*f(b)<0:
Bisection(c, b)
elif f(c)*f(a)<0:
Bisection(c, a)
elif f(c)==0:
print(c)
Input()
See we know that Bisection, Newton-Raphson, or most of all Numerical methods are the iteration processes so better we use function inside of function: f(f(f(f.....) Of course! by checking the conditions.
Here, I have used elif f(c)==0 this is something which we can't use for quadratic/cubic or higher-order polynomials because getting the exact root will not be possible for all the types of equations say like f(x) = mx^2 - n where m, n > 0 However, we can define the iterations to be performed.
By asking like Please enter the number of iterations to be performed:

Finding f(g) from f(x) and g(x) numerically

I'm studying an article where there are two functions:
$e(x) = (e_0/8)\cdot[(2x^3 + x)\sqrt{(1 + x^2)} − \sinh^{−1}(x)]$
$p(x) = (e_0/24)\cdot[(2x^3 - 3x)\sqrt{(1 + x^2)} + 3\sinh^{−1}(x)]$
The article ask me to find numerically $e(p)$ starting from these two expressions. The article suggests me to use a "root-finding routine" but I have no idea how to implement the code. Can someone please help me? I need, possibly, a more general numerical algorithm. (I'm writing in Python). I tried with pynverse library but it is not sufficiently accurate.
I solved my problem with the following code (it uses the bisection root finding):
import numpy as np
def bisection(func,a,b,N):
if func(a)*func(b) >= 0:
# No solutions.
return None
a_n = a
b_n = b
for n in range(1,N+1):
m_n = (a_n + b_n)/2
f_m_n = func(m_n)
if func(a_n)*f_m_n < 0:
a_n = a_n
b_n = m_n
elif func(b_n)*f_m_n < 0:
a_n = m_n
b_n = b_n
elif f_m_n == 0:
# Found exact solution.
return m_n
else:
print("No solutions with bisection. Return 'None'.")
return None
return (a_n + b_n)/2
def eden (pressure):
e = lambda x : (1/8)*((2*x**3 + x)*(1 + x**2)**(1/2) - np.arcsinh(x))
p = lambda x : (2/24)*((2*x**3 - 3*x)*(1 + x**2)**(1/2) + 3*np.arcsinh(x)) - pressure
x_p = bisection(p, -1e3, 1e3, 1000)
return e(x_p)

Quadratic Equation Solver Math Domain Error

I am trying to make a quadratic equation solver, but each time I run it, it displays a math domain error. Can anyone help me fix it? I am sorta new to Python.
import math
def quadratic(a, b, c):
return [((-b + i * math.sqrt(b**2 - 4*a*c)) / (2 * a)) for i in (-1,1)]
a = int(input("What is the value of a? "))
b = int(input("What is the value of b? "))
c = int(input("What is the value of c? "))
print(quadratic(a, b, c))
Your code works in general, but should check if b**4-a*c is positive. That is (probably) why you are getting an error
def quadratic(a, b, c):
D = b**2 - 4*a*c
if D >= 0:
return [((-b + i * math.sqrt(D)) / (2 * a)) for i in (-1, 1)]
else:
return None

Mathematical Function in Python does not work properly?

def trapezoidal(f, a, b, n):
h = float(b - a) / n
s = 0.0
s = s + f(a)
i=1
while i<=n-1:
s = s + f(a + i*h)
i= i +1
s = s + f(b)
s = s*h
return s
def f(x):
x = float(x)
return (-1/6)*(x-1)*(x-2)*(x+2)*(x-4)
lel = trapezoidal(f, -2, 4, 10)
print ("%.3f" % lel)
ok = f(-0.8)
print ok
I am trying to build a program that calculates integrals using the trapezoid rule. When I do it on paper it works fine but my f function does not work properly. For example f(-0.8) should be equal to 4.8384 but when I run it shows 29.0304. Please help?
If you are using Python 2.x
def f(x):
x = float(x)
return (-1/6)*(x-1)*(x-2)*(x+2)*(x-4)
The first term in your expression is doing integer division. The result of that division will be promoted to float later during the multiplication, but it is too late by then.
>>> (-1/6)
-1
You need to keep everything in floats
def f(x):
x = float(x)
return (-1.0/6.0)*(x-1)*(x-2)*(x+2)*(x-4)
Try
return (-1.0/6)*(x-1)*(x-2)*(x+2)*(x-4)

Python, square root function?

I have compiled multiple attempts at this and have failed miserably, some assistance would be greatly appreciated.
The function should have one parameter without using the print statement. Using Newton's method it must return the estimated square root as its value. Adding a for loop to update the estimate 20 times, and using the return statement to come up with the final estimate.
so far I have...
from math import *
def newton_sqrt(x):
for i in range(1, 21)
srx = 0.5 * (1 + x / 1)
return srx
This is not an assignment just practice. I have looked around on this site and found helpful ways but nothing that is descriptive enough.
This is an implementation of the Newton's method,
def newton_sqrt(val):
def f(x):
return x**2-val
def derf(x):
return 2*x
guess =val
for i in range(1, 21):
guess = guess-f(guess)/derf(guess)
#print guess
return guess
newton_sqrt(2)
See here for how it works. derf is the derivative of f.
I urge you to look at the section on Wikipedia regarding applying Newton's method to finding the square root of a number.
The process generally works like this, our function is
f(x) = x2 - a
f'(x) = 2x
where a is the number we want to find the square root of.
Therefore, our estimates will be
xn+1 = xn - (xn2 - a) / (2xn)
So, if your initial guess is x<sub>0</sub>, then our estimates are
x1 = x0 - (x02 - x) / (2x0)
x2 = x1 - (x12 - x) / (2x1)
x3 = x2 - (x22 - x) / (2x2)
...
Converting this to code, taking our initial guess to be the function argument itself, we would have something like
def newton_sqrt(a):
x = a # initial guess
for i in range(20):
x -= (x*x - a) / (2.0*x) # apply the iterative process once
return x # return 20th estimate
Here's a small demo:
>>> def newton_sqrt(a):
... x = a
... for i in range(20):
... x -= (x*x - a) / (2.0*x)
... return x
...
>>> newton_sqrt(2)
1.414213562373095
>>> 2**0.5
1.4142135623730951
>>>
>>> newton_sqrt(3)
1.7320508075688774
>>> 3**0.5
1.7320508075688772
In your code you are not updating x (and consequently srx) as you loop.
One problem is that x/1 is not going to do much and another is that since x never changes all the iterations of the loop will do the same.
Expanding on your code a bit, you could add a guess as a parameter
from math import *
def newton_sqrt(x, guess):
val = x
for i in range(1, 21):
guess = (0.5 * (guess + val / guess));
return guess
print newton_sqrt(4, 3) # Returns 2.0
You probably want something more like:
def newton_sqrt(x):
srx = 1
for i in range(1, 21):
srx = 0.5 * (srx + x/srx)
return srx
newton_sqrt(2.)
# 1.4142135623730949
This both: 1) updates the answer at each iteration, and 2) uses something much closer to the correct formula (ie, no useless division by 1).

Categories