Add complement
This commit is contained in:
parent
07943d45dd
commit
67380ab162
|
@ -18,6 +18,10 @@ public struct ContinuousFuzzySet: FuzzySet {
|
|||
public func alphaCut(_ alpha: Grade) -> Self {
|
||||
.init { max(membershipFunction($0), alpha) }
|
||||
}
|
||||
|
||||
public var complement: Self {
|
||||
.init { 1 - membershipFunction($0) }
|
||||
}
|
||||
}
|
||||
|
||||
public extension ContinuousFuzzySet {
|
||||
|
|
|
@ -38,6 +38,14 @@ public struct DiscreteMutableFuzzySet<Universe: Hashable>: FuzzySet {
|
|||
let newMap = Dictionary(uniqueKeysWithValues: newGradeTuples)
|
||||
grades = newMap
|
||||
}
|
||||
|
||||
public var complement: Self {
|
||||
let newGradeTuples = grades.map {
|
||||
($0.key, 1 - $0.value)
|
||||
}
|
||||
let newMap = Dictionary(uniqueKeysWithValues: newGradeTuples)
|
||||
return .init(elementToGradeMap: newMap)
|
||||
}
|
||||
}
|
||||
|
||||
public extension DiscreteMutableFuzzySet {
|
||||
|
|
|
@ -9,6 +9,8 @@ public protocol FuzzySet {
|
|||
subscript(_ element: Universe) -> Grade { get }
|
||||
|
||||
func alphaCut(_ alpha: Grade) -> Self
|
||||
|
||||
var complement: Self { get }
|
||||
}
|
||||
|
||||
public extension FuzzySet {
|
||||
|
|
|
@ -30,6 +30,12 @@ public struct IterableFuzzySet<Universe: Strideable> {
|
|||
Swift.max(function($0), alpha)
|
||||
}
|
||||
}
|
||||
|
||||
public var complement: Self {
|
||||
.init(range: range) {
|
||||
1 - function($0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension IterableFuzzySet: FuzzySet {
|
||||
|
|
|
@ -18,4 +18,20 @@ final class ContinuousFuzzySetTests: XCTestCase {
|
|||
XCTAssertEqual(1.0, peakResult)
|
||||
XCTAssertEqual(alpha, maxResult)
|
||||
}
|
||||
|
||||
func test_triangular_complement() {
|
||||
let a = 3.0
|
||||
let b = 5.0
|
||||
let c = 8.0
|
||||
let set = ContinuousFuzzySet(membershipFunction: .triangular(minimum: a, peak: b, maximum: c))
|
||||
|
||||
let sut = set.complement
|
||||
let minResult = sut[a]
|
||||
let peakResult = sut[b]
|
||||
let maxResult = sut[c]
|
||||
|
||||
XCTAssertEqual(1.0, minResult)
|
||||
XCTAssertEqual(0.0, peakResult)
|
||||
XCTAssertEqual(1.0, maxResult)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,4 +111,30 @@ final class DiscreteMutableFuzzySetTests: XCTestCase {
|
|||
assertExpectedGrade(element: element, expectedGrade: grade, sut: sut2)
|
||||
}
|
||||
}
|
||||
|
||||
func test_complement_gradesAreCorrect() {
|
||||
let initial = [
|
||||
"a": 1.0,
|
||||
"b": 0.88,
|
||||
"c": 0.69,
|
||||
"d": 0.42,
|
||||
"e": 0.001,
|
||||
"f": 0.0,
|
||||
]
|
||||
let expected = [
|
||||
"a": 0.0,
|
||||
"b": 0.12,
|
||||
"c": 0.31,
|
||||
"d": 0.58,
|
||||
"e": 0.999,
|
||||
"f": 1.0,
|
||||
]
|
||||
let set = DiscreteMutableFuzzySet(elementToGradeMap: initial)
|
||||
|
||||
let sut = set.complement
|
||||
|
||||
for (element, grade) in expected {
|
||||
assertExpectedGrade(element: element, expectedGrade: grade, sut: sut)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
import XCTest
|
||||
import FuzzyKit
|
||||
|
||||
func XCTAssertApproximatelyEqual(_ v1: Double, _ v2: Double, tolerance: Double = 0.0001) {
|
||||
let diff = v1 - v2
|
||||
XCTAssert(-tolerance <= diff && diff <= +tolerance)
|
||||
}
|
||||
|
||||
func assertExpectedGrade<E, S: FuzzySet>(element: E, expectedGrade: Grade, sut: S)
|
||||
where S.Universe == E {
|
||||
let grade1 = sut[element]
|
||||
let grade2 = sut.grade(forElement: element)
|
||||
|
||||
XCTAssertEqual(grade1, grade2)
|
||||
XCTAssertEqual(expectedGrade, grade1)
|
||||
XCTAssertEqual(expectedGrade, grade2)
|
||||
XCTAssertApproximatelyEqual(grade1, grade2)
|
||||
XCTAssertApproximatelyEqual(expectedGrade, grade1)
|
||||
XCTAssertApproximatelyEqual(expectedGrade, grade2)
|
||||
}
|
||||
|
|
|
@ -57,4 +57,17 @@ class IterableFuzzySetTests: XCTestCase {
|
|||
let allAreBelowAlpha = grades.allSatisfy { $0 >= alpha }
|
||||
XCTAssertTrue(allAreBelowAlpha)
|
||||
}
|
||||
|
||||
func test_complementOfTriangular_allValuesAddUpToOne() {
|
||||
let set = IterableFuzzySet(
|
||||
range: stride(from: 0.0, through: 100.0, by: 0.5),
|
||||
membershipFunction: .triangular(minimum: 42.0, peak: 69.0, maximum: 88.88)
|
||||
)
|
||||
|
||||
let sut = set.complement
|
||||
|
||||
let sums = zip(set, sut).map { $0.0.grade + $0.1.grade }
|
||||
|
||||
sums.forEach { XCTAssertApproximatelyEqual(1.0, $0) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue