You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by GitBox <gi...@apache.org> on 2022/08/29 21:35:15 UTC

[GitHub] [commons-numbers] aherbert commented on a diff in pull request #121: NUMBERS-186: Lists of Complex Numbers

aherbert commented on code in PR #121:
URL: https://github.com/apache/commons-numbers/pull/121#discussion_r957765010


##########
commons-numbers-complex-arrays/src/site/site.xml:
##########
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="Numbers">
+  <bannerRight>
+    <name>Apache Commons Numbers</name>
+    <src>/images/commons_numbers.small.png</src>
+    <href>/index.html</href>
+  </bannerRight>
+
+  <body>
+    <menu name="Numbers Complex Arrays">
+      <item name="Overview" href="index.html"/>
+      <item name="Latest API docs (development)"
+            href="apidocs/index.html"/>
+      <item name="Javadoc (1.0 release)"

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



##########
commons-numbers-complex-arrays/src/site/xdoc/index.xml:
##########
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+  -->
+
+<document>
+
+  <properties>
+    <title>Commons Numbers Complex Arrays</title>
+  </properties>
+
+  <body>
+
+    <section name="Apache Commons Numbers: Number Types and Utilities" href="summary">

Review Comment:
   This section name does not seem relevant



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+

Review Comment:
   Extra whitespace is not required



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();
+        assertListOperation(l -> {
+            l.addAll(list);
+            return l.addAll(0, list);
+        });
+    }
+
+    @Test
+    void testRemove() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(list);
+            list.remove(0);
+            return list.remove(0);
+        });
+    }
+
+    @Test
+    void testGetAndSetIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(4));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(5));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(-2, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(4, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(5, Complex.ofCartesian(200, 1)));
+    }
+
+    @Test
+    void testAddIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));

Review Comment:
   Build list using a simpler method



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {

Review Comment:
   Avoid modulus by checking if the number is odd using a mask: `(newArrayCapacity & 1) != 0`
   
   But given that you are just incrementing by 1 if it is odd then do it all in a single branchless operation:
   ```Java
   // Round-odd up to even
   newArrayCapacity += newArrayCapacity & 1;
   ```



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;

Review Comment:
   Here `minCapacity` can be negative if you add a very large list to this list. However the `minCapacity` will not be larger than the sum of two positive integers (assuming the other list added to this handles up to Integer.MAX_VALUE elements). So we can treat it as unsigned then double it:
   ```Java
   final long minArrayCapacity = Integer.toUnsignedLong(minCapacity) << 1;
   ```
   



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+    }
+
+    /**
+     * Appends all the elements in the specified collection to the end of this list, in the order that they are
+     * returned by the specified collection's Iterator. The behavior of this operation is undefined if the
+     * specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the specified collection is this list,
+     * and this list is nonempty.)
+     *
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(Collection<? extends Complex> c) {
+        final int numNew = c.size();
+        expand(numNew * 2);
+        double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        System.arraycopy(realAndImgData, 0, realAndImagParts, size * 2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Inserts all the elements in the specified collection into this list, starting at the specified position.
+     * Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices).
+     * The new elements will appear in the list in the order that they are returned by the specified collection's iterator.
+     *
+     * @param index – Index at which to insert the first element from the specified collection.
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(int index, Collection<? extends Complex> c) {
+        rangeCheckForInsert(index);
+        final int numNew = c.size();
+        final int numNew2 = numNew << 1;
+        expand(numNew * 2);

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



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/package-info.java:
##########
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Complex numbers.

Review Comment:
   Provides a list of complex numbers.



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();

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



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();
+        assertListOperation(l -> {
+            l.addAll(list);
+            return l.addAll(0, list);
+        });
+    }
+
+    @Test
+    void testRemove() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(list);
+            list.remove(0);
+            return list.remove(0);
+        });
+    }
+
+    @Test
+    void testGetAndSetIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(4));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(5));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(-2, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(4, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(5, Complex.ofCartesian(200, 1)));
+    }
+
+    @Test
+    void testAddIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(-1, Complex.ofCartesian(42, 13)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(5, Complex.ofCartesian(42, 13)));
+    }
+
+    @Test
+    void testRemoveIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(list);
+        list.remove(0);
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
+    }
+
+    @ParameterizedTest
+    @ValueSource(ints = {0, 1, 10})
+    void testConstructor(int size) {
+        ComplexList list = new ComplexList(size);

Review Comment:
   Here I would manually create the ComplexList and ArrayList and then just call the assert method with a few operations:
   ```Java
   List<Complex> l1 = new ArrayList<>(size);
   List<Complex> l2 = new ComplexList(size);
   Assertions.assertEquals(l1, l2);
   assertOperation(l -> l.add(Complex.ofCartesian(10, 20), l1, l2);
   // etc
   ```



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {

Review Comment:
   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:
   ```Java
   assertListOperation(list -> list.add(Complex.ofCartesian(42, 13)));
   assertListOperation(list -> list.add(1, Complex.ofCartesian(11, 12)));
   // etc
   ```



##########
commons-numbers-complex-arrays/pom.xml:
##########
@@ -0,0 +1,76 @@
+<?xml version="1.0" ?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>commons-numbers-parent</artifactId>
+        <groupId>org.apache.commons</groupId>
+        <version>1.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>commons-numbers-complex-arrays</artifactId>
+    <name>Apache Commons Numbers Complex Arrays</name>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-numbers-complex</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-rng-client-api</artifactId>
+            <version>1.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-rng-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-numbers-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <!-- The Java Module System Name -->
+        <commons.module.name>org.apache.commons.numbers.complex.arrays</commons.module.name>
+        <!-- This value must reflect the current name of the base package. -->
+        <commons.osgi.symbolicName>org.apache.commons.numbers.complex.arrays</commons.osgi.symbolicName>
+        <!-- OSGi -->
+        <commons.osgi.export>org.apache.commons.numbers.complex.arrays</commons.osgi.export>
+        <!-- Workaround to avoid duplicating config files. -->
+        <numbers.parent.dir>${basedir}/..</numbers.parent.dir>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.github.siom79.japicmp</groupId>
+                <artifactId>japicmp-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>

Review Comment:
   Is this required? Does JApiCmp break since there is no previous release?
   
   If so then add a TODO comment to remove this section after a release.



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();
+        assertListOperation(l -> {
+            l.addAll(list);
+            return l.addAll(0, list);
+        });
+    }
+
+    @Test
+    void testRemove() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(list);
+            list.remove(0);
+            return list.remove(0);
+        });
+    }
+
+    @Test
+    void testGetAndSetIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));

Review Comment:
   Adding using lots of different methods is confusing. Why not stream a size and add:
   ```Java
   // Empty list throws
   Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(0));
   int size = 5;
   IntStream.range(0, size).mapToObj(i -> Complex.ofCartesian(i, -i)).forEach(list::add);
   Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));
   Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(size));
   Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(size + 1));
   
   // Repeat for set
   ```



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.

Review Comment:
   All your javadoc has a `-` character between the argument and the description. This is not required.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+    }
+
+    /**
+     * Appends all the elements in the specified collection to the end of this list, in the order that they are
+     * returned by the specified collection's Iterator. The behavior of this operation is undefined if the
+     * specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the specified collection is this list,
+     * and this list is nonempty.)
+     *
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(Collection<? extends Complex> c) {
+        final int numNew = c.size();
+        expand(numNew * 2);
+        double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        System.arraycopy(realAndImgData, 0, realAndImagParts, size * 2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Inserts all the elements in the specified collection into this list, starting at the specified position.
+     * Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices).
+     * The new elements will appear in the list in the order that they are returned by the specified collection's iterator.
+     *
+     * @param index – Index at which to insert the first element from the specified collection.
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(int index, Collection<? extends Complex> c) {
+        rangeCheckForInsert(index);
+        final int numNew = c.size();
+        final int numNew2 = numNew << 1;
+        expand(numNew * 2);
+        final double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        final int numMoved = (size - index) * 2;
+        final int index2 = index << 1;
+        System.arraycopy(realAndImagParts, index2, realAndImagParts, index2 + numNew2, numMoved);
+        System.arraycopy(realAndImgData, 0, realAndImagParts, index2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Removes the element at the specified position in this list.
+     * Shifts any subsequent elements to the left (subtracts one from their indices).
+     *
+     * @param index – Index of the element to be removed.
+     * @return the element that was removed from the list.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public Complex remove(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final int s = size << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        final int numMoved = s - i - 2;
+        if (numMoved > 0) {
+            System.arraycopy(realAndImagParts, i + 2, realAndImagParts, i, numMoved);
+        }
+        size--;
+        realAndImagParts[s] = 0;
+        realAndImagParts[s + 1] = 0;
+
+        return oldValue;
+    }
+
+    /**
+     * Constructs an IndexOutOfBoundsException detail message.
+     *
+     * @param index – Index of the element.
+     * @return message detailing the exception.
+     */
+    private String outOfBoundsMsg(int index) {
+        return INDEX_MSG + index + SIZE_MSG + size;
+    }
+

Review Comment:
   Remove extra line.



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();
+        assertListOperation(l -> {
+            l.addAll(list);
+            return l.addAll(0, list);
+        });
+    }
+
+    @Test
+    void testRemove() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(list);
+            list.remove(0);
+            return list.remove(0);
+        });
+    }
+
+    @Test
+    void testGetAndSetIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(4));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(5));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(-2, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(4, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(5, Complex.ofCartesian(200, 1)));
+    }
+
+    @Test
+    void testAddIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(-1, Complex.ofCartesian(42, 13)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(5, Complex.ofCartesian(42, 13)));
+    }
+
+    @Test
+    void testRemoveIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(list);
+        list.remove(0);
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
+    }
+
+    @ParameterizedTest
+    @ValueSource(ints = {0, 1, 10})
+    void testConstructor(int size) {
+        ComplexList list = new ComplexList(size);
+        list.add(Complex.ofCartesian(20, 12));
+        list.addAll(list);
+        Assertions.assertEquals(Complex.ofCartesian(20, 12), list.get(0));
+        Assertions.assertEquals(Complex.ofCartesian(20, 12), list.get(1));
+    }
+
+    @Test
+    void testCapacityExceptions() {
+        Assertions.assertDoesNotThrow(() -> new ComplexList().ensureCapacity(64), () -> "unexpected exception for ensureCapacity(64)");
+
+        assertOutOfMemoryErrorOnConstructor(() -> new ComplexList(ComplexList.MAX_CAPACITY + 1));
+
+        assertOutOfMemoryErrorOnEnsureCapacity(() -> new ComplexList().ensureCapacity(ComplexList.MAX_CAPACITY + 1));
+
+        int oldCapacity = ComplexList.MAX_CAPACITY * 2 / 3;
+        assertOutOfMemoryErrorOnArrayCopy(() ->  new ComplexList().ensureCapacity((int) (oldCapacity * 1.4)), () -> "unexpected exception for ensureCapacity(" + (oldCapacity * 1.4) + ")");
+        assertOutOfMemoryErrorOnArrayCopy(() ->  new ComplexList().ensureCapacity((int) (oldCapacity * 1.5)), () -> "unexpected exception for ensureCapacity(" + (oldCapacity * 1.5) + ")");
+
+        assertOutOfMemoryErrorOnEnsureCapacity(() ->  new ComplexList().ensureCapacity((int) (oldCapacity * 1.6)));
+
+    }
+
+    private static void assertOutOfMemoryErrorOnArrayCopy(Executable executable, Supplier<String> msgSupplier) {
+        try {
+            executable.execute();
+        } catch (Throwable oom) {
+            Assertions.assertSame(oom.getClass(), OutOfMemoryError.class, msgSupplier);
+            Assertions.assertTrue(oom.getStackTrace().length > 1, msgSupplier);
+            StackTraceElement firstStackElement = oom.getStackTrace()[0];
+            Assertions.assertEquals("copyOf", firstStackElement.getMethodName(), msgSupplier);
+            Assertions.assertEquals(Arrays.class.getName(), firstStackElement.getClassName(), msgSupplier);
+        }
+    }
+
+    private static void assertOutOfMemoryErrorOnEnsureCapacity(Executable executable) {
+        try {
+            executable.execute();
+            Assertions.assertTrue(false, "failed to throw OutOfMemory Error");
+        } catch (Throwable oom) {
+            Assertions.assertSame(oom.getClass(), OutOfMemoryError.class);
+            Assertions.assertTrue(oom.getStackTrace().length > 1);
+            StackTraceElement firstStackElement = oom.getStackTrace()[0];
+            Assertions.assertEquals(ComplexList.class.getName(), firstStackElement.getClassName());
+            Assertions.assertEquals("ensureCapacityInternal", firstStackElement.getMethodName());
+        }
+    }
+
+    private static void assertOutOfMemoryErrorOnConstructor(Executable executable) {
+        try {
+            executable.execute();
+            Assertions.assertTrue(false, "failed to throw OutOfMemory Error");
+        } catch (Throwable oom) {
+            Assertions.assertSame(oom.getClass(), OutOfMemoryError.class);
+            Assertions.assertTrue(oom.getStackTrace().length > 1);
+            StackTraceElement firstStackElement = oom.getStackTrace()[0];
+            Assertions.assertEquals(ComplexList.class.getName(), firstStackElement.getClassName());
+            Assertions.assertEquals("<init>", firstStackElement.getMethodName());
+        }
+    }
+
+    private static <T> void assertListOperation(Function<List<Complex>, T> operation,
+                                                List<Complex> l1, List<Complex> l2) {
+        T t1 = operation.apply(l1);
+        T t2 = operation.apply(l2);
+        Assertions.assertEquals(t1, t2);
+        Assertions.assertEquals(l1, l2);
+    }
+
+    private static <T> void assertListOperation(Function<List<Complex>, T> operation) {
+        assertListOperation(operation, new ArrayList<>(), new ComplexList());
+    }
+
+    private static void assertListOperation(Consumer<List<Complex>> operation) {

Review Comment:
   I don't think the consumer operations are required. If your final function does not return then just call the method with the Function and return e.g. Boolean.TRUE.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));

Review Comment:
   I think it more appropriate here to throw an IllegalArgumentException.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;

Review Comment:
   Should not be public



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,

Review Comment:
   The capacity is not `always at least twice as large as the list size` since capacity is referring to the number of elements, not doubles, that may be added before resizing.
   
   This intro javadoc should describe the size limitation of the list. Since the data is stored using an interleaved format the maximum number of elements that may be added is approximately 2^30. This is half the maximum capacity of java.util.ArrayList. The memory usage is more efficient than using a List of Complex objects as the underlying numbers are not stored using instances of Complex.
   
   The javadoc can be expanded to describe how to manipulate the numbers efficiently using the Complex functional interfaces when this functionality is added to the list.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+    }
+
+    /**
+     * Appends all the elements in the specified collection to the end of this list, in the order that they are
+     * returned by the specified collection's Iterator. The behavior of this operation is undefined if the
+     * specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the specified collection is this list,
+     * and this list is nonempty.)
+     *
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(Collection<? extends Complex> c) {
+        final int numNew = c.size();
+        expand(numNew * 2);
+        double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;

Review Comment:
   I would just increment this in the loop:
   ```Java
           for (final Complex val : c) {
               realAndImgData[i++] = val.getReal();
               realAndImgData[i++] = val.getImaginary();
           }
   ```



##########
commons-numbers-complex-arrays/pom.xml:
##########
@@ -0,0 +1,76 @@
+<?xml version="1.0" ?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>commons-numbers-parent</artifactId>
+        <groupId>org.apache.commons</groupId>
+        <version>1.1-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>commons-numbers-complex-arrays</artifactId>
+    <name>Apache Commons Numbers Complex Arrays</name>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-numbers-complex</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-rng-client-api</artifactId>
+            <version>1.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-rng-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-numbers-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <properties>
+        <!-- The Java Module System Name -->
+        <commons.module.name>org.apache.commons.numbers.complex.arrays</commons.module.name>
+        <!-- This value must reflect the current name of the base package. -->
+        <commons.osgi.symbolicName>org.apache.commons.numbers.complex.arrays</commons.osgi.symbolicName>
+        <!-- OSGi -->
+        <commons.osgi.export>org.apache.commons.numbers.complex.arrays</commons.osgi.export>
+        <!-- Workaround to avoid duplicating config files. -->
+        <numbers.parent.dir>${basedir}/..</numbers.parent.dir>
+    </properties>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.github.siom79.japicmp</groupId>
+                <artifactId>japicmp-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

Review Comment:
   Add a newline at the end of the file



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {

Review Comment:
   You should check if this javadoc provides anything useful over the default javadoc in List. If not then remove it. The same applies to all List methods in the interface. You can use the `{@inheritDoc}` tag to pull in the parent javadoc then add to it any further information.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;

Review Comment:
   This should not be incremented unless the list has been structurally modified, i.e. anything that changes the number of elements. So it should be changed in add/remove methods.
   
   There are cases where this is called and the list will not change number of elements, e.g. ensureCapacity.
   
   You should move the modification of this flag to the appropriate methods.
   
   This behaviour could be tested:
   
   - Create a list
   - Get the iterator
   - Add an element
   - Try and use the iterator.forEach method
   
   It should throw a ConcurrentModificationException
   



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {

Review Comment:
   This could do with a note explaining that minArrayCapacity has already been checked against MAX_ARRAY_SIZE so we just clip the new capacity to the appropriate range: [minArrayCapacity, MAX_ARRAY_SIZE]



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+    }
+
+    /**
+     * Appends all the elements in the specified collection to the end of this list, in the order that they are
+     * returned by the specified collection's Iterator. The behavior of this operation is undefined if the
+     * specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the specified collection is this list,
+     * and this list is nonempty.)
+     *
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(Collection<? extends Complex> c) {
+        final int numNew = c.size();
+        expand(numNew * 2);
+        double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        System.arraycopy(realAndImgData, 0, realAndImagParts, size * 2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Inserts all the elements in the specified collection into this list, starting at the specified position.
+     * Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices).
+     * The new elements will appear in the list in the order that they are returned by the specified collection's iterator.
+     *
+     * @param index – Index at which to insert the first element from the specified collection.
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(int index, Collection<? extends Complex> c) {
+        rangeCheckForInsert(index);
+        final int numNew = c.size();
+        final int numNew2 = numNew << 1;
+        expand(numNew * 2);
+        final double[] realAndImgData = new double[c.size() * 2];

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



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);

Review Comment:
   You already have `2 * index` so you can reuse `i` here. For consistency perhaps use `size << 1` as well.



##########
commons-numbers-complex-arrays/src/main/java/org/apache/commons/numbers/complex/arrays/ComplexList.java:
##########
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Resizable-double array implementation of the List interface. Implements all optional list operations,
+ * and permits all elements. In addition to implementing the List interface,
+ * this class provides methods to manipulate the size of the array that is used internally to store the list.
+ *
+ * <p>Each ComplexList instance has a capacity. The capacity is half the size of the double array used to store the elements
+ * in the list. It is always at least twice as large as the list size. As elements are added to an ComplexList,
+ * its capacity grows automatically.</p>
+ *
+ * <p>An application can increase the capacity of an ComplexList instance before adding a large number of elements
+ * using the ensureCapacity operation. This may reduce the amount of incremental reallocation.</p>
+ */
+public class ComplexList extends AbstractList<Complex> {
+
+    /** The maximum size of array to allocate.
+     * Ensuring Max capacity is even with additional space for vm array headers.
+     */
+    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 9;
+
+    /** Max capacity for size of complex numbers in the list. */
+    public static final int MAX_CAPACITY = MAX_ARRAY_SIZE / 2;
+
+    /** error in case of allocation above max capacity. */
+    private static final String OOM_ERROR_STRING = "cannot allocate capacity %s greater than max " + MAX_CAPACITY;
+
+    /** Default initial capacity. */
+    private static final int DEFAULT_CAPACITY = 8;
+
+    /** Size label message. */
+    private static final String SIZE_MSG = ", Size: ";
+    /** Index position label message. */
+    private static final String INDEX_MSG = "Index: ";
+
+    /**
+     * The double array buffer into which the elements of the ComplexList are stored.
+     */
+    protected double[] realAndImagParts;
+
+    /**
+     * Size of ComplexList.
+     */
+    private int size;
+
+    /**
+     * Constructs an empty list with the specified capacity, if it's
+     * greater than the default capacity of 8.
+     *
+     * @param capacity - Capacity of list.
+     * @throws OutOfMemoryError - if the {@code capacity} is greater than {@code MAX_CAPACITY}.
+     */
+    public ComplexList(int capacity) {
+        if (capacity > MAX_CAPACITY) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, capacity));
+        }
+        final int arrayLength = Math.max(DEFAULT_CAPACITY, capacity) * 2;
+        realAndImagParts = new double[arrayLength];
+    }
+
+    /**
+     * Constructs an empty list with the default capacity of 8.
+     */
+    public ComplexList() {
+        realAndImagParts = new double[DEFAULT_CAPACITY * 2];
+    }
+
+    /**
+     * Gives the size of this ComplexList.
+     *
+     * @return the number of elements it contains.
+     */
+    @Override
+    public int size() {
+        return size;
+    }
+
+    /**
+     * Checks if the given index is in range.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range.
+     */
+    private void rangeCheck(int index) {
+        if (index < 0 || index >= size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * A version of rangeCheck used by add and addAll.
+     *
+     * @param index - Index of the element to range check.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    private void rangeCheckForInsert(int index) {
+        if (index < 0 || index > size) {
+            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
+        }
+    }
+
+    /**
+     * Gets the complex number \( (a + i b) \) at the indexed position of the list.
+     *
+     * @param index - Index of the element to get.
+     * @return the complex number.
+     */
+    @Override
+    public Complex get(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        return Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element's
+     * real and imaginary parts. No range checks are done.
+     *
+     * @param index - Index of the element to replace.
+     * @param real - Real part \( a \) of the complex number \( (a +ib) \).
+     * @param imaginary - Imaginary part \( b \) of the complex number \( (a +ib) \).
+     */
+    private void setNoRangeCheck(int index, double real, double imaginary) {
+        final int i = index << 1;
+        realAndImagParts[i] = real;
+        realAndImagParts[i + 1] = imaginary;
+    }
+
+    /**
+     * Replaces the element at the specified position in this list with the specified element.
+
+     * @param index - Index of the element to replace.
+     * @param element - Element to be stored at the specified position.
+     * @return the element previously at the specified position.
+     * @throws IndexOutOfBoundsException - if index isn't within the range of list.
+     */
+    @Override
+    public Complex set(int index, Complex element) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        setNoRangeCheck(index, element.getReal(), element.getImaginary());
+        return oldValue;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    public void ensureCapacity(int minCapacity) {
+        ensureCapacityInternal(minCapacity);
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least the number of elements specified by the minimum capacity argument.
+     *
+     * @param minCapacity – Desired minimum capacity.
+     * @return the backing double array.
+     * @throws OutOfMemoryError - if the {@code minCapacity} is greater than {@code MAX_ARRAY_SIZE}.
+     */
+    private double[] ensureCapacityInternal(int minCapacity) {
+        modCount++;
+        final long minArrayCapacity = minCapacity * 2L;
+        if (minArrayCapacity > MAX_ARRAY_SIZE) {
+            throw new OutOfMemoryError(String.format(OOM_ERROR_STRING, minArrayCapacity));
+        }
+        final long oldArrayCapacity = realAndImagParts.length;
+        if (minArrayCapacity > oldArrayCapacity) {
+            long newArrayCapacity = oldArrayCapacity + (oldArrayCapacity >> 1);
+            if (newArrayCapacity % 2 != 0) {
+                ++newArrayCapacity;
+            }
+            if (newArrayCapacity > MAX_ARRAY_SIZE) {
+                newArrayCapacity = MAX_ARRAY_SIZE;
+            } else if (newArrayCapacity < minArrayCapacity) {
+                newArrayCapacity = minArrayCapacity;
+            }
+            realAndImagParts = Arrays.copyOf(realAndImagParts, (int)newArrayCapacity);
+        }
+        return realAndImagParts;
+    }
+
+    /**
+     * Increases the capacity of this ComplexList instance, if necessary, to ensure that it can hold at
+     * least an additional number of elements specified by the capacity argument.
+     *
+     * @param capacity - Desired capacity.
+     */
+    private void expand(int capacity) {
+        ensureCapacityInternal(size + capacity);
+    }
+
+    /**
+     * Appends the specified complex element to the end of this list.
+     *
+     * @param element - Complex element to be appended to this list.
+     * @return true after element has been added and size has been updated.
+     */
+    @Override
+    public boolean add(Complex element) {
+        double[] e = realAndImagParts;
+        if (size == (e.length >>> 1)) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = size << 1;
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+        return true;
+    }
+
+    /**
+     * Inserts the specified element at the specified position in this list. Shifts the element currently at that
+     * position (if any) and any subsequent elements to the right (adds one to their indices).
+     *
+     * @param index – Index at which the specified element is to be inserted.
+     * @param element – Complex element to be inserted.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public void add(int index, Complex element) {
+        rangeCheckForInsert(index);
+        double[] e = realAndImagParts;
+        if (size == e.length >>> 1) {
+            e = ensureCapacityInternal(size + 1);
+        }
+        final int i = index << 1;
+        System.arraycopy(e, 2 * index, e, i + 2, (size * 2) - i);
+        e[i] = element.real();
+        e[i + 1] = element.imag();
+        size++;
+    }
+
+    /**
+     * Appends all the elements in the specified collection to the end of this list, in the order that they are
+     * returned by the specified collection's Iterator. The behavior of this operation is undefined if the
+     * specified collection is modified while the operation is in progress.
+     * (This implies that the behavior of this call is undefined if the specified collection is this list,
+     * and this list is nonempty.)
+     *
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(Collection<? extends Complex> c) {
+        final int numNew = c.size();
+        expand(numNew * 2);
+        double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        System.arraycopy(realAndImgData, 0, realAndImagParts, size * 2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Inserts all the elements in the specified collection into this list, starting at the specified position.
+     * Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices).
+     * The new elements will appear in the list in the order that they are returned by the specified collection's iterator.
+     *
+     * @param index – Index at which to insert the first element from the specified collection.
+     * @param c – Collection containing elements to be added to this list.
+     * @return true if this list changed as a result of the call.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     * @throws NullPointerException – if the specified collection is null.
+     */
+    @Override
+    public boolean addAll(int index, Collection<? extends Complex> c) {
+        rangeCheckForInsert(index);
+        final int numNew = c.size();
+        final int numNew2 = numNew << 1;
+        expand(numNew * 2);
+        final double[] realAndImgData = new double[c.size() * 2];
+        int i = 0;
+        for (final Complex val : c) {
+            final int i2 = i << 1;
+            realAndImgData[i2] = val.getReal();
+            realAndImgData[i2 + 1] = val.getImaginary();
+            i++;
+        }
+        final int numMoved = (size - index) * 2;
+        final int index2 = index << 1;
+        System.arraycopy(realAndImagParts, index2, realAndImagParts, index2 + numNew2, numMoved);
+        System.arraycopy(realAndImgData, 0, realAndImagParts, index2, realAndImgData.length);
+        size += numNew;
+        return numNew != 0;
+    }
+
+    /**
+     * Removes the element at the specified position in this list.
+     * Shifts any subsequent elements to the left (subtracts one from their indices).
+     *
+     * @param index – Index of the element to be removed.
+     * @return the element that was removed from the list.
+     * @throws IndexOutOfBoundsException – if index isn't within the range of list.
+     */
+    @Override
+    public Complex remove(int index) {
+        rangeCheck(index);
+        final int i = index << 1;
+        final int s = size << 1;
+        final Complex oldValue = Complex.ofCartesian(realAndImagParts[i], realAndImagParts[i + 1]);
+        final int numMoved = s - i - 2;
+        if (numMoved > 0) {
+            System.arraycopy(realAndImagParts, i + 2, realAndImagParts, i, numMoved);
+        }
+        size--;
+        realAndImagParts[s] = 0;

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



##########
commons-numbers-complex-arrays/src/test/java/org/apache/commons/numbers/complex/arrays/ComplexListTest.java:
##########
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.numbers.complex.arrays;
+
+import org.apache.commons.numbers.complex.Complex;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ComplexListTest {
+
+    @Test
+    void testGetAndSetMethod() {
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(1, list);
+            list.addAll(list);
+            list.set(2, Complex.ofCartesian(200, 1));
+            return list.get(2);
+        });
+
+    }
+
+    @Test
+    void testAddAndAddAll() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            return list.add(Complex.ofCartesian(11, 12));
+        });
+
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.add(1, Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.addAll(1, list);
+            list.add(Complex.ofCartesian(18, 19));
+            list.add(Complex.ofCartesian(11, 12));
+            list.add(Complex.ofCartesian(13, 14));
+            list.add(Complex.ofCartesian(15, 16));
+            list.add(Complex.ofCartesian(17, 18));
+            list.add(1, Complex.ofCartesian(11, 12));
+        });
+
+        ComplexList list = new ComplexList();
+        assertListOperation(l -> {
+            l.addAll(list);
+            return l.addAll(0, list);
+        });
+    }
+
+    @Test
+    void testRemove() {
+        assertListOperation(list -> {
+            list.add(Complex.ofCartesian(42, 13));
+            list.addAll(list);
+            list.remove(0);
+            return list.remove(0);
+        });
+    }
+
+    @Test
+    void testGetAndSetIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(4));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(5));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(-2, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(4, Complex.ofCartesian(200, 1)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.set(5, Complex.ofCartesian(200, 1)));
+    }
+
+    @Test
+    void testAddIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(1, list);
+        list.addAll(list);
+        list.set(2, Complex.ofCartesian(200, 1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(-1, Complex.ofCartesian(42, 13)));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () ->
+            list.add(5, Complex.ofCartesian(42, 13)));
+    }
+
+    @Test
+    void testRemoveIndexOutOfBoundExceptions() {
+        ComplexList list = new ComplexList();
+        list.add(Complex.ofCartesian(42, 13));
+        list.addAll(list);
+        list.remove(0);
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(1));
+        Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));
+    }
+
+    @ParameterizedTest
+    @ValueSource(ints = {0, 1, 10})
+    void testConstructor(int size) {
+        ComplexList list = new ComplexList(size);
+        list.add(Complex.ofCartesian(20, 12));
+        list.addAll(list);
+        Assertions.assertEquals(Complex.ofCartesian(20, 12), list.get(0));
+        Assertions.assertEquals(Complex.ofCartesian(20, 12), list.get(1));
+    }
+
+    @Test
+    void testCapacityExceptions() {

Review Comment:
   These tests are too specific. If the class is changed to alter the method names then the test will fail. The method names are not the critical part of the functionality.
   
   You should not have to expose the internal method `ensureCapacity`. You can add the required size to trigger exceptions with a dummy list:
   ```Java
       private static class SizedList extends ArrayList<Complex> {
           private final int fixedSize;
   
           SizedList(int fixedSize) {
               super();
               this.fixedSize = fixedSize;
           }
   
           @Override
           public int size() {
               return fixedSize;
           }
       }
   
       @Test
       void testCapacityExceptions() {
           // Set-up required sizes
           ComplexList list = new ComplexList();
           List<Complex> l = new SizedList(Integer.MAX_VALUE);
           Assertions.assertThrows(OutOfMemoryError.class, () -> list.add(l));
       }
   ```
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org