commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <>
Subject Re: [math] Complex division
Date Sat, 03 Sep 2011 21:55:33 GMT
On 9/3/11 2:17 PM, Gilles Sadowski wrote:
> On Sat, Sep 03, 2011 at 08:10:59AM -0700, Phil Steitz wrote:
>> On 9/3/11 2:30 AM, Gilles (JIRA) wrote:
>>>     [
>>> Gilles commented on MATH-657:
>>> -----------------------------
>>> I've just posted a mail on "dev".
>> Should be discussed on the dev list.
> That's why I posted the mail referred to above...
>> We should not be trying to
>> have discussions on API changes on JIRA tickets. That is not what
>> JIRA is for.
> Hmm, I thought I was doing the right thing by following the example of
> By the way, it shows that following a older dicussion on JIRA is much more
> convenient than hopping from one post to another on ML archive, with the
> myriad of quotes, double-quotes, triple-quotes, ...
>> It is an unwritten (well, probably is actually written
>> down somewhere by now) rule @apache that if a decision "did not
>> happen on the dev list, then it did not happen."   We should be
>> talking about API design issues on this list, not opening JIRAs each
>> time we think an API should be changed and trying to have the
>> discussion on the JIRA ticket.
> Sorry if I broke an old and venerable rule. It was not the intention;
> for me, it was just solving a trivial bug in the same manner I did already
> before, and not a unilateral decision to "change the API".
>>> IMO, the main argument is consistency. Also with how reals (i.e. {{double}})
work; IIUC, MATH-164 triggered a change for that same reason.
>>> Arne Plöse is a user and [reported|MATH-620] that the previous behaviour was
not fine for him.
>> What exactly was the practical problem?  Arne, care to elaborate?
> Not wanting to answer for Arne; just my own two cents: Why not give the
> right answer?

The problem is that it is not obvious that INF is "the right answer."
> Maybe that we can _decide_ that any manipulation of a "Complex" instance
> containing infinities is mildly meaningless (in the applications where CM
> is used) and return NaN for any operation involving them (?). That would
> probably simplify several methods (and make them more efficient). Unless I'm
> mistaken that would just cost a comment like
>   "Manipulating instances with infinities will result in undefined results."

That is a defensible view.  See comments below.
>>> I don't think that this one change can have a discernible performance impact.
>>> It might not be necessary to map all {{Complex}} instances that have an infinite
component to a single object. I pointed it as a convenient justification for fixing a bug
>> Not so clear it is a "bug" - the only way to characterize it as such
>> is to model the space as compactified.
> As you say yourself below, having an INF is to assume that the "Complex"
> class represents elements from C U {"point at infinity"}. At least that's
> how I interpret it.
> Had there not be a special handling of instances that have an infinity in
> their real or imaginary part, I'd say that the NaN result would be normal,
> as the output of the computational formulae.
> But this would entail to let operations produce their expected results,
> which is not the case with "z.multiply(z)", as reported by Arne:
>> I notice now that multiply sort of behaves this way, and as I said
>> on the ticket, we have already defined "INF" so an argument could be
>> made that we are partly there already.  I would like to understand
>> the practical arguments pro and con - and by "practical" I mean
>> examples of how the proposed change and any others impact actual
>> uses of the class in applications.  I have reviewed my own
>> applications and for those, there is no immediate impact (other than
>> performance hit in division and complex construction),
> Did you measure it?
> Are you sure that performance is not _improved_ for division? :-)
>>  but I worry a
>> little about losing the ability to represent directed infinities if
>> we decide to really aim for "consistency" here.
> What are the use-cases for those?
> When looking for references, I only stumbled on the usefulness of _one_
> "point at infinity".

When a sequence of iterates diverges in modulus to infinity, it
might in some cases be useful to know that the divergence was along
a specific vector, like for example the real or imaginary axis.  I
have - almost - needed this in applications that track orbits of
points under iterated functions, but I don't have a specific
application use case for this personally.
>> I guess we could
>> retain directed infinities by adding a directed INF with an argument
>> attribute, but that would again add overhead to several operations.
> If you have applications that deal with any "directed" infinities, don't you
> need polar coordinates too? That seems to be missing in class Complex
> (talking about new API...).
> Then, would the "argument attribute" be the angle?

Yes, the argument would effectively be the angle.
>> At this point, I would like to see r1164756 reverted until we have
>> agreed on this change.
> Well, that is done. And, IMHO, there is an identified bug (or at least
> an inconsistency worth removing) there. I would like to see use cases that
> justify keeping the inconsistency. A mathematical explanation will do too
> ;-).

The mathematical question is do we view our class as representing
the extended complex numbers.  If we agree that the answer to that
question is yes, then "the right answer" for the one division
instance being considered here is to return INF.  If we don't, then
NaN is a better answer.  If we agree yes, then we should also modify
equals and there are likely other changes required to other
arithmetic operations.

IIRC, we tried to find a compromise between efficiency, ease of
understanding the javadoc, C99x compliance and mathematical
correctness when defining the contracts for the complex arithmetic
operations that are documented in the javadoc now.  We could fiddle
with these contracts endlessly and add lots more ad hoc tests and
attributes to try to make them "more correct" or "consistent with X"
where X can be defined variously as "the way Doubles work", "IEEE
Floating Point specs," "C specs" or your favorite other package. 
Given that changes carry a cost for all users of the current code, I
think the onus is on those who want to make changes to explain in
practical terms why the proposed change is worth making.  I don't
(yet) see this one as worth making.  What would be really great
would be some input from users who can provide examples why
different contracts would be more (or less) useful in applications.

> Thanks,
> Gilles
> P.S. I've just seen that you completely removed changes that I find useful
>      _independently_ of the decision to change or not the behaviour of
>      division by zero:
>       * factoring out multiple tests into separate test methods,
>       * keeping track of test cases that correspond to an issue, and
>       * using a flag "isZero" in the "divide" method.
>      Thus, they were left on purpose, as supposed enhancements similar to
>      those which several people commit informally from time to time.
>      Is it customary to pull the rug out from under someone's feet?

I asked that the commit be reverted.  I just completed the reversion
because I saw that the javadoc contract change had not been
reverted.  I just used svn merge with revision numbers to do a clean
revert.  The added "isZero" attribute is part of the performance
hit.  This, btw, is yet another reason to separate commits.

> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message