Skip to content

Commit 56cfdd9

Browse files
committed
为向量序列和可迭代提供 sum() 扩展
1 parent af1ef51 commit 56cfdd9

5 files changed

Lines changed: 31 additions & 62 deletions

File tree

src/main/kotlin/org/mechdancer/algebra/Utility.kt

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,41 +23,31 @@ fun Iterable<Boolean>.alwaysTrue() = all { it }
2323
* 最好先判断维数相同
2424
*/
2525
infix fun Iterable<Double>.contentEquals(other: Iterable<Double>) =
26-
zip(other, ::doubleEquals).alwaysTrue()
26+
zip(other, ::doubleEquals).alwaysTrue()
2727

2828
/**
2929
* 判断两个浮点列表相同
3030
* 最好先判断维数相同
3131
*/
3232
infix fun DoubleArray.contentEquals(other: List<Double>) =
33-
zip(other, ::doubleEquals).alwaysTrue()
33+
zip(other, ::doubleEquals).alwaysTrue()
3434

3535
/**
3636
* 计算许多元素的哈希值
3737
* 慎用!有递归风险!
3838
*/
3939
fun hash(vararg elements: Any?) =
40-
elements.fold(0) { code, it -> code.hashCode() * 31 + (it?.hashCode() ?: 0) }
40+
elements.fold(0) { code, it -> code.hashCode() * 31 + (it?.hashCode() ?: 0) }
4141

42-
/**
43-
* 判断一个可迭代集中所有元素存在相等关系
44-
*/
4542
fun <T> Iterable<T>.isUnique() = toSet().size == 1
46-
47-
/**
48-
* 判断一个可迭代集中所有元素存在某种相等关系
49-
*/
50-
inline infix fun <T, U> Iterable<T>.uniqueOn(block: (T) -> U) = map(block).isUnique()
51-
52-
/**
53-
* 总结一个可迭代集中所有元素的特征
54-
*/
5543
fun <T> Iterable<T>.uniqueValue(): T? = toSet().singleOrNull()
44+
inline fun <T, U> Iterable<T>.uniqueOn(block: (T) -> U) = map(block).isUnique()
45+
inline fun <T, U> Iterable<T>.uniqueValue(block: (T) -> U): U? = map(block).uniqueValue()
5646

57-
/**
58-
* 总结一个可迭代集中所有元素的某项特征
59-
*/
60-
inline infix fun <T, U> Iterable<T>.uniqueValue(block: (T) -> U): U? = map(block).uniqueValue()
47+
fun <T> Sequence<T>.isUnique() = toSet().size == 1
48+
fun <T> Sequence<T>.uniqueValue(): T? = toSet().singleOrNull()
49+
fun <T, U> Sequence<T>.uniqueOn(block: (T) -> U) = map(block).isUnique()
50+
fun <T, U> Sequence<T>.uniqueValue(block: (T) -> U): U? = map(block).uniqueValue()
6151

6252
internal inline fun <T, U> List<T>.zipFast(other: List<T>, block: (T, T) -> U) =
63-
List(kotlin.math.min(size, other.size)) { block(this[it], other[it]) }
53+
List(kotlin.math.min(size, other.size)) { block(this[it], other[it]) }

src/main/kotlin/org/mechdancer/algebra/function/vector/Access.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package org.mechdancer.algebra.function.vector
22

33
import org.mechdancer.algebra.core.Vector
44

5-
//解绑定
5+
// 解绑定
66

77
operator fun Vector.component1() = this[0]
88
operator fun Vector.component2() = this[1]

src/main/kotlin/org/mechdancer/algebra/function/vector/Cauculate.kt

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.mechdancer.algebra.implement.vector.*
66
import org.mechdancer.algebra.uniqueValue
77
import org.mechdancer.algebra.zipFast
88
import kotlin.math.abs
9+
import kotlin.math.pow
910

1011
operator fun Vector.times(k: Number) = toList().map { it * k.toDouble() }.let(::ListVector)
1112
operator fun Vector.div(k: Number) = toList().map { it / k.toDouble() }.let(::ListVector)
@@ -72,26 +73,27 @@ fun Vector3D.normalize() =
7273
else
7374
div(length)
7475

75-
/** 求向量表示的点集的“重心” */
76-
fun Collection<Vector>.centre() =
76+
fun Sequence<Vector>.sum() =
7777
uniqueValue(Vector::dim)
7878
?.let(::listVectorOfZero)
7979
?.let { fold(it) { sum, v -> sum + v } }
80-
?.div(size)
8180
?: throw UnsupportedOperationException("vector dimensions are different")
8281

83-
/** 求二维向量表示的点集的“重心” */
84-
fun Collection<Vector2D>.centre() =
85-
Vector2D(
86-
map(Vector2D::x).average(),
87-
map(Vector2D::y).average()
88-
)
82+
fun Sequence<Vector2D>.sum() =
83+
fold(vector2DOfZero()) { sum, v -> sum + v }
84+
85+
fun Sequence<Vector3D>.sum() =
86+
fold(vector3DOfZero()) { sum, v -> sum + v }
87+
88+
fun Iterable<Vector>.sum() = asSequence().sum()
89+
fun Iterable<Vector2D>.sum() = asSequence().sum()
90+
fun Iterable<Vector3D>.sum() = asSequence().sum()
8991

9092
/** [n]范数 */
9193
fun Vector.norm(n: Int = 2) =
9294
when (n) {
93-
-1 -> toList().map(::abs).max()
94-
1 -> toList().sumByDouble(::abs)
95-
2 -> length
96-
else -> throw UnsupportedOperationException("please invoke length(-1) for infinite length")
95+
-1, Int.MAX_VALUE -> toList().map(::abs).max()
96+
1 -> toList().sumByDouble(::abs)
97+
2 -> length
98+
else -> toList().sumByDouble { it.pow(n) }.pow(1.0 / n)
9799
} ?: .0

src/main/kotlin/org/mechdancer/algebra/function/vector/Copy.kt

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,6 @@ package org.mechdancer.algebra.function.vector
22

33
import org.mechdancer.algebra.core.Vector
44
import org.mechdancer.algebra.implement.vector.ListVector
5-
import org.mechdancer.algebra.implement.vector.Vector2D
6-
import org.mechdancer.algebra.implement.vector.Vector3D
7-
8-
/**
9-
* Copy a 2-dimension vector
10-
* 复制一个二维向量
11-
*
12-
* @param x the 1st dimension
13-
* @param y the 2nd dimension
14-
*/
15-
fun Vector2D.copy(x: Number? = null, y: Number? = null) =
16-
Vector2D(x?.toDouble() ?: this.x, y?.toDouble() ?: this.y)
17-
18-
/**
19-
* Copy a 3-dimension vector
20-
* 复制一个二维向量
21-
*
22-
* @param x the 1st dimension
23-
* @param y the 2nd dimension
24-
* @param z the 3rd dimension
25-
*/
26-
fun Vector3D.copy(x: Number? = null, y: Number? = null, z: Number? = null) =
27-
Vector3D(x?.toDouble() ?: this.x, y?.toDouble() ?: this.y, z?.toDouble() ?: this.z)
285

296
/**
307
* Copy a vector and change value of the first 3 dimension by their name

src/main/kotlin/org/mechdancer/geometry/transformation/Calculate.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import org.mechdancer.algebra.core.Vector
55
import org.mechdancer.algebra.function.equation.solve
66
import org.mechdancer.algebra.function.matrix.times
77
import org.mechdancer.algebra.function.vector.DistanceType
8-
import org.mechdancer.algebra.function.vector.centre
98
import org.mechdancer.algebra.function.vector.div
109
import org.mechdancer.algebra.function.vector.minus
10+
import org.mechdancer.algebra.function.vector.sum
1111
import org.mechdancer.algebra.implement.equation.builder.EquationSetBuilder
1212
import org.mechdancer.algebra.implement.matrix.builder.foldToRows
1313
import org.mechdancer.algebra.implement.matrix.builder.matrix
@@ -48,8 +48,8 @@ fun PointMap.toTransformation(): MatrixTransformation? {
4848
?: throw IllegalArgumentException("points not in same dim")
4949
val temp = DoubleArray(dim * dim)
5050

51-
val ct = targets.centre()
52-
val cs = sources.centre()
51+
val ct = targets.sum() / size
52+
val cs = sources.sum() / size
5353

5454
return takeIf { size > dim }
5555
?.flatMap { (target, source) ->
@@ -80,8 +80,8 @@ private fun Point2DMap.toTransformation(
8080
buildMatrix: (Vector) -> Matrix
8181
): MatrixTransformation? {
8282
if (size < 2) return null
83-
val ct = keys.centre()
84-
val cs = values.centre()
83+
val ct = keys.sum() / size
84+
val cs = values.sum() / size
8585

8686
return EquationSetBuilder()
8787
.also { builder ->

0 commit comments

Comments
 (0)