Professional Documents
Culture Documents
1 Python Programming: 1.1 Getting Started With Python
1 Python Programming: 1.1 Getting Started With Python
Associated with objects are methods that act on these objects. By typing a ‘dot’
after the object variable name, you can access a list of methods associated with it.
For example, with the string object ‘a’ are methods to capitalize the first letter,
find a substring, etc. This is illustrated below; the reader is encouraged to
familiarize themselves with various methods associated with integer, float and
string objects.
One can manipulate, combine and display objects as illustrated below. Observe
that the meaning of the ‘+’ operator is context dependent. For integers and floats,
it is interpreted as the usual addition; for strings, it is interpreted in Python as a
concatenation.
Also, observe that, one can assign new variables to existing objects (as in b = a,
below). Reassigning the variable b to a different object (in this case) does not
alter the contents of a (as in b = ‘world!’).
1.3 Lists
A particularly useful object in Python is that of a list that is simply a collection
of other Python objects. Below are a few examples of list objects. Observe that: (1)
lists can contain a variety of objects (integers, strings, etc), and (2) they can even
contain other list objects as in b = [34, a], (3) addition of lists leads to a
concatenation as in c = a + a, and (4) access to individual elements of a list is
through the [] operator (as in a[2]); the indexing of individual elements of a list
starts from 0, rather than 1.
List objects are however different from integers, floats and strings in the
following sense. In the example below, observe that ‘a’ and ‘b’ variables are
initially ‘pointing’ to the same list object. However, modifying b, by accessing its
individual elements, modifies the underlying list, and is therefore reflected in the
variable a. This fundamental difference is to be noted.
A particularly useful method of creating a list of integers is the ‘range’ function.
Lists play an important role in this text since arrays (to be discussed later on) are
a special incarnation of lists.
You can execute the above program through the Run command (or via the F5
short-cut). When the Python program is executed for the first time in Spyder, the
following configuration window opens up. In the window, choose the Interactive
Python (IPython) mode, and hit Run.
Then, the following output appears in the Console window.
The reader is encouraged to study the Python script and the output.
In the above script file, we have included two types of Python comments: (1)
the hash (‘#’) symbol used for single-line comments, i.e., the remainder of the
line following the ‘#’ is treated as a comment, and (2) the triple-quotes for multi-
line comments, i.e., any text between two triple-quotes is treated as a comment;
the triple-quotes also serves as a means of documenting, also referred to as a
docstring, the script file (we shall revisit this topic later on).
This results in the figure below; the reader is encouraged to experiment with the
code.
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):
2
Figure 1-5: Plot of 1 − xe −x .
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
f (α, β ) = (α − 1)2 + (β − 4)4 (1.4)
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.
One can now run the SimpleFunctions.py module (through F5 shortcut), and the
result is shown below.
2
Figure 1-6: Plot of 1 − xe −x , and its gradient.
Python returns the integer component of the result. This implicit integer
interpretation is common to many languages, and can cause headaches in
numerical computation; the reader should therefore be very watchful of implicit
integer conversion. One can override this behavior as follows
In Python modules, the import statement must appear at the first line.
Henceforth, we shall include the above statement in all Python modules.
A second ‘feature’ unique to Python is the strict adherence to indentation at
the beginning of an expression. Consider the following code:
The only difference between this and the previous code was the inclusion of an
extra ‘space’ before the number of ‘5.0’. Python does not allow extraneous use of
space or tabs at the beginning of expressions. The underlying reason is that it
uses spaces and tabs to identify blocks of code associated. We shall revisit this
concept again later on.
The third aspect is particularly relevant to readers familiar with Matlab™.
Consider the multplication of a 2x2 matrix and a 2x1 vector. In Matlab, one
would construct a matrix and vector as follows:
Then, the multiplication in Matlab is as follows:
In Python, the syntax for creating matrices and vectors is a bit more elaborate:
♦
In practice, it is challenging to compute the Jacobian analytically via Equation
(1.9). Instead, a finite difference approximation may be used:
g (x + he j ) − gi (x)
Jij ≈ i (1.14)
h
where e1 = {1, 0,.., 0}T , e2 = {0,1,.., 0}T , 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 x 0 . 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:
T
{ }
In both cases, the solution converges to x * = 1 0 1 .
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.
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:
p(x ) = 1 − x + 3.2x 2 (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:
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:
p(x ) = a 0 + a1x + a 2x 2 + ... + a N −1x N −1
q(x ) = b0 + b1x + b2x 2 + ... + bN −1x N −1
(1.21)
⇒
p(x ) + q(x ) = (a 0 + b0 ) + (a1 + b1 ) x + (a 2 + b2 ) x 2 + ... + (a N −1 + bN −1 ) x N −1
In the Polynomial class, we create a new method with the keyword ‘__add__’
that overloads the ‘+’ operator:
Its usage is:
1.21 Exercises
Exercise 1-1: Under Python command prompt, evaluate the following
expressions: (a) 10 3 + 1 − 103 , (b) 1016 + 1 − 1016 , (c) 1 + 10−5 − 1 , and (d)
1 + 10−16 − 1 . Explain the apparent discrepancies.
2x + 3y + 4z = 5 2x + 3y + 4z = 5
2x + 3y + 4z = 5
x − 6y − 2z = 2 x − 6y − 2z = 2 x − 6y − 2z = 2 (1.22)
5x − 2y + 6z = −1
5x − 15y − 2z = 11
5x − 15y − 2z = 15
Explain the results.
Exercise 1-4: Find the eigen-values and eigen-vectors of the above matrices.
Now explain the conclusions of Equation via eigen-values and eigen-vectors.
d 2f
= −1; f (0) = f (1) = 0 (1.23)
dx 2
Pose and solve the above differential equation via central finite difference. The
theory to convert differential equation problem into a linear algebra problem via
finite difference. Also see the diag command in Python to capture the resulting
finite difference matrix.
Exercise 1-6: Using sampling, find the minimum location (to within 0.001) of
2
the function f (x ) = 1 − xe −x . Verify that the gradient of the function is nearly
zero at that location.
Exercise 1-7: Using sampling, find the location where the derivative of
2
f (x ) = 1 − xe −x 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
2
0.001) of the function f2 (x ) = 1 − xe −x . Verify that the gradient of the function is
nearly zero at that location.
Exercise 1-11: Using contour plots, find the minimum location (to within a
radius of 0.001) of the function
1 100 2
2 ( u 2 + (v + 1)2 − 1 +)
f (u, v ) =
1 2
500
2
( u 2 + (v − 1)2 − 1) − (10u + 8v )
Verify that the gradient of the function is nearly zero at that location.
Exercise 1-12: Modify the Polynomial class so that one can add Polynomials of
different orders. Include the following test case:
p(x ) = 1 − x + 3.2x 2
q(x ) = 1 + x
(1.24)
r (x ) = p(x ) + q(x ) = ?
r (x ) = q(x ) + p(x ) = ?
Exercise 1-13: Expand the Polynomial class to include subtraction of
polynomials of different orders. Include the following test case:
p(x ) = 1 − x + 3.2x 2
q(x ) = 1 + x
(1.25)
r (x ) = p(x ) − q(x ) = ?
r (x ) = q(x ) − p(x ) = ?
Exercise 1-14: Expand the Polynomial class to include multiplication of
polynomials of different orders. Include the following test case:
p(x ) = 1 − x + 3.2x 2
q(x ) = 1 + x
(1.26)
r (x ) = p(x )q(x ) = ?
r (x ) = q(x )p(x ) = ?