From 1015e238f13c17d944f2d1c215de9ef24f588556 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 29 Apr 2020 19:28:24 +0300 Subject: [PATCH] Basic geometry --- .../kmath/operations/AlgebraExtensions.kt | 2 + kmath-geometry/build.gradle.kts | 9 +++ .../kmath/geometry/Euclidean2DSpace.kt | 58 +++++++++++++++++++ .../kmath/geometry/Euclidean3DSpace.kt | 57 ++++++++++++++++++ .../kmath/geometry/GeometrySpace.kt | 17 ++++++ .../kotlin/scientifik/kmath/geometry/Line.kt | 6 ++ .../kmath/geometry/ReferenceFrame.kt | 4 ++ settings.gradle.kts | 1 + 8 files changed, 154 insertions(+) create mode 100644 kmath-geometry/build.gradle.kts create mode 100644 kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt create mode 100644 kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt create mode 100644 kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt create mode 100644 kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt create mode 100644 kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt index 1e0453f08..bfb4199a3 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt @@ -3,6 +3,8 @@ package scientifik.kmath.operations fun Space.sum(data: Iterable): T = data.fold(zero) { left, right -> add(left, right) } fun Space.sum(data: Sequence): T = data.fold(zero) { left, right -> add(left, right) } +fun > Iterable.sumWith(space: S): T = space.sum(this) + //TODO optimized power operation fun RingOperations.power(arg: T, power: Int): T { var res = arg diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts new file mode 100644 index 000000000..39aa833ad --- /dev/null +++ b/kmath-geometry/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("scientifik.mpp") +} + +kotlin.sourceSets.commonMain { + dependencies { + api(project(":kmath-core")) + } +} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt new file mode 100644 index 000000000..2313b2170 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt @@ -0,0 +1,58 @@ +package scientifik.kmath.geometry + +import scientifik.kmath.linear.Point +import scientifik.kmath.operations.SpaceElement +import scientifik.kmath.operations.invoke +import kotlin.math.sqrt + + +interface Vector2D : Point, Vector, SpaceElement { + val x: Double + val y: Double + + override val size: Int get() = 2 + + override fun get(index: Int): Double = when (index) { + 1 -> x + 2 -> y + else -> error("Accessing outside of point bounds") + } + + override fun iterator(): Iterator = listOf(x, y).iterator() + + override val context: Euclidean2DSpace get() = Euclidean2DSpace + + override fun unwrap(): Vector2D = this + + override fun Vector2D.wrap(): Vector2D = this +} + +val Vector2D.r: Double get() = Euclidean2DSpace.run { sqrt(norm()) } + +@Suppress("FunctionName") +fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y) + +private data class Vector2DImpl( + override val x: Double, + override val y: Double +) : Vector2D + +/** + * 2D Euclidean space + */ +object Euclidean2DSpace : GeometrySpace { + fun Vector2D.norm(): Double = sqrt(x * x + y * y) + + override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm() + + override fun add(a: Vector2D, b: Vector2D): Vector2D = + Vector2D(a.x + b.x, a.y + b.y) + + override fun multiply(a: Vector2D, k: Number): Vector2D = + Vector2D(a.x * k.toDouble(), a.y * k.toDouble()) + + override val zero: Vector2D = Vector2D(0.0, 0.0) + + override fun Vector2D.dot(other: Vector2D): Double = + x * other.x + y * other.y +} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt new file mode 100644 index 000000000..dd1776342 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt @@ -0,0 +1,57 @@ +package scientifik.kmath.geometry + +import scientifik.kmath.linear.Point +import scientifik.kmath.operations.SpaceElement +import kotlin.math.sqrt + + +interface Vector3D : Point, Vector, SpaceElement { + val x: Double + val y: Double + val z: Double + + override val size: Int get() = 3 + + override fun get(index: Int): Double = when (index) { + 1 -> x + 2 -> y + 3 -> z + else -> error("Accessing outside of point bounds") + } + + override fun iterator(): Iterator = listOf(x, y, z).iterator() + + override val context: Euclidean3DSpace get() = Euclidean3DSpace + + override fun unwrap(): Vector3D = this + + override fun Vector3D.wrap(): Vector3D = this +} + +@Suppress("FunctionName") +fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z) + +val Vector3D.r: Double get() = Euclidean3DSpace.run { sqrt(norm()) } + +private data class Vector3DImpl( + override val x: Double, + override val y: Double, + override val z: Double +) : Vector3D + +object Euclidean3DSpace : GeometrySpace { + override val zero: Vector3D = Vector3D(0.0, 0.0, 0.0) + + fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z) + + override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm() + + override fun add(a: Vector3D, b: Vector3D): Vector3D = + Vector3D(a.x + b.x, a.y + b.y, a.z + b.z) + + override fun multiply(a: Vector3D, k: Number): Vector3D = + Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble()) + + override fun Vector3D.dot(other: Vector3D): Double = + x * other.x + y * other.y + z * other.z +} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt new file mode 100644 index 000000000..b65a8dd3a --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt @@ -0,0 +1,17 @@ +package scientifik.kmath.geometry + +import scientifik.kmath.operations.Space + +interface Vector + +interface GeometrySpace: Space { + /** + * L2 distance + */ + fun V.distanceTo(other: V): Double + + /** + * Scalar product + */ + infix fun V.dot(other: V): Double +} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt new file mode 100644 index 000000000..d802a103f --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt @@ -0,0 +1,6 @@ +package scientifik.kmath.geometry + +data class Line(val base: V, val direction: V) + +typealias Line2D = Line +typealias Line3D = Line diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt new file mode 100644 index 000000000..420e38ce2 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt @@ -0,0 +1,4 @@ +package scientifik.kmath.geometry + +interface ReferenceFrame { +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 671db444a..a08d5f7ee 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -41,5 +41,6 @@ include( ":kmath-io", ":kmath-dimensions", ":kmath-for-real", + ":kmath-geometry", ":examples" )