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
2 changes: 1 addition & 1 deletion SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ The primary array type representing N-dimensional arrays.
- [x] 3.1.1: `NDArray::array($data, $dtype = null)` - From PHP array
- [x] 3.1.2: `NDArray::zeros($shape, $dtype = 'float64')` - Array of zeros
- [x] 3.1.3: `NDArray::ones($shape, $dtype = 'float64')` - Array of ones
- [x] 3.1.4: `NDArray::full($shape, $fill_value, $dtype = null)` - Filled array
- [x] 3.1.4: `NDArray::full($value, $shape, $dtype = null)` - Filled array
- [x] 3.1.5: `NDArray::empty($shape, $dtype = 'float64')` - Uninitialized array
- [x] 3.1.6: `NDArray::eye($n, $m = null, $k = 0, $dtype = 'float64')` - Identity matrix

Expand Down
181 changes: 135 additions & 46 deletions docs/api/array-creation.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ echo $mixed->dtype()->name; // Float64
**See Also:**
- [Data Types](/guide/fundamentals/data-types)
- [Understanding Arrays](/guide/fundamentals/understanding-arrays)
- [fromArray()](#ndarray-fromarray)

---

Expand Down Expand Up @@ -100,6 +101,115 @@ $zeros = NDArray::zeros([10], DType::Int32);

---

## NDArray::ones()

Create an array filled with ones.

```php
public static function ones(array $shape, DType $dtype = DType::Float64): self
```

**Parameters:**
- `array $shape` - Array dimensions
- `DType $dtype` - Data type (default: Float64)

**Examples:**

```php
$ones = NDArray::ones([2, 3]);
echo $ones;
// [[1. 1. 1.]
// [1. 1. 1.]]

// Useful for multiplicative operations
$data = NDArray::random([100, 100]);
$multiplier = NDArray::ones([100, 100])->multiply(2);
```

---

## NDArray::full()

Create an array filled with a specific value.

```php
public static function full(
float|int|bool $value,
array $shape,
?DType $dtype = null
): self
```

**Parameters:**
- `float|int|bool $value` - Value to fill array with
- `array $shape` - Array dimensions
- `?DType $dtype` - Data type (inferred from fillValue if null)

**Examples:**

```php
// Fill with 5
$full = NDArray::full(5, [2, 2]);
echo $full;
// [[5. 5.]
// [5. 5.]]

// Fill with 3.14
$pi_matrix = NDArray::full(3.14, [3, 3]);

// With specific type
$full = NDArray::full(100, [10], DType::Int32);
```

**See Also:**
- [zeros()](#ndarray-zeros)
- [ones()](#ndarray-ones)

---

## NDArray::fromArray()

Create an NDArray from a PHP array with optional explicit shape.

```php
public static function fromArray(
array $data,
?array $shape = null,
?DType $dtype = null
): self
```

This is an idiomatic alias for `array()` that follows the naming convention of other factory methods like `fromBuffer()`, `fromBytes()`, etc. It provides an optional shape parameter for explicit control.

**Parameters:**
- `array $data` - PHP array containing data
- `?array $shape` - Optional array shape. If null, inferred from data structure
- `?DType $dtype` - Optional data type. If null, inferred from data

**Returns:** NDArray with shape from parameter or inferred from data

**Examples:**

```php
// Same as array() - shape inferred from nested structure
$arr = NDArray::fromArray([[1, 2], [3, 4]]);
echo implode(',', $arr->shape()); // 2,3

// With explicit shape validation
$data = [1, 2, 3, 4, 5, 6];
$arr = NDArray::fromArray($data, [2, 3]); // Validates data size matches shape

// With explicit dtype
$arr = NDArray::fromArray([1, 2, 3], null, DType::Float32);
```

**See Also:**
- [array()](#ndarray-array) - Original method
- [fromBuffer()](#ndarray-frombuffer) - Create from C pointer
- [fromBytes()](#ndarray-frombytes) - Create from binary string

---

## NDArray::fromBuffer()

Create an array from an external C buffer pointer.
Expand Down Expand Up @@ -152,72 +262,48 @@ Verify your buffer matches both the type and size before calling.

---

## NDArray::ones()
## NDArray::fromBytes()

Create an array filled with ones.
Create an array from a binary string.

```php
public static function ones(array $shape, DType $dtype = DType::Float64): self
```

**Parameters:**
- `array $shape` - Array dimensions
- `DType $dtype` - Data type (default: Float64)

**Examples:**

```php
$ones = NDArray::ones([2, 3]);
echo $ones;
// [[1. 1. 1.]
// [1. 1. 1.]]

// Useful for multiplicative operations
$data = NDArray::random([100, 100]);
$multiplier = NDArray::ones([100, 100])->multiply(2);
```

---

## NDArray::full()

Create an array filled with a specific value.

```php
public static function full(
public static function fromBytes(
string $bytes,
array $shape,
float|int|bool $value,
?DType $dtype = null
DType $dtype
): self
```

Creates an NDArray by interpreting a PHP binary string as raw array data. The bytes are copied into a new array with the specified shape and dtype. Data is assumed to be in little-endian format.

**Parameters:**
- `array $shape` - Array dimensions
- `float|int $fillValue` - Value to fill array with
- `?DType $dtype` - Data type (inferred from fillValue if null)
- `string $bytes` - Binary string containing raw array data
- `array $shape` - Array shape dimensions
- `DType $dtype` - Data type of the data in the string

**Returns:** NDArray containing a copy of the binary data

**Throws:**
- `ShapeException` - If byte string length doesn't match expected size for the shape and dtype

**Examples:**

```php
// Fill with 5
$full = NDArray::full([2, 2], 5);
echo $full;
// [[5. 5.]
// [5. 5.]]
$binaryData = file_get_contents('data.bin');

// Fill with 3.14
$pi_matrix = NDArray::full([3, 3], 3.14);
$audio = NDArray::fromBytes($binaryData, [1000, 2], DType::Float32);

// With specific type
$full = NDArray::full([10], 100, DType::Int32);
// Verify size matches
// 1000 * 2 * 4 bytes = 8000 bytes expected for Float32
```

**See Also:**
- [zeros()](#ndarray-zeros)
- [ones()](#ndarray-ones)
- [toBytes()](/api/array-import-export#tbytes) — Export array to binary string
- [fromBuffer()](#ndarray-frombuffer) — Import from C pointer

---


## NDArray::flat()

Get a 1-D iterator over the array.
Expand Down Expand Up @@ -673,6 +759,9 @@ print_r($ints->toArray()); // [1, 2, 3]
| `zerosLike()` | Zeros like input | Same shape as array |
| `onesLike()` | Ones like input | Same shape as array |
| `fullLike()` | Filled like input | Same shape as array |
| `fromArray()` | From PHP array (with shape) | Import with explicit shape |
| `fromBuffer()` | From C pointer | FFI interoperability |
| `fromBytes()` | From binary string | File I/O, network data |
| `eye()` | Identity matrix | Linear algebra |
| `arange()` | Evenly spaced | Integer sequences |
| `linspace()` | Linear spacing | Continuous ranges |
Expand Down
90 changes: 67 additions & 23 deletions docs/api/array-import-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Reference for converting arrays to and from other formats.

These methods allow you to convert NDArray objects to PHP native types, raw bytes, or other formats for interoperability.
These methods allow you to convert NDArray objects to PHP native types, raw bytes, or FFI buffers for interoperability.

---

Expand Down Expand Up @@ -66,70 +66,114 @@ echo $arr->toScalar(); // 3.14

## toBytes()

Return raw bytes of the array/view in C-order.
Return raw bytes of the array/view in C-order as a binary string.

```php
public function toBytes(): string
```

Returns the raw binary representation in little-endian format. Useful for serialization, file I/O, or passing to other systems that expect binary data.

### Parameters

None.

### Returns

- `string` - Raw binary representation of the array data.
- `string` - Raw binary representation of the array data in little-endian format.

### Examples

```php
$arr = NDArray::array([1.0, 2.0, 3.0], DType::Float64);
$bytes = $arr->toBytes();
// Length = 3 * 8 = 24 bytes for Float64

// Save to file
file_put_contents('data.bin', $bytes);
```

---

## intoBuffer()
## toBuffer()

Copy flattened C-order data into a caller-allocated C buffer.
Export NDArray data to a C buffer for FFI interoperability.

```php
public function intoBuffer(CData $buffer, int $start = 0, ?int $len = null): int
public function toBuffer(?CData $buffer = null, int $start = 0, ?int $len = null): CData
```

Copies flattened C-order data into a C buffer. If no buffer is provided, allocates a new one with the appropriate type. The returned CData is owned by PHP's FFI and will be garbage collected when no longer referenced.

### Parameters

| Name | Type | Description |
|------|------|-------------|
| `$buffer` | `CData` | Destination typed C buffer (FFI) |
| `$buffer` | `CData\|null` | Optional destination typed C buffer. If null, a new buffer is allocated. |
| `$start` | `int` | Starting element offset (0-indexed). Default: 0 |
| `$len` | `int\|null` | Number of elements to copy. Default: null (copy to end) |
| `$len` | `int\|null` | Number of elements to copy. Default: null (copy remaining elements from start) |

### Returns

- `int` - Number of elements copied.
- `CData` - The buffer containing the copied data (either provided or newly allocated).

### Examples

```php
$arr = NDArray::array([1.0, 2.0, 3.0, 4.0, 5.0]);
$ffi = \PhpMlKit\NDArray\FFI\Lib::get();
$buffer = $ffi->new('double[5]');

// Copy all elements
$n = $arr->intoBuffer($buffer);
// $n === 5
// Allocate and copy all elements (new buffer)
$buffer = $arr->toBuffer();
// $buffer is CData (double[5])

// Copy into existing buffer
$existingBuffer = $ffi->new('double[5]');
$buffer = $arr->toBuffer($existingBuffer);
// $buffer === $existingBuffer

// Copy from offset
$buffer = $ffi->new('double[3]');
$n = $arr->intoBuffer($buffer, 2); // Start at index 2
// $n === 3 (elements 2, 3, 4)
$buffer = $arr->toBuffer(null, 2); // Start at index 2
// $buffer contains elements 2, 3, 4 (indices 2, 3, 4)

// Copy with explicit length
$buffer = $ffi->new('double[2]');
$n = $arr->intoBuffer($buffer, 1, 2); // Start at 1, copy 2 elements
// $n === 2 (elements 1, 2)
$buffer = $arr->toBuffer(null, 1, 2); // Start at 1, copy 2 elements
// $buffer contains elements 1, 2 (indices 1, 2)
```

### Important Notes

**Buffer Lifetime**: When `toBuffer()` allocates a buffer (no `$buffer` argument), the returned `CData` is managed by PHP's FFI. It will be garbage collected when no longer referenced. If you need the data to persist beyond the current scope, copy it to a location you control.

**Type Safety**: The buffer must match the array's dtype exactly. Passing a `float*` buffer for a `Float64` array will result in incorrect data.

---

## intoBuffer() (Deprecated)

::: warning Deprecated
`intoBuffer()` is deprecated and will be removed in a future version. Use `toBuffer()` instead.
:::

Copy flattened C-order data into a caller-allocated C buffer.

```php
public function intoBuffer(CData $buffer, int $start = 0, ?int $len = null): int
```

This method is functionally equivalent to calling `toBuffer($buffer, $start, $len)` and discarding the return value. It returns the number of elements copied instead of the buffer.

### Migration Guide

Replace:
```php
$n = $arr->intoBuffer($buffer, 0, 100);
```

With:
```php
$buffer = $arr->toBuffer($buffer, 0, 100);
// $buffer now contains the data
```

---
Expand All @@ -140,12 +184,12 @@ $n = $arr->intoBuffer($buffer, 1, 2); // Start at 1, copy 2 elements
|--------|---------------|----------|
| `toArray()` | Nested PHP array | Export to PHP code |
| `toScalar()` | Single value | Extract 0D array value |
| `toBytes()` | Binary string | Binary serialization |
| `intoBuffer()` | FFI C buffer | Low-level FFI interop |
| `toBytes()` | Binary string | Binary serialization, file I/O |
| `toBuffer()` | FFI C buffer | Low-level FFI interop |

---

## Next Steps

- [Array Creation](/api/array-creation) - Converting from PHP arrays
- [NDArray Class](/api/ndarray-class) - Array properties and metadata
- [Array Creation](/api/array-creation) - Converting from PHP arrays and binary data
- [NDArray Class](/api/ndarray-class) - Array properties and metadata
Loading