Rename and introduce type erasers
This commit is contained in:
parent
67380ab162
commit
c31c39cab3
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue