Encapsulation

Sometimes the use of inheritance is impractical or even impossible. This motivates the use of encapsulation. We will explain the concept of encapsulation by considering Python functions, that is, objects of the Python type function, which we encapsulate in a new class, Function, and provide with some relevant methods:

class Function:
    def __init__(self, f):
        self.f = f
    def __call__(self, x):
        return self.f(x)
    def __add__(self, g):
        def sum(x):
            return self(x) + g(x)
        return type(self)(sum) 
    def __mul__(self, g): 
        def prod(x):
            return self.f(x) * g(x)
        return type(self)(prod)
    def __radd__(self, g):
        return self + g
    def __rmul__(self, g):
        return self * g

Note that the __add__ and __mul__ operations should return an instance of the same class. This is achieved by the return type(self)(sum) statement, which in this case is a more general form of writing return Function(sum). We can now derive subclasses by inheritance:

Consider as an example  Chebyshev polynomials which can be computed in the interval [1,-1] by:

Encapsulation.

We construct a Chebyshev polynomial as an instance of the Function class:

T5 = Function(lambda x: cos(5 * arccos(x)))
T6 = Function(lambda x: cos(6 * arccos(x)))

Chebyshev polynomials are orthogonal in the sense:

Encapsulation

This can easily be checked using this construction:

import scipy.integrate as sci

weight = Function(lambda x: 1 / sqrt((1 - x ** 2)))
[integral, errorestimate] = 
        sci.quad(weight * T5 * T6, -1, 1) # (6.510878470473995e-17, 1.3237018925525037e-14)

Without encapsulation multiplying functions as simply as writing  weight * T5 * T6 would not have been possible.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.62.168