commonMain.ru.casperix.math.array.float32.FloatMap2D.kt Maven / Gradle / Ivy
package ru.casperix.math.array.float32
import ru.casperix.math.array.IndexedMap2D
import ru.casperix.math.array.MutableMap2D
import ru.casperix.math.axis_aligned.int32.Dimension2i
import ru.casperix.math.vector.int32.Vector2i
@kotlinx.serialization.Serializable
data class FloatMap2D(override val dimension: Vector2i, val array: FloatArray) : IndexedMap2D, MutableMap2D {
override fun setByIndex(index: Int, value: Float) {
array[index] = value
}
override fun getByIndex(index: Int): Float {
return array[index]
}
companion object {
fun create(dimension: Vector2i): FloatMap2D {
return FloatMap2D(dimension, FloatArray(dimension.volume()))
}
fun create(dimension: Vector2i, builder: (index: Int) -> Float): FloatMap2D {
return FloatMap2D(dimension, FloatArray(dimension.volume()) { builder(it) })
}
fun createByXY(dimension: Vector2i, builder: (pos: Vector2i) -> Float): FloatMap2D {
var x = -1
var y = 0
val array = FloatArray(dimension.volume()) {
x++
if (x == dimension.x) {
x = 0
y++
}
builder(Vector2i(x, y))
}
return FloatMap2D(dimension, array)
}
}
init {
if (array.size != dimension.volume()) throw Error("Invalid array size. Need: ${dimension.volume()}")
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as FloatMap2D
if (!array.contentEquals(other.array)) return false
if (dimension != other.dimension) return false
return true
}
override fun hashCode(): Int {
var result = array.contentHashCode()
result = 31 * result + dimension.hashCode()
return result
}
operator fun times(B: FloatMap2D): FloatMap2D? {
val A = this
if (A.dimension.x != B.dimension.y) return null
val outputDimension = Vector2i(B.dimension.x, A.dimension.y)
val output = FloatMap2D(outputDimension, FloatArray(outputDimension.volume()))
(0 until outputDimension.x).forEach { x->
(0 until outputDimension.y).forEach { y->
val value = (0 until A.dimension.x).map { index->
A.get(index, y) * B.get(x, index)
}.sum()
output.set(x, y, value)
}
}
return output
}
}