Re: comments on Matrix

2013/3/20 Rik Cabanier <cabanier@gmail.com>

>
>
> On Wed, Mar 20, 2013 at 6:29 PM, Benoit Jacob <jacob.benoit.1@gmail.com>wrote:
>
>>
>>
>> 2013/3/20 Rik Cabanier <cabanier@gmail.com>
>>
>>>
>>>
>>> On Tue, 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.
>>>>
>>>
>>> Are you suggesting that the user should check all the values to make
>>> sure that the matrix inversion didn't fail? That seems very expensive.
>>> Can you point us to an algorithm for inversion that you think the spec
>>> should include?
>>>
>>
>> No, I'm saying that we should _not_ check anything, or if we do (say in a
>> separate "checked inverse" method), it should be in a graceful way e.g. an
>> output boolean parameter, not throwing an exception which by default halts
>> the program. That's what I meant by "The consensus[...] is to just blindly
>> perform the computation --- in the worst case you'll get Inf or NaN values
>> in the result" above.
>>
>
> That's certainly tempting! I can see how that's easier (and less
> disrupting).
>
> I checked 2 of our internal libraries, as well as Cairo, Skia and Flash
> and they all refuse to calculate the matrix if it's not invertible. So, not
> all matrix libraries do as you suggest.
> SVGMatrix is also documented to throw.
> These are all matrix classes designed for graphics so I *think* it makes
> sense to follow what they did.
>

I had dedicated matrix libraries in mind, rather than the casual incidental
matrix computation in something like Cairo.


>
>
>>
>>
>> The algorithm for inversion is going to be plain closed-form matrix
>> inversion (i.e. by computing the cofactors) as in
>> http://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3.C3.973_matricesbut instead of mandating implementers to use particular formulas, a good
>> matrix API would rather carefully avoid being too sensitive to the exact
>> floating-point values (e.g. by not throwing on singular matrices) because
>> even mandating formulas won't ensure that the results are the same
>> everywhere up to the last bit of precision.
>>
>
> I don't know how important this is as it seems like this would only apply
> to edge cases.
> Are there any w3c specs that define how precise a calculation should
> happen? I can see how this would be very important for mathematical
> programs but less so for graphics.
>

That's my point: the last bits of mantissa are irrelevant to graphics, so
we should just make sure that our API doesn't accidentally make them unduly
important (e.g. by throwing on singular matrix or trying to avoid methods
like is2D() that can return true or false depending on them). Once we've
ensured that, we really don't need no worry about different browsers giving
slightly different values. That's a good thing, because it would be
completely unrealistic to expect exact values. Keep in mind that in
floating point, a*(b*c) and (a*b)*c give different results i.e.
associativity doesn't even hold. Same for distributivity: a*b+a*c !=
a*(b+c). So for example just a single browser having a SSE and a non-SSE
codepath would almost certainly get different results from them.

Benoit

Received on Thursday, 21 March 2013 03:38:59 UTC