Rename and introduce type erasers

This commit is contained in:
Alexander Ignatov 2021-12-21 21:33:16 +02:00
parent 67380ab162
commit c31c39cab3
6 changed files with 105 additions and 49 deletions

View File

@ -1,7 +1,6 @@
public struct ContinuousFuzzySet: FuzzySet {
public typealias Universe = Double
public struct AnyFuzzySet<Universe>: FuzzySet {
private let membershipFunction: MembershipFunction<Universe>
internal let membershipFunction: MembershipFunction<Universe>
public init(membershipFunction: MembershipFunction<Universe>) {
self.membershipFunction = membershipFunction
@ -24,7 +23,7 @@ public struct ContinuousFuzzySet: FuzzySet {
}
}
public extension ContinuousFuzzySet {
public extension AnyFuzzySet {
static var empty: Self {
.init(membershipFunction: .zero)
}
@ -33,3 +32,15 @@ public extension ContinuousFuzzySet {
.init(membershipFunction: .one)
}
}
public extension DiscreteMutableFuzzySet {
func eraseToAnyFuzzySet() -> AnyFuzzySet<Universe> {
.init(membershipFunction: .fromDictionary(grades))
}
}
public extension IterableFuzzySet {
func eraseToAnyFuzzySet() -> AnyFuzzySet<Universe> {
.init(membershipFunction: function)
}
}

View File

@ -12,8 +12,8 @@ public struct IterableFuzzySet<Universe: Strideable> {
public typealias Iterator = Array<Element>.Iterator
private let range: StrideThrough<Universe>
private let function: MembershipFunction<Universe>
internal let range: StrideThrough<Universe>
internal let function: MembershipFunction<Universe>
public init(range: StrideThrough<Universe>, membershipFunction: MembershipFunction<Universe>) {
self.range = range

View File

@ -1,4 +1,5 @@
public struct MembershipFunction<U: Strideable> {
import CoreGraphics
public struct MembershipFunction<U> {
public typealias FunctionType = (U) -> Grade
@ -22,12 +23,24 @@ public extension MembershipFunction {
static var one: Self {
.init { _ in 1 }
}
}
public extension MembershipFunction where U: Equatable {
static func fuzzySingleton(_ onlyMember: U) -> Self {
.init { $0 == onlyMember ? 1 : 0 }
}
}
public extension MembershipFunction where U: Hashable {
static func fromCrispSet(_ set: Set<U>) -> Self {
.init { set.contains($0) ? 1 : 0 }
}
static func fromDictionary(_ dictionary: [U: Grade]) -> Self {
.init { dictionary[$0] ?? 0 }
}
}
public extension MembershipFunction where U == Double {
static func triangular(minimum a: U, peak b: U, maximum c: U) -> Self {
.init { u in

View File

@ -0,0 +1,70 @@
import XCTest
import FuzzyKit
final class AnyFuzzySetTests: XCTestCase {
func test_initFromDiscreteMutableFuzzySet() {
let expected = [
"a": 1.0,
"b": 0.88,
"c": 0.69,
"d": 0.42,
"e": 0.0001,
"f": 0.0,
]
let set = DiscreteMutableFuzzySet(elementToGradeMap: expected)
let sut = set.eraseToAnyFuzzySet()
for (element, grade) in expected {
assertExpectedGrade(element: element, expectedGrade: grade, sut: sut)
}
}
func test_initFromIterableFuzzySet() {
let range = stride(from: 0, through: 10, by: 0.5)
let function = MembershipFunction.triangular(minimum: 42, peak: 69, maximum: 88)
let set = IterableFuzzySet(range: range, membershipFunction: function)
let sut = set.eraseToAnyFuzzySet()
for element in range {
let result = sut[element]
let expected = function(element)
XCTAssertApproximatelyEqual(expected, result)
}
}
func test_triangular_alphaCut() {
let a = 3.0
let b = 5.0
let c = 8.0
let alpha = 0.5
let set = AnyFuzzySet(membershipFunction: .triangular(minimum: a, peak: b, maximum: c))
let sut = set.alphaCut(alpha)
let minResult = sut[a]
let peakResult = sut[b]
let maxResult = sut[c]
XCTAssertEqual(alpha, minResult)
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 = AnyFuzzySet(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)
}
}

View File

@ -1,37 +0,0 @@
import XCTest
import FuzzyKit
final class ContinuousFuzzySetTests: XCTestCase {
func test_triangular_alphaCut() {
let a = 3.0
let b = 5.0
let c = 8.0
let alpha = 0.5
let set = ContinuousFuzzySet(membershipFunction: .triangular(minimum: a, peak: b, maximum: c))
let sut = set.alphaCut(alpha)
let minResult = sut[a]
let peakResult = sut[b]
let maxResult = sut[c]
XCTAssertEqual(alpha, minResult)
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)
}
}

View File

@ -3,11 +3,10 @@ import FuzzyKit
final class MembershipFunctionTests: XCTestCase {
func test_isCallable() throws {
let sut = MembershipFunction<Double>.one
let x = 1.0
let sut = MembershipFunction<Void>.one
let result = sut(x)
let result = sut(())
XCTAssertEqual(result, x)
XCTAssertApproximatelyEqual(result, 1.0)
}
}