Debugging Hints

AMath 585, Winter Quarter 2020 at the University of Washington. Developed by R.J. LeVeque and distributed under the BSD license. You are free to modify and use as you please, with attribution.

These notebooks are all available on Github.

This notebook shows a simple example.

In [1]:
%matplotlib inline
In [2]:
from pylab import *
from scipy.linalg import expm

The code below is supposed to solve $u'(t) = Iu(t)$ with $u(0) = \eta$ in the $5\times 5$ case where $I$ is the identity matrix and all elements of $\eta$ are equal to 1.

In [3]:
def utrue(t):
    # Solve u'(t) = A u(t) with A = I, u(0) = eta
    A = eye(5)   # 5x5 identity matrix
    eta = array([1.,1.,1.,1.])
    u = dot(expm(A*t),eta)  # matrix-vecor multiply
    return u
In [4]:
utrue(1.)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-e870a834c014> in <module>()
----> 1 utrue(1.)

<ipython-input-3-e80bc8810856> in utrue(t)
      3     A = eye(5)   # 5x5 identity matrix
      4     eta = array([1.,1.,1.,1.])
----> 5     u = dot(expm(A*t),eta)  # matrix-vecor multiply
      6     return u

ValueError: shapes (5,5) and (4,) not aligned: 5 (dim 1) != 4 (dim 0)

The error message above some information about where the error occurred, and you might figure out from this that we tried to multiply a $5\times 5$ matrix by a vector with only 4 components, due to a typo in specifying eta.

We can get more information by turning on the pdb debugger, using the Jupyter "magic" command pdb. If you execute this a second time, it turns the debugger off.

In [5]:
pdb
Automatic pdb calling has been turned ON
In [6]:
utrue(1.)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-e870a834c014> in <module>()
----> 1 utrue(1.)

<ipython-input-3-e80bc8810856> in utrue(t)
      3     A = eye(5)   # 5x5 identity matrix
      4     eta = array([1.,1.,1.,1.])
----> 5     u = dot(expm(A*t),eta)  # matrix-vecor multiply
      6     return u

ValueError: shapes (5,5) and (4,) not aligned: 5 (dim 1) != 4 (dim 0)
> <ipython-input-3-e80bc8810856>(5)utrue()
      2     # Solve u'(t) = A u(t) with A = I, u(0) = eta
      3     A = eye(5)   # 5x5 identity matrix
      4     eta = array([1.,1.,1.,1.])
----> 5     u = dot(expm(A*t),eta)  # matrix-vecor multiply
      6     return u

ipdb> A
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])
ipdb> eta
array([1., 1., 1., 1.])
ipdb> print(A.shape, eta.shape)
(5, 5) (4,)
ipdb> q

Note that it now gives a ipdb> prompt at the point where the exception occurred. You can query the state of variable, e.g. by typing an expresssion or a print statement and then hitting Enter. Type q and Enter to quit (which you have to do before you can execute any other cell).

In [7]:
pdb
Automatic pdb calling has been turned OFF

You can also put in a breakpoint to probe the state at some point, even if it is not giving an error. Here's a corrected version of the code with a breakpoint added.

In [8]:
from pdb import set_trace

def utrue(t):
    # Solve u'(t) = A u(t) with A = I, u(0) = eta
    A = eye(5)   # 5x5 identity matrix
    eta = array([1.,1.,1.,1.,1.])
    u = dot(expm(A*t),eta)
    print('This breakpoint is after setting A, eta, and u')
    set_trace()  # breakpoint here
    return u
In [9]:
utrue(1.)
This breakpoint is after setting A, eta, and u
> <ipython-input-8-41e99edc18f7>(10)utrue()
-> return u
(Pdb) print(A.shape, eta.shape)
(5, 5) (5,)
(Pdb) print(u[0])
2.718281828459045
(Pdb) c
Out[9]:
array([2.71828183, 2.71828183, 2.71828183, 2.71828183, 2.71828183])

You can end the (Pdb) prompt with q to quit, or if things are working right, with c to continue executing from this point.

If you happen to delete a cell when it's waiting for pdb input and the notebook hangs, remember that you can select Interrupt from the Kernel menu. Sometimes this doesn't work and you have to Restart the kernel instead.