Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Current snapshot date: 2026-04-04.
- 2D ndarray support with matrix validation.
- Creation helpers: `array`, `zeros`, `arange`.
- Addition operations: `add` and `addInPlace` with strict shape checks.
- Optional extensions: scalar addition and `sum()` reduction.
- `reshape(int... shape)` with size consistency validation.
- NumPy-like string display for 1D arrays (including ellipsis for large arrays).
- Defensive copy behavior on constructors and exports.
Expand All @@ -43,6 +44,8 @@ NdArray c = NdArray.arange(0f, 6f, 2f);
NdArray m = NdArray.array(new float[][] {{1f, 2f}, {3f, 4f}});
NdArray sum = m.add(NdArray.array(new float[][] {{10f, 10f}, {10f, 10f}}));
NdArray reshaped = NdArray.arange(6f).reshape(2, 3);
NdArray shifted = a.add(10f);
float total = shifted.sum();
```

## Tech Stack and Tooling Choices
Expand Down Expand Up @@ -168,6 +171,7 @@ Implemented:
- 1D and 2D ndarray support.
- Creation functions (`array`, `zeros`, `arange`).
- Addition operations (`add`, `addInPlace`).
- Scalar addition and `sum()` reduction.
- Reshape with validation.

In progress / next:
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/org/sadisamir/ndarray/NdArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,18 @@ public NdArray add(NdArray other) {
return new NdArray(result, numDimensions, shape);
}

/**
* Returns a new array with a scalar added to every element.
*/
public NdArray add(float scalar) {
float[] result = new float[totalElements];
for (int index = 0; index < totalElements; index++) {
result[index] = flatData[index] + scalar;
}

return new NdArray(result, numDimensions, shape);
}

/**
* Adds another array to this one in place.
*
Expand All @@ -278,6 +290,26 @@ public void addInPlace(NdArray other) {
}
}

/**
* Adds a scalar to this array in place.
*/
public void addInPlace(float scalar) {
for (int index = 0; index < totalElements; index++) {
flatData[index] += scalar;
}
}

/**
* Returns the sum of all elements in the array.
*/
public float sum() {
double total = 0.0d;
for (float value : flatData) {
total += value;
}
return (float) total;
}

/**
* Returns a reshaped view of this array.
*
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/sadisamir/ndarray/demo/NdArrayDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public static void main(String[] args) {
demo1DArrayCreation();
demo2DArrayCreation();
demoArithmeticOperations();
demoOptionalFeatures();
demoReshape();
demoLargeArrayDisplay();
printFooter();
Expand Down Expand Up @@ -105,6 +106,21 @@ private static void demoArithmeticOperations() {
LOGGER.info("");
}

private static void demoOptionalFeatures() {
printSection("Optional Features");

NdArray base = NdArray.array(new float[]{1f, 2f, 3f});
LOGGER.info("Scalar addition: base.add(10f)");
LOGGER.info(" Base: {}", base);
NdArray shifted = base.add(10f);
LOGGER.info(" Shifted: {}", shifted);
LOGGER.info("");

LOGGER.info("Reduction: shifted.sum()");
LOGGER.info(" Total: {}", shifted.sum());
LOGGER.info("");
}

private static void demoReshape() {
printSection("Reshape Operations");

Expand Down
65 changes: 65 additions & 0 deletions src/test/java/org/sadisamir/ndarray/NdArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,69 @@ void addInPlaceRejectsNullOperand() {

assertThrows(NullPointerException.class, () -> left.addInPlace(null));
}

@Test
void addScalarReturnsNewOneDimensionalArray() {
NdArray source = NdArray.array(new float[] {1.0f, 2.0f, 3.0f});

NdArray result = source.add(10.0f);

assertArrayEquals(new float[] {11.0f, 12.0f, 13.0f}, result.toArray(), 0.0f);
assertArrayEquals(new float[] {1.0f, 2.0f, 3.0f}, source.toArray(), 0.0f);
}

@Test
void addScalarPreservesTwoDimensionalMetadata() {
NdArray matrix = NdArray.array(new float[][] {{1.0f, 2.0f}, {3.0f, 4.0f}});

NdArray result = matrix.add(-1.5f);

assertEquals(2, result.getNdim());
assertArrayEquals(new int[] {2, 2}, result.getShape());
assertEquals(4, result.getSize());
assertArrayEquals(new float[] {-0.5f, 0.5f}, result.toMatrix()[0], 0.0f);
assertArrayEquals(new float[] {1.5f, 2.5f}, result.toMatrix()[1], 0.0f);
}

@Test
void addInPlaceScalarMutatesCurrentArray() {
NdArray source = NdArray.array(new float[] {1.0f, 2.0f, 3.0f});

source.addInPlace(2.5f);

assertArrayEquals(new float[] {3.5f, 4.5f, 5.5f}, source.toArray(), 0.0f);
}

@Test
void addInPlaceScalarPreservesTwoDimensionalShape() {
NdArray matrix = NdArray.array(new float[][] {{1.0f, 2.0f}, {3.0f, 4.0f}});

matrix.addInPlace(-1.0f);

assertEquals(2, matrix.getNdim());
assertArrayEquals(new int[] {2, 2}, matrix.getShape());
assertArrayEquals(new float[] {0.0f, 1.0f}, matrix.toMatrix()[0], 0.0f);
assertArrayEquals(new float[] {2.0f, 3.0f}, matrix.toMatrix()[1], 0.0f);
}

@Test
void sumReturnsTotalForOneDimensionalArray() {
NdArray source = NdArray.array(new float[] {1.0f, 2.5f, 3.5f});

assertEquals(7.0f, source.sum(), 0.0f);
}

@Test
void sumReturnsTotalForTwoDimensionalArray() {
NdArray matrix = NdArray.array(new float[][] {{1.0f, 2.0f}, {3.0f, 4.0f}});

assertEquals(10.0f, matrix.sum(), 0.0f);
}

@Test
void sumOfEmptyArrayIsZero() {
NdArray source = NdArray.array(new float[0]);

assertEquals(0.0f, source.sum(), 0.0f);
}
}
Loading