############################################################################
## CALCULUS - BIOINFORMATICS, 2018-19 T2
## Authors: Toni Guillamon, Alex Haro
## Sources: [G. Ledder, "Mathematics for the Life Sciences", Springer 2013]
############################################################################

import numpy as np
import matplotlib.pyplot as plt
#from math import*

############################
### List2-Ex4 ##############
############################

xmin=0.3
xmax=1.0
numint=1000
x = np.arange(xmin,xmax,1/numint)

ymin=0.0
ymax=1.0

plt.axis([xmin,xmax,ymin,ymax])
plt.xlabel('x')
plt.ylabel('y')
plt.title('Fixed points of 2^(-x)')
plt.plot(x,x)
plt.plot(x,2**(-x))

plt.show()

############################
### List2-Ex5 ##############
############################

xmin=0.0
xmax=1.0
numint=1000
x = np.arange(xmin,xmax,(xmax-xmin)/numint)
zer=[0]*numint

ymin=-6.0
ymax=2.0

plt.axis([xmin,xmax,ymin,ymax])
plt.xlabel('x')
plt.ylabel('y')
plt.title('x^3-7 x^2+14 x-6')
plt.plot(x,zer)
plt.plot(x,x**3-7*x**2+14*x-6)

plt.show()

####################################
### List2-Ex6 Graphics (family) ####
####################################

#We plot the function for different values of the parameter a.

xmin=0.0
xmax=2.0
numint=1000
x = np.arange(xmin,xmax,(xmax-xmin)/numint)
zer=[0]*numint
iMax=5
aIni=0
aFin=5

ymin=-2.5
ymax=2.0

plt.axis([xmin,xmax,ymin,ymax])
plt.xlabel('x')
plt.ylabel('x^3-a x-1')
plt.title('Plot for different values of a')
plt.text(60, .025, 'a from %lf to %lf', aIni, aFin)
plt.plot(x,zer)
for i in np.arange(0,iMax):
	a0=aIni+i*(aFin-aIni)/iMax
	plt.plot(x,x**3-a0*x-1)

plt.show()

####################################
### List2-Ex6 Graphics (single) ####
####################################

#We plot the function for a specific value of the parameter a.

xmin=1.0
xmax=4.0
numint=1000
x = np.arange(xmin,xmax,(xmax-xmin)/numint)
zer=[0]*numint

ymin=-2.5
ymax=2.0

plt.axis([xmin,xmax,ymin,ymax])
plt.xlabel('x')
plt.ylabel('x^3-3 x-1')
plt.title('Plot for a=3')
plt.plot(x,zer)
plt.plot(x,x**3-3*x-1)

plt.show()

############################
### List2-Ex6 Zeros ########
############################

#We implement the Newton-Raphson method to find the zeroes of f.

def ZNewtRaph(x0,a0,tol,nIter):
    j=0
    aux=2*tol
    while abs(aux)>tol and j<nIter:
        j=j+1
        aux=(x0**3-a0*x0-1)/(3*x0**2-a0)
        x1=x0-aux
        print(x1)
        x0=x1
    return 'xzero= {}, err={}, iterates={}'.format(x0,aux,j)

ZNewtRaph(4.,3,1e-03,100)

#You can also use the "fsolve" command already embedded in numpy. We first define the function "f" and then apply the method.

from scipy.optimize import fsolve

def f(x):
    return x**3-3*x-1

dzero = fsolve(f, 4.0)
dzero, f(dzero)
