Skip to content

Commit e4bd722

Browse files
committed
修改矩阵无法数除的 bug
1 parent 5837932 commit e4bd722

1 file changed

Lines changed: 99 additions & 99 deletions

File tree

  • src/main/kotlin/org/mechdancer/algebra/function/matrix

src/main/kotlin/org/mechdancer/algebra/function/matrix/Calculate.kt

Lines changed: 99 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,26 @@ import kotlin.math.sqrt
2121
// scale multiply
2222

2323
private 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

3131
operator fun Number.times(m: Matrix) = timesStub(m, this.toDouble())
3232
operator 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
//逐项应用某种操作
3838
private 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

4646
operator 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
*/
5454
operator 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
*/
6969
operator 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
*/
107107
infix 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

120120
operator fun Matrix.unaryPlus() = this
121121
operator fun Matrix.unaryMinus() = ListMatrix(column, toList().map { -it })
122122
fun 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

127127
fun Matrix.rowEchelon() = toArrayMatrix().rowEchelonAssign()
128128

129129
fun Matrix.cofactorOf(r: Int, c: Int) = Cofactor(this, r, c)
130130

131131
// 选择计算范围
132132
private 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
*/
139139
fun 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
*/
155155
fun 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
*/
168168
fun 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
*/
175175
fun Matrix.inverse(): Matrix {
176-
assertSquare()
177-
return inverseOrNull() ?: throw NotFullRankException
176+
assertSquare()
177+
return inverseOrNull() ?: throw NotFullRankException
178178
}
179179

180180
/**
181181
* 用空表示逆矩阵不存在
182182
*/
183183
fun 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

203203
object D {
204-
@JvmStatic
205-
operator fun invoke(matrix: Matrix) = matrix.det
204+
@JvmStatic
205+
operator fun invoke(matrix: Matrix) = matrix.det
206206
}
207207

208208
object Det {
209-
@JvmStatic
210-
operator fun invoke(matrix: Matrix) = matrix.det
209+
@JvmStatic
210+
operator fun invoke(matrix: Matrix) = matrix.det
211211
}
212212

213213
object R {
214-
@JvmStatic
215-
operator fun invoke(matrix: Matrix) = matrix.rank
214+
@JvmStatic
215+
operator fun invoke(matrix: Matrix) = matrix.rank
216216
}
217217

218218
object 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

Comments
 (0)