> For the complete documentation index, see [llms.txt](https://deeplearning4j.konduit.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://deeplearning4j.konduit.ai/en-1.0.0-rewrite/nd4j/quickstart.md).

# Quickstart

ND4J is a scientific computing library for the JVM designed for production use. It provides a versatile N-dimensional array object (`INDArray`), linear algebra and signal processing routines, and multi-platform execution including CPU and GPU. This guide follows the structure of the [NumPy quickstart](https://numpy.org/doc/stable/user/quickstart.html) so that Python users can map familiar concepts directly to ND4J equivalents.

### Maven Setup

Add the following to your `pom.xml`. You need the core platform bundle and a backend. Use `nd4j-native-platform` for CPU or `nd4j-cuda-11.x-platform` for GPU.

```xml
<properties>
  <dl4j.version>1.0.0-rewrite</dl4j.version>
</properties>

<dependencies>
  <!-- ND4J API -->
  <dependency>
    <groupId>org.nd4j</groupId>
    <artifactId>nd4j-api</artifactId>
    <version>${dl4j.version}</version>
  </dependency>

  <!-- CPU backend — replaces this with nd4j-cuda-11.x-platform for GPU -->
  <dependency>
    <groupId>org.nd4j</groupId>
    <artifactId>nd4j-native-platform</artifactId>
    <version>${dl4j.version}</version>
  </dependency>
</dependencies>
```

If you are using the broader DL4J stack (DataVec, DL4J training), add the BOM instead to keep versions consistent:

```xml
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.deeplearning4j</groupId>
      <artifactId>deeplearning4j-parent</artifactId>
      <version>${dl4j.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
```

### Imports Used in This Guide

All examples below assume these imports are present:

```java
import org.nd4j.linalg.api.buffer.DataType;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.indexing.NDArrayIndex;
import org.nd4j.linalg.ops.transforms.Transforms;
```

### Array Creation

ND4J arrays are created through static factory methods on `Nd4j`. You never call `new INDArray(...)` directly.

#### zeros, ones, rand

```java
// 1D array of five zeros (default type: FLOAT)
INDArray z = Nd4j.zeros(5);
// [0.0000, 0.0000, 0.0000, 0.0000, 0.0000]

// 1D array of five ones, explicitly typed
INDArray o = Nd4j.ones(DataType.FLOAT, 5);
// [1.0000, 1.0000, 1.0000, 1.0000, 1.0000]

// 3x4 matrix of uniform random values in [0, 1)
INDArray r = Nd4j.rand(DataType.FLOAT, 3, 4);

// 3x4 matrix of standard-normal random values N(0, 1)
INDArray n = Nd4j.randn(DataType.FLOAT, 3, 4);

// Explicit shape array — same as Nd4j.rand(DataType.FLOAT, 4, 5)
long[] shape = {4, 5};
INDArray r2 = Nd4j.rand(DataType.FLOAT, shape);
```

#### createFromArray

`Nd4j.createFromArray` is overloaded for `float`, `double`, `int`, and `long` up to 4D. Shape is inferred from the Java array structure.

```java
// 1D from a float array
float[] data1d = {1.0f, 2.0f, 3.0f, 4.0f};
INDArray v = Nd4j.createFromArray(data1d);
// [1.0000, 2.0000, 3.0000, 4.0000]

// 2D from a 2D float array
float[][] data2d = {{1.0f, 2.0f, 3.0f},
                    {4.0f, 5.0f, 6.0f}};
INDArray m = Nd4j.createFromArray(data2d);
// [[1.0000, 2.0000, 3.0000],
//  [4.0000, 5.0000, 6.0000]]

// Double precision — use double arrays
double[][] data2d_d = {{1.0, 2.0}, {3.0, 4.0}};
INDArray md = Nd4j.createFromArray(data2d_d);
```

#### arange and linspace

```java
// Integer-stepped range [0, 5)
INDArray range = Nd4j.arange(5);
// [0.0000, 1.0000, 2.0000, 3.0000, 4.0000]

// Range starting at 2, stopping before 7
INDArray range2 = Nd4j.arange(2, 7);
// [2.0000, 3.0000, 4.0000, 5.0000, 6.0000]

// 5 evenly-spaced points from 0.0 to 1.0 inclusive
INDArray lin = Nd4j.linspace(DataType.FLOAT, 0.0, 1.0, 5);
// [0.0000, 0.2500, 0.5000, 0.7500, 1.0000]
```

### Array Properties

```java
INDArray x = Nd4j.zeros(DataType.FLOAT, 3, 4);

// Number of dimensions
int rank = x.rank();              // 2

// Size of each dimension
long[] shape = x.shape();         // [3, 4]

// Total number of elements
long length = x.length();         // 12

// Element type
DataType dt = x.dataType();       // FLOAT
```

The default `DataType` for arrays created without an explicit type argument is `FLOAT`. In M2.1 the type is represented by the `DataType` enum — the old `DataBuffer.Type` enum was removed.

### Printing Arrays

`INDArray.toString()` produces NumPy-style output. Call it via `System.out.println` or string concatenation.

```java
// 1D
INDArray a = Nd4j.arange(6);
System.out.println(a);
// [0.0000, 1.0000, 2.0000, 3.0000, 4.0000, 5.0000]

// 2D — reshape from 1D (returns a view)
INDArray b = Nd4j.arange(12).reshape(4, 3);
System.out.println(b);
// [[0.0000, 1.0000, 2.0000],
//  [3.0000, 4.0000, 5.0000],
//  [6.0000, 7.0000, 8.0000],
//  [9.0000, 10.0000, 11.0000]]

// 3D
INDArray c = Nd4j.arange(24).reshape(2, 3, 4);
System.out.println(c);
// [[[0.0000,  1.0000,  2.0000,  3.0000],
//   [4.0000,  5.0000,  6.0000,  7.0000],
//   [8.0000,  9.0000, 10.0000, 11.0000]],
//  [[12.0000, 13.0000, 14.0000, 15.0000],
//   [16.0000, 17.0000, 18.0000, 19.0000],
//   [20.0000, 21.0000, 22.0000, 23.0000]]]
```

### Basic Operations

#### Copy operations (non-destructive)

Copy operations allocate a new array and leave the original unchanged.

```java
INDArray a = Nd4j.createFromArray(new float[]{1, 2, 3});
INDArray b = Nd4j.createFromArray(new float[]{10, 20, 30});

INDArray sumArr  = a.add(b);   // [11.0000, 22.0000, 33.0000]
INDArray diffArr = a.sub(b);   // [-9.0000, -18.0000, -27.0000]
INDArray prodArr = a.mul(b);   // [10.0000, 40.0000, 90.0000]
INDArray quotArr = a.div(b);   // [0.1000, 0.1000, 0.1000]

// Scalar variants work the same way
INDArray plus2 = a.add(2.0);   // [3.0000, 4.0000, 5.0000]
INDArray times3 = a.mul(3.0);  // [3.0000, 6.0000, 9.0000]

// a is still [1, 2, 3] — none of these modified it
```

#### In-place operations (i suffix)

In-place operations modify the array they are called on. They return the same Java object for method chaining.

```java
INDArray x = Nd4j.createFromArray(new float[]{1, 2, 3});

x.addi(10);    // x is now [11.0000, 12.0000, 13.0000]
x.muli(2);     // x is now [22.0000, 24.0000, 26.0000]
x.subi(4);     // x is now [18.0000, 20.0000, 22.0000]
x.divi(2);     // x is now [9.0000, 10.0000, 11.0000]

// Chain in-place operations in one expression
INDArray y = Nd4j.zeros(3).addi(5).muli(2);   // [10.0000, 10.0000, 10.0000]
```

The complete set of element-wise arithmetic methods:

| Operation      | Copy  | In-place |
| -------------- | ----- | -------- |
| Addition       | `add` | `addi`   |
| Subtraction    | `sub` | `subi`   |
| Multiplication | `mul` | `muli`   |
| Division       | `div` | `divi`   |

#### Data type requirement

Operands must share the same `DataType`. Mixing types throws `IllegalArgumentException`.

```java
INDArray floatArr  = Nd4j.zeros(DataType.FLOAT, 5);
INDArray doubleArr = Nd4j.zeros(DataType.DOUBLE, 5);

// This throws:
// java.lang.IllegalArgumentException: Op.X and Op.Y must have the same data type,
//   but got FLOAT vs DOUBLE
INDArray bad = floatArr.add(doubleArr);

// Fix: cast one operand before the operation
INDArray result = floatArr.add(doubleArr.castTo(DataType.FLOAT));

// Or cast the other direction
INDArray result2 = floatArr.castTo(DataType.DOUBLE).add(doubleArr);
```

`castTo` returns a new array of the requested type. The original is not modified.

### Reduction Operations

Reductions collapse one or more dimensions down to a scalar or a lower-rank array.

```java
INDArray x = Nd4j.rand(DataType.FLOAT, 2, 3);
// Example values:
// [[0.8621, 0.9224, 0.8407],
//  [0.1504, 0.5489, 0.9584]]

// Global reductions — return a scalar INDArray
INDArray total = x.sum();    // 4.2829
INDArray lo    = x.min();    // 0.1504
INDArray hi    = x.max();    // 0.9584
INDArray avg   = x.mean();   // 0.7138

// Extract as a Java number
double totalVal = x.sumNumber().doubleValue();
double maxVal   = x.maxNumber().doubleValue();
```

Pass a dimension argument to reduce along a specific axis. Dimension 0 collapses rows (result has one entry per column); dimension 1 collapses columns (result has one entry per row).

```java
INDArray m = Nd4j.arange(12).reshape(3, 4);
// [[0,  1,  2,  3],
//  [4,  5,  6,  7],
//  [8,  9, 10, 11]]

INDArray colSums = m.sum(0);   // sum each column → [12, 15, 18, 21]
INDArray rowMins = m.min(1);   // min of each row  → [0, 4, 8]
INDArray colMaxs = m.max(0);   // max of each column → [8, 9, 10, 11]
INDArray rowMeans = m.mean(1); // mean of each row   → [1.5, 5.5, 9.5]
```

### Transform Operations

Transforms apply a mathematical function element-wise and return a new array. They live in `org.nd4j.linalg.ops.transforms.Transforms`.

```java
import static org.nd4j.linalg.ops.transforms.Transforms.sin;
import static org.nd4j.linalg.ops.transforms.Transforms.cos;
import static org.nd4j.linalg.ops.transforms.Transforms.exp;
import static org.nd4j.linalg.ops.transforms.Transforms.sqrt;
import static org.nd4j.linalg.ops.transforms.Transforms.log;
import static org.nd4j.linalg.ops.transforms.Transforms.abs;

INDArray x = Nd4j.linspace(DataType.FLOAT, 0, 2, 4);
// [0.0000, 0.6667, 1.3333, 2.0000]

INDArray sinX  = sin(x);    // [0.0000, 0.6184, 0.9694, 0.9093]
INDArray cosX  = cos(x);    // [1.0000, 0.7859, 0.2350, -0.4161]
INDArray expX  = exp(x);    // [1.0000, 1.9477, 3.7937, 7.3891]
INDArray sqrtX = sqrt(x);   // [0.0000, 0.8165, 1.1547, 1.4142]
INDArray logX  = log(x.add(1));  // add 1 to avoid log(0)

// Evaluate sin over 100 points in [0, pi] — a common NumPy pattern
INDArray xpts  = Nd4j.linspace(DataType.DOUBLE, 0.0, Math.PI, 100);
INDArray ypts  = sin(xpts);
```

A second boolean argument on most transforms controls whether the result is written in-place:

```java
// false (default) → new array; true → modify x directly
INDArray y = sin(x, false);  // new array, x unchanged
sin(x, true);                // x modified in-place
```

### Matrix Multiplication

Element-wise multiplication uses `mul` / `muli` (covered above). For true matrix products use `mmul`, and for dot products use `Transforms.dot`.

```java
// mmul: matrix product
// x is [3 x 4], y is [4 x 3] → result is [3 x 3]
INDArray x = Nd4j.arange(12).reshape(3, 4);
INDArray y = Nd4j.arange(12).reshape(4, 3);

INDArray product = x.mmul(y);
// [[42,  48,  54],
//  [114, 136, 158],
//  [186, 224, 262]]

// dot product of two 1D vectors
INDArray u = Nd4j.arange(4);
INDArray v = Nd4j.arange(4);
INDArray dotResult = Nd4j.dot(u, v);   // 0*0 + 1*1 + 2*2 + 3*3 = 14

// Transpose before multiply — returns a view, not a copy
INDArray xT = x.transpose();   // shape [4, 3]
INDArray xtx = xT.mmul(x);     // [4 x 3] · [3 x 4] → [4 x 4]
```

### Indexing and Slicing

#### Single-element access

```java
INDArray x = Nd4j.createFromArray(new float[]{10, 20, 30, 40, 50});

float  val = x.getFloat(2);     // 30.0  — zero-based
double d   = x.getDouble(0);    // 10.0
```

For 2D arrays, pass row and column:

```java
INDArray m = Nd4j.createFromArray(new float[][]{{1, 2, 3}, {4, 5, 6}});

float v = m.getFloat(1, 2);    // 6.0  (row 1, col 2)
```

#### Exporting to Java arrays

```java
INDArray x = Nd4j.arange(5);

float[]  fv = x.toFloatVector();    // [0.0, 1.0, 2.0, 3.0, 4.0]
double[] dv = x.toDoubleVector();   // same values as double[]

// For 2D arrays
INDArray m = Nd4j.rand(DataType.FLOAT, 2, 3);
float[][] fm  = m.toFloatMatrix();
double[][] dm = m.toDoubleMatrix();
```

#### Slicing with NDArrayIndex

Use `NDArrayIndex` to extract contiguous and strided sub-arrays. Slices are **views** — modifying the slice modifies the source array.

```java
INDArray x = Nd4j.arange(10);
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// Elements at indices 2..5 (exclusive of 6)
INDArray slice = x.get(NDArrayIndex.interval(2, 6));
// [2.0000, 3.0000, 4.0000, 5.0000]

// Every 2nd element from index 0 to 8 (exclusive)
INDArray strided = x.get(NDArrayIndex.interval(0, 2, 8));
// [0.0000, 2.0000, 4.0000, 6.0000]
```

For 2D arrays, pass one `NDArrayIndex` per dimension:

```java
INDArray m = Nd4j.rand(DataType.FLOAT, 4, 5);

// Row 1 (all columns)
INDArray row1 = m.get(NDArrayIndex.point(1), NDArrayIndex.all());

// Rows 0..2, columns 1..3
INDArray sub = m.get(NDArrayIndex.interval(0, 3),
                     NDArrayIndex.interval(1, 4));

// Iterate over rows
for (int i = 0; i < m.rows(); i++) {
    INDArray row = m.get(NDArrayIndex.point(i), NDArrayIndex.all());
    // row is a view of row i
}
```

`getRow(i)` and `getColumn(j)` are convenience shortcuts for the common 2D case:

```java
INDArray row0 = m.getRow(0);    // view of row 0
INDArray col2 = m.getColumn(2); // view of column 2
```

#### Assigning into a slice

Because slices are views, you can assign into them using `assign`:

```java
INDArray x = Nd4j.zeros(10);

// Set elements 3..6 to 1.0
x.get(NDArrayIndex.interval(3, 7)).assign(1.0);
// [0,0,0,1,1,1,1,0,0,0]
```

### Shape Manipulation

#### reshape and ravel

`reshape` returns a **view** — it does not copy data. The total number of elements must remain the same.

```java
INDArray x = Nd4j.rand(DataType.FLOAT, 3, 4);
// shape [3, 4], 12 elements

INDArray flat = x.reshape(12);       // shape [12]  — view
INDArray grid = x.reshape(2, 6);     // shape [2,6] — view
INDArray cube = x.reshape(2, 2, 3);  // shape [2,2,3] — view

// ravel() is equivalent to reshape(-1) — flattens to 1D
INDArray flat2 = x.ravel();          // shape [12]  — view
```

Because `reshape` and `ravel` return views, a mutation in one propagates to all:

```java
INDArray a = Nd4j.rand(DataType.FLOAT, 3, 4);
INDArray b = a.ravel();

// Writes -1 at flat index 5, which is a[1][1] in the 3x4 array
b.putScalar(5, -1.0f);

System.out.println(a.getFloat(1, 1));  // -1.0  — a was also changed
```

Use `dup()` after reshape if you need an independent copy:

```java
INDArray independent = x.reshape(2, 6).dup();
```

#### Transpose

`transpose()` returns a view with swapped strides. For 2D arrays this swaps rows and columns:

```java
INDArray m = Nd4j.createFromArray(new float[][]{{1,2,3},{4,5,6}});
// shape [2, 3]

INDArray t = m.transpose();
// shape [3, 2]
// [[1, 4],
//  [2, 5],
//  [3, 6]]

// Transpose is a view — dup() for an independent copy
INDArray tCopy = m.transpose().dup();
```

### Stacking Arrays

`vstack` concatenates along dimension 0 (rows); `hstack` concatenates along dimension 1 (columns). Both accept varargs.

```java
INDArray a = Nd4j.createFromArray(new float[][]{{1, 2}, {3, 4}});
INDArray b = Nd4j.createFromArray(new float[][]{{5, 6}, {7, 8}});

INDArray v = Nd4j.vstack(a, b);
// [[1, 2],
//  [3, 4],
//  [5, 6],
//  [7, 8]]   shape [4, 2]

INDArray h = Nd4j.hstack(a, b);
// [[1, 2, 5, 6],
//  [3, 4, 7, 8]]  shape [2, 4]

// General concatenation along any axis
INDArray cat0 = Nd4j.concat(0, a, b);   // same as vstack
INDArray cat1 = Nd4j.concat(1, a, b);   // same as hstack
```

### Copies vs Views

Getting this right prevents subtle bugs.

#### Reference assignment — no copy

Java passes objects by reference. Assigning one `INDArray` variable to another gives you a second reference to the same object and the same underlying memory.

```java
INDArray x = Nd4j.rand(DataType.FLOAT, 2, 3);
INDArray y = x;          // y IS x — same object, same data

y.addi(1);               // modifies x too, since y and x point to the same buffer
System.out.println(x);  // x has changed
```

#### Views — shallow copy

`reshape`, `ravel`, `transpose`, `getRow`, `getColumn`, and `NDArrayIndex` slices all return **views**: new `INDArray` objects that share the same backing buffer. Mutating a view mutates the original.

```java
INDArray x = Nd4j.rand(DataType.FLOAT, 3, 4);
INDArray flat = x.ravel();          // view — same buffer
INDArray reshaped = x.reshape(6, 2); // view — same buffer

flat.putScalar(2, -99f);

// All three variables now show -99 at the corresponding position
System.out.println(x);         // element [0][2] is -99
System.out.println(flat);       // element [2] is -99
System.out.println(reshaped);   // element [1][0] is -99
```

#### Deep copy with dup()

`dup()` allocates a new buffer and copies all data into it. After calling `dup()`, the two arrays are completely independent.

```java
INDArray x = Nd4j.rand(DataType.FLOAT, 3, 4);
INDArray flat = x.ravel().dup();   // independent copy — new buffer

flat.putScalar(2, -99f);

// x is unchanged
System.out.println(x.getFloat(0, 2));  // original value, not -99
```

As a rule: if you are going to modify a slice or reshaped view and do not want the original to change, call `.dup()` on it first.

### Quick Reference

#### Array creation

| Method                                        | Description                      |
| --------------------------------------------- | -------------------------------- |
| `Nd4j.zeros(DataType, long...)`               | All-zeros array                  |
| `Nd4j.ones(DataType, long...)`                | All-ones array                   |
| `Nd4j.rand(DataType, long...)`                | Uniform random in \[0, 1)        |
| `Nd4j.randn(DataType, long...)`               | Standard-normal random           |
| `Nd4j.createFromArray(float[][])`             | From Java array (shape inferred) |
| `Nd4j.arange(start, stop)`                    | Integer range, exclusive of stop |
| `Nd4j.linspace(DataType, start, stop, count)` | Evenly-spaced points             |
| `Nd4j.eye(n)`                                 | n x n identity matrix            |

#### Element-wise arithmetic

| Op             | Copy       | In-place    |
| -------------- | ---------- | ----------- |
| Addition       | `a.add(b)` | `a.addi(b)` |
| Subtraction    | `a.sub(b)` | `a.subi(b)` |
| Multiplication | `a.mul(b)` | `a.muli(b)` |
| Division       | `a.div(b)` | `a.divi(b)` |

#### Reductions

| Method                        | Result                       |
| ----------------------------- | ---------------------------- |
| `x.sum()`                     | Global sum (scalar INDArray) |
| `x.sum(dim)`                  | Sum along dimension `dim`    |
| `x.min()` / `x.min(dim)`      | Minimum                      |
| `x.max()` / `x.max(dim)`      | Maximum                      |
| `x.mean()` / `x.mean(dim)`    | Mean                         |
| `x.sumNumber().doubleValue()` | Global sum as Java `double`  |

#### Transforms (Transforms class)

| Method                  | Description       |
| ----------------------- | ----------------- |
| `Transforms.sin(x)`     | Sine              |
| `Transforms.cos(x)`     | Cosine            |
| `Transforms.exp(x)`     | Exponential e^x   |
| `Transforms.sqrt(x)`    | Square root       |
| `Transforms.log(x)`     | Natural logarithm |
| `Transforms.abs(x)`     | Absolute value    |
| `Transforms.relu(x)`    | max(0, x)         |
| `Transforms.sigmoid(x)` | 1 / (1 + e^-x)    |

#### Shape manipulation

| Method               | Returns  | Notes                          |
| -------------------- | -------- | ------------------------------ |
| `x.reshape(long...)` | INDArray | View; total elements unchanged |
| `x.ravel()`          | INDArray | View; 1D flat                  |
| `x.transpose()`      | INDArray | View; swapped strides          |
| `x.dup()`            | INDArray | Independent deep copy          |
| `Nd4j.vstack(a, b)`  | INDArray | Concatenate along rows         |
| `Nd4j.hstack(a, b)`  | INDArray | Concatenate along columns      |

***

For a deeper treatment of `DataType`, memory ordering, and workspace-based memory management, see the [Tensors and NDArrays](https://github.com/KonduitAI/deeplearning4j-docs/blob/en-1.0.0-rewrite/docs/m2.1/core-concepts/tensors-and-ndarrays/README.md) page.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://deeplearning4j.konduit.ai/en-1.0.0-rewrite/nd4j/quickstart.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
