#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 18 10:59:40 2019

@author: kerkmann
"""

import numpy as np

# Aufgabe 5 (a) (4 Punkte)
def weights(z, x, k):
    '''Calculates the weights for a finite difference formula on the grid x'''
    # Input parameters:
    # z   location where approximations are to be accurate,
    # x   vector with x-coordinates for grid points,
    # k   highest derivative that we want to find weights for
    
    # Output parameters:
    # C   array with size k+1,length(x) containing (as output) in 
    #     successive rows the weights for derivatives 0,1,...,k.
    
    n = len(x)
    C = np.zeros((k+1,n))
    den_old = 1
    xj = x[0]-z
    C[0,0] = 1
    
    for j in np.arange(1,n):
        der_control = min(j,k)
        den = 1
        xjm1 = xj
        xj = x[j]-z
        
        for i in range(j):
            xjmxi = x[j]-x[i]
            den = den*xjmxi
            if i==j-1:
                C[1:der_control+1,j] = den_old/den*(np.arange(1,der_control+1)*C[:der_control,j-1].flatten() - xjm1*C[1:der_control+1,j-1])
                C[0,j] = -den_old/den*xjm1*C[0,j-1]
               
            C[1:der_control+1,i] = (xj*C[1:der_control+1,i]-(np.arange(1,der_control+1))*C[:der_control,i].flatten())/xjmxi
            C[0,i] = xj*C[0,i]/xjmxi
            
        den_old = den
        
    return C