From d0b3c7347cba777a68b230adfc3081a8781f5aa3 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 19 Feb 2022 20:52:27 +0700 Subject: [PATCH] Inverse, cofactor and adjugate matrices --- .../dbotthepony/kvector/api/DoubleMatrix.kt | 27 ++ .../ru/dbotthepony/kvector/api/FloatMatrix.kt | 27 ++ .../kvector/api/concrete/DoubleMatrix.kt | 441 +++++++++++++++++ .../kvector/api/concrete/FloatMatrix.kt | 442 ++++++++++++++++++ .../dbotthepony/kvector/matrix/functions.kt | 233 ++++++++- .../kvector/matrix/ndouble/MatrixVd.kt | 29 +- .../kvector/matrix/nfloat/MatrixVf.kt | 29 +- .../ru/dbotthepony/kstarbound/math/Angle.kt | 50 -- .../dbotthepony/kstarbound/test/MathTests.kt | 30 +- 9 files changed, 1200 insertions(+), 108 deletions(-) delete mode 100644 src/main/kotlin/ru/dbotthepony/kstarbound/math/Angle.kt diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/api/DoubleMatrix.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/api/DoubleMatrix.kt index 764071f1..e00104a2 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/api/DoubleMatrix.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/api/DoubleMatrix.kt @@ -66,6 +66,33 @@ interface IDoubleMatrix> : IMatrixGetterDouble { * This matrix determinant. If matrix is not square matrix, null is returned. */ val determinant: Double? + + /** + * This matrix' inverse matrix (this * I = identity). + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, or determinant is zero, null is returned. + */ + val inverse: T? + + /** + * This matrix' cofactor matrix. + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, null is returned. + */ + val cofactor: T? + + /** + * This matrix' adjugate matrix. + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, null is returned. + */ + val adjugate: T? } interface IMutableDoubleMatrix> : IMatrixSetterDouble { diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/api/FloatMatrix.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/api/FloatMatrix.kt index 383b7838..5778d01e 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/api/FloatMatrix.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/api/FloatMatrix.kt @@ -66,6 +66,33 @@ interface IFloatMatrix> : IMatrixGetterFloat { * This matrix determinant. If matrix is not square matrix, null is returned. */ val determinant: Float? + + /** + * This matrix' inverse matrix (this * I = identity). + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, or determinant is zero, null is returned. + */ + val inverse: T? + + /** + * This matrix' cofactor matrix. + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, null is returned. + */ + val cofactor: T? + + /** + * This matrix' adjugate matrix. + * + * This operation is computation intense, do cache its result. + * + * If this matrix is not square matrix, null is returned. + */ + val adjugate: T? } interface IMutableFloatMatrix> : IMatrixSetterFloat { diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/DoubleMatrix.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/DoubleMatrix.kt index 2b466a8a..893bead3 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/DoubleMatrix.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/DoubleMatrix.kt @@ -5,6 +5,8 @@ import ru.dbotthepony.kvector.api.IMatrix import ru.dbotthepony.kvector.api.ISquareMatrix import ru.dbotthepony.kvector.api.ITransposable import ru.dbotthepony.kvector.matrix.* +import ru.dbotthepony.kvector.matrix.ndouble.* +import ru.dbotthepony.kvector.matrix.nfloat.* import ru.dbotthepony.kvector.vector.ndouble.Vector2d import ru.dbotthepony.kvector.vector.ndouble.Vector3d import ru.dbotthepony.kvector.vector.ndouble.Vector4d @@ -33,6 +35,153 @@ interface IMatrix2d> : IMatrix, IDoubleMatrix, ITransposa val c1: Vector2d val r0: Vector2d val r1: Vector2d + + /** + * Creates a copy of this matrix as [Matrix4d], + * setting last two rows and columns to 0 + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00, c01, 0.0, 0.0, + c10, c11, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + * setting last row and column to 0 + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00, c01, 0.0, + c10, c11, 0.0, + 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d] + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d], + * setting last two columns and rows to 0 + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00, c01, 0.0, 0.0, + c10, c11, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d], + * setting last column and row to 0 + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00, c01, 0.0, + c10, c11, 0.0, + 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d] + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f], + * casing all [Double]s to [Float]s, + * setting last two columns and rows to 0 + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00.toFloat(), c01.toFloat(), 0f, 0f, + c10.toFloat(), c11.toFloat(), 0f, 0f, + 0f, 0f, 0f, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f], + * casing all [Double]s to [Float]s, + * setting last column and row to 0 + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00.toFloat(), c01.toFloat(), 0f, + c10.toFloat(), c11.toFloat(), 0f, + 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating last row and column + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f], + * setting last two columns and rows to 0, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00.toFloat(), c01.toFloat(), 0f, 0f, + c10.toFloat(), c11.toFloat(), 0f, 0f, + 0f, 0f, 0f, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f], + * setting last column and row to 0, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00.toFloat(), c01.toFloat(), 0f, + c10.toFloat(), c11.toFloat(), 0f, + 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } } /** @@ -83,6 +232,152 @@ interface IMatrix3d> : IMatrix, IDoubleMatrix, ITransposa val r2: Vector3d override val translation: Vector2d get() = Vector2d(r02, r12) + + /** + * Creates a copy of this matrix as [Matrix4d], + * setting last row and column to 0 + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00, c01, c02, 0.0, + c10, c11, c12, 0.0, + c20, c21, c22, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d], + * truncating last row and column + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d], + * setting last column and row to 0 + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00, c01, c02, 0.0, + c10, c11, c12, 0.0, + c20, c21, c22, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d] + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d], + * truncating last row and column + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f], + * casing all [Double]s to [Float]s, + * setting last column and row to 0 + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), 0f, + c10.toFloat(), c11.toFloat(), c12.toFloat(), 0f, + c20.toFloat(), c21.toFloat(), c22.toFloat(), 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f], + * casing all [Double]s to [Float]s + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f], + * setting last column and row to 0, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), 0f, + c10.toFloat(), c11.toFloat(), c12.toFloat(), 0f, + c20.toFloat(), c21.toFloat(), c22.toFloat(), 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f], + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } } /** @@ -163,4 +458,150 @@ interface IMatrix4d> : IMatrix, IDoubleMatrix, ITransposa val r3: Vector4d override val translation: Vector3d get() = Vector3d(r03, r13, r23) + + /** + * Creates a copy of this matrix as [Matrix4d] + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00, c01, c02, c03, + c10, c11, c12, c13, + c20, c21, c22, c23, + c30, c31, c32, c33, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + * truncating last row and column + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d], + * truncating two last rows and columns + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d] + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00, c01, c02, c03, + c10, c11, c12, c13, + c20, c21, c22, c23, + c30, c31, c32, c33, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d], + * truncating last row and column + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d], + * truncating two last rows and columns + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f], + * casing all [Double]s to [Float]s + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), c03.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), c13.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), c23.toFloat(), + c30.toFloat(), c31.toFloat(), c32.toFloat(), c33.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating two last rows and columns, + * casing all [Double]s to [Float]s + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f], + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), c03.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), c13.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), c23.toFloat(), + c30.toFloat(), c31.toFloat(), c32.toFloat(), c33.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00.toFloat(), c01.toFloat(), c02.toFloat(), + c10.toFloat(), c11.toFloat(), c12.toFloat(), + c20.toFloat(), c21.toFloat(), c22.toFloat(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating two last rows and columns, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00.toFloat(), c01.toFloat(), + c10.toFloat(), c11.toFloat(), + ) + } } diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/FloatMatrix.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/FloatMatrix.kt index 4539a1a2..2c7e5e99 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/FloatMatrix.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/api/concrete/FloatMatrix.kt @@ -8,6 +8,8 @@ import ru.dbotthepony.kvector.api.IMatrix import ru.dbotthepony.kvector.api.ISquareMatrix import ru.dbotthepony.kvector.api.ITransposable import ru.dbotthepony.kvector.matrix.* +import ru.dbotthepony.kvector.matrix.ndouble.* +import ru.dbotthepony.kvector.matrix.nfloat.* import ru.dbotthepony.kvector.vector.nfloat.* /** @@ -34,6 +36,156 @@ interface IMatrix2f> : IMatrix, IFloatMatrix, ITransposab val c1: Vector2f val r0: Vector2f val r1: Vector2f + + /** + * Creates a copy of this matrix as [Matrix4d], + * setting last two rows and columns to 0, + * casting all [Float]s to [Double]s + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00.toDouble(), c01.toDouble(), 0.0, 0.0, + c10.toDouble(), c11.toDouble(), 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + * setting last row and column to 0, + * casting all [Float]s to [Double]s + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00.toDouble(), c01.toDouble(), 0.0, + c10.toDouble(), c11.toDouble(), 0.0, + 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d], + * casting all [Float]s to [Double]s + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d], + * setting last two columns and rows to 0, + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00.toDouble(), c01.toDouble(), 0.0, 0.0, + c10.toDouble(), c11.toDouble(), 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d], + * setting last column and row to 0, + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00.toDouble(), c01.toDouble(), 0.0, + c10.toDouble(), c11.toDouble(), 0.0, + 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d], + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f], + * setting last two columns and rows to 0 + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00, c01, 0f, 0f, + c10, c11, 0f, 0f, + 0f, 0f, 0f, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f], + * setting last column and row to 0 + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00, c01, 0f, + c10, c11, 0f, + 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating last row and column + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f], + * setting last two columns and rows to 0, + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00, c01, 0f, 0f, + c10, c11, 0f, 0f, + 0f, 0f, 0f, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f], + * setting last column and row to 0, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00, c01, 0f, + c10, c11, 0f, + 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating last row and column, + * casing all [Double]s to [Float]s + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00, c01, + c10, c11, + ) + } } /** @@ -84,6 +236,152 @@ interface IMatrix3f> : IMatrix, IFloatMatrix, ITransposab val r2: Vector3f override val translation: Vector2f get() = Vector2f(r02, r12) + + /** + * Creates a copy of this matrix as [Matrix4d], + * setting last row and column to 0, + * casting all [Float]s to [Double]s + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), 0.0, + c10.toDouble(), c11.toDouble(), c12.toDouble(), 0.0, + c20.toDouble(), c21.toDouble(), c22.toDouble(), 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + * casting all [Float]s to [Double]s + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d], + * truncating last row and column, + * casting all [Float]s to [Double]s + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d], + * setting last column and row to 0, + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), 0.0, + c10.toDouble(), c11.toDouble(), c12.toDouble(), 0.0, + c20.toDouble(), c21.toDouble(), c22.toDouble(), 0.0, + 0.0, 0.0, 0.0, 0.0, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d], + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d], + * truncating last row and column, + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f], + * setting last column and row to 0 + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00, c01, c02, 0f, + c10, c11, c12, 0f, + c20, c21, c22, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f] + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating last row and column + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f], + * setting last column and row to 0 + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00, c01, c02, 0f, + c10, c11, c12, 0f, + c20, c21, c22, 0f, + 0f, 0f, 0f, 0f, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f] + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating last row and column + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00, c01, + c10, c11, + ) + } } /** @@ -164,4 +462,148 @@ interface IMatrix4f> : IMatrix, IFloatMatrix, ITransposab val r3: Vector4f override val translation: Vector3f get() = Vector3f(r03, r13, r23) + + /** + * Creates a copy of this matrix as [Matrix4d], + * casting all [Float]s to [Double]s + */ + fun toMatrix4d(): Matrix4d { + return Matrix4d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), c03.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), c13.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), c23.toDouble(), + c30.toDouble(), c31.toDouble(), c32.toDouble(), c33.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix3d], + * truncating last row and column, + * casting all [Float]s to [Double]s + */ + fun toMatrix3d(): Matrix3d { + return Matrix3d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix2d], + * truncating two last rows and columns, + * casting all [Float]s to [Double]s + */ + fun toMatrix2d(): Matrix2d { + return Matrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4d], + * casting all [Float]s to [Double]s + */ + fun toMutableMatrix4d(): MutableMatrix4d { + return MutableMatrix4d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), c03.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), c13.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), c23.toDouble(), + c30.toDouble(), c31.toDouble(), c32.toDouble(), c33.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3d], + * truncating last row and column + */ + fun toMutableMatrix3d(): MutableMatrix3d { + return MutableMatrix3d( + c00.toDouble(), c01.toDouble(), c02.toDouble(), + c10.toDouble(), c11.toDouble(), c12.toDouble(), + c20.toDouble(), c21.toDouble(), c22.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2d], + * truncating two last rows and columns + */ + fun toMutableMatrix2d(): MutableMatrix2d { + return MutableMatrix2d( + c00.toDouble(), c01.toDouble(), + c10.toDouble(), c11.toDouble(), + ) + } + + /** + * Creates a copy of this matrix as [Matrix4f] + */ + fun toMatrix4f(): Matrix4f { + return Matrix4f( + c00, c01, c02, c03, + c10, c11, c12, c13, + c20, c21, c22, c23, + c30, c31, c32, c33, + ) + } + + /** + * Creates a copy of this matrix as [Matrix3f], + * truncating last row and column + */ + fun toMatrix3f(): Matrix3f { + return Matrix3f( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [Matrix2f], + * truncating two last rows and columns + */ + fun toMatrix2f(): Matrix2f { + return Matrix2f( + c00, c01, + c10, c11, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix4f] + */ + fun toMutableMatrix4f(): MutableMatrix4f { + return MutableMatrix4f( + c00, c01, c02, c03, + c10, c11, c12, c13, + c20, c21, c22, c23, + c30, c31, c32, c33, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix3f], + * truncating last row and column + */ + fun toMutableMatrix3f(): MutableMatrix3f { + return MutableMatrix3f( + c00, c01, c02, + c10, c11, c12, + c20, c21, c22, + ) + } + + /** + * Creates a copy of this matrix as [MutableMatrix2f], + * truncating two last rows and columns + */ + fun toMutableMatrix2f(): MutableMatrix2f { + return MutableMatrix2f( + c00, c01, + c10, c11, + ) + } } diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/functions.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/functions.kt index 1f970d58..2d9ee255 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/functions.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/functions.kt @@ -316,14 +316,16 @@ private fun load(matrix: IMatrixGetterLong, buffers: Array): L } /** - * Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer]. + * Constructs new complement matrix from [input] representing square matrix, + * by taking out [column] and [row], and load result into [buffer]. * - * @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix + * @throws IllegalArgumentException if [column] or [row] is out of bounds, + * or if [input] does not represent a square matrix * * @return [buffer] */ fun complementMatrix(input: IMatrixGetterDouble, column: Int, row: Int, buffer: Double2Dimensional): Double2Dimensional { - require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" } + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } require(column < input.columns) { "$column < ${input.columns}" } require(row < input.rows) { "$row < ${input.rows}" } @@ -349,14 +351,16 @@ fun complementMatrix(input: IMatrixGetterDouble, column: Int, row: Int, buffer: } /** - * Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer]. + * Constructs new complement matrix from [input] representing square matrix, + * by taking out [column] and [row], and load result into [buffer]. * - * @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix + * @throws IllegalArgumentException if [column] or [row] is out of bounds, + * or if [input] does not represent a square matrix * * @return [buffer] */ fun complementMatrix(input: IMatrixGetterFloat, column: Int, row: Int, buffer: Float2Dimensional): Float2Dimensional { - require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" } + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } require(column < input.columns) { "$column < ${input.columns}" } require(row < input.rows) { "$row < ${input.rows}" } @@ -382,14 +386,16 @@ fun complementMatrix(input: IMatrixGetterFloat, column: Int, row: Int, buffer: F } /** - * Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer]. + * Constructs new complement matrix from [input] representing square matrix, + * by taking out [column] and [row], and load result into [buffer]. * - * @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix + * @throws IllegalArgumentException if [column] or [row] is out of bounds, + * or if [input] does not represent a square matrix * * @return [buffer] */ fun complementMatrix(input: IMatrixGetterInt, column: Int, row: Int, buffer: Int2Dimensional): Int2Dimensional { - require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" } + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } require(column < input.columns) { "$column < ${input.columns}" } require(row < input.rows) { "$row < ${input.rows}" } @@ -415,14 +421,16 @@ fun complementMatrix(input: IMatrixGetterInt, column: Int, row: Int, buffer: Int } /** - * Constructs new complement matrix from [input] representing square matrix, by taking out [column] and [row], and load result into [buffer]. + * Constructs new complement matrix from [input] representing square matrix, + * by taking out [column] and [row], and load result into [buffer]. * - * @throws IllegalArgumentException if [column] or [row] is out of bounds, or if [input] does not represent a square matrix + * @throws IllegalArgumentException if [column] or [row] is out of bounds, + * or if [input] does not represent a square matrix * * @return [buffer] */ fun complementMatrix(input: IMatrixGetterLong, column: Int, row: Int, buffer: Long2Dimensional): Long2Dimensional { - require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.rows} rows, ${input.columns} columns)" } + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } require(column < input.columns) { "$column < ${input.columns}" } require(row < input.rows) { "$row < ${input.rows}" } @@ -447,7 +455,184 @@ fun complementMatrix(input: IMatrixGetterLong, column: Int, row: Int, buffer: Lo return buffer } +/** + * Computes cofactor matrix of specified square matrix [input], + * returning result as [Double2Dimensional] + * + * This operation requires n * n determinant calculations of matrix, + * so do cache result of this function in performance critical context. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix + */ +fun cofactorMatrix(input: IMatrixGetterDouble): Double2Dimensional { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + + if (input.rows == 1) { + return Double2Dimensional(1, 1).also { it[0, 0] = input[0, 0] } + } else if (input.rows == 2) { + return Double2Dimensional(2, 2).also { + it[0, 0] = input[1, 1] + it[1, 0] = -input[1, 0] + it[0, 1] = -input[0, 1] + it[1, 1] = input[0, 0] + } + } + + val result = Double2Dimensional(input.columns, input.rows) + val buffers = Array(input.rows) { Double2Dimensional(it + 1, it + 1) } + + for (column in 0 until input.columns) { + for (row in 0 until input.rows) { + val minor = matrixDeterminant(complementMatrix(input, column, row, buffers[input.columns - 2]), input.columns - 1, buffers) + val cofactor = (-1.0).pow(row + column) * minor + result[column, row] = cofactor + } + } + + return result +} + +/** + * Computes cofactor matrix of specified square matrix [input], + * returning result as [Float2Dimensional] + * + * This operation requires n * n determinant calculations of matrix, + * so do cache result of this function in performance critical context. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix + */ +fun cofactorMatrix(input: IMatrixGetterFloat): Float2Dimensional { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + + if (input.rows == 1) { + return Float2Dimensional(1, 1).also { it[0, 0] = input[0, 0] } + } else if (input.rows == 2) { + return Float2Dimensional(2, 2).also { + it[0, 0] = input[1, 1] + it[1, 0] = -input[1, 0] + it[0, 1] = -input[0, 1] + it[1, 1] = input[0, 0] + } + } + + val result = Float2Dimensional(input.columns, input.rows) + val buffers = Array(input.rows) { Float2Dimensional(it + 1, it + 1) } + + for (column in 0 until input.columns) { + for (row in 0 until input.rows) { + val minor = matrixDeterminant(complementMatrix(input, column, row, buffers[input.columns - 2]), input.columns - 1, buffers) + val cofactor = (-1f).pow(row + column) * minor + result[column, row] = cofactor + } + } + + return result +} + +/** + * Computes adjugate matrix of specified square matrix [input], + * returning result as [Double2Dimensional], + * + * [https://en.wikipedia.org/wiki/Adjugate_matrix] + * + * This operation requires n * n determinant calculations of matrix, + * so do cache result of this function in performance critical context. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix + */ +fun adjugateMatrix(input: IMatrixGetterDouble): Double2Dimensional { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + return transposeMatrix(cofactorMatrix(input)) +} + +/** + * Computes adjugate matrix of specified square matrix [input], + * returning result as [Float2Dimensional], + * + * [https://en.wikipedia.org/wiki/Adjugate_matrix] + * + * This operation requires n * n determinant calculations of matrix, + * so do cache result of this function in performance critical context. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix + */ +fun adjugateMatrix(input: IMatrixGetterFloat): Float2Dimensional { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + return transposeMatrix(cofactorMatrix(input)) +} + +/** + * Computes inverse matrix of specified square matrix [input], + * returning result as [Double2Dimensional], + * + * This operation requires 1 + n * n determinant calculations of original matrix, + * so do cache result of this function in performance critical context. + * + * If determinant is zero, null is returned. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix, or null if determinant is zero. + */ +fun inverseMatrix(input: IMatrixGetterDouble): Double2Dimensional? { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + + var determinant = matrixDeterminant(input) + + if (determinant == 0.0) + return null + + determinant = 1.0 / determinant + val adjugate = adjugateMatrix(input) + + for (column in 0 until input.columns) { + for (row in 0 until input.rows) { + adjugate[column, row] *= determinant + } + } + + return adjugate +} + +/** + * Computes inverse matrix of specified square matrix [input], + * returning result as [Float2Dimensional], + * + * This operation requires 1 + n * n determinant calculations of original matrix, + * so do cache result of this function in performance critical context. + * + * If determinant is zero, null is returned. + * + * @throws IllegalArgumentException if provided [input] is not a square matrix + * @return 2d array containing result matrix, or null if determinant is zero. + */ +fun inverseMatrix(input: IMatrixGetterFloat): Float2Dimensional? { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } + + var determinant = matrixDeterminant(input) + + if (determinant == 0f) + return null + + determinant = 1f / determinant + val adjugate = adjugateMatrix(input) + + for (column in 0 until input.columns) { + for (row in 0 until input.rows) { + adjugate[column, row] *= determinant + } + } + + return adjugate +} + private fun matrixDeterminant(input: Double2Dimensional, size: Int, buffers: Array): Double { + if (input.rows == 1) + return input[0, 0] + val concrete = matrixConcreteDeterminant(input) if (concrete != null) { @@ -468,19 +653,19 @@ private fun matrixDeterminant(input: Double2Dimensional, size: Int, buffers: Arr /** * Recursive determinant finder of specified structure representing square matrix. * - * @throws IllegalArgumentException if [matrix] structure is not square matrix + * @throws IllegalArgumentException if [input] structure is not square matrix */ -fun matrixDeterminant(matrix: IMatrixGetterDouble): Double { - require(matrix.rows == matrix.columns) { "Provided matrix is not square matrix (${matrix.rows} rows, ${matrix.columns} columns)" } +fun matrixDeterminant(input: IMatrixGetterDouble): Double { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } - val concrete = matrixConcreteDeterminant(matrix) + val concrete = matrixConcreteDeterminant(input) if (concrete != null) { return concrete } - val buffers = Array(matrix.rows) { Double2Dimensional(it + 1, it + 1) } - return matrixDeterminant(load(matrix, buffers), matrix.columns, buffers) + val buffers = Array(input.rows) { Double2Dimensional(it + 1, it + 1) } + return matrixDeterminant(load(input, buffers), input.columns, buffers) } private fun matrixDeterminant(input: Float2Dimensional, size: Int, buffers: Array): Float { @@ -504,18 +689,18 @@ private fun matrixDeterminant(input: Float2Dimensional, size: Int, buffers: Arra /** * Recursive determinant finder of specified structure representing square matrix. * - * @throws IllegalArgumentException if [matrix] structure is not square matrix + * @throws IllegalArgumentException if [input] structure is not square matrix */ -fun matrixDeterminant(matrix: IMatrixGetterFloat): Float { - require(matrix.rows == matrix.columns) { "Provided matrix is not square matrix (${matrix.rows} rows, ${matrix.columns} columns)" } +fun matrixDeterminant(input: IMatrixGetterFloat): Float { + require(input.rows == input.columns) { "Provided matrix is not square matrix (${input.columns} columns, ${input.rows} rows)" } - val concrete = matrixConcreteDeterminant(matrix) + val concrete = matrixConcreteDeterminant(input) if (concrete != null) { return concrete } - val buffers = Array(matrix.rows) { Float2Dimensional(it + 1, it + 1) } - return matrixDeterminant(load(matrix, buffers), matrix.columns, buffers).toFloat() + val buffers = Array(input.rows) { Float2Dimensional(it + 1, it + 1) } + return matrixDeterminant(load(input, buffers), input.columns, buffers).toFloat() } diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/ndouble/MatrixVd.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/ndouble/MatrixVd.kt index 18986bf0..948a6a4c 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/ndouble/MatrixVd.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/ndouble/MatrixVd.kt @@ -4,10 +4,8 @@ package ru.dbotthepony.kvector.matrix.ndouble import ru.dbotthepony.kvector.api.* +import ru.dbotthepony.kvector.matrix.* import ru.dbotthepony.kvector.matrix.generated.MultiplicationsDouble -import ru.dbotthepony.kvector.matrix.matrixDeterminant -import ru.dbotthepony.kvector.matrix.multiplyMatrix -import ru.dbotthepony.kvector.matrix.transposeMatrix import ru.dbotthepony.kvector.narray.Double2Dimensional private fun checkRows(value: Int): Int { @@ -153,6 +151,31 @@ abstract class AbstractMatrixVd> protected constructor( return false } + + override val inverse: T? + get() { + if (!isSquareMatrix) + return null + + val result = inverseMatrix(memory) ?: return null + return factorize(result) + } + + override val cofactor: T? + get() { + if (!isSquareMatrix) + return null + + return factorize(cofactorMatrix(memory)) + } + + override val adjugate: T? + get() { + if (!isSquareMatrix) + return null + + return factorize(adjugateMatrix(memory)) + } } /** diff --git a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/nfloat/MatrixVf.kt b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/nfloat/MatrixVf.kt index f86beeb2..100b807b 100644 --- a/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/nfloat/MatrixVf.kt +++ b/src/kvector/kotlin/ru/dbotthepony/kvector/matrix/nfloat/MatrixVf.kt @@ -4,10 +4,8 @@ package ru.dbotthepony.kvector.matrix.nfloat import ru.dbotthepony.kvector.api.* +import ru.dbotthepony.kvector.matrix.* import ru.dbotthepony.kvector.matrix.generated.MultiplicationsFloat -import ru.dbotthepony.kvector.matrix.matrixDeterminant -import ru.dbotthepony.kvector.matrix.multiplyMatrix -import ru.dbotthepony.kvector.matrix.transposeMatrix import ru.dbotthepony.kvector.narray.Float2Dimensional private fun checkRows(value: Int): Int { @@ -153,6 +151,31 @@ abstract class AbstractMatrixVf> protected constructor( return false } + + override val inverse: T? + get() { + if (!isSquareMatrix) + return null + + val result = inverseMatrix(memory) ?: return null + return factorize(result) + } + + override val cofactor: T? + get() { + if (!isSquareMatrix) + return null + + return factorize(cofactorMatrix(memory)) + } + + override val adjugate: T? + get() { + if (!isSquareMatrix) + return null + + return factorize(adjugateMatrix(memory)) + } } /** diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Angle.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/math/Angle.kt deleted file mode 100644 index 1c89f45b..00000000 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/math/Angle.kt +++ /dev/null @@ -1,50 +0,0 @@ -package ru.dbotthepony.kstarbound.math - -import kotlin.math.cos -import kotlin.math.sin - -interface IAngle { - val pitch: Double - val yaw: Double - val roll: Double - - fun matrixX(): Matrix4f { - val s = sin(pitch).toFloat() - val c = cos(pitch).toFloat() - - return Matrix4f( - m11 = c, m12 = -s, - m21 = s, m22 = c, - ) - } - - fun matrixY(): Matrix4f { - val s = sin(yaw).toFloat() - val c = cos(yaw).toFloat() - - return Matrix4f( - m00 = c, m02 = s, - m20 = -s, m22 = c - ) - } - - fun matrixZ(): Matrix4f { - val s = sin(roll).toFloat() - val c = cos(roll).toFloat() - - return Matrix4f( - m00 = c, m01 = -s, - m10 = s, m11 = c - ) - } - - fun matrixXYZ(): Matrix4f { - return matrixX() * matrixY() * matrixZ() - } -} - -data class Angle( - override val pitch: Double = 0.0, - override val yaw: Double = 0.0, - override val roll: Double = 0.0, -) : IAngle diff --git a/src/test/kotlin/ru/dbotthepony/kstarbound/test/MathTests.kt b/src/test/kotlin/ru/dbotthepony/kstarbound/test/MathTests.kt index 603058ec..5e6bb18e 100644 --- a/src/test/kotlin/ru/dbotthepony/kstarbound/test/MathTests.kt +++ b/src/test/kotlin/ru/dbotthepony/kstarbound/test/MathTests.kt @@ -7,9 +7,9 @@ import ru.dbotthepony.kstarbound.world.CHUNK_SIZE import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_FF import ru.dbotthepony.kstarbound.world.CHUNK_SIZEd import ru.dbotthepony.kstarbound.world.ChunkPos -import ru.dbotthepony.kvector.matrix.matrixDeterminant +import ru.dbotthepony.kvector.matrix.adjugateMatrix import ru.dbotthepony.kvector.matrix.multiplyMatrix -import ru.dbotthepony.kvector.matrix.generated.* +import ru.dbotthepony.kvector.matrix.inverseMatrix import ru.dbotthepony.kvector.narray.Double2Dimensional object MathTests { @@ -155,30 +155,4 @@ object MathTests { check(product[1, 1] == 96.0) check(product[2, 1] == 26.0) } - - @Test - fun testAlloc() { - System.gc() - - var t = System.currentTimeMillis() - var escape2 = 0.0 - - for (i in 0 .. 8000000) { - val matrix = Matrix4d() - escape2 += matrix[2, 3] - } - - println(System.currentTimeMillis() - t) - System.gc() - t = System.currentTimeMillis() - var escape = 0.0 - - for (i in 0 .. 8000000) { - val matrix = Double2Dimensional(4, 4) - escape += matrix[2, 3] - } - - println(System.currentTimeMillis() - t) - println(escape) - } }