Skip to content

Commit 31270fc

Browse files
committed
implement critic method
1 parent abb7d2b commit 31270fc

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ project/**
1010
.metals/**
1111
.bsp/**
1212
.bloop/**
13+
14+
.scalafmt.conf

src/main/scala/critic.scala

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.expr.mcdm
2+
3+
import org.expr.mcdm.Vec
4+
import org.expr.mcdm.Mat
5+
6+
case class CriticResult(
7+
weights: Vec,
8+
corMat: Mat,
9+
scores: Vec
10+
) extends MCDMResult
11+
12+
def critic(
13+
mat: Mat,
14+
directions: Array[Direction],
15+
normalization: NormalizationFunction = Normalization.MaxMinRangeNormalization
16+
): CriticResult =
17+
18+
val (n, m) = Matrix.size(mat)
19+
20+
val normalizedMat = normalization(mat, Array.emptyDoubleArray, directions)
21+
22+
val onesMat = Matrix.ones(m, m)
23+
val correlations = Statistics.correlation(normalizedMat)
24+
25+
val corMat = Matrix.subtract(onesMat, correlations)
26+
27+
val stds = Matrix.applyFunctionToColumns(normalizedMat, Statistics.std)
28+
29+
var scores = Array.fill(m)(0.0)
30+
for i <- 0 until m do
31+
scores(i) = Matrix.getcolat(corMat, i).sum * stds(i)
32+
33+
val w = scores.map(_ / scores.sum)
34+
35+
CriticResult(
36+
w,
37+
corMat,
38+
scores)
39+
40+

src/main/scala/matrix.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,6 @@ object Matrix:
128128
case Direction.Maximize => Direction.Minimize
129129
}
130130

131+
def subtract(a: Mat, b: Mat): Mat =
132+
a.zip(b).map((rowa, rowb) => rowa.zip(rowb).map((x, y) => x - y))
133+

src/main/scala/statistics.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ object Statistics:
77
def variance(a: Vec) : Double =
88
val m = mean(a)
99
a.map(x => (x - m) * (x - m)).sum / (a.length - 1.0)
10+
11+
def std(a: Vec): Double = math.sqrt(variance(a))
1012

1113
def correlation(a: Vec, b: Vec): Double =
1214
val ma = mean(a)

src/test/scala/testcritic.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import munit.Assertions as A
2+
3+
import org.expr.mcdm.Matrix
4+
import org.expr.mcdm.Direction
5+
import org.expr.mcdm.critic
6+
7+
class TestCritic extends munit.FunSuite {
8+
9+
test("Critic Example - 1"){
10+
11+
val decmat = Array(
12+
Array(12.9918, 0.7264, -1.1009, 1.598139592),
13+
Array(4.1201 , 5.8824 , 3.4483 , 1.021563567),
14+
Array(4.1039 , 0.0000 , -0.5076 , 0.984469444)
15+
)
16+
17+
val directions = Array(
18+
Direction.Maximize,
19+
Direction.Maximize,
20+
Direction.Minimize,
21+
Direction.Maximize
22+
)
23+
24+
val result = critic(decmat, directions)
25+
26+
val expectedWeights = Array(0.16883925, 0.418444976, 0.249124763, 0.163591012)
27+
28+
A.assert(Matrix.elementwise_equal(result.weights, expectedWeights, 1e-5))
29+
}
30+
31+
}

src/test/scala/testmatrix.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,25 @@ class TestMatrix extends munit.FunSuite {
352352
Direction.Maximize)
353353
direction.zip(expected).foreach{case (a, b) => A.assertNotEquals(a, b)}
354354
}
355+
test("Matrix subtract"){
356+
val a = Array(
357+
Array(1.0, 5.0, 6.0, 10.0, 10.0),
358+
Array(-1.0, 11.0, 9.0, 11.0, 11.0),
359+
Array(9.0, 17.0, 12.0, 12.0, 12.0)
360+
)
361+
val b = Array(
362+
Array(2.0, 5.0, 6.0, 10.0, 10.0),
363+
Array(-1.0, 10.0, 9.0, 11.0, 11.0),
364+
Array(9.0, 17.0, 12.0, 12.0, 13.0)
365+
)
366+
val result = Matrix.subtract(a, b)
367+
val expected = Array(
368+
Array(-1.0, 0.0, 0.0, 0.0, 0.0),
369+
Array(0.0, 1.0, 0.0, 0.0, 0.0),
370+
Array(0.0, 0.0, 0.0, 0.0, -1.0)
371+
)
372+
A.assert(Matrix.elementwise_equal(result, expected, 1e-5))
373+
}
355374

356375
}
357376

0 commit comments

Comments
 (0)