comments on Matrix

Hi,

Seeing that a matrix API was being discussed (
https://dvcs.w3.org/hg/FXTF/raw-file/default/matrix/index.html), I thought
I'd take a look and chime in.

Here are the first few things that scare me, glancing at the current draft:

1. Some functions like inverse() throw on singular matrices. The problem is
it's impossible to define very firmly what singular means, in
floating-point arithmetic --- except perhaps by prescribing a mandatory
order in which the arithmetic operations inside of inverse() are performed,
which would be insane --- so saying that inverse() throws on singular
matrices means in effect that there are realistic matrices on which it is
implementation-defined whether inverse() throws or not. The consensus in
all the serious matrix libraries that I've seen, for closed-form matrix
inversion, is to just blindly perform the computation --- in the worst case
you'll get Inf or NaN values in the result, which you will have anyway on
some input matrices unless you mandate unduly expensive checks. More
generally, I would never throw on singular-ness in any function, and in the
case of 4x4 matrices and closed-form computations I wouldn't attempt to
report on singular-ness otherwise than by inf/nan values.

2. I am concerned that something like DecomposedMatrix is under-documented
and opens a pandora box of adding features.

2a. DecomposedMatrix is under-documented.

All I can see for documentation is the algorithms given in sections 5 and
6. I would like to see a mathematical description of the components of this
decomposition i.e. I shouldn't have to look at code. This is not precisely
implied by the sames of the fields in DecomposedMatrix.

2b. DecomposedMatrix is a pandora box of adding features

There are so many different ways of decomposing a matrix that once you
start offering something like DecomposedMatrix, people will ask for endless
variants, and you'll have to either bloat the API until it's really big or
accept that your API only is useful in a small minority of use cases. Just
an example, it seems that you chose to call "scaling" scaling coefficients
along the X, Y, Z axes. So when users will want to perform a polar
decomposition, say matrix = rotation * scaling where scaling is along
arbitrary axes (i.e. an arbitrary symmetric matrix), they won't find
DecomposedMatrix very useful. If you accept to add such a polar
decomposition, then next thing people will ask for polar decompositions on
the other side (matrix = scaling * rotation) and if you ask that, then next
thing is people will ask for SVD decompositions. Another example is you
chose to represent rotations as quaternions, so people will ask you to add
also rotation matrices (say for performance of multiplying with vectors)
and for angle-axis representation, and for Euler angles... That won't end
before your API has evolved into a full-blown matrix library, which will be
costly for browser developers to support.

3. Many concepts are not defined (and their mathematical names aren't that
specific).
Examples "the skew angle in degrees", the "perspective" vector, the order
of coefficients in a quaternion (is the unit quaternion 1,0,0,0 or 0,0,0,1
in your convention?)

4. Some method names are verbs, yet they do not perform an action on their
object. Example: translate(). I would call that translated(), I suppose.

5. Is2D() is going to suffer from the same caveats as discussed above about
singular-ness: it is going to be too capricious, in effect its return value
will be implementation-defined on realistic matrices. I don't think that a
Web-facing API should have such things.

6. More generally I am concerned that it is going to be difficult to find a
good compromise between keeping this small and easy for browsers to
implement, and making this useful to many people. There are so many things
to take care of in a matrix library. Suppose for a moment that this becomes
really popular. People are going to benchmark browsers running matrix
computations using this API. That will add pressure on browser developers
to make this run as fast as possible, yet this API is inherently unfriendly
to optimizing performance: from simple things like counting in degrees, to
deeper things such as the fact that this API forces to split nontrivial
matrix calculations into multiple calls (e.g. .scale().translated()....)
and that means that making this run as fast as possible, i.e. without
useless temporaries, will require dedicated support from the JS compiler
(to achieve the same temporaries-removing tricks that C++ matrix libraries
achive using expression templates). This is serious stuff --- performance
gains can be 2x on real-world operations. So this will really be a chore
for browser developers to maintain, and I haven't even started talking
about SIMD... Meanwhile, with things like asm.js, high-performance JS is
closing in on "native" performance, and since a JS matrix library
implicitly exposes the entire expression trees to the JS compiler, they can
automatically benefit from generic JS compiler optimizations for things
like the above-mentioned temporaries-removal, and more. Moreover, this
allows one to pick any existing high-quality C++ matrix library -- there
are many! -- rather than having to use a one-size-fits-all Web standard
library. In fact I expect that people will do that anyway, so that any
official standard Web matrix library, I am afraid, is at risk of being
another little-used Web API incurring overhead onto browser developers.

Benoit

Received on Wednesday, 20 March 2013 01:38:52 UTC