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 added additional complex list operations #123
NUMBERS-186 added additional complex list operations #123
Conversation
Codecov Report
@@ Coverage Diff @@
## complex-gsoc-2022 #123 +/- ##
====================================================
Coverage 99.13% 99.13%
Complexity 1699 1699
====================================================
Files 65 65
Lines 4274 4274
Branches 836 836
====================================================
Hits 4237 4237
Misses 10 10
Partials 27 27 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The forEach has been copied from replaceAll without removing the concurrent modification check or updating the javadoc. The test is also incorrectly named.
For your javadoc can you make sure you do not use the term element; here we should use complex number.
The tests should use data where each item in the list is unique. Index out of bound exceptions should be tested, especially at the upper size limit as without a range check the get methods can return stale/invalid data and the set methods may silently not error and write to an unused part of the backing array.
* @param real Real part \( a \) of the complex number \( (a + ib) \). | ||
* @param imaginary Imaginary part \( b \) of the complex number \( (a + ib) \). | ||
*/ | ||
void apply(double real, double imaginary); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
java.util.function.Consumer has the method accept
*/ | ||
public double getReal(int index) { | ||
rangeCheck(index); | ||
final int i = index << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this variable, just perform the index doubling inline
/** | ||
* Gets the real part \( a \) of the complex number \( (a + i b) \) at the indexed position of the list. | ||
* | ||
* @param index Index of the element's real part to get. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Index of the complex number.
@@ -177,6 +203,63 @@ public Complex set(int index, Complex element) { | |||
return oldValue; | |||
} | |||
|
|||
/** | |||
* Replaces the complex element's real part at the specified position |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change element
to number
. Element is for a generic list; since this is typed to Complex then all element occurrences should be changed to complex number
/** | ||
* Replaces the complex element's imaginary part at the specified position | ||
* in this list with the specified imaginary element. | ||
* @param index Index of the element's imaginary part to replace. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add an empty line
Assertions.assertEquals(list.get(i).getReal(), list.getReal(i)); | ||
} | ||
for (int i = 0; i < list.size(); i++) { | ||
Assertions.assertEquals(list.get(i).getImaginary(), list.getImaginary(i)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be placed in the same loop as above. Add a simple message to the assertion, e.g. "real".
list.addAll(list); | ||
list.setReal(2, 200); | ||
list.setImaginary(2, 1); | ||
Assertions.assertEquals(Complex.ofCartesian(200, 1), list.get(2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test set at all positions:
for (int i = 0; i < list.size(); i++) {
final double value = Math.PI * i;
list.setReal(i, value);
Assertions.assertEquals(value, list.get(i).getReal());
}
Also test set/get with invalid index positions (-1, size, size+1).
@Test | ||
void testToArrayRealAndImaginary() { | ||
ComplexList list = new ComplexList(); | ||
list.add(Complex.ofCartesian(42, 13)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a better random list.
list.addAll(list); | ||
list.set(2, Complex.ofCartesian(200, 1)); | ||
|
||
double[] expectedReal = {42, 42, 200, 42}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double[] expected = list.stream().mapToDouble(Complex::getReal).toArray();
|
||
double[] expectedReal = {42, 42, 200, 42}; | ||
double[] actualReal = list.toArrayReal(); | ||
for (int i = 0; i < expectedReal.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Assertions.assertArrayEquals
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks OK. Just a few minor changes to address. Thanks
*/ | ||
public void setImaginary(int index, double imaginary) { | ||
rangeCheck(index); | ||
final int i = index << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index i should be inlined.
*/ | ||
public void setReal(int index, double real) { | ||
rangeCheck(index); | ||
final int i = index << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index i should be inlined.
@@ -152,9 +153,9 @@ void testAddIndexOutOfBoundExceptions() { | |||
|
|||
@Test | |||
void testRemoveIndexOutOfBoundExceptions() { | |||
List<Complex> objectList = generateList(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since a lot of the tests now use generateList() then addAll to a new ComplexList instance this should be refactored into a method: private static ComplexList generateComplexList(int)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have removed too many uses of i = index << 1
. There are some where this is useful.
Also the test class should have generateList and generateComplexList. The later to be used only when the list will not be compared to another list using assertEquals, e.g. for tests for accessor methods.
*/ | ||
private static List<Complex> generateList(int size) { | ||
return ThreadLocalRandom.current().doubles(size, -Math.PI, Math.PI) | ||
private static ComplexList generateList(int size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are use cases for generateList
and generateComplexList
. The generateList would function as before and return a List implementation from the JDK. This can be assumed to work correctly. The generateComplexList would call generateList and then addAll to a new ComplexList instance. This should be asserted to be equal to the original List. This method can be used for convenience to populate a ComplexList for testing the accessor methods (get/set).
One case where you may wish to have a List that is not a ComplexList is in testing addAll. You also require a non ComplexList for any list compared for equality with ComplexList: you cannot have a list equals comparison to itself as there may be the same error in both implementations being compared.
* @return the complex number. | ||
*/ | ||
@Override | ||
public Complex get(int index) { | ||
rangeCheck(index); | ||
final int i = index << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The precomputed value i will be reused so it can be left as before, please revert.
rangeCheck(index); | ||
final int i = index << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The precomputed value i will be reused so it can be left as before, please revert.
In addition the call to setNoRangeCheck can be removed. Since you already have the value i this will avoid calling it again.
This PR introduces additional operations that can be done on ComplexList.
Summary of changes
ComplexListTest - unit tests for complex additional operations on ComplexList
ComplexConsumer - interface that acts as a consumer for the complex element's double real and imaginary parts