Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUMBERS-186: Lists of Complex Numbers #121

Conversation

sumanth-rajkumar
Copy link
Contributor

@sumanth-rajkumar sumanth-rajkumar commented Aug 29, 2022

This PR introduces a new complex arrays module that introduces ComplexList where the complex numbers in the complex module are stored using an interleaved format. This allow operations to be performed on lists of complex numbers.

Summary of changes

  1. ComplexList - representation of multiple complex numbers into a list structure storing real and imaginary parts.
  2. ComplexListTest - unit tests that tests all conditions of adding, removing, getting, and setting the list.

Copy link
Contributor

@aherbert aherbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I have added some comments from an initial review. Please ask questions if anything is unclear.

* limitations under the License.
*/
/**
* Complex numbers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Provides a list of complex numbers.

<item name="Overview" href="index.html"/>
<item name="Latest API docs (development)"
href="apidocs/index.html"/>
<item name="Javadoc (1.0 release)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are not required as this package has not been released. Only the latest API docs item is required.


<body>

<section name="Apache Commons Numbers: Number Types and Utilities" href="summary">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section name does not seem relevant

return list.add(Complex.ofCartesian(11, 12));
});

assertListOperation(list -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repeats the above test but changes the final add. The assert method with the consumer does not appear to be relevant and can be dropped and replaced with the assert method taking the function.

I think here would be better tested using smaller functions:

assertListOperation(list -> list.add(Complex.ofCartesian(42, 13)));
assertListOperation(list -> list.add(1, Complex.ofCartesian(11, 12)));
// etc

list.add(1, Complex.ofCartesian(11, 12));
});

ComplexList list = new ComplexList();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intension to add an empty list to an empty list? A comment would be useful.

final int numNew = c.size();
expand(numNew * 2);
double[] realAndImgData = new double[c.size() * 2];
int i = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just increment this in the loop:

        for (final Complex val : c) {
            realAndImgData[i++] = val.getReal();
            realAndImgData[i++] = val.getImaginary();
        }

rangeCheckForInsert(index);
final int numNew = c.size();
final int numNew2 = numNew << 1;
expand(numNew * 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expand method is expecting a number of elements, not a number of doubles. So this should not be doubled.

final int numNew = c.size();
final int numNew2 = numNew << 1;
expand(numNew * 2);
final double[] realAndImgData = new double[c.size() * 2];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reuse the numNew local variable instead of calling size again. The size method may be dynamically computed by the collection.

System.arraycopy(realAndImagParts, i + 2, realAndImagParts, i, numMoved);
}
size--;
realAndImagParts[s] = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has no purpose as this part of the array should never be accessed as it is out-of-range.

private String outOfBoundsMsg(int index) {
return INDEX_MSG + index + SIZE_MSG + size;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra line.

Copy link
Contributor

@aherbert aherbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sumanth-rajkumar

This just needs a few small changes to be ready. Thanks.

@@ -24,17 +24,9 @@
</properties>

<body>

<section name="Apache Commons Numbers: Number Types and Utilities" href="summary">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you still need this section.

You can render the site documentation using:

mvn site:site -DgenerateReports=false
open target/site/index.html

Looking at the documentation for other modules this seems to be standard boiler plate used in all modules. So you should reinstate it. Sorry for the error.

assertListOperation(list -> list.add(Complex.ofCartesian(21, 22)), l1, l2);
assertListOperation(list -> list.add(Complex.ofCartesian(23, 24)), l1, l2);

List<Complex> l3 = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not clear what is achieved in the l3, l4 test that has not already been done above.

List<Complex> l5 = new ArrayList<>();
List<Complex> l6 = new ComplexList();
assertListOperation(list -> list.add(Complex.ofCartesian(1, 2)), l5, l6);
assertListOperation(list -> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not better served by:

assertListOperation(list -> list.add(Complex.ofCartesian(1, 2)), l5, l6);
// Expand the list by doubling in size until at the known minArrayCapacity
while (l5.size() < 8) {
    assertListOperation(list -> list.addAll(list), l5, l6);
}
assertListOperation(list -> list.addAll(list1), l5, l6);

<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-complex</artifactId>
</dependency>
<dependency>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need these test dependencies at the moment

/**
* The double array buffer into which the elements of the ComplexList are stored.
*/
protected double[] realAndImagParts;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to be protected.

System.arraycopy(realAndImagParts, i + 2, realAndImagParts, i, numMoved);
}
size--;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra line

/**
* {@inheritDoc}
*
* @param index {@inheritDoc}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need all the inheritDoc here.

In fact you do not require it for any param where you are using the inheritDoc tag. If you delete the param tag totally IIUC it should just pull in the parent javadoc for that parameter. So you should be able to delete a lot of param tags that simple use inheritDoc.

You can test with:

mvn javadoc:javadoc

And then look at the output javadoc in the target directory. If this is OK then you can delete all the plain inheritDoc param tags. Note the inheritDoc will pull in the parent documentation. Then typically you add more information to it. If you are not adding information then do not bother.

* @throws IndexOutOfBoundsException if index isn't within the range.
*/
private void rangeCheck(int index) {
if (index < 0 || index >= size) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that ArrayList does not perform index < 0 here. This check is for access. If the index is negative then the IOOBE will be generated with the index value.

This is different from rangeCheckForInsert as there is copy operations that must be performed before the index is written to. If the index is negative then these operations may fail with unwanted runtime exception messages.

# limitations under the License.
# -----------------------------------------------------------------------------
#
# Empty file used to automatically trigger profile from commons parent pom
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trigger JApiCmp profile

assertListOperation(operation, new ArrayList<>(), new ComplexList());
}

private static class SizedList extends ArrayList<Complex> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be commented so its purpose is clear. It deliberately reports a fixed size (and is therefore a non-functional list) and is used to trigger capacity exceptions when adding a collection to the ComplexList.

@aherbert aherbert merged commit 2bd5755 into apache:complex-gsoc-2022 Sep 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants