Intro To Python Programming
Intro To Python Programming
= (1.3)
One can create the above function via the keyword def in Python as shown
below. The script is saved in a file called myFunction.py.
Once the above file has been created, you can load and use the function as follows
(assuming that the above file is in the current directory of Spyder).
One can now also use the plot function as follows (observe the vectorized
operation):
This results in the figure below.
Figure 1-5: Plot of
2
1
x
xe
.
1.12 Modules
One can include multiple functions within a single Python file, and access
each one of them individually (a distinct advantage over Matlab). For example,
below is a file SimpleFunctions.py containing multiple functions. For example,
the function f3 implements
2 4
( , ) ( 1) ( 4) f = (1.4)
Each of these functions is accessible once the SimpleFunctions.py has been
imported, as illustrated below.
Further, one can query the above module via the help command in Python:
Observe that Python has intelligently interpreted your code via the triple-quotes,
and provided a useful synopsis.
1.13 Module Testing
One can test individual modules (such as the SimpleFunctions.py) by
including a main function as part of the file. For example, continuing with the
above script, we add the following lines of Python code (observe the special
syntax of line-34).
One can now run the SimpleFunctions.py module (through F5 shortcut), and the
result is shown below.
Figure 1-6: Plot of
2
1
x
xe
l
=
l
x x J x g x (1.8)
where ( ) J x is the Jacobian matrix, associated with Equation (1.7), defined as:
i
ij
j
g
x
J (1.9)
Example 1-1: Find a solution to the set of nonlinear equations:
2 2
2 2 4 0
2 2 0
4 3 0
x x
y y
x x y
=
=
=
(1.10)
Solution: Note that the 3 unknowns are { , , } x y = x . As the reader can verify,
the Jacobian is given by:
2 2 0 2 4
0 2 2 2
2 4 2 0
x
y
x y
l
l
l
=
l
l
l
l
l
J (1.11)
Let
0
{0, 0, 0}
T
= x ; thus
0
0
( ) 0
3
' '
1 1
1 1
1 1
1 1
1 1
=
! !
1 1
1 1
1 1
1 1
1 1 + +
g x and
0
2 0 4
( ) 0 2 0
4 0 0
l
l
l
=
l
l
l
l
l
J x (1.12)
From Equation (1.8)
1
0.75 0 0.375
T
= x , and
1
0.5625
( ) 0
0.5625
' '
1 1
1 1
1 1
1 1
1 1
=
! !
1 1
1 1
1 1
1 1
1 1 + +
g x and
1
2.75 0 2.5
( ) 0 2.75 0
2.5 0 0
l
l
l
=
l
l
l
l
l
J x (1.13)
leading to
1
0.975 0 0.8475
T
= x . After few more iterations, the solution
converges towards
*
1 0 1
T
= x , the exact solution.
In practice, it is challenging to compute the Jacobian analytically via Equation
(1.9). Instead, a finite difference approximation may be used:
( ) ( )
i j i
ij
g he g
h
x x
J (1.14)
where
1 2
{1, 0, .., 0} , {0,1, .., 0}
T T
e e = = , etc.
We implement the Newton-Raphson method via a Python method 'fsolve'
(mimicking the Matlab function with the same name). The first few lines of the
fsolve module is as follows:
Observe that the function definition has two essential arguments: (1) the function
( ) g x and (2) the initial guess
0
x . Optional keyword arguments include the
Jacobian function, tolerances for termination and the maximum allowed
iterations.
If the Jacobian function is not provided, we rely on equation (1.14) to compute
an approximate Jacobian; its implementation is as follows:
Observe that the above function is defined inside the fsolve function. Then, the
main Newton-Raphson iteration is implemented as follows:
The reader is encouraged to study the above Python implementation.
The 'fsolve' function may be used as follows . First the g function is defined
per Equation (1.10):
One can now solve the nonlinear equations via:
Optionally, the Jacobian of Equation (1.11) may be defined via:
With this additional function, one can solve the problem via:
In both cases, the solution converges to
*
1 0 1
T
= x .
1.18 Dynamic Function Synthesis
Sometimes there is a need to dynamically synthesize or create a function. In
other words, the nature of function is determined during run-time. We will come
across such a scenario in Chapter 4. Here, we provide an illustrative example of
dynamic function synthesis.
Consider a scenario where a function ( ) f x is defined as follows:
sin( ); 0
( ; )
cos( ); 0
x
f x
x
' '
1 1
1 1
1 1
=
! !
1 1 <
1 1
1 1 + +
(1.15)
In other words, depending on the value of , the function is defined dynamically.
In Python one would implement and test this as follows.
Observe that the function fCreate returns a function object. The function
returned by fCreate depends on the auxiliary variable . Once the function is
created, it can be used like any function in Python.
1.19 Logging in Python
Python also provides excellent tools for debugging large software projects.
One such tool is logging. Below is an example to illustrate the use of logging in
Python. Observe that we have imported the logging module. There are various
methods for configuring logging; a few different options are illustrated below. In
particular, the level argument can be used to determine the behavior of the
logging utility. We shall make extensive use of logging later in the text.
When the above is executed, we see the following output on the console.
Further a file example.log is also created, with the following contents:
1.20 Python Class
Finally, we discuss the important concept of a class. A class, in object
oriented languages such as Python, is a collection of objects and methods that are
closely related. We illustrate the notion of a class through a simple example of a
polynomial class. The objective is to treat polynomials of the form:
2 1
0 1 2 1
( ) ...
N
N
p x a a x a x a x
= (1.16)
as objects with intrinsic methods such as evaluation of polynomials at a point,
addition of polynomials, etc. The polynomial in Equation (1.16) is fully defined by
the array of coefficients:
0 1 2 1
...
N
a a a a
= a (1.17)
For example, the following polynomial:
2
( ) 1 3.2 p x x x = (1.18)
is captured by the coefficients:
1, 1, 3.2 = a (1.19)
In Python, a Polynomial class may be defined via the following syntax:
Observe the use of the keyword class, and the keyword self that allows access to
quantities associated with a polynomial object. The py.array is used to copy aIn
so we do not experience the quirk we saw when dealing with lists. Once the above
class is defined in a file PolynomialClass.py, we can create a polynomial object as
follows:
The above code, by convention of the class, creates the polynomial object
representing:
2
( ) 1 3.2 p x x x = (1.20)
The class does nothing more at this point, since we have not associated any
behavior with this object. Let us now overload the __str__ method so that
print provides a human readable form:
The above code essentially retrieves the coefficients and creates a string for
display; the reader is encouraged to understand the logic behind the code. We
can now display the polynomial object created earlier as follows:
We can also add a method to evaluate polynomial objects at a particular point:
Its usage is:
The reader can verify that the reported value is indeed correct.
Next, we consider the addition of polynomials of the same order. Recall that
the addition operator takes on different interpretation depending on the object
associated with it. For integers and floats, it is interpreted as the usual addition,
while for strings and lists, it is interpreted as concatenation. We now overload the
addition operator for the polynomial class, with the natural interpretation:
( ) ( ) ( ) ( )
2 1
0 1 2 1
2 1
0 1 2 1
2 1
0 0 1 1 2 2 1 1
( ) ...
( ) ...
( ) ( ) ...
N
N
N
N
N
N N
p x a a x a x a x
q x b b x b x b x
p x q x a b a b x a b x a b x
=
=
=
(1.21)
In the Polynomial class, we create a new method with the keyword __add__
that overloads the + operator:
Its usage is:
We can continue to add other methods (such as subtraction of polynomials,
multiplication of a polynomial by a scalar, etc).
1.21 Exercises
Exercise 1-1: Under Python command prompt, evaluate the following
expressions: (a)
3 3
10 1 10 , (b)
16 16
10 1 10 , (c)
5
1 10 1
, and (d)
16
1 10 1
= is almost zero (to within 0.001). Compare the result with the
previous exercise.
Exercise 1-8: Write a Python function binSearch.py that asks the reader to
think of an integer between 0 & 1000. Then guess this number using no more
than 10 questions for which the user must reply with a y/n (yes or no).
Exercise 1-9: Write a Python function coins.py that asks the reader to input an
integer between 1 and 100 (cents). Then the program should return the least
number of coins to reconstruct the input integer. Allowed coins are: a penny (1
cent), nickel (5 cents), dime (10 cents) and quarter (25 cents). For examples,
suppose the user specifies 38 cents, the desired solution is 1 quarter, 1 dime, 3
pennies.
Exercise 1-10: Use graphical means to find the minimum location (to within
0.001) of the function
2
2
( ) 1
x
f x xe