Skip to content

Commit

Permalink
Restructure Dim.kt to avoid stack overflows
Browse files Browse the repository at this point in the history
Previously when running Keigen on the roboRIO, the class hierarchy
created in Dim.kt would be enough to crash the roboRIO's JRE when trying
to load all the superclasses.

The structure is now flattened such that every type number is a subclass
of Num. This loses the order encoded in the class hierarchy, however for
hte purposes of matrix shape, that isn't necessary.
  • Loading branch information
Redrield committed May 29, 2019
1 parent 3475af5 commit ac3789e
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 80 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ publishing {
create<MavenPublication>("mavenLocal") {
groupId = "frc.team4069"
artifactId = "Keigen"
version = "1.2.0"
version = "1.3.0"

from(components["java"])
}
Expand Down
163 changes: 104 additions & 59 deletions src/main/kotlin/frc/team4069/keigen/Dim.kt
Original file line number Diff line number Diff line change
@@ -1,64 +1,109 @@
/*
* This file is taken from [Kotlingrad](https://github.com/breandan/kotlingrad). It provides a type-safe notion of numbers from
* 0 to 100
*/
package frc.team4069.keigen

open class `0`(override val i: Int = 0): `1`(i) { companion object: `0`(), Nat<`0`> }
open class `1`(override val i: Int = 1): `2`(i) { companion object: `1`(), Nat<`1`> }
open class `2`(override val i: Int = 2): `3`(i) { companion object: `2`(), Nat<`2`> }
open class `3`(override val i: Int = 3): `4`(i) { companion object: `3`(), Nat<`3`> }
open class `4`(override val i: Int = 4): `5`(i) { companion object: `4`(), Nat<`4`> }
open class `5`(override val i: Int = 5): `6`(i) { companion object: `5`(), Nat<`5`> }
open class `6`(override val i: Int = 6): `7`(i) { companion object: `6`(), Nat<`6`> }
open class `7`(override val i: Int = 7): `8`(i) { companion object: `7`(), Nat<`7`> }
open class `8`(override val i: Int = 8): `9`(i) { companion object: `8`(), Nat<`8`> }
open class `9`(override val i: Int = 9): `10`(i) { companion object: `9`(), Nat<`9`> }
open class `10`(override val i: Int = 10): `11`(i) { companion object: `10`(), Nat<`10`> }
open class `11`(override val i: Int = 11): `12`(i) { companion object: `11`(), Nat<`11`> }
open class `12`(override val i: Int = 12): `13`(i) { companion object: `12`(), Nat<`12`> }
open class `13`(override val i: Int = 13): `14`(i) { companion object: `13`(), Nat<`13`> }
open class `14`(override val i: Int = 14): `15`(i) { companion object: `14`(), Nat<`14`> }
open class `15`(override val i: Int = 15): `16`(i) { companion object: `15`(), Nat<`15`> }
open class `16`(override val i: Int = 16): `17`(i) { companion object: `16`(), Nat<`16`> }
open class `17`(override val i: Int = 17): `18`(i) { companion object: `17`(), Nat<`17`> }
open class `18`(override val i: Int = 18): `19`(i) { companion object: `18`(), Nat<`18`> }
open class `19`(override val i: Int = 19): `20`(i) { companion object: `19`(), Nat<`19`> }
open class `20`(override val i: Int = 20): `21`(i) { companion object: `20`(), Nat<`20`> }
open class `21`(override val i: Int = 21): `22`(i) { companion object: `21`(), Nat<`21`> }
open class `22`(override val i: Int = 22): `23`(i) { companion object: `22`(), Nat<`22`> }
open class `23`(override val i: Int = 23): `24`(i) { companion object: `23`(), Nat<`23`> }
open class `24`(override val i: Int = 24): `25`(i) { companion object: `24`(), Nat<`24`> }
open class `25`(override val i: Int = 25): `26`(i) { companion object: `25`(), Nat<`25`> }
open class `26`(override val i: Int = 26): `27`(i) { companion object: `26`(), Nat<`26`> }
open class `27`(override val i: Int = 27): `28`(i) { companion object: `27`(), Nat<`27`> }
open class `28`(override val i: Int = 28): `29`(i) { companion object: `28`(), Nat<`28`> }
open class `29`(override val i: Int = 29): `30`(i) { companion object: `29`(), Nat<`29`> }
open class `30`(override val i: Int = 30): `31`(i) { companion object: `30`(), Nat<`30`> }
open class `31`(override val i: Int = 31): `32`(i) { companion object: `31`(), Nat<`31`> }
open class `32`(override val i: Int = 32): `33`(i) { companion object: `32`(), Nat<`32`> }
open class `33`(override val i: Int = 33): `34`(i) { companion object: `33`(), Nat<`33`> }
open class `34`(override val i: Int = 34): `35`(i) { companion object: `34`(), Nat<`34`> }
open class `35`(override val i: Int = 35): `36`(i) { companion object: `35`(), Nat<`35`> }
open class `36`(override val i: Int = 36): `37`(i) { companion object: `36`(), Nat<`36`> }
open class `37`(override val i: Int = 37): `38`(i) { companion object: `37`(), Nat<`37`> }
open class `38`(override val i: Int = 38): `39`(i) { companion object: `38`(), Nat<`38`> }
open class `39`(override val i: Int = 39): `40`(i) { companion object: `39`(), Nat<`39`> }
open class `40`(override val i: Int = 40): `41`(i) { companion object: `40`(), Nat<`40`> }
open class `41`(override val i: Int = 41): `42`(i) { companion object: `41`(), Nat<`41`> }
open class `42`(override val i: Int = 42): `43`(i) { companion object: `42`(), Nat<`42`> }
open class `43`(override val i: Int = 43): `44`(i) { companion object: `43`(), Nat<`43`> }
open class `44`(override val i: Int = 44): `45`(i) { companion object: `44`(), Nat<`44`> }
open class `45`(override val i: Int = 45): `46`(i) { companion object: `45`(), Nat<`45`> }
open class `46`(override val i: Int = 46): `47`(i) { companion object: `46`(), Nat<`46`> }
open class `47`(override val i: Int = 47): `48`(i) { companion object: `47`(), Nat<`47`> }
open class `48`(override val i: Int = 48): `49`(i) { companion object: `48`(), Nat<`48`> }
open class `49`(override val i: Int = 49): `50`(i) { companion object: `49`(), Nat<`49`> }
sealed class Num(open val i: Int)

sealed class `50`(open val i: Int = 50) {
companion object: `50`(), Nat<`50`>

override fun toString() = "$i"
interface Nat<T: Num> {
val i: Int
}

interface Nat<T: `50`> { val i: Int }
open class `0`(override val i: Int = 0): Num(i) { companion object: `0`(), Nat<`0`> }
open class `1`(override val i: Int = 1): Num(i) { companion object: `1`(), Nat<`1`> }
open class `2`(override val i: Int = 2): Num(i) { companion object: `2`(), Nat<`2`> }
open class `3`(override val i: Int = 3): Num(i) { companion object: `3`(), Nat<`3`> }
open class `4`(override val i: Int = 4): Num(i) { companion object: `4`(), Nat<`4`> }
open class `5`(override val i: Int = 5): Num(i) { companion object: `5`(), Nat<`5`> }
open class `6`(override val i: Int = 6): Num(i) { companion object: `6`(), Nat<`6`> }
open class `7`(override val i: Int = 7): Num(i) { companion object: `7`(), Nat<`7`> }
open class `8`(override val i: Int = 8): Num(i) { companion object: `8`(), Nat<`8`> }
open class `9`(override val i: Int = 9): Num(i) { companion object: `9`(), Nat<`9`> }
open class `10`(override val i: Int = 10): Num(i) { companion object: `10`(), Nat<`10`> }
open class `11`(override val i: Int = 11): Num(i) { companion object: `11`(), Nat<`11`> }
open class `12`(override val i: Int = 12): Num(i) { companion object: `12`(), Nat<`12`> }
open class `13`(override val i: Int = 13): Num(i) { companion object: `13`(), Nat<`13`> }
open class `14`(override val i: Int = 14): Num(i) { companion object: `14`(), Nat<`14`> }
open class `15`(override val i: Int = 15): Num(i) { companion object: `15`(), Nat<`15`> }
open class `16`(override val i: Int = 16): Num(i) { companion object: `16`(), Nat<`16`> }
open class `17`(override val i: Int = 17): Num(i) { companion object: `17`(), Nat<`17`> }
open class `18`(override val i: Int = 18): Num(i) { companion object: `18`(), Nat<`18`> }
open class `19`(override val i: Int = 19): Num(i) { companion object: `19`(), Nat<`19`> }
open class `20`(override val i: Int = 20): Num(i) { companion object: `20`(), Nat<`20`> }
open class `21`(override val i: Int = 21): Num(i) { companion object: `21`(), Nat<`21`> }
open class `22`(override val i: Int = 22): Num(i) { companion object: `22`(), Nat<`22`> }
open class `23`(override val i: Int = 23): Num(i) { companion object: `23`(), Nat<`23`> }
open class `24`(override val i: Int = 24): Num(i) { companion object: `24`(), Nat<`24`> }
open class `25`(override val i: Int = 25): Num(i) { companion object: `25`(), Nat<`25`> }
open class `26`(override val i: Int = 26): Num(i) { companion object: `26`(), Nat<`26`> }
open class `27`(override val i: Int = 27): Num(i) { companion object: `27`(), Nat<`27`> }
open class `28`(override val i: Int = 28): Num(i) { companion object: `28`(), Nat<`28`> }
open class `29`(override val i: Int = 29): Num(i) { companion object: `29`(), Nat<`29`> }
open class `30`(override val i: Int = 30): Num(i) { companion object: `30`(), Nat<`30`> }
open class `31`(override val i: Int = 31): Num(i) { companion object: `31`(), Nat<`31`> }
open class `32`(override val i: Int = 32): Num(i) { companion object: `32`(), Nat<`32`> }
open class `33`(override val i: Int = 33): Num(i) { companion object: `33`(), Nat<`33`> }
open class `34`(override val i: Int = 34): Num(i) { companion object: `34`(), Nat<`34`> }
open class `35`(override val i: Int = 35): Num(i) { companion object: `35`(), Nat<`35`> }
open class `36`(override val i: Int = 36): Num(i) { companion object: `36`(), Nat<`36`> }
open class `37`(override val i: Int = 37): Num(i) { companion object: `37`(), Nat<`37`> }
open class `38`(override val i: Int = 38): Num(i) { companion object: `38`(), Nat<`38`> }
open class `39`(override val i: Int = 39): Num(i) { companion object: `39`(), Nat<`39`> }
open class `40`(override val i: Int = 40): Num(i) { companion object: `40`(), Nat<`40`> }
open class `41`(override val i: Int = 41): Num(i) { companion object: `41`(), Nat<`41`> }
open class `42`(override val i: Int = 42): Num(i) { companion object: `42`(), Nat<`42`> }
open class `43`(override val i: Int = 43): Num(i) { companion object: `43`(), Nat<`43`> }
open class `44`(override val i: Int = 44): Num(i) { companion object: `44`(), Nat<`44`> }
open class `45`(override val i: Int = 45): Num(i) { companion object: `45`(), Nat<`45`> }
open class `46`(override val i: Int = 46): Num(i) { companion object: `46`(), Nat<`46`> }
open class `47`(override val i: Int = 47): Num(i) { companion object: `47`(), Nat<`47`> }
open class `48`(override val i: Int = 48): Num(i) { companion object: `48`(), Nat<`48`> }
open class `49`(override val i: Int = 49): Num(i) { companion object: `49`(), Nat<`49`> }
open class `50`(override val i: Int = 50): Num(i) { companion object: `50`(), Nat<`50`> }
open class `51`(override val i: Int = 51): Num(i) { companion object: `51`(), Nat<`51`> }
open class `52`(override val i: Int = 52): Num(i) { companion object: `52`(), Nat<`52`> }
open class `53`(override val i: Int = 53): Num(i) { companion object: `53`(), Nat<`53`> }
open class `54`(override val i: Int = 54): Num(i) { companion object: `54`(), Nat<`54`> }
open class `55`(override val i: Int = 55): Num(i) { companion object: `55`(), Nat<`55`> }
open class `56`(override val i: Int = 56): Num(i) { companion object: `56`(), Nat<`56`> }
open class `57`(override val i: Int = 57): Num(i) { companion object: `57`(), Nat<`57`> }
open class `58`(override val i: Int = 58): Num(i) { companion object: `58`(), Nat<`58`> }
open class `59`(override val i: Int = 59): Num(i) { companion object: `59`(), Nat<`59`> }
open class `60`(override val i: Int = 60): Num(i) { companion object: `60`(), Nat<`60`> }
open class `61`(override val i: Int = 61): Num(i) { companion object: `61`(), Nat<`61`> }
open class `62`(override val i: Int = 62): Num(i) { companion object: `62`(), Nat<`62`> }
open class `63`(override val i: Int = 63): Num(i) { companion object: `63`(), Nat<`63`> }
open class `64`(override val i: Int = 64): Num(i) { companion object: `64`(), Nat<`64`> }
open class `65`(override val i: Int = 65): Num(i) { companion object: `65`(), Nat<`65`> }
open class `66`(override val i: Int = 66): Num(i) { companion object: `66`(), Nat<`66`> }
open class `67`(override val i: Int = 67): Num(i) { companion object: `67`(), Nat<`67`> }
open class `68`(override val i: Int = 68): Num(i) { companion object: `68`(), Nat<`68`> }
open class `69`(override val i: Int = 69): Num(i) { companion object: `69`(), Nat<`69`> }
open class `70`(override val i: Int = 70): Num(i) { companion object: `70`(), Nat<`70`> }
open class `71`(override val i: Int = 71): Num(i) { companion object: `71`(), Nat<`71`> }
open class `72`(override val i: Int = 72): Num(i) { companion object: `72`(), Nat<`72`> }
open class `73`(override val i: Int = 73): Num(i) { companion object: `73`(), Nat<`73`> }
open class `74`(override val i: Int = 74): Num(i) { companion object: `74`(), Nat<`74`> }
open class `75`(override val i: Int = 75): Num(i) { companion object: `75`(), Nat<`75`> }
open class `76`(override val i: Int = 76): Num(i) { companion object: `76`(), Nat<`76`> }
open class `77`(override val i: Int = 77): Num(i) { companion object: `77`(), Nat<`77`> }
open class `78`(override val i: Int = 78): Num(i) { companion object: `78`(), Nat<`78`> }
open class `79`(override val i: Int = 79): Num(i) { companion object: `79`(), Nat<`79`> }
open class `80`(override val i: Int = 80): Num(i) { companion object: `80`(), Nat<`80`> }
open class `81`(override val i: Int = 81): Num(i) { companion object: `81`(), Nat<`81`> }
open class `82`(override val i: Int = 82): Num(i) { companion object: `82`(), Nat<`82`> }
open class `83`(override val i: Int = 83): Num(i) { companion object: `83`(), Nat<`83`> }
open class `84`(override val i: Int = 84): Num(i) { companion object: `84`(), Nat<`84`> }
open class `85`(override val i: Int = 85): Num(i) { companion object: `85`(), Nat<`85`> }
open class `86`(override val i: Int = 86): Num(i) { companion object: `86`(), Nat<`86`> }
open class `87`(override val i: Int = 87): Num(i) { companion object: `87`(), Nat<`87`> }
open class `88`(override val i: Int = 88): Num(i) { companion object: `88`(), Nat<`88`> }
open class `89`(override val i: Int = 89): Num(i) { companion object: `89`(), Nat<`89`> }
open class `90`(override val i: Int = 90): Num(i) { companion object: `90`(), Nat<`90`> }
open class `91`(override val i: Int = 91): Num(i) { companion object: `91`(), Nat<`91`> }
open class `92`(override val i: Int = 92): Num(i) { companion object: `92`(), Nat<`92`> }
open class `93`(override val i: Int = 93): Num(i) { companion object: `93`(), Nat<`93`> }
open class `94`(override val i: Int = 94): Num(i) { companion object: `94`(), Nat<`94`> }
open class `95`(override val i: Int = 95): Num(i) { companion object: `95`(), Nat<`95`> }
open class `96`(override val i: Int = 96): Num(i) { companion object: `96`(), Nat<`96`> }
open class `97`(override val i: Int = 97): Num(i) { companion object: `97`(), Nat<`97`> }
open class `98`(override val i: Int = 98): Num(i) { companion object: `98`(), Nat<`98`> }
open class `99`(override val i: Int = 99): Num(i) { companion object: `99`(), Nat<`99`> }
open class `100`(override val i: Int = 100): Num(i) { companion object: `100`(), Nat<`100`> }
4 changes: 2 additions & 2 deletions src/main/kotlin/frc/team4069/keigen/Matrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.ejml.dense.row.CommonOps_DDRM
import org.ejml.dense.row.NormOps_DDRM
import org.ejml.simple.SimpleMatrix

open class Matrix<R: `50`, C: `50`>(private val rows: Nat<R>, private val cols: Nat<C>, internal val storage: SimpleMatrix) {
open class Matrix<R: Num, C: Num>(private val rows: Nat<R>, private val cols: Nat<C>, internal val storage: SimpleMatrix) {
val numCols get() = cols.i

val numRows get() = rows.i
Expand All @@ -20,7 +20,7 @@ open class Matrix<R: `50`, C: `50`>(private val rows: Nat<R>, private val cols:
fun minInternal() = CommonOps_DDRM.elementMin(this.storage.ddrm)
fun mean() = elementSum() / storage.numElements.toDouble()

operator fun <C2: `50`> times(other: Matrix<C, C2>): Matrix<R, C2>
operator fun <C2: Num> times(other: Matrix<C, C2>): Matrix<R, C2>
= Matrix(rows, other.cols, this.storage.mult(other.storage))

operator fun times(value: Double): Matrix<R, C>
Expand Down
15 changes: 4 additions & 11 deletions src/main/kotlin/frc/team4069/keigen/creatorDsl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package frc.team4069.keigen

import org.ejml.simple.SimpleMatrix

fun <R : `50`, C : `50`> mat(rows: Nat<R>, cols: Nat<C>) = MatBuilder(rows, cols)
fun <R : Num, C : Num> mat(rows: Nat<R>, cols: Nat<C>) = MatBuilder(rows, cols)

fun <D : `50`> vec(dim: Nat<D>) = VecBuilder(dim)
fun <D : Num> vec(dim: Nat<D>) = VecBuilder(dim)

class MatBuilder<R : `50`, C : `50`>(val rows: Nat<R>, val cols: Nat<C>) {
class MatBuilder<R : Num, C : Num>(val rows: Nat<R>, val cols: Nat<C>) {
fun fill(vararg data: Double): Matrix<R, C> {
if (data.size != rows.i * cols.i) {
throw IllegalArgumentException("Invalid matrix data provided. Wanted ${rows.i} x ${cols.i} matrix, but got ${data.size} elements")
Expand All @@ -26,7 +26,7 @@ class MatBuilder<R : `50`, C : `50`>(val rows: Nat<R>, val cols: Nat<C>) {
}
}

class VecBuilder<D : `50`>(val dim: Nat<D>) {
class VecBuilder<D : Num>(val dim: Nat<D>) {
fun fill(vararg data: Double): Vector<D> {
if (data.size != dim.i) {
throw IllegalArgumentException("Invalid number of elements for ${dim.i}-dimensional vector. got ${data.size} elements")
Expand All @@ -43,10 +43,3 @@ class VecBuilder<D : `50`>(val dim: Nat<D>) {
return Matrix(dim, `1`, SimpleMatrix(dim.i, 1, false, data.map { it.toDouble() }.toDoubleArray()))
}
}


fun x() {
vec(`2`).fill(1.0, 2.0)

mat(`2`, `2`).fill(1, 2, 3, 4)
}
10 changes: 5 additions & 5 deletions src/main/kotlin/frc/team4069/keigen/creators.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package frc.team4069.keigen
import org.ejml.dense.row.CommonOps_DDRM
import org.ejml.simple.SimpleMatrix

fun <R: `50`, C: `50`> zeros(rows: Nat<R>, cols: Nat<C>) = Matrix(rows, cols, SimpleMatrix(rows.i, cols.i))
fun <D: `50`> zeros(size: Nat<D>) = Matrix(size, `1`, SimpleMatrix(size.i, 1))
fun <R: Num, C: Num> zeros(rows: Nat<R>, cols: Nat<C>) = Matrix(rows, cols, SimpleMatrix(rows.i, cols.i))
fun <D: Num> zeros(size: Nat<D>) = Matrix(size, `1`, SimpleMatrix(size.i, 1))

fun <D: `50`> eye(size: Nat<D>) = Matrix(size, size, SimpleMatrix.identity(size.i))
fun <D: Num> eye(size: Nat<D>) = Matrix(size, size, SimpleMatrix.identity(size.i))

fun <R: `50`, C: `50`> ones(rows: Nat<R>, cols: Nat<C>): Matrix<R, C> {
fun <R: Num, C: Num> ones(rows: Nat<R>, cols: Nat<C>): Matrix<R, C> {
val out = SimpleMatrix(rows.i, cols.i)
CommonOps_DDRM.fill(out.ddrm, 1.0)
return Matrix(rows, cols, out)
}
fun <D: `50`> ones(size: Nat<D>): Matrix<D, `1`> {
fun <D: Num> ones(size: Nat<D>): Matrix<D, `1`> {
val out = SimpleMatrix(size.i, 1)
CommonOps_DDRM.fill(out.ddrm, 1.0)

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/frc/team4069/keigen/vector.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package frc.team4069.keigen

typealias Vector<D> = Matrix<D, `1`>

operator fun <D: `50`> Matrix<D, `1`>.get(i: Int) = storage[i, 0]
operator fun <D: `50`> Matrix<D, `1`>.set(i: Int, j: Double) {
operator fun <D: Num> Matrix<D, `1`>.get(i: Int) = storage[i, 0]
operator fun <D: Num> Matrix<D, `1`>.set(i: Int, j: Double) {
storage[i, 0] = j
}

0 comments on commit ac3789e

Please sign in to comment.