Update IterableFuzzySet to accept any Sequence
This commit is contained in:
parent
0360090ac6
commit
6a967d4e76
|
@ -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 element: Universe
|
||||||
public let grade: Grade
|
public let grade: Grade
|
||||||
|
|
||||||
|
@ -12,16 +12,16 @@ public struct IterableFuzzySet<Universe: Strideable> {
|
||||||
|
|
||||||
public typealias Iterator = Array<Element>.Iterator
|
public typealias Iterator = Array<Element>.Iterator
|
||||||
|
|
||||||
internal let range: StrideThrough<Universe>
|
internal let sequence: S
|
||||||
internal let function: MembershipFunction<Universe>
|
internal let function: MembershipFunction<Universe>
|
||||||
|
|
||||||
public init(range: StrideThrough<Universe>, membershipFunction: MembershipFunction<Universe>) {
|
public init(_ sequence: S, membershipFunction: MembershipFunction<Universe>) {
|
||||||
self.range = range
|
self.sequence = sequence
|
||||||
self.function = membershipFunction
|
self.function = membershipFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(range: StrideThrough<Universe>, membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
|
public init(_ sequence: S, membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
|
||||||
self.range = range
|
self.sequence = sequence
|
||||||
self.function = .init(membershipFunction)
|
self.function = .init(membershipFunction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,43 +34,43 @@ extension IterableFuzzySet: FuzzySet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func alphaCut(_ alpha: Grade) -> Self {
|
public func alphaCut(_ alpha: Grade) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
Swift.max(function($0), alpha)
|
Swift.max(function($0), alpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func complement(method: ComplementFunction = .standard) -> Self {
|
public func complement(method: ComplementFunction = .standard) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
method.function(function($0))
|
method.function(function($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func intersection(_ other: Self, method: TNormFunction = .minimum) -> Self {
|
public func intersection(_ other: Self, method: TNormFunction = .minimum) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
method.function(function($0), other.function($0))
|
method.function(function($0), other.function($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func union(_ other: Self, method: SNormFunction = .maximum) -> Self {
|
public func union(_ other: Self, method: SNormFunction = .maximum) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
method.function(function($0), other.function($0))
|
method.function(function($0), other.function($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func difference(_ other: Self, method: DifferenceFunction = .tNormAndComplement(.minimum, .standard)) -> Self {
|
public func difference(_ other: Self, method: DifferenceFunction = .tNormAndComplement(.minimum, .standard)) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
method.function(function($0), other.function($0))
|
method.function(function($0), other.function($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func symmetricDifference(_ other: Self, method: SymmetricDifferenceFunction = .absoluteValue) -> Self {
|
public func symmetricDifference(_ other: Self, method: SymmetricDifferenceFunction = .absoluteValue) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
method.function(function($0), other.function($0))
|
method.function(function($0), other.function($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func power(_ n: Double) -> Self {
|
public func power(_ n: Double) -> Self {
|
||||||
.init(range: range) {
|
.init(sequence) {
|
||||||
Double.pow(function($0), n)
|
Double.pow(function($0), n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ extension IterableFuzzySet: FuzzySet {
|
||||||
|
|
||||||
extension IterableFuzzySet: Sequence {
|
extension IterableFuzzySet: Sequence {
|
||||||
public func makeIterator() -> Iterator {
|
public func makeIterator() -> Iterator {
|
||||||
range
|
sequence
|
||||||
.map { .init(
|
.map { .init(
|
||||||
element: $0,
|
element: $0,
|
||||||
grade: grade(forElement: $0)
|
grade: grade(forElement: $0)
|
||||||
|
@ -88,3 +88,10 @@ extension IterableFuzzySet: Sequence {
|
||||||
.makeIterator()
|
.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 {}
|
||||||
|
|
|
@ -24,7 +24,7 @@ final class AnyFuzzySetTests: XCTestCase {
|
||||||
func test_initFromIterableFuzzySet() {
|
func test_initFromIterableFuzzySet() {
|
||||||
let range = stride(from: 0, through: 10, by: 0.5)
|
let range = stride(from: 0, through: 10, by: 0.5)
|
||||||
let function = MembershipFunction.triangular(minimum: 42, peak: 69, maximum: 88)
|
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()
|
let sut = set.eraseToAnyFuzzySet()
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import XCTest
|
||||||
import FuzzyKit
|
import FuzzyKit
|
||||||
|
|
||||||
class IterableFuzzySetTests: XCTestCase {
|
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: 0, grade: 0.0),
|
||||||
.init(element: 1, grade: 0.25),
|
.init(element: 1, grade: 0.25),
|
||||||
.init(element: 2, grade: 0.50),
|
.init(element: 2, grade: 0.50),
|
||||||
|
@ -20,7 +20,7 @@ class IterableFuzzySetTests: XCTestCase {
|
||||||
let expected = near4Support4
|
let expected = near4Support4
|
||||||
let range = stride(from: 0, through: 10, by: 1)
|
let range = stride(from: 0, through: 10, by: 1)
|
||||||
|
|
||||||
let sut = IterableFuzzySet(range: range) {
|
let sut = IterableFuzzySet(range) {
|
||||||
expected[$0].grade
|
expected[$0].grade
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,14 @@ class IterableFuzzySetTests: XCTestCase {
|
||||||
|
|
||||||
func test_initFromDoubleRangeAndContinuousFunction() {
|
func test_initFromDoubleRangeAndContinuousFunction() {
|
||||||
let expected = near4Support4.map {
|
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(
|
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)
|
membershipFunction: .triangular(minimum: 0.0, peak: 4.0, maximum: 8.0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +50,7 @@ class IterableFuzzySetTests: XCTestCase {
|
||||||
func test_alphaCut_allValuesAreBelowAlpha() {
|
func test_alphaCut_allValuesAreBelowAlpha() {
|
||||||
let alpha = 0.5
|
let alpha = 0.5
|
||||||
let set = IterableFuzzySet(
|
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)
|
membershipFunction: .triangular(minimum: 42.0, peak: 69.0, maximum: 88.88)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,7 +63,7 @@ class IterableFuzzySetTests: XCTestCase {
|
||||||
|
|
||||||
func test_complementOfTriangular_allValuesAddUpToOne() {
|
func test_complementOfTriangular_allValuesAddUpToOne() {
|
||||||
let set = IterableFuzzySet(
|
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)
|
membershipFunction: .triangular(minimum: 42.0, peak: 69.0, maximum: 88.88)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue