Newton's Method with Looping Recursion - python

I have the code here all figured out. The directions say to "Convert Newton’s method for approximating square roots in Project 1 to a recursive function named newton. (Hint: The estimate of the square root should be passed as a second argument to the function.)"
How would I work out these directions according to my code here?
# Initialize the tolerance
TOLERANCE = 0.000001
def newton(x):
"""Returns the square root of x."""
# Perform the successive approximations
estimate = 1.0
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= TOLERANCE:
break
return estimate
def main():
"""Allows the user to obtain square roots."""
while True:
# Receive the input number from the user
x = input("Enter a positive number or enter/return to quit: ")
if x == "":
break
x = float(x)
# Output the result
print("The program's estimate is", newton(x))
print("Python's estimate is ", math.sqrt(x))
if __name__ == "__main__":
main()

essentialy you need to convert the while True: part of your code in the recursive function
something like this:
def newton(x, estimate):
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference > TOLERANCE:
estimate = newton(x, estimate)
return estimate
notice how the condition is different so you check if you need to continue, after you don't the final value is carried along out of the recursion and returned

This is the full code of the answer and comments discussion of jimakr
I utilized this in the def newton function (credits to NP890):
def newton(x, estimate = 1.0):
I also import math module to utilize the math.sqrt :
def main():
"""Allows the user to obtain square roots."""
while True:
import math
#Continuation
THE FULL CODE:
# Initialize the tolerance
TOLERANCE = 0.000001
def newton(x, estimate = 1.0):
"""Returns the square root of x."""
# Perform the successive approximations
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference > TOLERANCE:
estimate = newton(x, estimate)
return estimate
def main():
"""Allows the user to obtain square roots."""
while True:
import math
# Receive the input number from the user
x = input("Enter a positive number or enter/return to quit: ")
if x == "":
break
x = float(x)
# Output the result
print("The program's estimate is", newton(x))
print("Python's estimate is ", math.sqrt(x))
if __name__ == "__main__":
main()

Related

Restructure Newton's method [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed yesterday.
Improve this question
Restructure Newton's method (Case Study: Approximating Square Roots) by decomposing it into three cooperating functions: newton, limitReached, and improveEstimate.
The newton function can use either the recursive strategy of Project 2 or the iterative strategy of the Approximating Square Roots Case Study. The task of testing for the limit is assigned to a function named limitReached, whereas the task of computing a new approximation is assigned to a function named improveEstimate. Each function expects the relevant arguments and returns an appropriate value.
# Modify the code below
"""
Program: newton.py
Author: Ken
Compute the square root of a number.
1. The input is a number.
2. The outputs are the program's estimate of the square root
using Newton's method of successive approximations, and
Python's own estimate using math.sqrt.
"""
import math
# Receive the input number from the user
x = float(input("Enter a positive number: "))
# Initialize the tolerance and estimate
tolerance = 0.000001
estimate = 1.0
# Perform the successive approximations
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= tolerance:
break
# Output the result
print("The program's estimate is", estimate)
print("Python's estimate is ", math.sqrt(x))
This is what I have so far and it kind of works. I'm new to python and stuck on improveEstimate. I'm not sure what to do.
import math
tolerance = 0.000001
def newton(x):
estimate = 1.0
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= tolerance:
break
return estimate
def limitReached(x, estimate):
difference=x-estimate ** 2
return abs(difference) <= 0.000001
def improveEstimate(x, estimate):
while True:
estimate = (estimate + x / estimate) / 2
difference = abs(x - estimate ** 2)
if difference <= tolerance:
break
return estimate
def main():
while True:
x = input("Enter a positive number or enter/return to quit: ")
if x == "":
break
x = float(x)
print("The program's estimate is", newton(x))
print("Python's estimate is ", math.sqrt(x))
if __name__ == "__main__":
main()

Adjusting the mean and standard deviation of a list of random numbers?

I have to create a list of random numbers (with decimals) in the range between -3 and 3. The problem is that the list must have a mean of 0 and a standard deviation of 1. How can I adjust the mean and standard deviation parameters? Is there a function I can use?
I was already able to create a list of random numbers between -3 and 3.
import random
def lista_aleatorios(n):
lista = [0] * n
for i in range(n):
lista[i] = random.uniform(-3, 3)
return lista
print("\nHow many numbers do you want?: ")
n = int(input())
print (lista_aleatorios(n))
The function random.normalvariate(mu, sigma) allows you to specify the mean and the stdev for normally distributed random variables.
Use random.gauss, then scale:
import numpy as np
from random import gauss
def bounded_normal(n, mean, std, lower_bound, upper_bound):
# generate numbers between lower_bound and upper_bound
result = []
for i in range(n):
while True:
value = gauss(mean, std)
if lower_bound < value < upper_bound:
break
result.append(value)
# modify the mean and standard deviation
actual_mean = np.mean(result)
actual_std = np.std(result)
mean_difference = mean - actual_mean
std_difference = std / actual_std
new_result = [(element + mean_difference) * std_difference for element in result]
return new_result
Ok, here is quick way to solution (if you want to use truncated gaussian). Set boundaries and desired stddev. I assume mean is 0. Then quick-and-crude code to do binary search for distribution sigma, solving for non-linear root (brentq() should be used in production code). All formulas are taken from Wiki page on Truncated Normal. It (sigma) shall be larger than desired stddev due to the fact, that truncation removes random values which contribute to large stddev. Then we do quick sampling test - and mean and stddev are close to desired values but never exactly equal to them. Code (Python-3.7, Anaconda, Win10 x64)
import numpy as np
from scipy.special import erf
from scipy.stats import truncnorm
def alpha(a, sigma):
return a/sigma
def beta(b, sigma):
return b/sigma
def xi(x, sigma):
return x/sigma
def fi(xi):
return 1.0/np.sqrt(2.0*np.pi) * np.exp(-0.5*xi*xi)
def Fi(x):
return 0.5*(1.0 + erf(x/np.sqrt(2.0)))
def Z(al, be):
return Fi(be) - Fi(al)
def Variance(sigma, a, b):
al = alpha(a, sigma)
be = beta(b, sigma)
ZZ = Z(al, be)
return sigma*sigma*(1.0 + (al*fi(al) - be*fi(be))/ZZ - ((fi(al)-fi(be))/ZZ)**2)
def stddev(sigma, a, b):
return np.sqrt(Variance(sigma, a, b))
m = 0.0 # mean
s = 1.0 # this is what we want
a = -3.0 # left boundary
b = 3.0 # right boundary
#print(stddev(s , a, b))
#print(stddev(s + 0.1, a, b))
slo = 1.0
shi = 1.1
stdlo = stddev(slo, a, b)
stdhi = stddev(shi, a, b)
sigma = -1.0
while True: # binary search for sigma
sme = (slo + shi) / 2.0
stdme = stddev(sme, a, b)
if stdme - s == 0.0:
sigma = stdme
break
elif stdme - s < 0.0:
slo = sme
else:
shi = sme
if shi - slo < 0.0000001:
sigma = (shi + slo) / 2.0
break
print(sigma) # we got it, shall be slightly bigger than s, desired stddev
np.random.seed(73123457)
rvs = truncnorm.rvs(a, b, loc=m, scale=sigma, size=1000000) # quick sampling test
print(np.mean(rvs))
print(np.std(rvs))
For me it printed
sigma = 1.0153870105743408
mean = -0.000400729471992301
stddev = 1.0024267696681475
with different seed or sequence length you might get output like
1.0153870105743408
-0.00015923177289006116
0.9999974266369461

How can I take cosine of a variable in python?

I am trying to make a program that will find the x and y components of an applied force at an angle. Here is what I have so far. When I run it I get an error that basically says that you cannot take the cosine of a variable and that it has to be a real number. How would I make this type of program work?
Import math
Angle = input("Enter angle:")
Force = input("Enter applied force:")
X = math.cos(angle)
Y = x * force
Print("The x component of the applied force is", y)
B = math.cos(angle)
A = b * force
Print("The y component of the applied force is", A)
Here's code after fixing capitalization and changing type of inputted values to floats:
import math
angle = float(input("Enter angle:"))
force = float(input("Enter applied force:"))
x = math.cos(angle)
y = x * force
print("The x component of the applied force is", y)
b = math.cos(angle)
a = b * force
print("The y component of the applied force is", a)

Foward/Inverse Kinematics Calculations 2-DOF python

The program calculates the points of an end-effector with forward kinematics using the equation,
x = d1cos(a1) + d2cos(a1+a2)
y = d1sin(a1) + d2sin(a1+a2)
where d1 is the length of the first joint, d2 is the length of the second joint, a1 is the angle of the first joint and a2 is the angle of the second joint.
It calculates inverse kinematics by this equation
So, by entering the input required for forward kinematics I should get the points of the end effector. By entering in the same input and the points found in forward kinematics for inverse kinematics, I should get the angles I entered in as input for forward kinematics. But I do not get them back.
Here is my code,
'''
Created on Oct 5, 2015
#author: justin
'''
import math
def getOption():
print('Select an option:\n')
print('\t1) Forward Kinematics\n')
print('\t2) Inverse Kinematics\n')
option = input()
try:
option = int(option)
if option == 1:
fowardKinematics()
elif option == 2:
inverseKinematics()
else:
print('Not an option')
return
except ValueError:
print('Not an integer/Point cannot be reached')
return
def fowardKinematics():
'''
Ask user for input and computing points of end-effector
'''
length1 = input('Enter length of joint 1 (a1):\n') # Getting input from keyboard
angle1 = input('Enter angle of joint 1 (theta1):\n')
length2 = input('Enter length of joint 2 (a2):\n')
angle2 = input("Enter angle of join 2 (theta2)\n")
try:
length1 = float(length1) # Testing to see if user entered a number
length2 = float(length2) # Testing to see if user entered a number
angle1 = float(angle1) # Testing to see if user entered a number
angle2 = float(angle2) # Testing to see if user entered a number
except ValueError:
print('Invalid input, check your input again')
return
x = (length1 * math.cos(math.radians(angle1))) + (length2 * math.cos((math.radians(angle1 + angle2)))) # a1c1 + a2c12
y = (length1 * math.sin(math.radians(angle1))) + (length2 * math.sin((math.radians(angle1 + angle2)))) # a1s1 + a2s12
print('The position of the end-effector P(x,y) is:\n')
print('X: ' + str(x)) # Convert x to string
print('Y: ' + str(y)) # Convert y to string
def inverseKinematics():
length1 = input('Enter length of joint 1 (a1):\n')
length2 = input('Enter length of joint 2 (a2):\n')
x = input('Enter position of X:\n')
y = input('Enter position of Y:\n')
try:
length1 = float(length1)
length2 = float(length2)
x = float(x)
y = float(y)
except ValueError:
print('Invalid input, check your input again')
return
# Computing angle 2 Elbow up/down
numerator = ((length1 + length2)**2) - ((x**2) + (y**2))
denominator = ((x**2) + (y**2)) - ((length1 - length2)**2)
angle2UP = math.degrees(math.atan(math.sqrt(numerator/denominator)))
angle2DOWN = angle2UP * -1
# Angle 1 Elbow up
numerator = (length2 * math.sin(math.radians(angle2UP)))
denominator = ((length1 + length2) * math.cos(math.radians(angle2UP)))
angle1UP = math.degrees(math.atan2(numerator, denominator))
# Angle 1 Elbow down
numerator = (length2 * math.sin(math.radians(angle2DOWN)))
denominator = ((length1 + length2) * math.cos(math.radians(angle2DOWN)))
angle1DOWN = math.degrees(math.atan2(numerator, denominator))
print("Angle 1 Elbow up: " + str(angle1UP))
print("Angle 1 Elbow down: " + str(angle1DOWN))
print("Angle 2 Elbow up: " + str(angle2UP))
print("Angle 2 Elbow down: " + str(angle2DOWN))
if __name__ == '__main__':
getOption()
pass
I think the problem is when the trig functions get introduced. The parameters for them are supposed to be in radians, they return the answer is degrees. Somewhere I am mixing up the two. I just don't know where. Thanks
There is, I'm afraid, quite a bit wrong with this, either in your code or in the equations you're using. Your equation for theta2 doesn't make any sense to me if x and y are distances and a1 and a2 are angles (check your equation or give a source). Even if these should be d1 and d2, this equation involves subtracting two quantities with different dimensions (length^4 and length^2).
Then check your implementation of it, which does not evaluate the equation as given.
My advice about radians / degrees is to use radians throughout: accept the angles in degrees if you want, but then immediately convert to radians for the calculations, and convert angular results back to degrees for output.
Some more advice:
you don't need to cast your floats to strings for output using print, just use print('x: ', x) and so on.
Give your variables the same names as the symbols they represent in your formula. This would make it easier to debug (well, it would if the equations were correct).
Hope that helps.

Given f, is there an automatic way to calculate fprime for Newton's method?

The following was ported from the pseudo-code from the Wikipedia article on Newton's method:
#! /usr/bin/env python3
# https://en.wikipedia.org/wiki/Newton's_method
import sys
x0 = 1
f = lambda x: x ** 2 - 2
fprime = lambda x: 2 * x
tolerance = 1e-10
epsilon = sys.float_info.epsilon
maxIterations = 20
for i in range(maxIterations):
denominator = fprime(x0)
if abs(denominator) < epsilon:
print('WARNING: Denominator is too small')
break
newtonX = x0 - f(x0) / denominator
if abs(newtonX - x0) < tolerance:
print('The root is', newtonX)
break
x0 = newtonX
else:
print('WARNING: Not able to find solution within the desired tolerance of', tolerance)
print('The last computed approximate root was', newtonX)
Question
Is there an automated way to calculate some form of fprime given some form of f in Python 3.x?
A common way of approximating the derivative of f at x is using a finite difference:
f'(x) = (f(x+h) - f(x))/h Forward difference
f'(x) = (f(x+h) - f(x-h))/2h Symmetric
The best choice of h depends on x and f: mathematically the difference approaches the derivative as h tends to 0, but the method suffers from loss of accuracy due to catastrophic cancellation if h is too small. Also x+h should be distinct from x. Something like h = x*1e-15 might be appropriate for your application. See also implementing the derivative in C/C++.
You can avoid approximating f' by using the secant method. It doesn't converge as fast as Newton's, but it's computationally cheaper and you avoid the problem of having to calculate the derivative.
You can approximate fprime any number of ways. One of the simplest would be something like:
lambda fprime x,dx=0.1: (f(x+dx) - f(x-dx))/(2*dx)
the idea here is to sample f around the point x. The sampling region (determined by dx) should be small enough that the variation in f over that region is approximately linear. The algorithm that I've used is known as the midpoint method. You could get more accurate by using higher order polynomial fits for most functions, but that would be more expensive to calculate.
Of course, you'll always be more accurate and efficient if you know the analytical derivative.
Answer
Define the functions formula and derivative as the following directly after your import.
def formula(*array):
calculate = lambda x: sum(c * x ** p for p, c in enumerate(array))
calculate.coefficients = array
return calculate
def derivative(function):
return (p * c for p, c in enumerate(function.coefficients[1:], 1))
Redefine f using formula by plugging in the function's coefficients in order of increasing power.
f = formula(-2, 0, 1)
Redefine fprime so that it is automatically created using functions derivative and formula.
fprime = formula(*derivative(f))
That should solve your requirement to automatically calculate fprime from f in Python 3.x.
Summary
This is the final solution that produces the original answer while automatically calculating fprime.
#! /usr/bin/env python3
# https://en.wikipedia.org/wiki/Newton's_method
import sys
def formula(*array):
calculate = lambda x: sum(c * x ** p for p, c in enumerate(array))
calculate.coefficients = array
return calculate
def derivative(function):
return (p * c for p, c in enumerate(function.coefficients[1:], 1))
x0 = 1
f = formula(-2, 0, 1)
fprime = formula(*derivative(f))
tolerance = 1e-10
epsilon = sys.float_info.epsilon
maxIterations = 20
for i in range(maxIterations):
denominator = fprime(x0)
if abs(denominator) < epsilon:
print('WARNING: Denominator is too small')
break
newtonX = x0 - f(x0) / denominator
if abs(newtonX - x0) < tolerance:
print('The root is', newtonX)
break
x0 = newtonX
else:
print('WARNING: Not able to find solution within the desired tolerance of', tolerance)
print('The last computed approximate root was', newtonX)

Categories

Resources