Newton-Raphson Root-Finding Algorithim Question

Hi all,

Beginner here to Python programming for economic research. I have just encountered a problem with the newton-raphson function that I wanted to clarify.

For background, I am coding up a CES Function of the form f(x,y) = (x^rho + y^rho)^(1/rho). I want to find the roots of a new function: it’s derivative minus a fixed constant. Using the newton-raphson function in the quantecon package, the trouble I am facing is a “failure to converge”, using most values of rho (the ones I’ve tried) that is not equal to 3. In fact, 3 should not be used at all (as the rho parameter in a Ces function has to be less than 1, and not equal to 0). Nevertheless, it is the only value that works in my code.

I am not sure if this is a problem in the starting value I am selecting, or due to an error in my code. If it is the latter, any suggestions to fix it would be much appreciated. If it is the former, I am an undergrad so please excuse my lack of knowledge of maths, any help on that would also be appreciated. Thanks very much everyone!

Setup Code:

##Load Libraries##
from numba import jit
import numpy as np 

####################QuantEcon Methods#######################
from quantecon.optimize.root_finding import newton, newton_halley, newton_secant\
, bisect, brentq

##Coded Up Functions (Jitted)##

@jit 
def ces(x,y,rho):
    U = (x**rho + y**rho)**(1/rho)
    return U # original CES Function

@jit
def ces_d(x,y,rho):
    U_x = (x**(rho-1)) * ((x**rho + y**rho)**((1-rho)/rho)) 
    return U_x # CES Derivative

@jit
def ces_dd(x,y,rho,ud):
    U_xd = (x**(rho-1)) * ((x**rho + y**rho)**((1-rho)/rho)) - ud
    return U_xd # New Function: CES Derivative - ud

@jit
def ces_d2(x,y,rho,z):
    U_xx = (rho-1) * (x**(rho-2)) *(y**rho) * ((x**rho + y**rho)**(1/rho-2))  - z  
    return U_xx # New Function Derivative - z #the z is just a placeholder variable, to make it work with ces_inv, should not affect it?

@jit
def ces_d3(x,y,rho,z):
    U_xxx = ( (rho-2) * (rho-1) * (x**(rho-3)) * (y**rho) * ((x*rho + y*rho)**(1/rho-2)) \
    + ((rho-1)* rho * x**(2*rho-3) * y**rho * ((x**rho + y**rho)**(1/(rho-2)-1)))/(rho-2) ) - z 
    return U_xxx #New Function Second Derivative - z #same reasoning as above
    
##Default Newton-Raphson##

@jit
def ces_inv(y,rho,ud):
 args = (y,rho,ud) #order must be preserved
 x_bar = newton(ces_dd, 0 ,ces_d2, args=args)
 return x_bar 

Trying it with rho = 3

print(ces_inv(2,3,4))
results(root=-1.922999428365063, function_calls=24, iterations=12, converged=True)

Trying it with rho = 0.005 (StackTrace Included)

Traceback (most recent call last):

  File "<ipython-input-61-b8dbad107a2e>", line 44, in <module>
    print(ces_inv(2,0.005,4))

  File "C:\Users\Orphanides\anaconda3\lib\site-packages\quantecon\optimize\root_finding.py", line 105, in newton
    raise RuntimeError(msg)

RuntimeError: Failed to converge

Hi @GildedCrowEscapee ,

It is always helpful to visualise the functions that you are working on. In the case that rho = 0.005, the function looks like below.

As you can see, the root of this function might be very large. So it is hard to converge depending on the starting value.

Thank you for your question.

1 Like

Hi @saya,

Thank you for your help! I figured out also my algebra was completely wrong, so I will fix that up and see how the newton function works. I do appreciate your suggestion to use a graph though, I will use that to select a good starting value!