def taylor(x,f,i,n): """taylor(x,f,i,n): This function approximates the function f over the domain x, using a taylor expansion centered at x[i] with n+1 terms (starts counting from 0). Args: x: The domain of the function f: The function that will be expanded/approximated i: The ith term in the domain x that the expansion is centered around n: The number of terms in the expansion (n+1 terms) Returns: (x,fapprox): A pair of numpy arrays where x is the original domain array and f approx is the approximation of f over all of the domain points x using the taylor expansion. """ a = x[i] N = np.size(x) fa = f[i]*np.ones_like(x) D = ac.derivative(x[0],x[N-1],N) fact = 1 fapprox = fa Dk = np.eye(N) for k in range(1,n+1): fact = fact*k Dk = np.matmul(Dk,D) #fapprox += (np.matmul(np.matmul(Dk,fa),((x-a)**k)))/fact fapprox = np.add(fapprox, (np.matmul(np.matmul(Dk,fa),((x-a)**k)))/fact, out=fapprox, casting="unsafe") return (x,fapprox)
def taylor(x, f, i, n): """taylor(x,f,i,n) Inputs: -x: array of domain points -f: array of range points for a function f(x) -i: integer, between 0 and len(x), such that x[i] will be the point expanded around -n: positive integer, number of terms kept in the approximation Returns: (x, fapprox) -x: same array of domain points as inputted -fapprox: array of the taylor approximated function at point x[i]""" length = len(x) mat = ac.derivative(x[0], x[length - 1], length) fapprox = np.zeros(length) def mat_generator(): n_mat = np.eye(length) while True: n_mat = np.dot(n_mat, mat) yield n_mat g = mat_generator() k = np.arange(length) a = x[i] fapprox[k] = f[i] for j in range(1, n): n_mat = next(g) fapprox += (np.dot(n_mat, f)[i] * ((x - a)**j) / (np.math.factorial(j))) return (x, fapprox)
def test_derivative(): """Tests derivative(a,b,n) with following tests: - derivative(0,9,10) multiplied by f = [0,1,2,3,4,5,6,7,8,9] """ actual = np.array([1,1,1,1,1,1,1,1,1,1]) trial = ac.derivative(0,9,10)@(np.array([0,1,2,3,4,5,6,7,8,9])) print("Testing: actual ?= trial: ",actual," += ",trial) np.testing.assert_almost_equal(actual,trial)
def test_derivative(): """ test_derivative function description: Tests whether the central finite difference is close to the derivative of the function """ f = lambda x: x**2 Df = ac.derivative(f, xmax=99) for i in range(1, len(Df) - 1): assert math.isclose(Df[i], 2 * i)
def test_derivative(): """test_derivative() Tests for the first derivative accuracy """ a = 0 b = 3 n = 3 f = np.array([2.0, 2.0, 2.0]) answer = np.empty(n) D1 = array_calculus.derivative(a, b, n) answer = D1 @ f desired = np.array([0.0, 0.0, 0.0]) np.testing.assert_almost_equal(answer, desired)
def test_derivative_2(): """test_derivative_2() Tests for the first derivative accuracy specifically for function x^2 """ a = 0 b = 5 n = 5 #f(x)=x^2 and x_array=[(0,1,2,3,4)], which is why the f array is defined this way f = np.array([0.0, 1.0, 4.0, 9.0, 16.0]) answer = np.empty(n) D1 = array_calculus.derivative(a, b, n) #D2 = array_calculus.second_derivative(a,b,n) answer = D1 @ f desired = np.array([0.8, 1.6, 3.2, 4.8, 5.6]) np.testing.assert_almost_equal(answer, desired)
def test_derivative(): """Testing our derivative matrix for three point of an exponential function""" # Testing for derivative of exponential at points x=0,1,2 actual = np.array([(np.exp(1)-np.exp(0)), (np.exp(2)-np.exp(0))/2, (np.exp(2)-np.exp(1))]) # Testing implementation def exponential(): t = np.linspace(0,2,3) ex = np.vectorize(np.exp) ex = ex(t) return ex trial = np.dot(ac.derivative(0,2,3),exponential()) # Debug message print("Should be: ",actual," but returned this: ",trial) for m in range(3): nose.tools.assert_almost_equal(actual[m],trial[m],4)
def test_derivative(): """Test_derivative() tests the derivative matrix for the chosen values of x= -1, 0, and 1.""" desired = np.array([(np.sin(0) - np.sin(-1)), (np.sin(1) - np.sin(-1) / 2), (np.sin(1) - np.sin(0))]) def sin(): x = np.linspace(-1, 1, 3) sin = np.sin(x) return sin obtained = np.array(ac.derivative(-1, 1, 3), sin()) print("Desired: ", desired) print("Obtained: ", obtained) np.testing.assert_almost_equal(obtained, desired)
def taylor(x, f, i, n): y = len(x) mat = ac.derivative(x[0], x[y - 1], y) fx = np.zeros(y) #array on zeros of length y def tay_matrix(): matrix = np.eye(y) while True: matrix = np.dot(matrix, mat) yield matrix yint = np.arange(y) m = tay_matrix() fx[yint] = f[i] array = x[i] for k in range(1, n): matrix = next(m) fx += (np.dot(matrix, f)[i] * ((x - array)**k) / (np.math.factorial(k))) return (x, fx)
def taylor(x, f, i, n): '''taylor(x,f,i,n=10) Takes the taylor series approximation around a specific point at position i. Args: x (array) : x-coordinates f (array) : y-coordinates i (index int) : position of point between 0 and the domain n (int) : number of terms to keep in Taylor expansion sum Returns: (x, fapprox) : Pair of numpy arrays x : x-coordinates domain fapprox : new approximate function y-coordinates obtained by Taylor formula at x[i] ''' fapprox = np.zeros(len(x)) for xValue in range(0, len(x)): answer = 0 for term in range(0, n + 1): D = array_calculus.derivative(x[0], x[len(x) - 1], len(x)) D_operator = np.linalg.matrix_power(D, term) myDerivative = D_operator @ f answer = answer + (myDerivative[i] * (( (x[xValue] - x[i])**term) / math.factorial(term))) fapprox[xValue] = answer return (x, fapprox)
def test_first_and_Second_derivatives(): actual = calc.second_derivative(0,9,9) trial = calc.derivative(0,9,9)@calc.derivative(0,9,9) print("Testing first derivative: ",actual," ?= ",trial) np.testing.assert_array_almost_equal(actual, trial)