2014-06-03 18:26 GMT-04:00 Rik Cabanier <caban...@gmail.com>:

>
>
>
> On Tue, Jun 3, 2014 at 2:40 PM, Benoit Jacob <jacob.benoi...@gmail.com>
> wrote:
>
>>
>>
>>
>> 2014-06-03 17:34 GMT-04:00 Benoit Jacob <jacob.benoi...@gmail.com>:
>>
>>
>>>
>>>
>>> 2014-06-03 16:20 GMT-04:00 Rik Cabanier <caban...@gmail.com>:
>>>
>>>
>>>>
>>>>
>>>> On Tue, Jun 3, 2014 at 6:06 AM, Benoit Jacob <jacob.benoi...@gmail.com>
>>>> wrote:
>>>>
>>>>>
>>>>>
>>>>>
>>>>> 2014-06-03 3:34 GMT-04:00 Dirk Schulze <dschu...@adobe.com>:
>>>>>
>>>>>
>>>>>> On Jun 2, 2014, at 12:11 AM, Benoit Jacob <jacob.benoi...@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>> > Objection #6:
>>>>>> >
>>>>>> > The determinant() method, being in this API the only easy way to get
>>>>>> > something that looks roughly like a measure of invertibility, will
>>>>>> probably
>>>>>> > be (mis-)used as a measure of invertibility. So I'm quite confident
>>>>>> that it
>>>>>> > has a strong mis-use case. Does it have a strong good use case?
>>>>>> Does it
>>>>>> > outweigh that? Note that if the intent is precisely to offer some
>>>>>> kind of
>>>>>> > measure of invertibility, then that is yet another thing that would
>>>>>> be best
>>>>>> > done with a singular values decomposition (along with solving, and
>>>>>> with
>>>>>> > computing a polar decomposition, useful for interpolating
>>>>>> matrices), by
>>>>>> > returning the ratio between the lowest and the highest singular
>>>>>> value.
>>>>>>
>>>>>> Looking at use cases, then determinant() is indeed often used for:
>>>>>>
>>>>>> * Checking if a matrix is invertible.
>>>>>> * Part of actually inverting the matrix.
>>>>>> * Part of some decomposing algorithms as the one in CSS Transforms.
>>>>>>
>>>>>> I should note that the determinant is the most common way to check
>>>>>> for invertibility of a matrix and part of actually inverting the matrix.
>>>>>> Even Cairo Graphics, Skia and Gecko’s representation of matrix3x3 do use
>>>>>> the determinant for these operations.
>>>>>>
>>>>>
>>>>> I didn't say that determinant had no good use case. I said that it had
>>>>> more bad use cases than it had good ones. If its only use case if checking
>>>>> whether the cofactors formula will succeed in computing the inverse, then
>>>>> make that part of the inversion API so you don't compute the determinant
>>>>> twice.
>>>>>
>>>>> Here is a good use case of determinant, except it's bad because it
>>>>> computes the determinant twice:
>>>>>
>>>>>   if (matrix.determinant() != 0) {    // once
>>>>>     result = matrix.inverse();         // twice
>>>>>   }
>>>>>
>>>>> If that's the only thing we use the determinant for, then we're better
>>>>> served by an API like this, allowing to query success status:
>>>>>
>>>>>   var matrixInversionResult = matrix.inverse();   // once
>>>>>   if (matrixInversionResult.invertible()) {
>>>>>     result = matrixInversionResult.inverse();
>>>>>   }
>>>>>
>>>>
>>>> This seems to be the main use case for Determinant(). Any objections if
>>>> we add isInvertible to DOMMatrixReadOnly?
>>>>
>>>
>>> Can you give an example of how this API would be used and how it would
>>> *not* force the implementation to compute the determinant twice if people
>>> call isInvertible() and then inverse() ?
>>>
>>
>> Actually, inverse() is already spec'd to throw if the inversion fails. In
>> that case (assuming we keep it that way) there is no need at all for any
>> isInvertible kind of method. Note that in floating-point arithmetic there
>> is no absolute notion of invertibility; there just are different matrix
>> inversion algorithms each failing on different matrices, so "invertibility"
>> only makes sense with respect to one inversion algorithm, so it is actually
>> better to keep the current exception-throwing API than to introduce a
>> separate isInvertible getter.
>>
>
> That would require try/catch around all the "invert()" calls. This is ugly
> but more importantly, it will significantly slow down javascript execution.
> I'd prefer that we don't throw at all but we have to because SVGMatrix did.
>

So, if we have to have inverse() throw, do you agree that this removes the
need for any isInvertible() kind of method? For the reason I explained
above (invertibility is relative to a particular inversion algorithm) I
would rather have inversion and invertibility-checking be provided by a
single function. If we do have the option of not throwing, then that could
be a single function returning both the inverse and a boolean.

Benoit


>
>
>
>>  Typical bad uses of the determinant as "measures of invertibility"
>>>>> typically occur in conjunction with people thinking they do the right 
>>>>> thing
>>>>> with "fuzzy compares", like this typical bad pattern:
>>>>>
>>>>>   if (matrix.determinant() < 1e-6) {
>>>>>     return error;
>>>>>   }
>>>>>   result = matrix.inverse();
>>>>>
>>>>> Multiple things are wrong here:
>>>>>
>>>>>  1. First, as mentioned above, the determinant is being computed twice
>>>>> here.
>>>>>
>>>>>  2. Second, floating-point scale invariance is broken: floating point
>>>>> computations should generally work for all values across the whole 
>>>>> exponent
>>>>> range, which for doubles goes from 1e-300 to 1e+300 roughly. Take the
>>>>> matrix that's 0.01*identity, and suppose we're dealing with 4x4 matrices.
>>>>> The determinant of that matrix is 1e-8, so that matrix is incorrectly
>>>>> treated as non-invertible here.
>>>>>
>>>>>  3. Third, if the primary use for the determinant is invertibility and
>>>>> inversion is implemented by cofactors (as it would be for 4x4 matrices)
>>>>> then in that case only an exact comparison of the determinant to 0 is
>>>>> relevant. That's a case where no fuzzy comparison is meaningful. If one
>>>>> wanted to guard against cancellation-induced imprecision, one would have 
>>>>> to
>>>>> look at cofactors themselves, not just at the determinant.
>>>>>
>>>>> In full generality, the determinant is just the volume of the unit
>>>>> cube under the matrix transformation. It is exactly zero if and only if 
>>>>> the
>>>>> matrix is singular. That doesn't by itself give any interpretation of 
>>>>> other
>>>>> nonzero values of the determinant, not even "very small" ones.
>>>>>
>>>>> For special classes of matrices, things are different. Some classes of
>>>>> matrices have a specific determinant, for example rotations have
>>>>> determinant one, which can be used to do useful things. So in a
>>>>> sufficiently advanced or specialized matrix API, the determinant is useful
>>>>> to expose. DOMMatrix is special in that it is not advanced and not
>>>>> specialized.
>>>>>
>>>>> Benoit
>>>>>
>>>>>
>>>>>> Greetings,
>>>>>> Dirk
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to