Update IterableFuzzySet to accept any Sequence

This commit is contained in:
Alexander Ignatov 2021-12-23 00:39:51 +02:00
parent 0360090ac6
commit 6a967d4e76
3 changed files with 32 additions and 22 deletions

View File

@ -1,6 +1,6 @@
public struct IterableFuzzySet<Universe: Strideable> {
public struct IterableFuzzySet<Universe, S: Sequence> where S.Element == Universe {
public struct Element: Equatable {
public struct Element {
public let element: Universe
public let grade: Grade
@ -12,16 +12,16 @@ public struct IterableFuzzySet<Universe: Strideable> {
public typealias Iterator = Array<Element>.Iterator
internal let range: StrideThrough<Universe>
internal let sequence: S
internal let function: MembershipFunction<Universe>
public init(range: StrideThrough<Universe>, membershipFunction: MembershipFunction<Universe>) {
self.range = range
public init(_ sequence: S, membershipFunction: MembershipFunction<Universe>) {
self.sequence = sequence
self.function = membershipFunction
}
public init(range: StrideThrough<Universe>, membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
self.range = range
public init(_ sequence: S, membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
self.sequence = sequence
self.function = .init(membershipFunction)
}
}
@ -34,43 +34,43 @@ extension IterableFuzzySet: FuzzySet {
}
public func alphaCut(_ alpha: Grade) -> Self {
.init(range: range) {
.init(sequence) {
Swift.max(function($0), alpha)
}
}
public func complement(method: ComplementFunction = .standard) -> Self {
.init(range: range) {
.init(sequence) {
method.function(function($0))
}
}
public func intersection(_ other: Self, method: TNormFunction = .minimum) -> Self {
.init(range: range) {
.init(sequence) {
method.function(function($0), other.function($0))
}
}
public func union(_ other: Self, method: SNormFunction = .maximum) -> Self {
.init(range: range) {
.init(sequence) {
method.function(function($0), other.function($0))
}
}
public func difference(_ other: Self, method: DifferenceFunction = .tNormAndComplement(.minimum, .standard)) -> Self {
.init(range: range) {
.init(sequence) {
method.function(function($0), other.function($0))
}
}
public func symmetricDifference(_ other: Self, method: SymmetricDifferenceFunction = .absoluteValue) -> Self {
.init(range: range) {
.init(sequence) {
method.function(function($0), other.function($0))
}
}
public func power(_ n: Double) -> Self {
.init(range: range) {
.init(sequence) {
Double.pow(function($0), n)
}
}
@ -80,7 +80,7 @@ extension IterableFuzzySet: FuzzySet {
extension IterableFuzzySet: Sequence {
public func makeIterator() -> Iterator {
range
sequence
.map { .init(
element: $0,
grade: grade(forElement: $0)
@ -88,3 +88,10 @@ extension IterableFuzzySet: Sequence {
.makeIterator()
}
}
// MARK: - Utility
extension IterableFuzzySet.Element: Equatable where Universe: Equatable {}
extension IterableFuzzySet.Element: Hashable where Universe: Hashable {}
extension IterableFuzzySet.Element: Encodable where Universe: Encodable {}
extension IterableFuzzySet.Element: Decodable where Universe: Decodable {}

View File

@ -24,7 +24,7 @@ final class AnyFuzzySetTests: XCTestCase {
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 set = IterableFuzzySet(range, membershipFunction: function)
let sut = set.eraseToAnyFuzzySet()

View File

@ -2,7 +2,7 @@ import XCTest
import FuzzyKit
class IterableFuzzySetTests: XCTestCase {
private var near4Support4: [IterableFuzzySet<Int>.Element] = [
private var near4Support4: [IterableFuzzySet<Int, StrideThrough<Int>>.Element] = [
.init(element: 0, grade: 0.0),
.init(element: 1, grade: 0.25),
.init(element: 2, grade: 0.50),
@ -20,7 +20,7 @@ class IterableFuzzySetTests: XCTestCase {
let expected = near4Support4
let range = stride(from: 0, through: 10, by: 1)
let sut = IterableFuzzySet(range: range) {
let sut = IterableFuzzySet(range) {
expected[$0].grade
}
@ -31,11 +31,14 @@ class IterableFuzzySetTests: XCTestCase {
func test_initFromDoubleRangeAndContinuousFunction() {
let expected = near4Support4.map {
IterableFuzzySet<Double>.Element(element: Double($0.element), grade: $0.grade)
IterableFuzzySet<Double, StrideThrough<Double>>.Element(
element: Double($0.element),
grade: $0.grade
)
}
let sut = IterableFuzzySet(
range: stride(from: 0.0, through: 10.0, by: 1),
stride(from: 0.0, through: 10.0, by: 1),
membershipFunction: .triangular(minimum: 0.0, peak: 4.0, maximum: 8.0)
)
@ -47,7 +50,7 @@ class IterableFuzzySetTests: XCTestCase {
func test_alphaCut_allValuesAreBelowAlpha() {
let alpha = 0.5
let set = IterableFuzzySet(
range: stride(from: 0.0, through: 100.0, by: 0.5),
stride(from: 0.0, through: 100.0, by: 0.5),
membershipFunction: .triangular(minimum: 42.0, peak: 69.0, maximum: 88.88)
)
@ -60,7 +63,7 @@ class IterableFuzzySetTests: XCTestCase {
func test_complementOfTriangular_allValuesAddUpToOne() {
let set = IterableFuzzySet(
range: stride(from: 0.0, through: 100.0, by: 0.5),
stride(from: 0.0, through: 100.0, by: 0.5),
membershipFunction: .triangular(minimum: 42.0, peak: 69.0, maximum: 88.88)
)