inf1100 lectures, chapter 9: object-oriented programming … · 2013-12-02 · inf1100 lectures,...

98
INF1100 Lectures, Chapter 9: Object-Oriented Programming Hans Petter Langtangen Simula Research Laboratory University of Oslo, Dept. of Informatics November 05, 2009

Upload: vokien

Post on 02-Jul-2018

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

INF1100 Lectures, Chapter 9:Object-Oriented Programming

Hans Petter Langtangen

Simula Research Laboratory

University of Oslo, Dept. of Informatics

November 05, 2009

Page 2: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Before we start: define the heading of this chapter

Object-oriented programming (OO) means different things todifferent people:

programming with classes (better: object-based programming)programming with class hierarchies (class families)

The 2nd def. is most widely accepted and used here

Page 3: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

New concept: collect classes in families (hierarchies)

What is a class hierarchy?

A family of closely related classes

A key concept is inheritance: child classes can inheritattributes and methods from parent class(es) – this savesmuch typing and code duplication

As usual, we shall learn through examples

OO is a Norwegian invention – one of the most importantinventions in computer science, because OO is used in all bigcomputer systems today

Page 4: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Warnings: OO is difficult and takes time to master

The OO concept might be difficult to understand

Let ideas mature with time and try to work with it

OO is less important in Python than in C++, Java and C#,so the benefits of OO are less obvious in Python

Our examples here on OO employ numerical methods fordifferentiation, integration og ODEs – make sure youunderstand the simplest of these numerical methods beforeyou study the combination of OO and numerics

Ambitions: write simple OO code and understand how tomake use of ready-made OO modules

Page 5: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A class for straight lines

Let us make a class for evaluating lines y = c0 + c1x

class Line:def __init__(self, c0, c1):

self.c0, self.c1 = c0, c1

def __call__(self, x):return self.c0 + self.c1*x

def table(self, L, R, n):"""Return a table with n points for L <= x <= R."""s = ’’for x in linspace(L, R, n):

y = self(x)s += ’%12g %12g\n’ % (x, y)

return s

Page 6: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A class for parabolas

Let us make a class for evaluating parabolas y = c0 + c1x + c2x2

class Parabola:def __init__(self, c0, c1, c2):

self.c0, self.c1, self.c2 = c0, c1, c2

def __call__(self, x):return self.c2*x**2 + self.c1*x + self.c0

def table(self, L, R, n):"""Return a table with n points for L <= x <= R."""s = ’’for x in linspace(L, R, n):

y = self(x)s += ’%12g %12g\n’ % (x, y)

return s

This is almost the same code as class Line, except for the thingswith c2

Page 7: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 8: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 9: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 10: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 11: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 12: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 13: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 14: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; principles

Parabola code = Line code + a little extra with the c2 term

Can we utilize class Line code in class Parabola?

This is what inheritance is about!

Writingclass Parabola(Line):

pass

makes Parabola inherit all methods and attributes from Line,so Parabola has attributes c0 and c1 and three methods

Line is a superclass, Parabola is a subclass

(parent class, base class; child class, derived class)

Class Parabola must add code to Line’s constructor (an extrac2 attribute), call (an extra term), but table can be usedunaltered

The principle is to reuse as much code in Line as possible andavoid duplicated code

Page 15: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class Parabola as a subclass of Line; code

A subclass method can call a superclass method in this way:superclass_name.method(self, arg1, arg2, ...)

Class Parabola as a subclass of Line:class Parabola(Line):

def __init__(self, c0, c1, c2):Line.__init__(self, c0, c1) # Line stores c0, c1self.c2 = c2

def __call__(self, x):return Line.__call__(self, x) + self.c2*x**2

What is gained? class Parabola just adds code to the alreadyexisting code in class Line – no duplication of storing c0 andc1, and computing c0 + c1x

Class Parabola also has a table method – it is inherited

The constructor and call are overrided, meaning that thesubclass redefines these methods (here: redefined method =call superclass method + something extra)

Page 16: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Demo of class Parabola

Main program:p = Parabola(1, -2, 2)p1 = p(2.5)print p1print p.table(0, 1, 3)

Output:8.5

0 10.5 0.51 1

Follow the program flow of p(2.5)!

Page 17: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Checking class types and class relations

>>> l = Line(-1, 1)>>> isinstance(l, Line)True>>> isinstance(l, Parabola)False

>>> p = Parabola(-1, 0, 10)>>> isinstance(p, Parabola)True>>> isinstance(p, Line)True

>>> issubclass(Parabola, Line)True>>> issubclass(Line, Parabola)False

>>> p.__class__ == ParabolaTrue>>> p.__class__.__name__ # string version of the class name’Parabola’

Page 18: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Next example: class for functions (part 1)

Suppose we want to implement mathematical functionsf (x ; p1, . . . , pn) with parameters as classes. These classesshould also support computation of df /dx and d2f /dx2

Example on such a class:class SomeFunc:

def __init__(self, parameter1, parameter2, ...)# store parameters

def __call__(self, x):# evaluate function

def df(self, x):# evaluate the first derivative

def ddf(self, x):# evaluate the second derivative

If we do not bother to derive the analytical derivatives, we canuse numerical differentation formulas in df and ddf

Page 19: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Next example: class for functions (part 2)

Observation: with numerical differentiation, all such classescontain the same df and ddf methods

Such duplication of code is considered a bad thing

Better: collect df and ddf in a superclass and let subclassesautomatically inherit these methods

Page 20: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Super- and subclass for functions

class FuncWithDerivatives:def __init__(self, h=1.0E-9):

self.h = h # spacing for numerical derivatives

def __call__(self, x):raise NotImplementedError\

(’___call__ missing in class %s’ % \self.__class__.__name__)

def df(self, x):# compute 1st derivative by a finite difference:h = float(self.h) # short formreturn (self(x+h) - self(x-h))/(2*h)

def ddf(self, x):# compute 2nd derivative by a finite difference:h = float(self.h) # short formreturn (self(x+h) - 2*self(x) + self(x-h))/h**2

The superclass is not useful in itself – a subclass is needed toimplement a specific mathematical function

Page 21: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

How to implement a specific function as a subclass

Inherit from superclass FuncWithDerivatives

Store parameters in constructor

Implement function formula in call

Rely on inherited df and ddf for numerical derivatives, orreimplement df and ddf with exact expressions

Page 22: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A subclass for a function; no direct use of superclass

Say we want to implement f (x) = cos(ax) + x3

We do this in a subclass:class MyFunc(FuncWithDerivatives):

def __init__(self, a):self.a = a

def __call__(self, x):return cos(self.a*x) + x**3

def df(self, x):a = self.areturn -a*sin(a*x) + 3*x**2

def ddf(self, x):a = self.areturn -a*a*cos(a*x) + 6*x

This subclass inherits from the superclass, but does not makeuse of anything from the superclass – no practical use of thesuperclass in this example

Page 23: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A subclass for a function; use of superclass

Say we want to implement f (x) = ln |p tanh(qx cos rx)|

We are lazy and want to avoid hand derivation of longexpressions for f ′(x) and f ′′(x) – use finite differences instead

Implementation as a subclass:class MyComplicatedFunc(FuncWithDerivatives):

def __init__(self, p, q, r, h=1.0E-9):FuncWithDerivatives.__init__(self, h)self.p, self.q, self.r = p, q, r

def __call__(self, x):p, q, r = self.p, self.q, self.rreturn log(abs(p*tanh(q*x*cos(r*x))))

This time we inherit df and ddf

Note also that we must pass h on to the superclass constructor

It is always a good habit to call the superclass constructor

Page 24: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Interactive example

f (x) = ln |p tanh(qx cos rx)|compute f (x), f ′(x), f ′′(x) for x = π/2

>>> from math import *>>> f = MyComplicatedFunc(1, 1, 1)>>> x = pi/2>>> f(x)-36.880306514638988>>> f.df(x)-60.593693618216086>>> f.ddf(x)3.3217246931444789e+19

Page 25: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class for numerical differentiation (Ch. 9)

Simplest numerical differentiation formula:

f ′(x) ≈f (x + h) − f (x)

h

for a small h, say h = 10−9

Class Derivative stores f and h as attributes and applies thedifferentation formula in the call special method

class Derivative:def __init__(self, f, h=1E-9):

self.f = fself.h = float(h)

def __call__(self, x):f, h = self.f, self.h # make short formsreturn (f(x+h) - f(x))/h

Page 26: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

There are numerous formulas numerical differentiation

f ′(x) =f (x + h) − f (x)

h+ O(h)

f ′(x) =f (x) − f (x − h)

h+ O(h)

f ′(x) =f (x + h) − f (x − h)

2h+ O(h2)

f ′(x) =4

3

f (x + h) − f (x − h)

2h−

1

3

f (x + 2h) − f (x − 2h)

4h+ O(h4)

f ′(x) =3

2

f (x + h) − f (x − h)

2h−

3

5

f (x + 2h) − f (x − 2h)

4h+

1

10

f (x + 3h) − f (x − 3h)

6h+ O(h6)

f ′(x) =1

h

(

−1

6f (x + 2h) + f (x + h) −

1

2f (x) −

1

3f (x − h)

)

+ O(h3)

Page 27: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 28: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 29: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 30: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 31: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 32: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 33: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical differentiation formula can be implemented as aclass: h and f are attributes and a call special methodevaluates the formula

The Derivative class appears as a plain function in use

All classes for different differentiation formulas are similar: theconstructor is the same, only call differs

Code duplication (of the constructors) is a bad thing (=rule!)

The general OO idea: place code common to many classes ina superclass and inherit that code – here we let a superclassimplement the common constructor

Subclasses extend the superclass with code specific to a mathformula

Page 34: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Class hierarchy for numerical differentiation

Superclass:

class Diff:def __init__(self, f, h=1E-9):

self.f = fself.h = float(h)

Subclass for simple forward formula:

class Forward1(Diff):def __call__(self, x):

f, h = self.f, self.hreturn (f(x+h) - f(x))/h

Subclass for 4-th order central formula:

class Central4(Diff):def __call__(self, x):

f, h = self.f, self.hreturn (4./3)*(f(x+h) - f(x-h)) /(2*h) - \

(1./3)*(f(x+2*h) - f(x-2*h))/(4*h)

Page 35: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Use of the differentiation classes

Interactive example: f (x) = sin x , compute f ′(x) for x = π>>> from Diff import *>>> from math import sin>>> mycos = Central4(sin)>>> # compute sin’(pi):>>> mycos(pi)-1.000000082740371

Note: Central4(sin) calls inherited constructor in superclass,while mycos(pi) calls call in the subclass Central4

Page 36: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A flexible main program for numerical differentiation

Suppose we want to differentiate function expressions fromthe command line:

Unix/DOS> python df.py ’exp(sin(x))’ Central 2 3.1-1.04155573055

Unix/DOS> python df.py f(x) difftype difforder xf’(x)

With eval and the Diff class hierarchy this main program canbe realized in a few lines (many lines in C# and Java!):

import sysfrom Diff import *from math import *from scitools.StringFunction import StringFunction

f = StringFunction(sys.argv[1])difftype = sys.argv[2]difforder = sys.argv[3]classname = difftype + difforderdf = eval(classname + ’(f)’)x = float(sys.argv[4])print df(x)

Page 37: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A flexible main program for numerical differentiation

Suppose we want to differentiate function expressions fromthe command line:

Unix/DOS> python df.py ’exp(sin(x))’ Central 2 3.1-1.04155573055

Unix/DOS> python df.py f(x) difftype difforder xf’(x)

With eval and the Diff class hierarchy this main program canbe realized in a few lines (many lines in C# and Java!):

import sysfrom Diff import *from math import *from scitools.StringFunction import StringFunction

f = StringFunction(sys.argv[1])difftype = sys.argv[2]difforder = sys.argv[3]classname = difftype + difforderdf = eval(classname + ’(f)’)x = float(sys.argv[4])print df(x)

Page 38: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A flexible main program for numerical differentiation

Suppose we want to differentiate function expressions fromthe command line:

Unix/DOS> python df.py ’exp(sin(x))’ Central 2 3.1-1.04155573055

Unix/DOS> python df.py f(x) difftype difforder xf’(x)

With eval and the Diff class hierarchy this main program canbe realized in a few lines (many lines in C# and Java!):

import sysfrom Diff import *from math import *from scitools.StringFunction import StringFunction

f = StringFunction(sys.argv[1])difftype = sys.argv[2]difforder = sys.argv[3]classname = difftype + difforderdf = eval(classname + ’(f)’)x = float(sys.argv[4])print df(x)

Page 39: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Investigating numerical approximation errors

We can empirically investigate the accuracy of our family of 6numerical differentiation formulas

Sample function: f (x) = exp (−10x)

See the book for a little program that computes the errors:. h Forward1 Central2 Central46.25E-02 -2.56418286E+00 6.63876231E-01 -5.32825724E-023.12E-02 -1.41170013E+00 1.63556996E-01 -3.21608292E-031.56E-02 -7.42100948E-01 4.07398036E-02 -1.99260429E-047.81E-03 -3.80648092E-01 1.01756309E-02 -1.24266603E-053.91E-03 -1.92794011E-01 2.54332554E-03 -7.76243120E-071.95E-03 -9.70235594E-02 6.35795004E-04 -4.85085874E-08

halving h from row to row reduces the errors by a factor of 2,4 and 16, i.e, the errors go like h, h2, and h4

Observe the superior accuracy of Central4 compared with thesimple

f (x + h) − f (x)

hForward1

Page 40: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Alternative implementations (in the book)

Pure Python functions

downside: more arguments to transfer, cannot apply formulastwice to get 2nd-order derivatives etc.

Functional programming

gives the same flexibility as the OO solution

One class and one common math formula

applies math notation instead of programming techniques togeneralize code

These techniques are beyond scope in the course, but place OOinto a bigger perspective

Page 41: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Formulas for numerical integration

There are numerous formulas for numerical integration and allof them can be put into a common notation:

∫ b

a

f (x)dx ≈

n−1∑

i=0

wi f (xi )

wi : weights, xi : points (specific to a certain formula)

The Trapezoidal rule has h = (b − a)/(n − 1) and

xi = a + ih, w0 = wn−1 =h

2, wi = h (i 6= 0, n − 1)

The Midpoint rule has h = (b − a)/n and

xi = a +h

2+ ih, wi = h

Page 42: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

More formulas

Simpson’s rule has

xi = a + ih, h =b − a

n − 1

w0 = wn−1 =h

6

wi =h

3for i even, wi =

2h

3for i odd

Other rules have more complicated formulas for wi and xi

Page 43: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 44: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 45: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 46: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 47: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 48: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 49: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Why should these formulas be implemented in a classhierarchy?

A numerical integration formula can be implemented as aclass: a, b and n are attributes and an integrate methodevaluates the formula

We argued in the class chapter that this is smart

All such classes are quite similar: the evaluation of∑

j wj f (xj)is the same, only the definition of the points and weightsdiffer among the classes

Recall: code duplication is a bad thing!

The general OO idea: place code common to many classes ina superclass and inherit that code – here we put

j wj f (xj) ina superclass (method integrate)

Subclasses extend the superclass with code specific to a mathformula, i.e., definition of wi and xi in this case, in a methodconstruct rule

Page 50: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

The superclass for integration

class Integrator:def __init__(self, a, b, n):

self.a, self.b, self.n = a, b, nself.points, self.weights = self.construct_method()

def construct_method(self):raise NotImplementedError(’no rule in class %s’ %

def integrate(self, f):s = 0for i in range(len(self.weights)):

s += self.weights[i]*f(self.points[i])return s

def vectorized_integrate(self, f):# f must be vectorizedreturn dot(self.weights, f(self.points))

Page 51: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A subclass: the Trapezoidal rule

class Trapezoidal(Integrator):def construct_method(self):

h = (self.b - self.a)/float(self.n - 1)x = linspace(self.a, self.b, self.n)w = zeros(len(x))w[1:-1] += hw[0] = h/2; w[-1] = h/2return x, w

Note: Both superclass and subclass implement construct rule! The superclassprovides a default dummy version, while class Trapezoidal overloads (redefines)this method. This is often done in OO programming. If we forget to implementthe method in a subclass, the superclass version is inherited, and this gives anerror message about the missing implementation.

Page 52: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Another subclass: Simpson’s rule

Simpson’s rule is more tricky to implement because ofdifferent formulas for odd and even points

Don’t bother with the details of wi and xi in Simpson’s rulenow – focus on the class design!

class Simpson(Integrator):

def construct_method(self):if self.n % 2 != 1:

print ’n=%d must be odd, 1 is added’ % self.nself.n += 1

<code for computing x and w>return x, w

Page 53: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

About the program flow

Let us integrate∫ 20 x2dx using 101 points:

def f(x):return x*x

m = Simpson(0, 2, 101)print m.integrate(f)

m = Simpson(...): this invokes the superclass constructor,which calls construct rule

There are two construct rule methods, the one in the subclassis used (the subclass overloads (overrides) the superclassversion)

m.integrate(f) invokes the inherited integrate method

Page 54: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Applications of the family of integration classes

We can empirically test out the accuracy of differentintegration methods Midpoint, Trapezoidal, Simpson,GaussLegendre2, ...

Sample integral:

1∫

0

(

1 +1

m

)

t1m dt = 1

This integral is ”difficult” numerically for m > 1

Key problem: the error in numerical integration formulas is ofthe form Cn−r , mathematical theory can predict r (the”order”), but we can estimate r empirically too

See the book for computational details

Here we focus on the conclusions

Page 55: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Convergence rates for m < 1 (easy case)

Simpson and Gauss-Legendre reduce the error faster than Midpointand Trapezoidal (plot has ln(error) versus ln n)

-30

-25

-20

-15

-10

-5

0

2 2.5 3 3.5 4 4.5 5 5.5 6 6.5

ln(e

rror

)

ln(n)

m=0.25

MidpointTrapezoidal

SimpsonGaussLegendre2

Page 56: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Convergence rates for m > 1 (problematic case)

Simpson and Gauss-Legendre, which are theoretically ”smarter”than Midpoint and Trapezoidal do not show superior behavior!

-14

-13

-12

-11

-10

-9

-8

-7

-6

-5

-4

2 2.5 3 3.5 4 4.5 5 5.5 6 6.5

ln(e

rror

)

ln(n)

m=2

MidpointTrapezoidal

SimpsonGaussLegendre2

Page 57: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Ordinary differential equations

Mathematical problem:

u′(t) = f (u, t)

Initial condition:u(0) = u0

Possible applications:

Exponential growth of money or populations: f (u, t) = αu,α = const

Logistic growth of a population under limited resources:

f (u, t) = αu(

1 −u

R

)

where R is the maximum possible value of u

Radioactive decay of a substance: f (u, t) = −αu, α = const

Page 58: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Numerical solution of ordinary differential equations

Numerous methods for u′(t) = f (u, t), u(0) = u0

The Forward Euler method:

uk+1 = uk + ∆t f (uk , tk)

The 4th-order Runge-Kutta method:

uk+1 = uk +1

6(K1 + 2K2 + 2K3 + K4)

K1 = ∆t f (uk , tk),

K2 = ∆t f (uk +1

2K1, tk +

1

2∆t),

K3 = ∆t f (uk +1

2K2, tk +

1

2∆t),

K4 = ∆t f (uk + K3, tk + ∆t)

There is a jungle of different methods – how to program?

Page 59: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A superclass for ODE methods

Common tasks for ODE solvers:

Store the solution uk and the corresponding time levels tk ,k = 0, 1, 2, . . . ,N

Store the right-hand side function f (u, t)

Store the time step ∆t and last time step number k

Set the initial condition

Implement the loop over all time steps

Code for the steps above are common to all classes and henceplaced in superclass ODESolver

Subclasses, e.g., ForwardEuler, just implement the specificstepping formula in a method advance

Page 60: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

The superclass code

class ODESolver:def __init__(self, f, dt):

self.f = fself.dt = dt

def set_initial_condition(self, u0, t0=0):self.u = [] # u[k] is solution at time t[k]self.t = [] # time levels in the solution processself.u.append(u0)self.t.append(t0)self.k = 0 # time level counter

def solve(self, T):tnew = 0while tnew < T:

unew = self.advance() # the numerical formulaself.u.append(unew)

tnew = self.t[-1] + self.dtself.t.append(tnew)self.k += 1

return numpy.array(self.u), numpy.array(self.t)

def advance(self):raise NotImplementedError

Page 61: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Implementation of the Forward Euler method

Subclass code:

class ForwardEuler(ODESolver):def advance(self):

u, dt, f, k, t = \self.u, self.dt, self.f, self.k, self.t[-1]

unew = u[k] + dt*f(u[k], t)return unew

Application code for u′ = u, u(0) = 1, t ∈ [0, 3], ∆t = 0.1:

from ODESolver import ForwardEulerdef test1(u, t):

return u

method = ForwardEuler(test1, dt=0.1)method.set_initial_condition(u0=1)u, t = method.solve(T=3)plot(t, u)

Page 62: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

The implementation of a Runge-Kutta method

Subclass code:

class RungeKutta4(ODESolver):def advance(self):

u, dt, f, k, t = \self.u, self.dt, self.f, self.k, self.t[-1]

dt2 = dt/2.0K1 = dt*f(u[k], t)K2 = dt*f(u[k] + 0.5*K1, t + dt2)K3 = dt*f(u[k] + 0.5*K2, t + dt2)K4 = dt*f(u[k] + K3, t + dt)unew = u[k] + (1/6.0)*(K1 + 2*K2 + 2*K3 + K4)return unew

Application code (same as for ForwardEuler):

from ODESolver import RungeKutta4def test1(u, t):

return u

method = ForwardEuler(test1, dt=0.1)method.set_initial_condition(u0=1)u, t = method.solve(T=3)plot(t, u)

Page 63: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Making a flexible toolbox for solving ODEs

We can continue to implement formulas for differentnumerical methods for ODEs – a new method just requiresthe formula, not the rest of the code needed to set initialconditions and loop in time

The OO approach saves typing – no code duplication

Challenge: you need to understand exactly which ”slots” insubclases you have to fill in – the overall code is an interplayof the superclass and the subclass

Warning: more sophisticated methods for ODEs do not fitstraight into our simple superclass – a more sophisticatedsuperclass is needed, but the basic ideas of using OO remainthe same

Believe our conclusion: ODE methods are best implementedin a class hierarchy!

Page 64: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Example on a system of ODEs

Several coupled ODEs make up a system of ODEs

A simple example:

u′(t) = v(t),

v ′(t) = −u(t)

Two ODEs with two unknowms u(t) and v(t)

Each unknown must have an initial condition, say

u(0) = 0, v(0) = 1

One can then derive the exact solution

u(t) = sin(t), v(t) = cos(t)

Systems of ODEs appear frequently in physics, biology,finance, ...

Page 65: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Another example on a system of ODEs

Second-order ordinary differential equation, for a spring-masssystem,

mu′′ + βu′ + ku = 0, u(0) = u0, u′(0) = 0

We can rewrite this as a system of two first-order equations

Introduce two new unknowns

u(0)(t) ≡ u(t), u(1)(t) ≡ u′(t)

The first-order system is then

d

dtu(0)(t) = u(1)(t),

d

dtu(1)(t) = −m−1βu(1) − m−1ku(0)

u(0)(0) = u0, u(1)(0) = 0

Page 66: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Vector notation for systems of ODEs (part 1)

In general we have n unknowns

u(0)(t), u(1)(t), . . . , u(n−1)(t)

in a system of n ODEs:

d

dtu(0) = f (0)(u(0), u(1), . . . , u(n−1), t)

d

dtu(1) = f (1)(u(0), u(1), . . . , u(n−1), t)

· · · = · · ·d

dtu(n−1) = f (n−1)(u(0), u(1), . . . , u(n−1), t)

Page 67: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Vector notation for systems of ODEs (part 2)

We can collect the u(i)(t) functions and right-hand sidefunctions f (i) in vectors:

u = (u(0), u(1), . . . , u(n−1))

f = (f (0), f (1), . . . , f (n−1))

The first-order system can then be written

u′ = f (u, t), u(0) = u0

where u and f are vectors and u0 is a vector of initialconditions Why is this notation useful? The notation make ascalar ODE and a system look the same, and we can easilymake Python code that can handle both cases within thesame lines of code (!)

Page 68: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

How to make class ODESolver work for systems

Recall: ODESolver was written for a scalar ODE

Now we want it to work for a system u′ = f , u(0) = u0,where u, f and u0 are vectors (arrays)

Forward Euler for a system:

uk+1 = uk + ∆t f (uk , tk)

(vector = vector + scalar × vector)

In Python code:unew = u[k] + dt*f(u[k], t)

where u is a list of arrays (u[k] is an array) and f is a functionreturning an array (all the right-hand sides f (0), . . . , f (n−1))

Result: ODESolver will work for systems!

The only change: ensure that f(u,t) returns an array(This can be done be a general adjustment in the superclass!)

Page 69: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Proof: go through the code and check that it will work fora system as well

def set_initial_condition(self, u0, t0=0):self.u = [] # list of arraysself.t = []self.u.append(u0) # append array u0self.t.append(t0)self.k = 0

def solve(self, T):tnew = 0while tnew < T:

unew = self.advance() # unew is arrayself.u.append(unew) # append array

tnew = self.t[-1] + self.dtself.t.append(tnew)self.k += 1

return numpy.array(self.u), numpy.array(self.t)

# Forward Euler:def advance(self):

# ok for vector if f returns array:unew = u[k] + dt*f(u[k], t)return unew

Page 70: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Smart trick

Potential problem: f(u,t) may return a list, not array

Solution: ODESolver can make a wrapper around the user’s f

function:self.f = lambda u, t: numpy.asarray(f(u, t), float)

Now the user can return right-hand side of the ODE as list,tuple or array - all existing method classes will work forsystems of ODEs!

Page 71: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Back to implementing a system (part 1)

Spring-mass system formulated as a system of ODEs:

u(t) = (u(0)(t), u(1)(t))

f (u, t) = (u(1)(t),−m−1βu(1) − m−1ku(0))

u′(t) = f (u, t)

Code defining the right-hand side:

def myf(u, t):# u is array with two components u[0] and u[1]:return [u[1],

-beta*u[1]/m - k*u[0]/m]

Page 72: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Back to implementing a system (part 2)

Better (no global variables):

class MyF:def __init__(self, m, k, beta):

self.m, self.k, self.beta = m, k, beta

def __call__(self, u, t):m, k, beta = self.m, self.k, self.betareturn [u[1], -beta*u[1]/m - k*u[0]/m]

Main program:

from ODESolver import ForwardEuler# initial condition:u0 = [1.0, 0]f = MyF(1.0, 1.0, 0.0) # u’’ + u = 0, u(t)=cos(t)T = 4*pi; dt = pi/20method = ForwardEuler(f, dt)method.set_initial_condition(u0)u, t = method.solve(T)

# u is an array of [u0,u1] arrays, plot all u0 values:u0_values = u[:,0]u0_exact = cos(t)plot(t, u0_values, ’r-’, t, u0_exact, ’b-’)

Page 73: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Application: throwing a ball (part 1)

Newton’s 2nd law for a ball’s trajectory through air leads to

dx

dt= vx

dvx

dt= 0

dy

dt= vy

dvy

dt= −g

Air resistance is neglected but can easily be added!

4 ODEs with 4 unknowns: the ball’s position x(t), y(t) andthe velocity vx(t), vy (t)

Page 74: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Application: throwing a ball (part 2)

Define the right-hand side:

def f(u, t):x, vx, y, vy = ug = 9.81return [vx, 0, vy, -g]

Main program:

from ODESolver import ForwardEuler# t=0: prescribe velocity magnitude and anglev0 = 5; theta = 80*pi/180# initial condition:u0 = [0, v0*cos(theta), 0, v0*sin(theta)]

T = 1.2; dt = 0.01method = ForwardEuler(f, dt)method.set_initial_condition(u0)u, t = method.solve(T)# u is an array of [x,vx,y,vy] arrays, plot y vs x:plot(u[:,0], u[:,1])

Page 75: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Application: throwing a ball (part 3)

Comparison of exact and Forward Euler solutions

-0.2

0

0.2

0.4

0.6

0.8

1

1.2

1.4

0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9

dt=0.01

numericalexact

Page 76: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A class hierarchy for geometric shapes

Goal: make a drawing program where simple figures can be drawnby simple Python commands (statements)

Example:

l1 = Line(start=(0,0), stop=(1,1)) # define linel1.draw() # make plot datadisplay() # display the plot data

r1 = Rectangle(lower_left_corner=(0,1), width=3, height=5)r1.draw()

Circle(center=(5,7), radius=1).draw()Wheel(center=(6,2), radius=2, inner_radius=0.5, nlines=7).draw()display()hardcopy(’tmp’) # create PNG file tmp.png

Page 77: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

The resulting figure...

Page 78: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

How can we realize this drawing tool?

We need objects for geometric shapes: Line, Rectangle, Circle,Arc, Wheel, Arrow, Spring, Man, Car, etc.

Objects are naturally related in a family

Superclass Shape provides functionality (code) common for allgeometric shapes, and subclasses add code for a specific shape

Line is a subclass of Shape

Arc is a subclass of Shape

Circle is a subclass of Arc (special Arc of 360 degrees)

Wheel has two Circles and several Lines

Page 79: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Is-a versus has-a relationships

In OO one distinguishes between is-a and has-a relationships

An Arc is a Shape

A Circle is an Arc

⇒ is-a means subclass of

A Wheel has two Circle objects many Line objects

⇒ has-a means attribute

Note: a shape is (in general) built of other shapes, so a shapeis another shape and has other shapes

Page 80: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Overview of the class hierarchy

Superclass Shape has a drawing tool (we omit the details)

The drawing tool can draw a curve, set the linetype,thickness, color, etc., make hardcopies, display all curvesdefined so far on the screen, etc. (We use Gnuplot)

Class Curve represents some set of connected x and y points

Basic shapes just define their curve

More complicated shapes are built of other shapes(and curves)

Class Shape contains

the common parts of all constructorsa draw method for drawing all shapes/curves of a classother common methods for geometric transforms (later)

Subclasses (Line, Circle, ...) define their shapes/curves in amethod subshapes, which returns a list of Shape subclassobjects – the superclass Shape can perform commonoperations on this list

Page 81: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Let us show some code to be specific: the superclass

class Shape:def __init__(self):

self.shapes = self.subshapes()if isinstance(self.shapes, Shape):

self.shapes = [self.shapes] # turn to list

def subshapes(self):"""Define self.shapes as list of Shape instances."""raise NotImplementedError(self.__class__.__name__)

def draw(self):for shape in self.shapes:

shape.draw()

Page 82: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

The subclass Line

class Line(Shape):def __init__(self, start, stop):

self.start, self.stop = start, stopShape.__init__(self)

def subshapes(self):x = [self.start[0], self.stop[0]]y = [self.start[1], self.stop[1]]return Curve(x,y)

The subclass stores geometric info about its shape in theconstructor and defines, in the subshape method, enoughcoordinates to draw the shape

Page 83: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A Rectangle has slightly more code

Specification: lower left corner point + width + height

class Rectangle(Shape):def __init__(self, lower_left_corner, width, height):

self.lower_left_corner = lower_left_corner # 2-tupleself.width, self.height = width, heightShape.__init__(self)

def subshapes(self):ll = self.lower_left_corner # short formx = [ll[0], ll[0]+self.width,

ll[0]+self.width, ll[0], ll[0]]y = [ll[1], ll[1], ll[1]+self.height,

ll[1]+self.height, ll[1]]return Curve(x,y)

Page 84: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

And here is an Arc

class Arc(Shape):def __init__(self, center, radius,

start_degrees, opening_degrees, resolution=180):self.center = centerself.radius = radiusself.start_degrees = start_degrees*pi/180self.opening_degrees = opening_degrees*pi/180self.resolution = resolutionShape.__init__(self)

def subshapes(self):t = linspace(self.start_degrees,

self.start_degrees + self.opening_degrees,self.resolution+1)

x0 = self.center[0]; y0 = self.center[1]R = self.radiusx = x0 + R*cos(t)y = y0 + R*sin(t)return Curve(x,y)

Page 85: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A Circle is a special kind of an Arc

class Circle(Arc):def __init__(self, center, radius, resolution=180):

Arc.__init__(self, center, radius, 0, 360, resolution)

Page 86: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A Wheel is more complicated...

class Wheel(Shape):def __init__(self, center, radius, inner_radius, nlines=10):

self.center = centerself.radius = radiusself.inner_radius = inner_radiusself.nlines = nlinesShape.__init__(self)

def subshapes(self):outer = Circle(self.center, self.radius)inner = Circle(self.center, self.inner_radius)lines = []t = linspace(0, 2*pi, self.nlines)Ri = self.inner_radius; Ro = self.radiusx0 = self.center[0]; y0 = self.center[1]xinner = x0 + Ri*cos(t)yinner = y0 + Ri*sin(t)xouter = x0 + Ro*cos(t)youter = y0 + Ro*sin(t)lines = [Line((xi,yi),(xo,yo)) for xi, yi, xo, yo inreturn [outer, inner] + lines

Page 87: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

And now to the real strength of OO!

We now have a lot of different geometric shapes we can draw

But can we make a wheel roll?

Yes, if the wheel can be rotated and translated

The great thing is that we can implement general formulas fortranslation and rotation of a set of points in class Curve, andclass Shape can translate and rotate any subclass figure justas it can draw any subclass figure

All subclasses automatically inherit general functionality fortranslating and rotating themselves!

See the book for details

This is a good example on the power of mathematics and OO!

Page 88: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Let the Wheel roll...

center = (6,2)radius = 2angle = 2total_rotation_angle = 200w1 = Wheel(center=center, radius=radius,

inner_radius=0.5, nlines=7)for i in range(int(total_rotation_angle/angle)):

w1.draw()display()

L = radius*angle*pi/180 # translation = arc lengthw1.rotate(angle, center[0], center[1])w1.translate(-L, 0)center = (center[0] - L, center[1])

erase()

Page 89: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Summary of object-orientation principles

A subclass inherits everything from the superclass

When to use a subclass/superclass?

if code common to several classes can be placed in a superclassif the problem has a natural child-parent concept

The program flow jumps between super- and sub-classes

It takes time to master when and how to use OO

Study examples!

Page 90: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class hierarchy for differentiation

Mathematical principles

Collection of difference formulas for f′(x). For example,

f′(x) ≈

f (x + h) − f (x − h)

2h

Superclass Diff contains common code (constructor), subclasses implement

various difference formulas.

Implementation example (superclass and one subclass)

class Diff:def __init__(self, f, h=1E-9):

self.f = fself.h = float(h)

class Central2(Diff):def __call__(self, x):

f, h = self.f, self.hreturn (f(x+h) - f(x-h))/(2*h)

Page 91: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class hierarchy for integration (part 1)

Mathematical principles

General integration formula for numerical integration:

∫ b

a

f (x)dx ≈n−1∑

j=0

wi f (xi )

Superclass Integrator contains common code (constructor,∑

j wi f (xi )), subclasses implement definition of wi and xi .

Page 92: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class hierarchy for integration (part 2)

Implementation example (superclass and one subclass)

class Integrator:def __init__(self, a, b, n):

self.a, self.b, self.n = a, b, nself.points, self.weights = self.construct_method()

def integrate(self, f):s = 0for i in range(len(self.weights)):

s += self.weights[i]*f(self.points[i])return s

class Trapezoidal(Integrator):def construct_method(self):

x = linspace(self.a, self.b, self.n)h = (self.b - self.a)/float(self.n - 1)w = zeros(len(x)) + hw[0] /= 2; w[-1] /= 2 # adjust end weightsreturn x, w

Page 93: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class hierarchy for solution of ODEs (part 1)

Mathematical principles

Many different formulas for solving ODEs numerically:

u′ = f (u, t), Ex: uk+1 = uk + ∆tf (uk , tk)

Superclass ODESolver implements common code (constructor, setinitial condition u(0) = u0, solve), subclasses implement definitionof stepping formula (advance method).

Page 94: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Recall the class hierarchy for solution of ODEs (part 2)

Implementation example (superclass and one subclass)

class ODESolver:def __init__(self, f, dt):

self.f, self.dt = f, dt

def set_initial_condition(self, u0):...

def solve(self, T):...while tnew < T:

unew = self.advance() # unew is array# update tnew, store unew and tnew

return numpy.array(self.u), numpy.array(self.t)

class ForwardEuler(ODESolver):def advance(self):

u, dt, f, k, t = \self.u, self.dt, self.f, self.k, self.t[-1]

unew = u[k] + dt*f(u[k], t)return unew

Page 95: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

A summarizing example: generalized reading of input data

With a little tool, we can easily read data into our programs

Example program: dump n f (x) values in [a, b] to file

outfile = open(filename, ’w’)from numpy import linspacefor x in linspace(a, b, n):

outfile.write(’%12g %12g\n’ % (x, f(x)))outfile.close()

I want to read a, b, n, filename and a formula for f from...

the command linea file of the form

a = 0b = 2filename = mydat.dat

similar commands in the terminal windowquestions in the terminal windowa graphical user interface

Page 96: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

Graphical user interface

Page 97: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

What we write in the application code

from ReadInput import *

# define all input parameters as name-value pairs in a dict:p = dict(formula=’x+1’, a=0, b=1, n=2, filename=’tmp.dat’)

# read from some input medium:inp = ReadCommandLine(p)# orinp = PromptUser(p) # questions in the terminal window# orinp = ReadInputFile(p) # read file or interactive commands# orinp = GUI(p) # read from a GUI

# load input data into separate variables (alphabetic order)a, b, filename, formula, n = inp.get_all()

# go!

Page 98: INF1100 Lectures, Chapter 9: Object-Oriented Programming … · 2013-12-02 · INF1100 Lectures, Chapter 9: Object-Oriented Programming ... base class; child class, ... should also

About the implementation

A superclass ReadInput stores the dict and provides methodsfor getting input into program variables (get, get all)

Subclasses read from different input sources

ReadCommandLine, PromptUser, ReadInputFile, GUI

See the book or ReadInput.py for implementation details

For now the ideas and principles are more important thancode details!