Use Newton's method to find square root of a number? - python

Here is my code thus far. I don't know why it doesn't print anything. I hope it isn't because of some stupid mistake.
y = float(raw_input("Enter a number you want square rooted: "))
x = 0
# Newton's Method: y = (x+y)/x + 2
while y > x:
x += 0.1
if x == y/(2*y-1):
print x
else:
pass
Any suggestions or alternatives?
Any help would be greatly appreciated.

Your code doesn't resemble Newton's method at all. Here is code with rewritten logic:
y = float(raw_input("Enter a number you want square rooted: "))
# Solve f(x) = x^2 - y = 0 for x.
# Newton's method: Iterate new_x = x - f(x)/f'(x).
# Note that f'(x) = 2x. Thus new_x = x - (x^2 - y)/(2x).
prevx = -1.0
x = 1.0
while abs(x - prevx) > 1e-10: # Loop until x stabilizes
prevx = x
x = x - (x*x - y) / (2*x)
print(x)
Side note: An alternate but similar way of iteratively approximating the square root is the Babylonian method.

Related

Unexpected output for keras ReLU layer

In the keras documentation, the function keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0.0) is defined as:
f(x) = max_value for x >= max_value,
f(x) = x for threshold <= x < max_value,
f(x) = alpha * (x - threshold) otherwise.
I did a small test with alpha=0.01, threshold=5.0 and max_value=100.0 and for x=5.0 the output I get is f(x)=0.0.
If I am not mistaken, since x == threshold, I should get f(x)=x=5.0.
Can anyone explain please?
Thanks,
Julien
The documentation in the source code is wrong. (And you should be moving to tf.keras instead of keras). It should be,
f(x) = max_value for x >= max_value,
--> f(x) = x for threshold < x < max_value,
f(x) = alpha * (x - threshold) otherwise.
So when your x == threshold it goes to the third case which has a 0 in it (i.e. x - threshold). This is why you get 0.
If you need the behavior documented this line needs to change as,
x = x * tf.cast(tf.greater_equal(x, threshold), floatx())

Access current time step in scipy.integrate.odeint within the function

Is there a way to access what the current time step is in scipy.integrate.odeint?
I am trying to solve a system of ODEs where the form of the ode depends on whether or not a population will be depleted. Basically I take from population x provided x doesn't go below a threshold. If the amount I need to take this timestep is greater than that threshold I will take all of x to that point and the rest from z.
I am trying to do this by checking how much I will take this time step, and then allocating between populations x and z in the DEs.
To do this I need to be able to access the step size within the ODE solver to calculate what will be taken this time step. I am using scipy.integrate.odeint - is there a way to access the time step within the function defining the odes?
Alternatively, can you access what the last time was in the solver? I know it won't necessarily be the next time step, but it's likely a good enough approximation for me if that is the best I can do. Or is there another option I've not thought of to do this?
The below MWE is not my system of equations but what I could come up with to try to illustrate what I'm doing. The problem is that on the first time step, if the time step were 1 then the population will go too low, but since the timestep will be small, initially you can take all from x.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
plt.interactive(False)
tend = 5
tspan = np.linspace(0.0, tend, 1000)
A = 3
B = 4.09
C = 1.96
D = 2.29
def odefunc(P,t):
x = P[0]
y = P[1]
z = P[2]
if A * x - B * x * y < 0.6:
dxdt = A/5 * x
dydt = -C * y + D * x * y
dzdt = - B * z * y
else:
dxdt = A * x - B * x * y
dydt = -C * y + D * x * y
dzdt = 0
dPdt = np.ravel([dxdt, dydt, dzdt])
return dPdt
init = ([0.75,0.95,100])
sol = odeint(odefunc, init, tspan, hmax = 0.01)
x = sol[:, 0]
y = sol[:, 1]
z = sol[:, 2]
plt.figure(1)
plt.plot(tspan,x)
plt.plot(tspan,y)
plt.plot(tspan,z)
Of course you can hack something together that might work.
You could log t but you have to be aware that the values
might not be constantly increasing. This depends on the ODE algorithm and how it works (forward, backward, and central finite differences).
But it will give you an idea where about you are.
logger = [] # visible in odefunc
def odefunc(P,t):
x = P[0]
y = P[1]
z = P[2]
print(t)
logger.append(t)
if logger: # if the list is not empty
if logger[-1] > 2.5: # then read the last value
print('hua!')
if A * x - B * x * y < 0.6:
dxdt = A/5 * x
dydt = -C * y + D * x * y
dzdt = - B * z * y
else:
dxdt = A * x - B * x * y
dydt = -C * y + D * x * y
dzdt = 0
dPdt = np.ravel([dxdt, dydt, dzdt])
return dPdt
print(logger)
As pointed out in the another answer, time may not be strictly increasing at each call to the ODE function in odeint, especially for stiff problems.
The most robust way to handle this kind of discontinuity in the ode function is to use an event to find the location of the zero of (A * x - B * x * y) - 0.6 in your example. For a discontinuous solution, use a terminal event to stop the computation precisely at the zero, and then change the ode function. In solve_ivp you can do this with the events parameter. See the solve ivp documentation and specifically the examples related to the cannonball trajectories. odeint does not support events, and solve_ivp has an LSODA method available that calls the same Fortran library as odeint.
Here is a short example, but you may want to additionally check that sol1 reached the terminal event before solving for sol2.
from scipy.integrate import solve_ivp
tend = 10
def discontinuity_zero(t, y):
return y[0] - 10
discontinuity_zero.terminal = True
def ode_func1(t, y):
return y
def ode_func2 (t, y):
return -y**2
sol1 = solve_ivp(ode_func1, t_span=[0, tend], y0=[1], events=discontinuity_zero, rtol=1e-8)
t1 = sol1.t[-1]
y1 = [sol1.y[0, -1]]
print(f'time={t1} y={y1} discontinuity_zero={discontinuity_zero(t1, y1)}')
sol2 = solve_ivp(ode_func2, t_span=[t1, tend], y0=y1, rtol=1e-8)
plt.plot(sol1.t, sol1.y[0,:])
plt.plot(sol2.t, sol2.y[0,:])
plt.show()
This prints the following, where the time of the discontinuity is accurate to 7 digits.
time=2.302584885712467 y=[10.000000000000002] discontinuity_zero=1.7763568394002505e-15

Python How to get the value of one specific point of derivative?

from sympy import *
x = Symbol('x')
y = x ** 2
dx = diff(y, x)
This code can get the derivative of y.
It's easy dx = 2 * x
Now I want to get the value of dx for x = 2.
Clearly, dx = 2 * 2 = 4 when x = 2
But how can I realize this with python codes?
Thanks for your help!
Probably the most versatile way is to lambdify:
sympy.lambdify creates and returns a function that you can assign to a name, and call, like any other python callable.
from sympy import *
x = Symbol('x')
y = x**2
dx = diff(y, x)
print(dx, dx.subs(x, 2)) # this substitutes 2 for x as suggested by #BugKiller in the comments
ddx = lambdify(x, dx) # this creates a function that you can call
print(ddx(2))
According to SymPy's documentation you have to evaluate the value of the function after substituting x with the desired value:
>>> dx.evalf(subs={x: 2})
4.00000000000000
or
>>> dx.evalf(2, subs={x: 2})
4.0
to limit the output to two digits.

How to use a variable as a divisor in PuLP

I was trying to resolve a LP problem with a constraint that is calculated by dividing variable A by variable B.
The simple version of the problem is as below:
The product is made by two materials (A and B)
% of A should be greater than 50%
% of B should be less than 40%
Total amount of A and B are 100
Objective: What's the minimum amount of A?
The code is like:
from pulp import *
prob = LpProblem('Simple problem', LpMinimize)
x = LpVariable('x', 0, None, 'Integer')
y = LpVariable('y', 0, None, 'Integer')
prob += x
prob += x / (x + y) > 0.5 # <== Where the error happens
prob += y / (x + y) < 0.4
prob += x + y == 100
prob.solve()
print 'Result: %s' % LpStatus[prob.status]
print 'Amount of A: %s' % value(prob.objective)
However I'm getting an error message saying:
TypeError: Expressions cannot be divided by a non-constant expression
It looks like PuLP does not support variable as divisor.
https://github.com/coin-or/pulp/blob/master/src/pulp/pulp.py#L800
Any idea? If PuLP is not the right library to use, I'm happy to switch to any library that fits in.
UPDATE 27 Nov 2015
For some reason, the sample above does not make sense (not working as expected). I am very newbie to this library. Maybe it's not the right one to solve my problem at all. So if any one has suggestions of other libraries, it'd be appreciated.
BTW, Koen Peters's advice below is great. The error is gone after taking his advice. Thank you.
Linear Programming doesn't understand divisions, hence the error :)
You have to reformulate it so that the division is formulated linearly.
In this case:
prob += x / (x + y) > 0.5
prob += y / (x + y) < 0.4
is equivalent to:
prob += x > 0.5 * (x + y)
prob += y < 0.4 * (x + y)
Which are linear constraints.
Good luck!
I felt like zero shouldn't be allowed in my solution — and I included a variable that was the sum of x and y (think you're referring to it as A).
from pulp import LpProblem, LpStatus, LpVariable
from pulp import LpMinimize, LpMaximize, lpSum, value
# I feel like zero shouldn't be allowed for lower bound...
x = LpVariable("x", lowBound=1, cat="Integer")
y = LpVariable("y", lowBound=1, cat="Integer")
z = LpVariable("z", lowBound=1, cat="Integer")
model = LpProblem("Divison problem", LpMinimize)
model += x
model += z == x + y
model += z == 100
# Rather than division, we can use multiplication
model += x >= z * 0.5
model += y <= z * 0.4
model.solve()
print(LpStatus[model.status])
print(f"""
x = {int(x.varValue):>3} # 60
y = {int(y.varValue):>3} # 40
z = {int(z.varValue):>3} # 100
""")

defining integral using trapezoidal rule(beginner)

My programm aims in defining the integral of a given function between two numbers (x1,x2),using n trapezoids.As it seems,my department's auto evaluating programm gives different answers than the ones of mine.Problem is that i cant find anything wrong in my code...
def funct(x):
val= -(1./6)*(x-1)*(x-2)*(x+2)*(x-4)
return val
x1,x2,n=input()
Dx=float(x2-x1)/n
Sum=0
i=x1+Dx
while i<x2:
val=funct(i)
Sum+=val
i+=Dx
Sum=2*Sum
val1=funct(x1)
val2=funct(x2)
S=(Dx/2)*(val1+val2+Sum)
print "%.3f" %S
Due to rounding issues, your while cycle always includes last value of x, try using exact integer arithmetic
x0, x1 = -88.787529, 83.494648
n = 1942
dx = (x1-x0)/n
s = 0
i = 1
while i < n:
# if we allow i == n, in the following row we'll have
# x0 + n*dx = x0 + n * (x1-x0) / n = x0 + x1 - x0 = x1
# but we want to exclude the last term
s = s + funct(x0+i*dx)
i = i + 1
result = (s + funct(x0)/2.0 + funct(x1)/2.0)*dx
I know this is probably some sort of homework question, but in general, don't reinvent the wheel:
import numpy
def funct(x):
return -(1./6)*(x-1)*(x-2)*(x+2)*(x-4)
x1, x2 = -88.787529, 83.494648
n = 1942
# n "panels", n+1 points
x = numpy.linspace(x1, x2, n+1)
y = funct(x)
result = numpy.trapz(y, x)

Categories

Resources