W3C home > Mailing lists > Public > public-fx@w3.org > January to March 2013

Re: comments on Matrix

From: Dirk Schulze <dschulze@adobe.com>
Date: Tue, 19 Mar 2013 23:14:33 -0700
To: Benoit Jacob <jacob.benoit.1@gmail.com>
CC: "public-fx@w3.org" <public-fx@w3.org>
Message-ID: <2E084C42-EC3C-4CBB-987B-682422B2B0ED@adobe.com>
Hi Benoit,

On Mar 19, 2013, at 6:38 PM, Benoit Jacob <jacob.benoit.1@gmail.com> wrote:

> 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.

It is easier to answer to the answers entirely, even if we can discuss details in separate threats later.

The specification describes a unified way to exchange matrices across other specifications. This is a very reasonable approach for me. We already have matrix definitions in SVG (SVGMatrix). And even if SVGMatrix is less specified than with this specifications, we have a huge amount of compatible implementations, including all major browsers and even more SVG viewers. I am much less concerned about the specification than you are. In fact, there is a need for an exchange format of transformation descriptions. Currently, HTML Canvas relies on SVGMatrix to describe a CTM.

The primary goal of the specification is interoperability and backwards compatibility. As mentioned before, SVG described SVGMatrix. This specification replaces SVGMatrix with the requirement to be as much backwards compatible as possible. This requires to follow the naming schema chosen in the specification. The interoperability is not limited to SVGMatrix. There is a strong relation to CSS Transforms. The decomposing code is entirely based on the matrix decomposing for CSS Transforms. It was a request from SVG WG members to provide one decomposing operation. To use the same as CSS Transforms is a logical way. The composing and decomposing are described by the pseudo code at the end of the specification (will be removed to avoid duplication with CSS Transforms). I understand your concerns about additional decomposing algorithms, but this is the reasoning for this specific algorithm.

To point 6. This is not a matrix library. The spec provides a simple set of functions to do basic operations. It does not aim to allow full linear algebra. It just specifies what is necessary to fulfill the goal as an common exchange format for transformation matrices. You are mentioning benchmarks for browsers. I actually hope that browsers will optimize for performance as well. This brings the question of precision over performance. Either you make a compromise or decide for one or the other. Again, for me this is not the priority. I can live with one or the other direction.

I hope this answers some of your questions.


> Benoit
Received on Wednesday, 20 March 2013 06:14:59 UTC

This archive was generated by hypermail 2.3.1 : Monday, 22 June 2015 03:33:49 UTC