Another day, another way it doesn’t do what it say

May 29, 2010 at 3:14 am (lying documentation, matlab is bad at math, Simple trivia about its fundamental behavior that you probably can't answer)

The documentation for sparse claims,

S = sparse(i,j,s,m,n,nzmax) uses vectors i, j, and s to generate an m-by-n sparse matrix such that S(i(k),j(k)) = s(k).

This claim is, plainly, false. That is to say, there are easy to find values of i, j and s where

sparse(i,j,s,m,n,nzmax)

produces numerically wildly different results from

X = zeros(m, n)
X(sub2ind([m n], i(:), j(:))) = s(:);

and, therefore,

S = sparse(i,j,s,m,n,nzmax)
if all( S( sub2ind(size(S), i, j) == s )
print("documentation passes!")
else
print("documentation is lying!")
end

produces the expected result (i.e. the result you expect from its being written on this blog.)

Can you figure out under what condition sparse behaves differently from the promises the documentation makes?

Hint: I’m populating a stochastic matrix that encodes dynamics over a discretized state space. That space has boundary conditions, so that while in the middle of the state space you might diffuse in N dimensions to your 2^N nearest grid points, at the edges of the state space you are stuck at the wall and have to reflect onto fewer points.

For extra credit, comment on the ease of converting code using non-sparse matrices to code using sparse matrices, given that it won’t even be numerically the same to begin with.

Permalink Leave a Comment

Graphics puzzle.

August 20, 2009 at 10:50 pm (matlab is bad at math, powerfully stupid graphics, Simple trivia about its fundamental behavior that you probably can't answer, trouble with small numbers)

Hey, I basically wrote the entire answer to the previous indexing puzzle as a comment in response to a request for a hint from a MathWorks employee. I didn’t dig up any examples for it — which is not a function of not having ready examples in my code, but more of a function of having too many examples, and the prospect of digging through all of my previous pissed-off code comments I’ve made every time I ran into the same dumb issue isn’t something that makes me feel good about my productivity in the years I’ve been using MATLAB. So I’ll dig up examples sooner or later.

Funny that I started this blog when I noticed I had reached some critical mass (a blogsweight) of code comments detailing stupid things MATLAB does. Funny because I haven’t even started looking through those comments.

Tonight I was just trying to make a plot on log-log axes — ironically, I was trying to clean and tighten up some graphics code in my archives to make it as fair a comparison as possible for when I go on to show the same graph produced in R using much less code. I wanted two scales and sets of tickmarks on the graph, so I was plotting on two overlapping axes created via plotyy. Some data points on one axis, some lines on the other axis. Something like this:

[ax, h1, h2] = plotyy([1 8], [10/3 90], [2 4], [10 30]);
set(h2, 'Marker', '.', 'LineStyle', 'none');
set(ax(1), 'Xscale', 'log', 'Yscale', 'log');
set(ax(2), 'Xscale', 'log', 'Yscale', 'log'...
    , 'XLim', get(ax(1), 'Xlim'), 'YLim', get(ax(1), 'Ylim'));

Now, correct me if I’m mistaken on the mathematics of logarithms, which I’m not, but if two overlapping axes are both on a log-log scale, and have the same limits — and you can verify that the axes are set up the same–

>> cellfun(@(x) isequal(get(ax(1), x), get(ax(2), x)), {'Xlim', 'Ylim', 'Xscale', 'Yscale', 'XLimMode', 'YLimMode'})
ans =
     1     1     1     1     1     1

– for these log-log axes with identical limits, points (2,10) and (4, 30) ought to lie on top of the line from (1, 10/3) to (8, 90), right?

crap

I’ll give you some time to work out what the problem is.

Or switch to a system that actually plots what you tell it to plot.

If I had wanted crap graphics that bore no relation to the input data I’d use Excel.

Permalink 4 Comments

Integer challenge.

August 6, 2009 at 8:00 pm (matlab is bad at math, Simple trivia about its fundamental behavior that you probably can't answer, unexpressive language, unsystematic type system)

The ninth Mersenne prime is 261 – 1 = 2305843009213693951. Try to cause MATLAB to represent this value in a simple variable, then display it.

For example here is a Python session that passes by direct calculation:

>>> x = pow(2,61) - 1
>>> x
2305843009213693951L

That obtained the value by calculation, but no mathematical sophistication should be required to stuff a number in a variable. In fact, you may want to see if there’s any way you can simply type the number in to MATLAB and have it represented, as you see here in Python:

>>> x = 2305843009213693951
>>> x
2305843009213693951L

MATLAB has built-in uint64 and int64 data types that are, in principle, able to hold this value, so you should have no problem either way. Heh.

(A contrived example, you suggest? I have experiments running in MATLAB that communicate with a simple data acquisition device, one that has an onboard 64-bit timer/counter; I need to read and set that timer.)

Permalink 1 Comment

For your thoughts, a question in three parts

August 1, 2009 at 7:00 am (Simple trivia about its fundamental behavior that you probably can't answer, trouble with small numbers)

Something to chew on: You are presumably aware of array indexing/slicing, in which you have an expression

C = A(B)

and both A and B are arrays (and B is a non-logical array of integers).

1. Write from memory the rules determining what the size of array C will be, in terms of the sizes of arrays A and B.

2. You just want to linearly index into A and get a vector back as the result of your indexing operation. For all A, is there an array B such that A(B) is a column vector?

3. Proceed to rant about how completely dumb that is. Compare with every other array-slicing language on the planet, if necessary.

Permalink 3 Comments

Follow

Get every new post delivered to your Inbox.