1. Adapt the Gradient_univ for polynomial 2x**2 +2x +1
2. Adapt the program for x**4


```python
from sympy import *
from sympy.matrices import Matrix
import numpy as np
from matplotlib import pyplot as plt

x = Symbol('x')

# Function
y = 2*x**2 +2*x + 1
# First derivative with respect to x
yprime = y.diff(x)


# Initial sequence
theta = 2
theta2 = 0

# Initiale the step size
alpha = .001

iterations = 0
check = 0
precision = 1/100000
iterationsMax = 100000

while True:
    theta2 = theta - alpha*yprime.evalf(subs={x:theta})
    iterations += 1
    
    # If we make too much iterations our program
    # stops and we need to check it to be sure the
    # parameters are correct and it is working properly
    if iterations > iterationsMax:
        print("Too many iterations")
        break
        
    if abs(theta - theta2) < precision:
        break
    
    theta = theta2


print("Number of iterations:",iterations,"value of theta:",theta2,sep=" ")
plt.plot(theta,y.evalf(subs={x:theta}),marker='o',color='r')
space = np.linspace(-5,5,100)
data = np.array([y.evalf(subs={x: value}) for value in space])
plt.plot(space, data)
plt.show()
```


```python
# Function
y = x**4
# First derivative with respect to x
yprime = y.diff(x)


# Initial sequence
theta = 2
theta2 = 0

# Initiale the step size
alpha = .0001

iterations = 0
check = 0
precision = 1/100000
iterationsMax = 100000

while True:
    theta2 = theta - alpha*yprime.evalf(subs={x:theta})
    iterations += 1
    
    # If we make too much iterations our program
    # stops and we need to check it to be sure the
    # parameters are correct and it is working properly
    if iterations > iterationsMax:
        print("Too many iterations")
        break
        
    if abs(theta - theta2) < precision:
        break
    
    theta = theta2


print("Number of iterations:",iterations,"value of theta:",theta2,sep=" ")
plt.plot(theta,y.evalf(subs={x:theta}),marker='o',color='r')
space = np.linspace(-5,5,100)
data = np.array([y.evalf(subs={x: value}) for value in space])
plt.plot(space, data)
plt.show()
```

1. Make a 2 by 2 matrix of second partial derivatives (Hessian)
2. Adapt the program for a function of 2 variables. Precision?


```python
x,y = symbols('x y')
#function
z = x**2 + y**2

# Hessian
f11 = z.diff(x).diff(x)
f12 = z.diff(x).diff(y)
f21 = z.diff(y).diff(x)
f22 = z.diff(y).diff(y)
hessian = np.array([[f11, f12], [f21, f22]])
H = sympy.Matrix(hessian)
det = H.det()
print(hessian)
print('The determinant is', det)

if det >= 0:
    print('The matrix positive semidefinite!')
else:
    print('The matrix is not positive semidefinite!')
#det = f11 * f22 - f12 * f21
```

    [[2 0]
     [0 2]]
    The determinant is 4
    The matrix positive semidefinite!



```python
# Function
z = x**2 + y**2 + 1

zprimex = z.diff(x)
zprimey = z.diff(y)

# Initial sequence
thetaX = 2
thetaY = 2

theta2X = 0
theta2Y = 0

# Initiale the step size
alpha = .0001

iterations = 0
check = 0
precision = 1/100000
iterationsMax = 100000

while True:
    theta2X = thetaX - alpha*zprimex.evalf(subs={x:thetaX, y:thetaY})
    theta2Y = thetaY - alpha*zprimey.evalf(subs={x:thetaX, y:thetaY})
    
    
    iterations += 1
    
    # If we make too much iterations our program
    # stops and we need to check it to be sure the
    # parameters are correct and it is working properly
    if iterations > iterationsMax:
        print("Too many iterations")
        break
        
    if ((thetaX - theta2X)**2 + (thetaY - theta2Y)**2) < precision**2:
        break
    
    thetaX = theta2X
    thetaY = theta2Y


print("Number of iterations:",iterations,"value of theta:", theta2X, theta2Y,sep=" ")
#plt.plot(theta,y.evalf(subs={x:theta}),marker='o',color='r')
#space = np.linspace(-5,5,100)
#data = np.array([y.evalf(subs={x: value}) for value in space])
#plt.plot(space, data)
#plt.show()
```

    Number of iterations: 20177 value of theta: 0.0353429474378087 0.0353429474378087



```python
# Crazy Function
z = log(1-y**2 + x**4)

zprimex = z.diff(x)
zprimey = z.diff(y)

# Initial sequence
thetaX = 2
thetaY = 2

theta2X = 0
theta2Y = 0

# Initiale the step size
alpha = .0001

iterations = 0
check = 0
precision = 1/100000
iterationsMax = 100000

while True:
    theta2X = thetaX - alpha*zprimex.evalf(subs={x:thetaX, y:thetaY})
    theta2Y = thetaY - alpha*zprimey.evalf(subs={x:thetaX, y:thetaY})
    
    
    iterations += 1
    
    # If we make too much iterations our program
    # stops and we need to check it to be sure the
    # parameters are correct and it is working properly
    if iterations > iterationsMax:
        print("Too many iterations")
        break
        
    if ((thetaX - theta2X)**2 + (thetaY - theta2Y)**2) < precision**2:
        break
    
    thetaX = theta2X
    thetaY = theta2Y


print("Number of iterations:",iterations,"value of theta:", theta2X, theta2Y,sep=" ")
#plt.plot(theta,y.evalf(subs={x:theta}),marker='o',color='r')
#space = np.linspace(-5,5,100)
#data = np.array([y.evalf(subs={x: value}) for value in space])
#plt.plot(space, data)
#plt.show()
```

    Too many iterations
    Number of iterations: 100001 value of theta: 13.6925203998118 -8.48404427992362



```python

```




    -2.0000000000000004




```python

```

0f966a52feb7393d3322e3f4a7f8f2a849828548
ipynb
Jupyter Notebook
Exercises/DaigleGradientDescentExercise.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Exercises/DaigleGradientDescentExercise.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Exercises/DaigleGradientDescentExercise.ipynb
ChristopherDaigle/ConvexOptimizationWithPython
b7a1b5126b076d06ec03e906b19930bf324272ff
Unlicense
Qwen/Qwen-72B
1. YES
2. YES