Operations
Scalar, element-wise, transform, reduction, broadcast, comparison, and linear algebra operations on INDArrays
ND4J defines five categories of operations that can be performed on INDArray objects:
Scalar ops — apply a single number to every element
Transform ops — element-wise mathematical functions (tanh, exp, log, etc.)
Accumulation (reduction) ops — collapse an array to a scalar or lower-rank array
Index accumulation ops — return the index of a value (argmax, argmin)
Broadcast / vector ops — add or multiply a row/column vector across a matrix
Each category can be executed over the entire array or along one or more dimensions.
In-Place vs. Copy Operations
Every mutating operation in ND4J exists in two variants. The naming convention is consistent across the entire API:
Copy
(none)
Returns a new INDArray; the original is unchanged
In-place
i
Modifies the original array and returns a reference to it
INDArray x = Nd4j.create(new double[]{1, 2, 3, 4}, new int[]{2, 2});
INDArray y = Nd4j.create(new double[]{10, 20, 30, 40}, new int[]{2, 2});
// Copy: x is not modified; z is a new array
INDArray z = x.add(y);
// In-place: x is modified directly; result is the same object as x
x.addi(y);After x.add(y), the variable x is still [[1,2],[3,4]] and z holds [[11,22],[33,44]].
After x.addi(y), x itself becomes [[11,22],[33,44]].
This convention applies uniformly: sub/subi, mul/muli, div/divi, rsub/rsubi, rdiv/rdivi, and so on.
Tip: When chaining operations on a view (e.g., a row returned by
getRow()), in-place operations modify the backing array without allocating new memory. Use this deliberately:
Data Type Requirement
ND4J requires that both operands in a binary operation share the same DataType. Mixing float and double arrays, for example, will produce an error at runtime.
Use castTo(DataType) to convert an array before operating on it:
Common DataType values: FLOAT, DOUBLE, LONG, INT, SHORT, HALF, BFLOAT16.
To change the default type for all newly created arrays:
1. Scalar Operations
Scalar ops apply a single numeric value to every element of an INDArray. ND4J exposes the most common ones directly on the INDArray interface.
Standard scalar ops
Reverse scalar ops
The "reverse" variants swap the operands, computing scalar OP element instead of element OP scalar. This is most useful for subtraction and division:
Scalar ops via the executor (advanced)
You can also invoke scalar ops directly through the op executor when you need finer control:
2. Element-Wise Operations
Element-wise (Hadamard) ops pair each element of one array with the corresponding element of a second array of the same shape.
Basic element-wise ops
Assignment
assign copies all values from one array into another. The target array is modified in-place:
This is equivalent to target.get(...).assign(source) when operating on a view, and is the preferred way to set a block of values without allocating a new array.
3. Transform Operations
Transform ops apply a mathematical function element-wise across an entire array. ND4J provides two convenient entry points: the Transforms utility class and Nd4j.getExecutioner().execAndReturn().
Using the Transforms class
By default, Transforms methods return a copy (the original is unchanged). Pass false as the second argument to operate in-place:
Softmax along a dimension
Softmax is typically applied along dimension 1 (across columns of each row):
Using the executor directly
You can also create a transform by name using the op factory:
4. Accumulation / Reduction Operations
Reduction ops collapse array values into a summary statistic. They can run over the entire array (returning a scalar) or along one or more dimensions (returning a lower-rank array).
Full-array reductions
All of these return a Number; call .doubleValue(), .floatValue(), or .longValue() as needed.
Dimension-wise reductions
Passing a dimension index to the reduction narrows the scope of the operation. The result has one fewer dimension for each axis reduced.
For a 2D array with shape [rows, cols]:
sum(0)sums down each column → result shape[1, cols]sum(1)sums across each row → result shape[rows, 1]
Dimension-wise reductions generalize to higher-rank arrays. For a rank-3 array of shape [a, b, c], calling sum(1) produces an array of shape [a, 1, c].
Reduction via executor (advanced)
5. Index Accumulation Operations
Index accumulation ops return the index of the element that satisfies some condition (maximum, minimum, absolute maximum). They are the ND4J equivalents of NumPy's argmax / argmin.
Full-array index accumulation
Dimension-wise index accumulation
More commonly, you want the index of the max/min within each row or column:
Visual example — given a 3×3 array:
argmax(dim=0) (index of max in each column): [1, 2, 2]
argmax(dim=1) (index of max in each row): [1, 0, 1]
IAMax — argmax of absolute values
6. Broadcast and Vector Operations
Vector ops broadcast a 1D (or rank-2 vector) array across every row or every column of a matrix.
addRowVector / addColumnVector
muliColumnVector / muliRowVector (in-place)
Full set of broadcast vector methods
The following methods all follow the same in-place (i) / copy pattern:
addRowVector(v)
addiRowVector(v)
add row vector to each row
subRowVector(v)
subiRowVector(v)
subtract row vector from each row
mulRowVector(v)
muliRowVector(v)
multiply each row by row vector
divRowVector(v)
diviRowVector(v)
divide each row by row vector
addColumnVector(v)
addiColumnVector(v)
add column vector to each column
subColumnVector(v)
subiColumnVector(v)
subtract column vector from each column
mulColumnVector(v)
muliColumnVector(v)
multiply each column by column vector
divColumnVector(v)
diviColumnVector(v)
divide each column by column vector
General broadcast via Nd4j.exec
For more complex broadcast patterns, use BroadcastAddOp and related ops:
7. Comparison Operations
Comparison ops evaluate a condition element-wise and return a binary mask: 1.0 where the condition is true, 0.0 where it is false. The result is always a new array of the same shape; the original is never modified.
Element-wise comparison against another array
Element-wise comparison against a scalar
Using masks
Binary masks can be multiplied against an array to zero out unwanted values:
For more sophisticated conditional selection (applying an operation only where a mask is true), see the boolean indexing APIs in BooleanIndexing.
8. Linear Algebra Operations
Matrix multiplication (mmul)
mmul computes the standard matrix product, not the Hadamard product. The number of columns in the left operand must equal the number of rows in the right operand.
Inner product (row vector × column vector → scalar):
Outer product (column × row → matrix):
Transpose
transpose() returns a view (no copy) of the transposed array. Modifying the transpose modifies the original.
Transposing is O(1) because it only changes the stride metadata, not the underlying data buffer.
Combined: transpose then multiply (t().mmul())
A common pattern is computing Aᵀ × A or A × Bᵀ:
Diagonal matrix
Nd4j.diag() has two behaviours depending on the shape of its argument:
Matrix inverse
The invert method uses LU decomposition internally and works for any square non-singular matrix.
Quick Reference
The table below summarises the most common operations and their in-place variants.
Scalar ops
arr.add(n)
arr.addi(n)
element + scalar
arr.sub(n)
arr.subi(n)
element - scalar
arr.mul(n)
arr.muli(n)
element × scalar
arr.div(n)
arr.divi(n)
element ÷ scalar
arr.rsub(n)
arr.rsubi(n)
scalar - element
arr.rdiv(n)
arr.rdivi(n)
scalar ÷ element
Element-wise (array-array) ops
a.add(b)
a.addi(b)
element-wise addition
a.sub(b)
a.subi(b)
element-wise subtraction
a.mul(b)
a.muli(b)
element-wise (Hadamard) product
a.div(b)
a.divi(b)
element-wise division
a.assign(b)
(always in-place)
copy values from b into a
Transform ops (Transforms.)
Transforms.tanh(arr)
tanh(x)
Transforms.sigmoid(arr)
1 / (1 + e^−x)
Transforms.relu(arr)
max(0, x)
Transforms.exp(arr)
e^x
Transforms.log(arr)
ln(x)
Transforms.sqrt(arr)
√x
Transforms.abs(arr)
|x|
Transforms.sin(arr)
sin(x)
Transforms.cos(arr)
cos(x)
Transforms.softmax(arr)
softmax(x)
Reduction ops
arr.sumNumber()
Number
sum of all elements
arr.meanNumber()
Number
mean of all elements
arr.minNumber()
Number
minimum value
arr.maxNumber()
Number
maximum value
arr.norm1Number()
Number
L1 norm
arr.norm2Number()
Number
L2 norm
arr.stdNumber(b)
Number
standard deviation
arr.varNumber(b)
Number
variance
arr.sum(dim)
INDArray
sum along dimension
arr.mean(dim)
INDArray
mean along dimension
arr.max(dim)
INDArray
max along dimension
arr.min(dim)
INDArray
min along dimension
arr.norm1(dim)
INDArray
L1 norm along dimension
arr.norm2(dim)
INDArray
L2 norm along dimension
Index accumulation ops
IMax
index of maximum value (argmax)
IMin
index of minimum value (argmin)
IAMax
index of maximum absolute value
Comparison ops (return binary mask)
a.gt(b)
a > b
a.lt(b)
a < b
a.eq(b)
a == b
a.neq(b)
a != b
a.gte(b)
a >= b
a.lte(b)
a <= b
Linear algebra
a.mmul(b)
matrix multiplication
arr.transpose()
transpose (returns a view)
Nd4j.diag(v)
create diagonal matrix from vector, or extract diagonal
InvertMatrix.invert(m, false)
matrix inverse (copy)
Last updated
Was this helpful?