From 3736120179c029b776d3ce0e6f5174b4e7405f73 Mon Sep 17 00:00:00 2001 From: Peva Blanchard Date: Thu, 20 Jul 2023 04:19:14 +0200 Subject: [PATCH] make all tests pass --- .../lcaplugin/core/assessment/Assessment.kt | 6 ++-- .../core/lang/evaluator/Evaluator.kt | 7 ++-- .../lcaplugin/core/lang/value/SystemValue.kt | 6 ++++ .../kleis/lcaplugin/core/math/DualMatrix.kt | 8 ++++- .../kleis/lcaplugin/core/math/DualNumber.kt | 1 + .../lcaplugin/core/math/ejml/EJMLMatrix.kt | 36 +++++++++++++------ .../kotlin/ch/kleis/lcaplugin/e2e/E2ETest.kt | 18 +++++++--- 7 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/assessment/Assessment.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/assessment/Assessment.kt index e933cfc0c..f3397657d 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/assessment/Assessment.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/assessment/Assessment.kt @@ -35,7 +35,7 @@ class Assessment( substanceCharacterizations, observableProducts, observableSubstances, - system.parameters.size, + system.effectiveParametersSize, ) val terminalProducts = processes @@ -56,13 +56,13 @@ class Assessment( terminalProducts, terminalSubstances, indicators, - system.parameters.size, + system.effectiveParametersSize, ) demandMatrix = DemandMatrix( targetProcess, observablePorts, - system.parameters.size, + system.effectiveParametersSize, ) } diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/lang/evaluator/Evaluator.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/lang/evaluator/Evaluator.kt index efb1c0ef9..69425c8a5 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/lang/evaluator/Evaluator.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/lang/evaluator/Evaluator.kt @@ -41,8 +41,11 @@ class Evaluator( fun trace(expression: EProcessTemplateApplication): EvaluationTrace { LOG.info("Start recursive Compile") try { - val result = EvaluationTrace.empty(expression.arguments.mapValues { it.value.toValue() }) - recursiveCompile(result, HashSet(), HashSet(setOf(expression))) + val arguments = expression.arguments.mapValues { + dataReducer.reduce(it.value) + } + val result = EvaluationTrace.empty(arguments.mapValues { it.value.toValue() }) + recursiveCompile(result, HashSet(), HashSet(setOf(EProcessTemplateApplication(expression.template, arguments)))) LOG.info("End recursive Compile, found ${result.getNumberOfProcesses()} processes and ${result.getNumberOfSubstanceCharacterizations()} substances") return result } catch (e: Exception) { diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/lang/value/SystemValue.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/lang/value/SystemValue.kt index 897ac4ad3..7fb8c9dc0 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/lang/value/SystemValue.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/lang/value/SystemValue.kt @@ -1,5 +1,6 @@ package ch.kleis.lcaplugin.core.lang.value +import arrow.core.filterIsInstance import ch.kleis.lcaplugin.core.HasUID @@ -8,6 +9,11 @@ data class SystemValue( val processes: Set, val substanceCharacterizations: Set, ) : Value, HasUID { + val effectiveParametersSize = parameters + .filterIsInstance() + .filter { it.value.amount.first.isNotEmpty() } + .size + val productToProcessMap: Map = processes.flatMap { process -> process.products.map { it.product to process } }.toMap() diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualMatrix.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualMatrix.kt index 17f4068ef..3e1a65e9d 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualMatrix.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualMatrix.kt @@ -11,6 +11,10 @@ import org.jetbrains.kotlinx.multik.ndarray.operations.minus import org.jetbrains.kotlinx.multik.ndarray.operations.plus import org.jetbrains.kotlinx.multik.ndarray.operations.unaryMinus +/* + TODO: TEST ME !!! + */ + private fun d2Ejml(m: D2Array): EJMLMatrix { val (rows, cols) = m.shape val r = EJMLMatrixFactory.INSTANCE.zero(rows, cols) @@ -22,7 +26,8 @@ private fun d2Ejml(m: D2Array): EJMLMatrix { } private fun d3Ejml(m: D3Array): EJMLMatrix { - val (rows, cols, nParams) = m.shape + val (rows, cols, nps) = m.shape + val nParams = if (nps == 0) 1 else nps val r = EJMLMatrixFactory.INSTANCE.zero(rows, cols * nParams) m.forEachMultiIndexed { index, d -> val (i, j, k) = index @@ -45,6 +50,7 @@ private fun ejmlD2(m: EJMLMatrix): D2Array { private fun ejmlD3(m: EJMLMatrix, nParams: Int): D3Array { val (rows, cols) = Pair(m.rowDim(), m.colDim()) val r = mk.zeros(rows, cols, nParams) + if (nParams == 0) return r val iterator = m.matrix.getMatrix().createCoordinateIterator() while (iterator.hasNext()) { val v = iterator.next() diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualNumber.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualNumber.kt index e0aca7472..7b6ade79c 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualNumber.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/math/DualNumber.kt @@ -12,6 +12,7 @@ data class DualNumber( val zeroth: Double, val first: D1Array, ) { + override fun toString(): String { return "$zeroth" } diff --git a/src/main/kotlin/ch/kleis/lcaplugin/core/math/ejml/EJMLMatrix.kt b/src/main/kotlin/ch/kleis/lcaplugin/core/math/ejml/EJMLMatrix.kt index ed47af50c..6d93a2e8c 100644 --- a/src/main/kotlin/ch/kleis/lcaplugin/core/math/ejml/EJMLMatrix.kt +++ b/src/main/kotlin/ch/kleis/lcaplugin/core/math/ejml/EJMLMatrix.kt @@ -3,43 +3,57 @@ package ch.kleis.lcaplugin.core.math.ejml import org.ejml.simple.SimpleMatrix class EJMLMatrix(internal val matrix: SimpleMatrix) { - fun value(row: Int, col: Int): Double = + fun value(row: Int, col: Int): Double = matrix[row, col] - operator fun minus(other: EJMLMatrix): EJMLMatrix { + operator fun minus(other: EJMLMatrix): EJMLMatrix { return EJMLMatrix( matrix - other.matrix ) } - operator fun plus(other: EJMLMatrix): EJMLMatrix { + operator fun plus(other: EJMLMatrix): EJMLMatrix { return EJMLMatrix( matrix + other.matrix ) } - fun matDiv(other: EJMLMatrix): EJMLMatrix? { + fun matDiv(other: EJMLMatrix): EJMLMatrix? { val solver = EJMLSolver.INSTANCE return solver.solve(this, other) } - fun matMul(other: EJMLMatrix): EJMLMatrix { + fun matMul(other: EJMLMatrix): EJMLMatrix { + if (this.isScalar()) { + return EJMLMatrix( + other.matrix.scale(value(0, 0)) + ) + } + if (other.isScalar()) { + return EJMLMatrix( + this.matrix.scale(other.value(0, 0)) + ) + } return EJMLMatrix( matrix.mult(other.matrix) ) } - fun add(row: Int, col: Int, value: Double) { + private fun isScalar(): Boolean { + return rowDim() == 1 && colDim() == 1 + } + + fun add(row: Int, col: Int, value: Double) { matrix.set(row, col, value(row, col) + value) } - fun set(row: Int, col: Int, value: Double) = + fun set(row: Int, col: Int, value: Double) = matrix.set(row, col, value) - fun negate(): EJMLMatrix = EJMLMatrix(matrix.negative()) - fun transpose(): EJMLMatrix = EJMLMatrix(matrix.transpose()) + fun negate(): EJMLMatrix = EJMLMatrix(matrix.negative()) + fun transpose(): EJMLMatrix = EJMLMatrix(matrix.transpose()) - fun rowDim(): Int = matrix.numRows + fun rowDim(): Int = matrix.numRows - fun colDim(): Int = matrix.numCols + fun colDim(): Int = matrix.numCols } diff --git a/src/test/kotlin/ch/kleis/lcaplugin/e2e/E2ETest.kt b/src/test/kotlin/ch/kleis/lcaplugin/e2e/E2ETest.kt index 59f95390c..d7a6f1351 100644 --- a/src/test/kotlin/ch/kleis/lcaplugin/e2e/E2ETest.kt +++ b/src/test/kotlin/ch/kleis/lcaplugin/e2e/E2ETest.kt @@ -19,6 +19,7 @@ import ch.kleis.lcaplugin.core.lang.value.FromProcessRefValue import ch.kleis.lcaplugin.core.lang.value.ProductValue import ch.kleis.lcaplugin.core.lang.value.QuantityValue import ch.kleis.lcaplugin.core.lang.value.UnitValue +import ch.kleis.lcaplugin.core.math.times import ch.kleis.lcaplugin.core.prelude.Prelude import ch.kleis.lcaplugin.language.parser.LcaLangAbstractParser import ch.kleis.lcaplugin.language.psi.LcaFile @@ -311,9 +312,9 @@ class E2ETest : BasePlatformTestCase() { val key = ProductValue( "in", kg, ) - assertEquals( - QuantityValue(DualNumber.constant(3.0), kg), actual.impacts[key] - ) + val nParams = 3 + val expected = QuantityValue(DualNumber.constant(3.0), kg) + assertEquals(expected, actual.impacts[key]) } @Test @@ -350,7 +351,10 @@ class E2ETest : BasePlatformTestCase() { val actual = reducer.reduce(expr) // then - val expected = EQuantityScale(DualNumber.constant(200.0), EUnitLiteral(UnitSymbol.of("m").pow(4.0), 1.0, Prelude.length.pow(4.0))) + val expected = EQuantityScale( + DualNumber.constant(200.0), + EUnitLiteral(UnitSymbol.of("m").pow(4.0), 1.0, Prelude.length.pow(4.0)) + ) TestCase.assertEquals(expected, actual) } @@ -539,7 +543,11 @@ class E2ETest : BasePlatformTestCase() { } val ratio = result.valueRatio(output, input) - assertEquals(QuantityValue(DualNumber.constant(3.0), asValue(UnitFixture.kg)), ratio) + val expected = QuantityValue( + DualNumber.constant(3.0), + asValue(UnitFixture.kg) + ) + assertEquals(expected, ratio) } @Test