Re: [Numbers] Arrays of "Complex" objects and RAM

2019-11-08 Thread Gilles Sadowski
Hi.

Le sam. 9 nov. 2019 à 01:48, Alex Herbert  a écrit :
>
>
>
> > On 7 Nov 2019, at 23:29, Eric Barnhill  wrote:
> >
> > On Thu, Nov 7, 2019 at 3:25 PM Gilles Sadowski  wrote:
> >
> >> Le jeu. 7 nov. 2019 à 18:36, Eric Barnhill  a
> >> écrit :
> >>>
> >>> I should also add on this note, my use case for developing ComplexUtils
> >> in
> >>> the first place was compatibility with JTransforms and JOCL. In both
> >> cases
> >>> I wanted to convert Complex[] arrays into interleaved double[] arrays to
> >>> feed into algorithms using those libraries.
> >>
> >> Implicit in my remark below is the question: Where does the "Complex[]"
> >> come from?  If it is never a good idea to create such an array, why provide
> >> code to convert from it?  Do we agree that we should rather create the
> >> "ComplexList" abstraction, including accessors that shape the data for
> >> use with e.g. JTransforms?
> >>
> >>
> > I completely agree this is a superior solution and look forward to its
> > development.
>
> I think at least the minimum implementation of the abstraction will be fairly 
> easy. It can then be performance checked with a few variants.
>
> There currently is not a JMH module for numbers. Should I create one under a 
> module included with an optional profile?

What is going to be benchmarked?

>
> I have spent a fair bit of time trying to fix coverage of Complex. It is now 
> at 100% with 95% branch coverage. It currently tests all the edge cases for 
> the C standard. However it doesn’t really test actual computations.

Actual computations?
Coveralls seems OK:

https://coveralls.io/builds/26869201/source?filename=commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java

> I am going to continue on this to add more tests that the computations output 
> the same values as a C reference implementation, and hit all the branches.
>
> When working on the class it raised a few questions:
>
> 1. HashCode
>
> This is current the same for any number with a NaN component. However the C 
> standard states that NaN components are allowed in infinites. So perhaps the 
> hashCode should be updated to at least distinguish infinites from NaN.

What would be the purpose?

>
> 2. NaN definition
>
> What is not clear is if there exists a definition of NaN for a complex 
> number. The C library has no way to test it with a single function call. You 
> have to test both the real and imaginary components. On top of this you can 
> do computation with NaNs. The GNU g++ compiler computes:
>
> (1e300 + i 1e300) * (1e30 + i NAN) = inf + i inf
>
> Thus this is allowing some computations with NaN to produce results. I don’t 
> know if this is a bug in GNU g++ or intentional. The C standard states:
>
> “If both operands of the * operator are complex or if the second operand of 
> the / operator
> is complex, the operator raises floating-point exceptions if appropriate for 
> the calculation
> of the parts of the result, and may raise spurious floating-point exceptions.”
>
> That is pretty vague. It says that you can do what is “appropriate”.
>
> So it seems that perhaps we should only call a complex a NaN is both fields 
> are NaN. If only one is NaN then the complex is semi-NaN and results of 
> computations may or may not make sense.

Do you have an example of a NaN that makes sense?
What is semi-NaN?

>
> 3. Multiplication
>
> I applied a change to the algorithm provided in the C standard when 
> recovering (NaN,NaN) results of multiplying infinities. If you multiply 
> infinity by zero this should be NaN.
>
> “if one operand is an infinity and the other operand is a nonzero finite 
> number or an
> infinity, then the result of the * operator is an infinity;"
>
> Note the “non-zero” condition.
>
> But the algorithm provided does not do this and you can get an infinite 
> result back.
>
> This is what GNU g++ does:
>
> multiply(0 + i 0, 0 + i inf) = -nan + i -nan
> multiply(-0 + i 0, 0 + i inf) = -nan + i -nan
> multiply(0 + i 0, -0 + i inf) = -nan + i -nan
> multiply(-0 + i 0, -0 + i inf) = -nan + i -nan
> multiply(0 + i 0, 1 + i -inf) = -nan + i -nan
> multiply(-0 + i 0, 1 + i -inf) = -nan + i -nan
>
> So they have implemented the multiply differently because here multiply 
> infinity by zero is NaN. Note how printf distinguishes the sign of infinite 
> values. I don’t think Java does this. It collates NaN into one 
> representation. I will have to convert to raw long bits to get the sign for a 
> cross reference to a C version.

I don't follow.  Why would it be useful to distinguish -NaN from NaN or i NaN?

>
> 4. Divide
>
> I have applied a change to this algorithm to check for overflow in the 
> division. The reference text states:
>
> “if the first operand is a finite number and the second operand is an 
> infinity, then the
> result of the / operator is a zero;”
>
> But for example GNU g++ does this:
>
> divide(1e+308 + i 1e+308, inf + i inf) = -nan + i 0
>
> This is what the reference 

Re: [Numbers] Arrays of "Complex" objects and RAM

2019-11-08 Thread Alex Herbert


> On 7 Nov 2019, at 23:29, Eric Barnhill  wrote:
> 
> On Thu, Nov 7, 2019 at 3:25 PM Gilles Sadowski  wrote:
> 
>> Le jeu. 7 nov. 2019 à 18:36, Eric Barnhill  a
>> écrit :
>>> 
>>> I should also add on this note, my use case for developing ComplexUtils
>> in
>>> the first place was compatibility with JTransforms and JOCL. In both
>> cases
>>> I wanted to convert Complex[] arrays into interleaved double[] arrays to
>>> feed into algorithms using those libraries.
>> 
>> Implicit in my remark below is the question: Where does the "Complex[]"
>> come from?  If it is never a good idea to create such an array, why provide
>> code to convert from it?  Do we agree that we should rather create the
>> "ComplexList" abstraction, including accessors that shape the data for
>> use with e.g. JTransforms?
>> 
>> 
> I completely agree this is a superior solution and look forward to its
> development.

I think at least the minimum implementation of the abstraction will be fairly 
easy. It can then be performance checked with a few variants.

There currently is not a JMH module for numbers. Should I create one under a 
module included with an optional profile?



I have spent a fair bit of time trying to fix coverage of Complex. It is now at 
100% with 95% branch coverage. It currently tests all the edge cases for the C 
standard. However it doesn’t really test actual computations. I am going to 
continue on this to add more tests that the computations output the same values 
as a C reference implementation, and hit all the branches.

When working on the class it raised a few questions:

1. HashCode

This is current the same for any number with a NaN component. However the C 
standard states that NaN components are allowed in infinites. So perhaps the 
hashCode should be updated to at least distinguish infinites from NaN.

2. NaN definition

What is not clear is if there exists a definition of NaN for a complex number. 
The C library has no way to test it with a single function call. You have to 
test both the real and imaginary components. On top of this you can do 
computation with NaNs. The GNU g++ compiler computes:

(1e300 + i 1e300) * (1e30 + i NAN) = inf + i inf

Thus this is allowing some computations with NaN to produce results. I don’t 
know if this is a bug in GNU g++ or intentional. The C standard states:

“If both operands of the * operator are complex or if the second operand of the 
/ operator
is complex, the operator raises floating-point exceptions if appropriate for 
the calculation
of the parts of the result, and may raise spurious floating-point exceptions.”

That is pretty vague. It says that you can do what is “appropriate”.

So it seems that perhaps we should only call a complex a NaN is both fields are 
NaN. If only one is NaN then the complex is semi-NaN and results of 
computations may or may not make sense.

3. Multiplication

I applied a change to the algorithm provided in the C standard when recovering 
(NaN,NaN) results of multiplying infinities. If you multiply infinity by zero 
this should be NaN. 

“if one operand is an infinity and the other operand is a nonzero finite number 
or an
infinity, then the result of the * operator is an infinity;"

Note the “non-zero” condition.

But the algorithm provided does not do this and you can get an infinite result 
back. 

This is what GNU g++ does:

multiply(0 + i 0, 0 + i inf) = -nan + i -nan
multiply(-0 + i 0, 0 + i inf) = -nan + i -nan
multiply(0 + i 0, -0 + i inf) = -nan + i -nan
multiply(-0 + i 0, -0 + i inf) = -nan + i -nan
multiply(0 + i 0, 1 + i -inf) = -nan + i -nan
multiply(-0 + i 0, 1 + i -inf) = -nan + i -nan

So they have implemented the multiply differently because here multiply 
infinity by zero is NaN. Note how printf distinguishes the sign of infinite 
values. I don’t think Java does this. It collates NaN into one representation. 
I will have to convert to raw long bits to get the sign for a cross reference 
to a C version.

4. Divide

I have applied a change to this algorithm to check for overflow in the 
division. The reference text states:

“if the first operand is a finite number and the second operand is an infinity, 
then the
result of the / operator is a zero;”

But for example GNU g++ does this:

divide(1e+308 + i 1e+308, inf + i inf) = -nan + i 0

This is what the reference algorithm does if it is not changed. Here overflow 
cause problems in the result (which should be zero). So I think my patch is 
correct and the result should be (0 + i 0). The current unit tests are 
enforcing this requirement.

5. Edge cases

Some of the methods have a large amount of if statements to test edge cases. 
These are very verbose and hard to follow. They also leave the common path of a 
non infinite, non nan, non zero value at the end. So a rearrangement may allow 
better branch prediction for the common use case. I’ll carry on working on this 
as I add more tests. 

6. tanh

I have put a TODO: note in the code about this. It tests 

Re: [commons-numbers] branch master updated: Fix Javadoc using tags.

2019-11-08 Thread Gilles Sadowski
Hi.

Le sam. 9 nov. 2019 à 00:18, Alex Herbert  a écrit :
>
>
>
> > On 8 Nov 2019, at 22:57, Gilles Sadowski  wrote:
> >
> > Hi.
> >
> >> [...]
> >>
> >> commit 7b1b38167c9241462cd08578a37d63d5cd9b7a04
> >> Author: Alex Herbert mailto:aherb...@apache.org>>
> >> AuthorDate: Fri Nov 8 20:28:15 2019 +
> >>
> >>Fix Javadoc using  tags.
> >
> > IMO, the below should rather use MathJax.
>
> I was removing  tags too enthusiastically and broke the javadoc. I just 
> restored it to what was there before.
>
> MathJax can be done in a big block for the whole class (when I have time).

Just an improvement; nothing urgent.  Could be done after the release.

Regards,
Gilles

> >> ---
> >> .../main/java/org/apache/commons/numbers/complex/Complex.java  | 10 
> >> ++
> >> 1 file changed, 10 insertions(+)
> >>
> >> diff --git 
> >> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> >>  
> >> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> >> index 4cfc306..f3e4348 100644
> >> --- 
> >> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> >> +++ 
> >> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> >> @@ -333,9 +333,11 @@ public final class Complex implements Serializable  {
> >>  * {@code (this / divisor)}.
> >>  * Implements the definitional formula
> >>  * 
> >> + * 
> >>  *   a + bi ac + bd + (bc - ad)i
> >>  *   --  =  
> >>  *   c + di   c2 + d2
> >> + * 
> >>  * 
> >>  *
> >>  * Recalculates to recover infinities as specified in C.99
> >> @@ -832,7 +834,9 @@ public final class Complex implements Serializable  {
> >>  * inverse cosine of this complex number.
> >>  * Implements the formula:
> >>  * 
> >> + * 
> >>  *   acos(z) = -i (log(z + i (sqrt(1 - z2
> >> + * 
> >>  * 
> >>  *
> >>  * @return the inverse cosine of this complex number.
> >> @@ -871,7 +875,9 @@ public final class Complex implements Serializable  {
> >>  * http://mathworld.wolfram.com/InverseSine.html;>
> >>  * inverse sine of this complex number.
> >>  * 
> >> + * 
> >>  *   asin(z) = -i (log(sqrt(1 - z2) + iz))
> >> + * 
> >>  * 
> >>  *
> >>  * As per the C.99 standard this function is computed using the 
> >> trigonomic identity:
> >> @@ -1231,7 +1237,9 @@ public final class Complex implements Serializable  {
> >>  * Returns of value of this complex number raised to the power of 
> >> {@code x}.
> >>  * Implements the formula:
> >>  * 
> >> + * 
> >>  *   yx = exp(xlog(y))
> >> + * 
> >>  * 
> >>  * where {@code exp} and {@code log} are {@link #exp} and
> >>  * {@link #log}, respectively.
> >> @@ -1534,7 +1542,9 @@ public final class Complex implements Serializable  {
> >>  * Computes the n-th roots of this complex number.
> >>  * The nth roots are defined by the formula:
> >>  * 
> >> + * 
> >>  *   zk = abs1/n (cos(phi + 2k/n) + i 
> >> (sin(phi + 2k/n))
> >> + * 
> >>  * 
> >>  * for {@code k=0, 1, ..., n-1}, where {@code abs} and {@code 
> >> phi}
> >>  * are respectively the {@link #abs() modulus} and
> >>
> >
> > -
> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org 
> > 
> > For additional commands, e-mail: dev-h...@commons.apache.org 
> > 

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



Re: [commons-numbers] branch master updated: Fix Javadoc using tags.

2019-11-08 Thread Alex Herbert


> On 8 Nov 2019, at 22:57, Gilles Sadowski  wrote:
> 
> Hi.
> 
>> [...]
>> 
>> commit 7b1b38167c9241462cd08578a37d63d5cd9b7a04
>> Author: Alex Herbert mailto:aherb...@apache.org>>
>> AuthorDate: Fri Nov 8 20:28:15 2019 +
>> 
>>Fix Javadoc using  tags.
> 
> IMO, the below should rather use MathJax.

I was removing  tags too enthusiastically and broke the javadoc. I just 
restored it to what was there before.

MathJax can be done in a big block for the whole class (when I have time).

> 
> Regards,
> Gilles
> 
>> ---
>> .../main/java/org/apache/commons/numbers/complex/Complex.java  | 10 
>> ++
>> 1 file changed, 10 insertions(+)
>> 
>> diff --git 
>> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
>>  
>> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
>> index 4cfc306..f3e4348 100644
>> --- 
>> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
>> +++ 
>> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
>> @@ -333,9 +333,11 @@ public final class Complex implements Serializable  {
>>  * {@code (this / divisor)}.
>>  * Implements the definitional formula
>>  * 
>> + * 
>>  *   a + bi ac + bd + (bc - ad)i
>>  *   --  =  
>>  *   c + di   c2 + d2
>> + * 
>>  * 
>>  *
>>  * Recalculates to recover infinities as specified in C.99
>> @@ -832,7 +834,9 @@ public final class Complex implements Serializable  {
>>  * inverse cosine of this complex number.
>>  * Implements the formula:
>>  * 
>> + * 
>>  *   acos(z) = -i (log(z + i (sqrt(1 - z2
>> + * 
>>  * 
>>  *
>>  * @return the inverse cosine of this complex number.
>> @@ -871,7 +875,9 @@ public final class Complex implements Serializable  {
>>  * http://mathworld.wolfram.com/InverseSine.html;>
>>  * inverse sine of this complex number.
>>  * 
>> + * 
>>  *   asin(z) = -i (log(sqrt(1 - z2) + iz))
>> + * 
>>  * 
>>  *
>>  * As per the C.99 standard this function is computed using the 
>> trigonomic identity:
>> @@ -1231,7 +1237,9 @@ public final class Complex implements Serializable  {
>>  * Returns of value of this complex number raised to the power of {@code 
>> x}.
>>  * Implements the formula:
>>  * 
>> + * 
>>  *   yx = exp(xlog(y))
>> + * 
>>  * 
>>  * where {@code exp} and {@code log} are {@link #exp} and
>>  * {@link #log}, respectively.
>> @@ -1534,7 +1542,9 @@ public final class Complex implements Serializable  {
>>  * Computes the n-th roots of this complex number.
>>  * The nth roots are defined by the formula:
>>  * 
>> + * 
>>  *   zk = abs1/n (cos(phi + 2k/n) + i (sin(phi 
>> + 2k/n))
>> + * 
>>  * 
>>  * for {@code k=0, 1, ..., n-1}, where {@code abs} and {@code phi}
>>  * are respectively the {@link #abs() modulus} and
>> 
> 
> -
> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org 
> 
> For additional commands, e-mail: dev-h...@commons.apache.org 
> 


Re: [commons-numbers] branch master updated: Fix Javadoc using tags.

2019-11-08 Thread Gilles Sadowski
Hi.

> [...]
>
> commit 7b1b38167c9241462cd08578a37d63d5cd9b7a04
> Author: Alex Herbert 
> AuthorDate: Fri Nov 8 20:28:15 2019 +
>
> Fix Javadoc using  tags.

IMO, the below should rather use MathJax.

Regards,
Gilles

> ---
>  .../main/java/org/apache/commons/numbers/complex/Complex.java  | 10 
> ++
>  1 file changed, 10 insertions(+)
>
> diff --git 
> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
>  
> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> index 4cfc306..f3e4348 100644
> --- 
> a/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> +++ 
> b/commons-numbers-complex/src/main/java/org/apache/commons/numbers/complex/Complex.java
> @@ -333,9 +333,11 @@ public final class Complex implements Serializable  {
>   * {@code (this / divisor)}.
>   * Implements the definitional formula
>   * 
> + * 
>   *   a + bi ac + bd + (bc - ad)i
>   *   --  =  
>   *   c + di   c2 + d2
> + * 
>   * 
>   *
>   * Recalculates to recover infinities as specified in C.99
> @@ -832,7 +834,9 @@ public final class Complex implements Serializable  {
>   * inverse cosine of this complex number.
>   * Implements the formula:
>   * 
> + * 
>   *   acos(z) = -i (log(z + i (sqrt(1 - z2
> + * 
>   * 
>   *
>   * @return the inverse cosine of this complex number.
> @@ -871,7 +875,9 @@ public final class Complex implements Serializable  {
>   * http://mathworld.wolfram.com/InverseSine.html;>
>   * inverse sine of this complex number.
>   * 
> + * 
>   *   asin(z) = -i (log(sqrt(1 - z2) + iz))
> + * 
>   * 
>   *
>   * As per the C.99 standard this function is computed using the 
> trigonomic identity:
> @@ -1231,7 +1237,9 @@ public final class Complex implements Serializable  {
>   * Returns of value of this complex number raised to the power of {@code 
> x}.
>   * Implements the formula:
>   * 
> + * 
>   *   yx = exp(xlog(y))
> + * 
>   * 
>   * where {@code exp} and {@code log} are {@link #exp} and
>   * {@link #log}, respectively.
> @@ -1534,7 +1542,9 @@ public final class Complex implements Serializable  {
>   * Computes the n-th roots of this complex number.
>   * The nth roots are defined by the formula:
>   * 
> + * 
>   *   zk = abs1/n (cos(phi + 2k/n) + i (sin(phi 
> + 2k/n))
> + * 
>   * 
>   * for {@code k=0, 1, ..., n-1}, where {@code abs} and {@code phi}
>   * are respectively the {@link #abs() modulus} and
>

-
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org