Skip to content

Commit 135c168

Browse files
committed
implement piv
1 parent 98cdda1 commit 135c168

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/main/scala/piv.scala

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.expr.mcdm
2+
3+
import org.expr.mcdm.Direction.{Minimize, Maximize}
4+
5+
case class PivResult(
6+
scores: Vec
7+
) extends MCDMResult
8+
9+
def piv(
10+
decmat: Mat,
11+
weights: Vec,
12+
directions: Array[Direction],
13+
normalization: NormalizationFunction =
14+
Normalization.VectorNormNormalization,
15+
options: Map[String, Any] = Map.empty
16+
): PivResult =
17+
18+
val (nrow, ncol) = Matrix.size(decmat)
19+
20+
val normalized_dec_mat = normalization(decmat, weights, directions)
21+
22+
val weighted_norm_mat = Matrix.weightizeColumns(normalized_dec_mat, weights)
23+
24+
val dirfunctions = directions.map {
25+
case Maximize => Statistics.maximum
26+
case Minimize => Statistics.minimum
27+
}
28+
val desiredvalues = Matrix.applyFunctionsToColumns(weighted_norm_mat, dirfunctions)
29+
30+
var finalmat = Matrix.zeros(nrow, ncol)
31+
32+
for i <- 0 until nrow do
33+
for j <- 0 until ncol do
34+
if directions(j) == Maximize then
35+
finalmat(i)(j) = desiredvalues(j) - weighted_norm_mat(i)(j)
36+
else if directions(j) == Minimize then
37+
finalmat(i)(j) = weighted_norm_mat(i)(j) - desiredvalues(j)
38+
39+
// di values are scores
40+
val di = Matrix.rowsums(finalmat)
41+
42+
PivResult(
43+
di
44+
)

src/test/scala/testpiv.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import munit.Assertions as A
2+
3+
import org.expr.mcdm.piv
4+
import org.expr.mcdm.Direction.{Maximize, Minimize}
5+
import org.expr.mcdm.Matrix
6+
7+
class TestPiv extends munit.FunSuite {
8+
test("Piv Example - 1") {
9+
10+
val decmat = Array(
11+
Array(60.0, 2.5, 2540.0, 500.0, 990.0),
12+
Array(6.35, 6.667, 1016.0, 3000.0, 1041.0),
13+
Array(6.8, 10.0, 1727.0, 1500.0, 1676.0),
14+
Array(10.0, 5.0, 1000.0, 2000.0, 965.0),
15+
Array(2.5, 9.8, 560.0, 500.0, 915.0),
16+
Array(4.5, 12.5, 1016.0, 350.0, 508.0),
17+
Array(3.0, 10.0, 1778.0, 1000.0, 920.0)
18+
)
19+
20+
val weights = Array(0.1761, 0.2042, 0.2668, 0.1243, 0.2286)
21+
22+
val directions = Array(Maximize, Maximize, Maximize, Maximize, Maximize)
23+
24+
val expected_scores = Array(0.22086675609968962, 0.35854940101222144,
25+
0.2734184099704686, 0.4005382183676046, 0.4581157878699193,
26+
0.43595371718873477, 0.3580651803072459)
27+
28+
val result = piv(decmat, weights, directions)
29+
30+
A.assert(Matrix.elementwise_equal(result.scores, expected_scores, 1e-05), "PIV scores do not match expected values")
31+
}
32+
}

0 commit comments

Comments
 (0)