@@ -21,26 +21,26 @@ import kotlin.math.sqrt
2121// scale multiply
2222
2323private fun timesStub (m : Matrix , k : Double ): Matrix =
24- when (m) {
25- is ZeroMatrix -> m
26- is NumberMatrix -> NumberMatrix [m.dim, m.value * k]
27- is DiagonalMatrix -> DiagonalMatrix (m.diagonal.map { it * k })
28- else -> m.toList().map { it * k }.foldToRows(m.row)
29- }
24+ when (m) {
25+ is ZeroMatrix -> m
26+ is NumberMatrix -> NumberMatrix [m.dim, m.value * k]
27+ is DiagonalMatrix -> DiagonalMatrix (m.diagonal.map { it * k })
28+ else -> m.toList().map { it * k }.foldToRows(m.row)
29+ }
3030
3131operator fun Number.times (m : Matrix ) = timesStub(m, this .toDouble())
3232operator fun Matrix.times (k : Number ) = timesStub(this , k.toDouble())
33- operator fun Matrix.div (k : Number ) = timesStub(this , k.toDouble())
33+ operator fun Matrix.div (k : Number ) = timesStub(this , 1 / k.toDouble())
3434
3535// calculate between same size matrix
3636
3737// 逐项应用某种操作
3838private inline fun Matrix.zip (
39- other : Matrix ,
40- block : (Double , Double ) -> Double
39+ other : Matrix ,
40+ block : (Double , Double ) -> Double
4141): Matrix {
42- assertSameSize(this , other)
43- return ListMatrix (column, toList().zipFast(other.toList(), block))
42+ assertSameSize(this , other)
43+ return ListMatrix (column, toList().zipFast(other.toList(), block))
4444}
4545
4646operator fun Matrix.plus (other : Matrix ) = zip(other) { a, b -> a + b }
@@ -52,44 +52,44 @@ operator fun Matrix.minus(other: Matrix) = zip(other) { a, b -> a - b }
5252 * 矩阵右乘向量
5353 */
5454operator fun Matrix.times (right : Vector ): Vector {
55- assertCanMultiply(this , right)
56- return when {
57- this is ZeroMatrix || right.isZero() ->
58- listVectorOfZero(row)
59- this is NumberMatrix ->
60- right.select(0 until row) * value
61- else ->
62- rows.map { it dot right }.toListVector()
63- }
55+ assertCanMultiply(this , right)
56+ return when {
57+ this is ZeroMatrix || right.isZero() ->
58+ listVectorOfZero(row)
59+ this is NumberMatrix ->
60+ right.select(0 until row) * value
61+ else ->
62+ rows.map { it dot right }.toListVector()
63+ }
6464}
6565
6666/* *
6767 * 矩阵右乘矩阵
6868 */
6969operator fun Matrix.times (right : Matrix ): Matrix {
70- assertCanMultiply(this , right)
71- return when {
72- this is ZeroMatrix || right is ZeroMatrix ->
73- ZeroMatrix [row, right.column]
74- this is NumberMatrix ->
75- timesStub(right, value)
76- right is NumberMatrix ->
77- timesStub(this , right.value)
78- this is DiagonalMatrix -> {
79- if (right is DiagonalMatrix )
80- DiagonalMatrix (diagonal.zipFast(right.diagonal) { a, b -> a * b })
81- else
82- listMatrixOf(row, right.column) { r, c -> diagonal[r] * right[r, c] }
83- }
84- right is DiagonalMatrix ->
85- listMatrixOf(row, right.column) { r, c -> right.diagonal[c] * get(r, c) }
86- else -> {
87- val period = 0 until column
88- listMatrixOf(row, right.column) { r, c ->
89- period.sumByDouble { i -> this [r, i] * right[i, c] }
90- }
91- }
92- }
70+ assertCanMultiply(this , right)
71+ return when {
72+ this is ZeroMatrix || right is ZeroMatrix ->
73+ ZeroMatrix [row, right.column]
74+ this is NumberMatrix ->
75+ timesStub(right, value)
76+ right is NumberMatrix ->
77+ timesStub(this , right.value)
78+ this is DiagonalMatrix -> {
79+ if (right is DiagonalMatrix )
80+ DiagonalMatrix (diagonal.zipFast(right.diagonal) { a, b -> a * b })
81+ else
82+ listMatrixOf(row, right.column) { r, c -> diagonal[r] * right[r, c] }
83+ }
84+ right is DiagonalMatrix ->
85+ listMatrixOf(row, right.column) { r, c -> right.diagonal[c] * get(r, c) }
86+ else -> {
87+ val period = 0 until column
88+ listMatrixOf(row, right.column) { r, c ->
89+ period.sumByDouble { i -> this [r, i] * right[i, c] }
90+ }
91+ }
92+ }
9393}
9494
9595/* *
@@ -105,56 +105,56 @@ operator fun Matrix.invoke(right: Number) = times(right)
105105 * 矩阵乘方
106106 */
107107infix fun Matrix.power (n : Int ): Matrix {
108- assertSquare()
109- assert (n >= 0 )
110- return when (n) {
111- 0 -> I [dim]
112- else -> {
113- var temp = this
114- for (i in 1 until n) temp * = this
115- temp
116- }
117- }
108+ assertSquare()
109+ assert (n >= 0 )
110+ return when (n) {
111+ 0 -> I [dim]
112+ else -> {
113+ var temp = this
114+ for (i in 1 until n) temp * = this
115+ temp
116+ }
117+ }
118118}
119119
120120operator fun Matrix.unaryPlus () = this
121121operator fun Matrix.unaryMinus () = ListMatrix (column, toList().map { - it })
122122fun Matrix.transpose () =
123- if (isSymmetric())
124- (this as ? ValueMutableMatrix )?.clone() ? : this
125- else listMatrixOf(column, row) { r, c -> this [c, r] }
123+ if (isSymmetric())
124+ (this as ? ValueMutableMatrix )?.clone() ? : this
125+ else listMatrixOf(column, row) { r, c -> this [c, r] }
126126
127127fun Matrix.rowEchelon () = toArrayMatrix().rowEchelonAssign()
128128
129129fun Matrix.cofactorOf (r : Int , c : Int ) = Cofactor (this , r, c)
130130
131131// 选择计算范围
132132private fun range (column : Int ) =
133- max(1E- 8 , min(1E- 4 , 10.0 .pow(column * 0.2 - 12 )))
133+ max(1E- 8 , min(1E- 4 , 10.0 .pow(column * 0.2 - 12 )))
134134
135135/* *
136136 * 范数
137137 * @param n 阶数
138138 */
139139fun Matrix.norm (n : Int = 2) =
140- when (n) {
141- - 1 -> rows.map { it.norm(1 ) }.max()
142- 1 -> columns.map { it.norm(1 ) }.max()
143- 2 -> (transpose() * this )
144- .jacobiLevelUp(1E- 3 , range(column))
145- ?.firstOrNull()
146- ?.first
147- ?.let (::sqrt)
148- else -> throw UnsupportedOperationException (" please invoke length(-1) for infinite length" )
149- } ? : Double .NaN
140+ when (n) {
141+ - 1 -> rows.map { it.norm(1 ) }.max()
142+ 1 -> columns.map { it.norm(1 ) }.max()
143+ 2 -> (transpose() * this )
144+ .jacobiLevelUp(1E- 3 , range(column))
145+ ?.firstOrNull()
146+ ?.first
147+ ?.let (::sqrt)
148+ else -> throw UnsupportedOperationException (" please invoke length(-1) for infinite length" )
149+ } ? : Double .NaN
150150
151151/* *
152152 * 条件数
153153 * @param n 阶数
154154 */
155155fun Matrix.cond (n : Int = 2): Double {
156- assertSquare()
157- return norm(n) * inverse().norm(n)
156+ assertSquare()
157+ return norm(n) * inverse().norm(n)
158158}
159159
160160/* *
@@ -166,56 +166,56 @@ fun Matrix.companion() = companionOrNull() ?: throw NotSquareException
166166 * 用空表示伴随矩阵不存在
167167 */
168168fun Matrix.companionOrNull () =
169- if (row != column) null
170- else listMatrixOf(row, column) { r, c -> algebraCofactorOf(c, r)!! }
169+ if (row != column) null
170+ else listMatrixOf(row, column) { r, c -> algebraCofactorOf(c, r)!! }
171171
172172/* *
173173 * 求不可变矩阵的逆矩阵
174174 */
175175fun Matrix.inverse (): Matrix {
176- assertSquare()
177- return inverseOrNull() ? : throw NotFullRankException
176+ assertSquare()
177+ return inverseOrNull() ? : throw NotFullRankException
178178}
179179
180180/* *
181181 * 用空表示逆矩阵不存在
182182 */
183183fun Matrix.inverseOrNull () =
184- when {
185- // 不方,无法求逆
186- isNotSquare() -> null
187- // 对角阵上各元素取倒数可得逆对角阵
188- isDiagonal() ->
189- diagonal
190- .takeIf { list -> list.all { it != .0 } }
191- ?.map { 1 / it }
192- ?.toDiagonalListMatrix()
193- // 正交矩阵的转置与逆相等
194- isOrthogonal() -> transpose()
195- // 对于值可变矩阵,克隆可能有更高的效率,否则重新构造可变矩阵
196- else ->
197- ((this as ? ValueMutableMatrix )
198- ?.clone()
199- ? : toArrayMatrix())
200- .inverseDestructive()
201- }
184+ when {
185+ // 不方,无法求逆
186+ isNotSquare() -> null
187+ // 对角阵上各元素取倒数可得逆对角阵
188+ isDiagonal() ->
189+ diagonal
190+ .takeIf { list -> list.all { it != .0 } }
191+ ?.map { 1 / it }
192+ ?.toDiagonalListMatrix()
193+ // 正交矩阵的转置与逆相等
194+ isOrthogonal() -> transpose()
195+ // 对于值可变矩阵,克隆可能有更高的效率,否则重新构造可变矩阵
196+ else ->
197+ ((this as ? ValueMutableMatrix )
198+ ?.clone()
199+ ? : toArrayMatrix())
200+ .inverseDestructive()
201+ }
202202
203203object D {
204- @JvmStatic
205- operator fun invoke (matrix : Matrix ) = matrix.det
204+ @JvmStatic
205+ operator fun invoke (matrix : Matrix ) = matrix.det
206206}
207207
208208object Det {
209- @JvmStatic
210- operator fun invoke (matrix : Matrix ) = matrix.det
209+ @JvmStatic
210+ operator fun invoke (matrix : Matrix ) = matrix.det
211211}
212212
213213object R {
214- @JvmStatic
215- operator fun invoke (matrix : Matrix ) = matrix.rank
214+ @JvmStatic
215+ operator fun invoke (matrix : Matrix ) = matrix.rank
216216}
217217
218218object Tr {
219- @JvmStatic
220- operator fun invoke (matrix : Matrix ) = matrix.trace
219+ @JvmStatic
220+ operator fun invoke (matrix : Matrix ) = matrix.trace
221221}
0 commit comments