Add fuzzy numbers and modularize

This commit is contained in:
Alexander Ignatov 2021-12-24 01:07:41 +02:00
parent 05d79f2d8f
commit 3f9857f8cc
16 changed files with 150 additions and 10 deletions

View File

@ -3,12 +3,30 @@
import PackageDescription
enum SubmoduleName: String {
case fuzzyKit = "FuzzyKit"
case fuzzySets = "FuzzySets"
case fuzzyNumbers = "FuzzyNumbers"
var name: String { rawValue }
var target: String { rawValue }
var testTarget: String { rawValue + "Tests" }
}
let package = Package(
name: "FuzzyKit",
products: [
.library(
name: "FuzzyKit",
targets: ["FuzzyKit"]
name: SubmoduleName.fuzzyKit.name,
targets: [SubmoduleName.fuzzyKit.target]
),
.library(
name: SubmoduleName.fuzzySets.name,
targets: [SubmoduleName.fuzzySets.target]
),
.library(
name: SubmoduleName.fuzzyNumbers.name,
targets: [SubmoduleName.fuzzyNumbers.target]
),
],
dependencies: [
@ -16,14 +34,35 @@ let package = Package(
],
targets: [
.target(
name: "FuzzyKit",
name: SubmoduleName.fuzzyKit.target,
dependencies: [
.target(name: SubmoduleName.fuzzySets.target),
.target(name: SubmoduleName.fuzzyNumbers.target),
]
),
.target(
name: SubmoduleName.fuzzySets.target,
dependencies: [
.product(name: "RealModule", package: "swift-numerics"),
]
),
.testTarget(
name: "FuzzyKitTests",
dependencies: ["FuzzyKit"]
name: SubmoduleName.fuzzySets.testTarget,
dependencies: [
.target(name: SubmoduleName.fuzzySets.target)
]
),
.target(
name: SubmoduleName.fuzzyNumbers.target,
dependencies: [
.target(name: SubmoduleName.fuzzySets.target),
]
),
.testTarget(
name: SubmoduleName.fuzzyNumbers.testTarget,
dependencies: [
.target(name: SubmoduleName.fuzzyNumbers.target),
]
),
]
)

View File

@ -0,0 +1,4 @@
// A module that re-exports the complete FuzzyKit public API.
@_exported import FuzzySets
@_exported import FuzzyNumbers

View File

@ -0,0 +1,18 @@
import FuzzySets
public protocol FuzzyNumber {
typealias Universe = Double
func eraseToAnyFuzzySet() -> AnyFuzzySet<Universe>
static func + (lhs: Self, rhs: Self) -> Self
static func - (lhs: Self, rhs: Self) -> Self
prefix static func - (x: Self) -> Self
// func approximatelyMultiplied(by other: Self) -> Self
//
// func approximatelyDivided(by other: Self) -> Self
}

View File

@ -0,0 +1,65 @@
import FuzzySets
public struct TriangularFuzzyNumber: FuzzyNumber {
public typealias Universe = Double
public let minimum: Universe
public let peak: Universe
public let maximum: Universe
internal let function: MembershipFunction<Universe>
public init(minimum: Universe, peak: Universe, maximum: Universe) {
self.minimum = minimum
self.peak = peak
self.maximum = maximum
self.function = .triangular(minimum: minimum, peak: peak, maximum: maximum)
}
public init(peak: Universe, leftInterval: Universe, rightInterval: Universe) {
self.minimum = peak - leftInterval
self.peak = peak
self.maximum = peak + rightInterval
self.function = .triangular(minimum: minimum, peak: peak, maximum: maximum)
}
public func eraseToAnyFuzzySet() -> AnyFuzzySet<Universe> {
.init(membershipFunction: function)
}
public static func + (lhs: TriangularFuzzyNumber, rhs: TriangularFuzzyNumber) -> TriangularFuzzyNumber {
.init(
minimum: lhs.minimum + rhs.minimum,
peak: lhs.peak + rhs.peak,
maximum: lhs.maximum + rhs.maximum
)
}
public static func - (lhs: TriangularFuzzyNumber, rhs: TriangularFuzzyNumber) -> TriangularFuzzyNumber {
.init(
minimum: lhs.minimum - rhs.maximum,
peak: lhs.peak - rhs.peak,
maximum: lhs.maximum - rhs.minimum
)
}
prefix public static func - (x: TriangularFuzzyNumber) -> TriangularFuzzyNumber {
.init(minimum: -x.maximum, peak: -x.peak, maximum: -x.minimum)
}
//
// public func approximatelyMultiplied(by other: TriangularFuzzyNumber) -> TriangularFuzzyNumber {
// // TODO
// }
//
// public func approximatelyDivided(by other: TriangularFuzzyNumber) -> TriangularFuzzyNumber {
// // TODO
// }
}
extension TriangularFuzzyNumber: Equatable {
public static func == (lhs: TriangularFuzzyNumber, rhs: TriangularFuzzyNumber) -> Bool {
lhs.minimum == rhs.minimum && lhs.peak == rhs.peak && lhs.maximum == rhs.maximum
}
}

View File

@ -0,0 +1,14 @@
import XCTest
import FuzzyNumbers
final class TriangularFuzzyNumberTests: XCTestCase {
func test_addition() {
let a = TriangularFuzzyNumber(minimum: -3, peak: 2, maximum: 4)
let b = TriangularFuzzyNumber(minimum: -1, peak: 0, maximum: 6)
let expect = TriangularFuzzyNumber(minimum: -4, peak: 2, maximum: 10)
let result = a + b
XCTAssertEqual(result, expect)
}
}

View File

@ -1,5 +1,5 @@
import XCTest
import FuzzyKit
import FuzzySets
final class AnyFuzzySetTests: XCTestCase {
func test_initFromDiscreteMutableFuzzySet() {

View File

@ -1,5 +1,5 @@
import XCTest
import FuzzyKit
import FuzzySets
final class DiscreteMutableFuzzySetTests: XCTestCase {
func test_defaultInit_allGradesAreZero() throws {

View File

@ -1,5 +1,5 @@
import XCTest
import FuzzyKit
import FuzzySets
final class MembershipFunctionTests: XCTestCase {
func test_isCallable() throws {

View File

@ -1,5 +1,5 @@
import XCTest
import FuzzyKit
import FuzzySets
func XCTAssertApproximatelyEqual(_ v1: Double, _ v2: Double, tolerance: Double = 0.0001) {
let diff = v1 - v2

View File

@ -1,5 +1,5 @@
import XCTest
import FuzzyKit
import FuzzySets
class IterableFuzzySetTests: XCTestCase {
private var near4Support4: [IterableFuzzySet<Int, StrideThrough<Int>>.Element] = [