Skip to content

Commit

Permalink
Add dedicated 2-axis array
Browse files Browse the repository at this point in the history
  • Loading branch information
Martmists-GH committed Dec 18, 2024
1 parent 097a36c commit 2c182af
Show file tree
Hide file tree
Showing 11 changed files with 773 additions and 66 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repositories {
}

dependencies {
implementation("com.martmists.ndarray-simd:ndarray-simd:1.1.1")
implementation("com.martmists.ndarray-simd:ndarray-simd:1.2.0")
}
```

Expand Down
29 changes: 28 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ plugins {
}

group = "com.martmists.ndarray-simd"
version = "1.1.1"
version = "1.2.0"
val isProduction = (findProperty("production") ?: System.getProperty("production")) != null

repositories {
Expand Down Expand Up @@ -266,9 +266,36 @@ if (isProduction) {
}
}



publications {
withType<MavenPublication> {
version = releaseVersion
pom {
name = "NDArray.simd"
description = "Kotlin/Multiplatform NDArray with SIMD optimizations and low memory footprint"
url = "https://github.com/martmists-gh/ndarray.simd"

licenses {
license {
name = "3-Clause BSD NON-AI License"
url = "https://github.com/non-ai-licenses/non-ai-licenses/blob/main/NON-AI-BSD3"
distribution = "repo"
}
}

developers {
developer {
id = "Martmists"
name = "Martmists"
url = "https://github.com/martmists-gh"
}
}

scm {
url = "https://github.com/martmists-gh/ndarray.simd"
}
}
}
}
}
Expand Down
118 changes: 100 additions & 18 deletions src/commonMain/kotlin/com/martmists/ndarray/simd/F64Array.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ interface F64Array {
*/
fun reshape(vararg shape: Int): F64Array = flatten().reshape(*shape)

/**
* Reshapes the array to the specified shape.
*
* @param rows the number of rows
* @param cols the number of columns
* @return the reshaped array
* @since 1.2.0
*/
fun reshape(rows: Int, cols: Int): F64TwoAxisArray = flatten().reshape(rows, cols)

/**
* Flattens the array to a 1D array.
*
Expand Down Expand Up @@ -1360,6 +1370,7 @@ interface F64Array {
*
* @return the diagonal
*/
@Deprecated("Will be moved to F64TwoAxisArray in the future")
fun diagonal(): F64FlatArray = unsupported()

/**
Expand All @@ -1368,6 +1379,7 @@ interface F64Array {
* @return the determinant
* @since 1.1.1
*/
@Deprecated("Will be moved to F64TwoAxisArray in the future")
fun determinant(): Double = unsupported()

/**
Expand All @@ -1377,12 +1389,14 @@ interface F64Array {
* @return the inverse matrix
* @since 1.1.1
*/
fun inverse(): F64Array = unsupported()
@Deprecated("Will be moved to F64TwoAxisArray in the future")
fun inverse(): F64TwoAxisArray = unsupported()

/**
* Computes the matrix multiplication of this array with another array.
*/
infix fun matmul(other: F64Array): F64Array = unsupported()
@Deprecated("Will be moved to F64TwoAxisArray in the future")
infix fun matmul(other: F64Array): F64TwoAxisArray = unsupported()

/**
* Returns the data from the array as a flat array.
Expand All @@ -1406,7 +1420,18 @@ interface F64Array {
*/
@JvmStatic
@JvmName("create")
operator fun invoke(vararg shape: Int) = F64FlatArray.create(DoubleArray(shape.product())).reshape(*shape)
operator fun invoke(vararg shape: Int): F64Array = F64FlatArray.create(DoubleArray(shape.product())).reshape(*shape)

/**
* Creates a new array with the specified shape.
*
* @param rows the number of rows
* @param cols the number of columns
* @since 1.2.0
*/
@JvmStatic
@JvmName("create")
operator fun invoke(rows: Int, cols: Int): F64TwoAxisArray = F64FlatArray.create(DoubleArray(rows * cols)).reshape(rows, cols)

/**
* Creates a new flat array with the specified size and initializes it with the given function.
Expand All @@ -1417,11 +1442,7 @@ interface F64Array {
*/
@JvmStatic
@JvmName("create1D")
operator fun invoke(size: Int, init: (Int) -> Double): F64FlatArray = F64Array(size).apply {
for (i in 0 until size) {
this[i] = init(i)
}
} as F64FlatArray
operator fun invoke(size: Int, init: (Int) -> Double): F64FlatArray = F64FlatArray.of(DoubleArray(size, init))

/**
* Creates a new 2D array with the specified shape and initializes it with the given function.
Expand All @@ -1433,7 +1454,7 @@ interface F64Array {
*/
@JvmStatic
@JvmName("create2D")
operator fun invoke(numRows: Int, numColumns: Int, init: (Int, Int) -> Double) = F64Array(numRows, numColumns).apply {
operator fun invoke(numRows: Int, numColumns: Int, init: (Int, Int) -> Double): F64TwoAxisArray = F64Array(numRows, numColumns).apply {
for (r in 0 until numRows) {
for (c in 0 until numColumns) {
this[r, c] = init(r, c)
Expand Down Expand Up @@ -1493,6 +1514,20 @@ interface F64Array {
return F64FlatArray.create(DoubleArray(shape.product()).apply { fill(init) }).reshape(*shape)
}

/**
* Creates a new array with the given shape, filled with the given value.
*
* @param rows the row count
* @param cols the column count
* @param init the initialization value
* @return the created array
* @since 1.2.0
*/
@JvmStatic
fun full(rows: Int, cols: Int, init: Double): F64TwoAxisArray {
return F64FlatArray.create(DoubleArray(rows * cols).apply { fill(init) }).reshape(rows, cols)
}

/**
* Creates a new array with the given shape, filled with the given value.
*
Expand All @@ -1508,12 +1543,12 @@ interface F64Array {
/**
* Creates a 2D identity matrix of the given size.
*
* @param n the size of the matrix
* @param size the size of the matrix
* @return the created matrix
*/
@JvmStatic
fun identity(n: Int): F64Array = zeros(n, n).apply {
for (i in 0 until n) {
fun identity(size: Int): F64TwoAxisArray = zeros(size, size).apply {
for (i in 0 until size) {
this[i, i] = 1.0
}
}
Expand All @@ -1525,7 +1560,7 @@ interface F64Array {
* @return the created matrix
*/
@JvmStatic
fun diagonal(values: DoubleArray): F64Array {
fun diagonal(values: DoubleArray): F64TwoAxisArray {
val n = values.size
val result = zeros(n, n)
for (i in 0 until n) {
Expand All @@ -1541,7 +1576,7 @@ interface F64Array {
* @return the created matrix
*/
@JvmStatic
fun diagonal(values: F64Array): F64Array {
fun diagonal(values: F64Array): F64TwoAxisArray {
val n = values.length
val result = zeros(n, n)
for (i in 0 until n) {
Expand All @@ -1559,6 +1594,17 @@ interface F64Array {
@JvmStatic
fun zeros(vararg shape: Int): F64Array = full(*shape, init=0.0)

/**
* Creates a new array with the given shape, filled with zeros.
*
* @param rows the number of rows
* @param cols the number of columns
* @return the created array
* @since 1.2.0
*/
@JvmStatic
fun zeros(rows: Int, cols: Int): F64TwoAxisArray = full(rows, cols, init=0.0)

/**
* Creates a new array with the given shape, filled with zeros.
*
Expand All @@ -1579,6 +1625,17 @@ interface F64Array {
@JvmStatic
fun ones(vararg shape: Int): F64Array = full(*shape, init=1.0)

/**
* Creates a new array with the given shape, filled with ones.
*
* @param rows the number of rows
* @param cols the number of columns
* @return the created array
* @since 1.2.0
*/
@JvmStatic
fun ones(rows: Int, cols: Int): F64TwoAxisArray = full(rows, cols, init=1.0)

/**
* Creates a new array with the given shape, filled with ones.
*
Expand All @@ -1597,7 +1654,7 @@ interface F64Array {
* @return the created array
*/
@JvmStatic
fun ofRows(rows: List<DoubleArray>): F64Array = ofRows(rows.map { F64FlatArray.of(it) })
fun ofRows(rows: List<DoubleArray>): F64TwoAxisArray = ofRows(rows.map { F64FlatArray.of(it) })

/**
* Creates a new array from the given list of rows.
Expand All @@ -1607,9 +1664,9 @@ interface F64Array {
*/
@JvmStatic
@JvmName("ofRowsArray")
fun ofRows(rows: List<F64Array>): F64Array {
fun ofRows(rows: List<F64Array>): F64TwoAxisArray {
val args = rows.map { it.reshape(1, *it.shape) }
return concat(args[0], *args.slice(1 until args.size).toTypedArray(), axis = 0)
return concat(args[0], *args.slice(1 until args.size).toTypedArray(), axis = 0) as F64TwoAxisArray
}

/**
Expand Down Expand Up @@ -1645,6 +1702,7 @@ interface F64Array {
return result
}

// TODO: Replace Random with @JvmOverloads
/**
* Creates an array of the given shape with random values.
* The values are uniformly distributed between 0 (inclusive) and 1 (exclusive).
Expand All @@ -1656,18 +1714,42 @@ interface F64Array {
@JvmStatic
fun random(vararg shape: Int): F64Array = random(*shape, random = Random)

/**
* Creates an array of the given shape with random values.
* The values are uniformly distributed between 0 (inclusive) and 1 (exclusive).
*
* @param rows the number of rows
* @param cols the number of columns
* @return the created array
* @since 1.2.0
*/
fun random(rows: Int, cols: Int): F64TwoAxisArray = random(rows, cols, random = Random)

/**
* Creates an array of the given shape with random values.
* The values are uniformly distributed between 0 (inclusive) and 1 (exclusive).
*
* @param shape the shape of the array
* @param random the random number generator
* @param random the random source
* @return the created array
* @since 1.0.7
*/
@JvmStatic
fun random(vararg shape: Int, random: Random): F64Array = F64FlatArray.create(DoubleArray(shape.product()) { random.nextDouble() }).reshape(*shape)

/**
* Creates an array of the given shape with random values.
* The values are uniformly distributed between 0 (inclusive) and 1 (exclusive).
*
* @param rows the number of rows
* @param cols the number of columns
* @param random the random source
* @return the created array
* @since 1.2.0
*/
@JvmStatic
fun random(rows: Int, cols: Int, random: Random): F64TwoAxisArray = F64FlatArray.create(DoubleArray(rows * cols) { random.nextDouble() }).reshape(rows, cols)

/**
* Creates an array with a linear range of values.
*
Expand Down
Loading

0 comments on commit 2c182af

Please sign in to comment.