left-icon

MATLAB Succinctly®
by Dmitri Nesteruk

Previous
Chapter

of
A
A
A

CHAPTER 8

A Mathematical Smörgåsbord

A Mathematical Smörgåsbord


We have spent most of this book discussing the facilities MATLAB provides; now let’s take a look at a few hands-on examples. After all, scripts and plots and OOP are all very nice, but sometimes you just want to calculate something, and it is great to know in advance what function to call.

Elementary Math

No, really, I’m not going to reiterate primary school material. What I will talk about are some of the most basic facilities that are implemented via functions.

Let’s start with a simple fact: every operator, be it * or .^ or the matrix \ operator, has a correspondingly named function. For example, + can be invoked as

>> plus(i,j)

ans =
   0.0000 + 2.0000i

These notations are of little use to us (who would want to be using functions instead of operators?) except in cases where we want to use them as function handles, or when we want to implement (overload) it for our classes. For example, say you have a class called Size and you want to support two sizes being added together. In this case, you define your class like this:

classdef Size < handle

  properties

    w = 0

    h = 0

  end

  methods

    function obj = Size(ww,hh)

      obj.w = ww;

      obj.h = hh;

    end

    function obj = plus(a,b)

      obj = Size(a.w + b.w, a.h + b.h);

    end

  end

end

The plus function takes care of the operator calls, and here’s how you would use it:

>> s1 = Size(2,3);
>> s2 = Size(20,30);
>> s1+s2

ans =

  Size with properties:

    w: 22
    h: 33

Next up, we have various cumulative calculation functions. For example, sum and prod calculate the sum or product of all the elements in an array (these functions generally do not care about array dimensions—they treat all arrays as flattened). In addition to cumsum (cumulative sum) that we’ve already seen, there is a corresponding cumprod (cumulative product) function.

>> x = [1 2 3 4];
>> sum(x),prod(x)

ans =
    10


ans =
    24

>> cumsum(x),cumprod(x)

ans =
     1     3     6    10

ans =
     1     2     6    24

There is also a function called diff that calculates the differences between adjacent elements in an array. One of its uses is to calculate the “delta” value of an array initialized with linspace:

>> z = linspace(0,1,101);
>> dz = diff(z(1:2))

dz =

    0.0100

Lastly, we have functions for calculating the floor and ceiling of a number—these are floor and ceil, respectively. Also, we have the round function that rounds to the nearest integer, and fix, which rounds towards zero:

>> y=-5.55;
>> [floor(y) ceil(y) round(y) fix(y)]

ans =
    -6    -5    -6    -5

Finally, mod does modulo division (MATLAB hijacked the % operator for comments, unfortunately) and rem calculates the remainder of division. These are identical for positive values but yield different results for negative ones:

>> [mod(11,3),rem(11,3);mod(-11,3),rem(-11,3)]

ans =

     2     2
     1    -2

Trigonometry, Exponents, and Logs

Life wouldn’t be fun without trigonometry, would it? As one would expect, MATLAB comes with support for all the common trig functions and their hyperbolic variations. Bizarrely, each function exists in two variations: an ordinary function that takes its arguments in radians, and the same function postfixed with –d (e.g., cosd) that takes degrees. Also, inverse functions are prefixed with a rather than arc, so the inverse cotangent would be acot.

The only function of note is hypot, which calculates the square root of the sum of squares (or the hypotenuse of a triangle).

>> hypot(3,4)

ans =
     5

Moving on, we have the fairly obvious exp (calculates ⅇx, note there is no “e” constant in MATLAB), log (the natural logarithm), and sqrt (x). log10 calculates the base 10 logarithm. There are also more obscure functions to calculate logarithms and exponents for small values of x as well as versions of exp/log/sqrt prefixed with real- that throw exceptions on negative input:

>> realsqrt(-1)
Error using realsqrt
Realsqrt produced complex result.

Complex Numbers

The support for complex numbers is built into MATLAB, and you get the i/j constants (functions, really, but you get the idea) for defining and manipulating complex values. In addition to ordinary arithmetic, you can calculate the real and imag (imaginary) parts of complex numbers, the complex conj (conjugate) and a few other, less exciting things.

>> u = 2+3i;
>> [real(u) imag(u) conj(u)]

ans =
   2.0000 + 0.0000i   3.0000 + 0.0000i   2.0000 - 3.0000i

Notice how the result of real is still a complex number.

Note that there is a difference between calling x' and transpose(x) on a matrix that has complex values: the first performs a conjugate transpose, the second a non-conjugate one:

>> a = sqrt(-magic(2))
a =
   0.0000 + 1.0000i   0.0000 + 1.7321i
   0.0000 + 2.0000i   0.0000 + 1.4142i

>> a'
ans =
   0.0000 - 1.0000i   0.0000 - 2.0000i
   0.0000 - 1.7321i   0.0000 - 1.4142i

>> transpose(a)
ans =

   0.0000 + 1.0000i   0.0000 + 2.0000i
   0.0000 + 1.7321i   0.0000 + 1.4142i

Special Functions

While MATLAB doesn’t give you every single special function under the sun, it does give you the popular ones such as Beta, Gamma, a variety of Bessel functions, the Error function, and its complementary functions such as the Legendre function.

Also, MATLAB isn’t shy in using special functions in its own results when it cannot derive something. For example, using the Symbolic Toolbox to calculate xn ex we get:

>> int(x^n*exp(x),x)
ans =
(x^n*igamma(n + 1, -x))/(-x)^n

Of course, it would be very surprising if we actually got an analytic solution for the above integral!

The “2008” Problem

Discrete Math

As we’ve mentioned in our discussion on basic syntax, MATLAB has hijacked the ! operator to send calls to the underlying operating system. This unfortunately prevents us from being able to use ! for factorials—instead MATLAB gives us the factorial function. Oh, and there is no double factorial or subfactorial support, which can be a problem if you want to solve that famous “2008” problem.

Discrete math functions let you calculate lots of independent things, like the greatest common divisor and least common multiple (gcd and lcm respectively), prime values such as the lowest prime less or equal to a value (primes), or all the prime factors of a number (factor).

Incidentally, you’ll sometimes see toolboxes reuse (overload) existing functions for their own, nefarious ends. The factor function is a good example:

>> syms a b
>> factor(a*x*x+b*x)

ans =
x*(b + a*x)

Test Matrices

MATLAB has lots of different functions for generating various matrices useful for testing or demonstrations. We’ve already used the magic square matrix to show sorting, but there are lots of other matrices such as the Hilbert, Hadamard, Toeplitz, Hankel, and other matrices.

In addition to these, there is also a gallery function that has even more sample matrices (use help gallery to get a listing). For example, to generate a 5 × 5 matrix filled with zeros or ones, you can write:

>> gallery('rando',5)

ans =

     1     0     0     1     0
     0     1     1     1     0
     0     0     1     0     0
     0     0     1     1     0
     1     0     0     0     0

Interpolation

MATLAB supports several types of interpolation. Let’s look at 1D interpolation first—this requires juts a single list of values. The spline function, for instance, lets us perform cubic interpolation, which lets us ”fill in the dots” on an incomplete data set:

>> x = linspace(0,3*pi,11);
>> y = sin(x) ./ x;
>> x2 = linspace(0,3*pi,101);
>> y2 = spline(x,y,x2);
Warning: Columns of data containing NaN values have been ignored during interpolation.
> In interp1>Interp1DStripNaN at 239
  In interp1 at 176
>> plot(x,y,'xr',x2,y2)

And here’s the plot with x marks indicating the original values, and the line indicating the interpolated spline:

36

Original values and the interpolated spline.

In fact, the spline function is a specialization of the interp1 function with a ‘spline’ parameter. For 2D and 3D data we simply have interp2 and interp3 respectively. To illustrate 3D interpolation, let’s use the flow function to generate a coarse approximation of fluid flow and then interpolate over a finer mesh:

[x,y,z,v] = flow(10);
[xi,yi,zi] = meshgrid(0.1:.2:10,-4:.2:4,-4:.2:4);
vi = interp3(x,y,z,v,xi,yi,zi);
slice(xi,yi,zi,vi,[6 9.5],2,[-2 .2])
shading('flat')

To render the image shown below, we used the slice function to effectively take and show slices out of a volumetric plot:

37

Slice plot of an interpolated flow model.

Incidentally, it’s worth mentioning that in addition to meshgrid, which works in 2D and 3D space, there is also a corresponding ngrid function that works in N-D space. Its operation is very similar to meshgrid: you simply provide the coordinate values for however many dimensions you have and get the corresponding set of arrays.

Optimization

MATLAB supports typical optimization problems: minimizing or maximizing single- or multivariate functions and solving constraint problems. Optimization is a very big topic, so we’ll just look at a few examples, and you can consult the MATLAB documentation and relevant texts on all the scary details of various optimization problems.

Consider the function fx=sinxex

C:\Dropbox\Publications\Books\MATLAB Succintly\38.png

A plot of the function fx=sinxex.

To locate the local minimum in the range (-4, 0) we need, first of all, to define the function to search over—MATLAB’s support for function literals comes in handy here. Then, we use the fminbnd function to find the minimum within the specified bounds:

>> f = @(x) sin(x)/exp(x)

f =

    @(x)sin(x)/exp(x)

>> fminbnd(f,-4,0)

ans =

          -2.3561989868868

There is no corresponding maximizing function: if you need the maximum of fx, simply calculate the mimimum of fx.

In addition to supporting functions of one variable, MATLAB also supports searching for minimums of functions of many variables. For instance, let us suppose that you want to find the maximum of fx1,x2=x1-x12-x22, which looks like this:

40

Surface plot of the function fx1,x2=x1-x12-x22. A particularly good-looking plot that MATLAB documentation really likes to show off.

We can instruct MATLAB to search for a minimum starting somewhere in the (10, 20) range:

>> f = @(x) x(1)*exp(-x(1)^2-x(2)^2);
>> fminsearch(f,[10 20])

ans =
                   11.3125                    25.875

Note that, unlike the bounded fminbnd, fminsearch performs unconstrained optimization.

Let’s move on. The fzero function attempts to locate a root of one equation with one variable. For example, given the following function:

39

A plot of the function fx=x2+10x+16. This quadratic equation actually has two roots,
but we constrained the range in this chart, so you only see one.

We can locate the root by making the assumption that it lies somewhere in the (-6, 6) range:

>> f = @(x) x*x+10*x+16;
>> options = optimset('Display','iter');
>> fzero(f,[-6 6],options)

Func-count    x          f(x)             Procedure
    2              -6            -8        initial
    3            -5.2         -8.96        interpolation
    4            -5.2         -8.96        bisection
    5        -3.47692      -6.68024        interpolation
    6        -1.53846       2.98225        bisection
    7        -2.13675     -0.801812        interpolation
    8        -2.00998    -0.0597757        interpolation
    9        -1.99997   0.000194854        interpolation
   10              -2  -3.24619e-07        interpolation
   11              -2  -1.75504e-12        interpolation
   12              -2             0        interpolation

Zero found in the interval [-6, 6]

ans =

    -2

We have deliberately turned on verbose output options for the above call so as to show you the iterative process. Without the extra setting, the fzero call just gives you the final result.

MATLAB supports a few more optimization algorithms, but a lot more fun can be had with the Optimization Toolbox (for local optimizations) and the Global Optimization Toolbox.

Numerical Integration and Differential Equations

First and foremost, if you want symbolic differentiation or integration (i.e., analytical solutions rather than numeric ones), you need the Symbolic Math Toolbox, because MATLAB doesn’t include this functionality by default. What MATLAB does give you is the ability to perform numerical integration and differentiation as well as methods for solving ordinary (ODE) and partial (PDE) differential equations.

Let’s start with numeric integration. This is done using the integral function, and requires the function itself as well as the integration limits:

>> f = @(x) exp(-x.^2);
>> integral(f,0,1)

ans =
         0.746824132812427

Note: Can you see anything unusual about this code sample? That’s right—when working with numerical methods, your x value might be an array—ergo, we use the elementwise operator (x.^2). Had we used an ordinary exponentiation, we would get a rather cryptic error.

Double and triple integrals are evaluated with integral2 and integral3, respectively. MATLAB also comes with support for a variety of numerical integration methods such as Trapezoidal (trapz) and Simpson (quad).

Now, let’s move on to the fun stuff: solving ODEs (ordinary differential equations). MATLAB comes with several functions all prefixed with ode- followed by numbers and letters, such as ode15i and ode23tb. These are used to distinguish whether the equation to be solved is stiff or nonstiff, and what method (low order, medium order, etc.) is used to solve the equation.

For example, let’s solve the equation:

y'=-ty2-y2

with initial conditions y(0)=1,t[0,5]. For this, we first define our function:

>> f = @(t,y) -t*y/sqrt(2-y^2);

We then use ode45 (nonstiff, medium order method) to solve the equation and plot the results:

>> [tt ff] = ode45(f,[0 5],1);
>> plot(tt,ff)
>> grid on

41

A plot of the solution to our differential equation.

The PDE solver that comes with MATLAB supports 1D parabolic-elliptic PDEs with initial-boundary values. The function pdepe is used to solve the equation, and pdeval evaluates the numerical solution using pdepe’s output. Additional PDE support is provided by functions in the Partial Differential Equation Toolbox.

Fourier Analysis and Filtering

In the realm of Fourier analysis the key operation is, of course, the Fast Fourier Transform function fft as well as its 2D and N-D variants (fft2 and fftn) and their inverse transforms (ifft, ifft2 and ifftn respectively).

As is custom, we illustrate FFT by first creating some data that includes both oscillations as well as noise:

fs = 1000;

t = 1/fs;

l = 1000;

t = (0:l-1)*t;

x = 0.6*sin(2*pi*50*t) + sin(2*pi*120*t);

y = x + 2*randn(size(t));

We now convert to the frequency domain and apply FFT to get the discrete Fourier transform of the noisy signal:

n = 2^nextpow2(l);

yy = fft(y,n)/l;

f = fs/2*linspace(0,1,n/2+1);

In the above, nextpow2 gets us the next power of 2 of a variable. Having performed the transform, we can now plot the spectrum:

42

One-sided spectrum plot of the function yt.

And there you have it—two clear peaks at 50 and 120. Of course, thanks to the noise, we don’t get the exact amplitudes, but then life isn’t perfect either.

So let’s now talk about filtering. MATLAB has functions for 1D and 2D digital filtering, 2D and N‑D convolutions, and a few other things besides. Filtering, which in the 1D case is done with the filter function, is rather interesting. Its signature takes three parameters: the first two are the numerator and denominator coefficient vectors, and last one is the data to filter.

The filter function is useful for lots of things. For example, let’s generate a random path and then plot the simple moving average of a few periods of data:

pointCount = 500;

t = linspace(0,1,pointCount+1);

dt=diff(t(1:2));

dw=randn(pointCount,1)*sqrt(dt);

w = cumsum([0;dw]);

 

periods = 30;

maData = filter(ones(1,periods)/periods,1,w);

plot(t,[w maData])

And here is the end result:

43

A Brownian motion path (blue) and its 30-period moving average (green).

Note: The author of this manuscript makes no claims whatsoever as to the effectiveness of technical analysis techniques (such as use of moving averages) for purposes of financial analysis

It’s virtually impossible to cover every feature of MATLAB in a single book, so we’ll stop here. It is a Succinctly title, after all.

The “2008” Problem

As promised, here’s the solution to the problem presented earlier. First, a reminder: you are given thirteen zeros (0 0 0 0 0 0 0 0 0 0 0 0 0) and you need to use these zeros with some mathematical operations to arrive at a value of 2008.

The trick here is to use the factorial function and the fact that 0!=1 to make some real numbers. The solution can then be acquired from adding up several 0! terms and taking their factorial so, for example

2008=3!+1!2-232

The use of double factorials allows for even shorter solutions. For example,

2008=3*-3!-13*+1-1

where 3*=3!=48. Then there are subfactorials and lots of other tricks to reduce the number of required zeros to a minimum. See if you can find some shorter solutions.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.