Skip to main content

Section B.7 Best approximation

Warning B.7.1.

This page contains several redefinitions of a Python function inprod. You will get incorrect results or errors if you Evaluate a Sage cell defining that function in one subsection below, and then Evaluate Sage cells that use a function by that same name in a different subsection below without evaluating the appropriate Sage cell near the beginning of that different subsection that redefines that inprod function to the appropriate formula used in the example in that particular subsection.

The best way to avoid this problem is to Evaluate every Sage cell in a particular subsection, from the beginning, in order.

Subsection B.7.1 Approximating a matrix

Here we will use Sage to carry out the calculations in Example 38.3.1.

We carry out the whole process, including Gram-Schmidt to obtain the orthogonal basis. The subspace \(U\) is described as consisting of [those] upper-triangular matrices with \((1,2)\) entry equal to the trace of the matrix. Parametrically, we can describe \(U\) as

\begin{equation*} U = \left\{ \begin{bmatrix} a \amp a + b \\ 0 \amp b \end{bmatrix} \right\} \text{,} \end{equation*}

where \(a\) and \(b\) are free parameters. This leads to (non-orthogonal) basis

\begin{equation*} \left\{ \begin{bmatrix} 1 \amp 1 \\ 0 \amp 0 \end{bmatrix}, \begin{bmatrix} 0 \amp 1 \\ 0 \amp 1 \end{bmatrix} \right\} \text{,} \end{equation*}

where these matrices correspond to parameter choices \(\{a = 1, b = 0\}\) and \(\{a = 0, b = 1\}\text{,}\) respectively.

Set up.

First let's load our initial basis vectors for \(U\) into Sage.

As in Section B.6, let's make life easier by creating a Python procedure for our inner product.

Note: B.T is a Sage “shortcut” for B.transpose().

Gram-Schmidt That Thing.

It's the dead duo's time to shine.

Ugh, fractions. Since scaling doesn't affect orthogonality, let's scale \(E_2\) to clear the fractions.

That's better.

Projection time.

The point of this example is to compute the matrix in \(U\) that is closest to being the identity matrix. For that, we want to compute \(\proj_U I\text{.}\)

As expected, this is an upper-triangular matrix with the \((1,2)\) entry equal to the trace. In other words, the result does indeed lie in the subspace \(U\text{.}\)

Let's verify that \(\proj_U I\) and \(\proj_{U^\perp} I = I - proj_U I\) are orthogonal.

Yep, they're orthogonal. Which means we can use the projection onto \(U^\perp\) to compute the distance from \(I\) to the space \(U\text{.}\)

Subsection B.7.2 Approximating a function

Here we will use Sage to carry out the calculations in Example 38.3.2.

As we have already demonstrated using Sage to apply Gram-Schmidt on our initial basis for this problem in Section B.6, we'll skip that part this time and proceed immediately to entering in our function, our orthogonal basis, and our inner product function.

Time to drop that perp.

Note: The backslash at the end of some lines are a Python line continuation character, so that separate lines can be joined into one command for better readability.

Huh, that was pretty easy. Who knew that with the right set-up, a computer could turn a tedious calculation into something so simple?

Finally, let's calculate the “error” in our approximation.

How does this compare to the “error” in the “naive” approximation described at the beginning of Example 38.3.2?

So the orthogonal projection is better by a factor of \(2\text{.}\) (Though this judgement is relative to the definition of the inner product.)