An open API service indexing awesome lists of open source software.

https://github.com/yalishanda42/fuzzykit

Fuzzy sets and fuzzy logic theory implementations in Swift.
https://github.com/yalishanda42/fuzzykit

dsl dsl-syntax fuzzy fuzzy-inference-system fuzzy-logic fuzzy-logic-control fuzzy-sets fuzzy-systems hacktoberfest spm swift-package-manager

Last synced: 8 months ago
JSON representation

Fuzzy sets and fuzzy logic theory implementations in Swift.

Awesome Lists containing this project

README

          

![Cover photo](Resources/cover.png)

# FuzzyKit

Fuzzy sets and fuzzy logic theory implementations.

![Made for Swift](https://img.shields.io/badge/MADE%20FOR-SWIFT-orange?style=for-the-badge&logo=swift)
![Swift Package Manager supported](https://img.shields.io/badge/SWIFT%20PACKAGE%20MANAGER-SUPPORTED-green?style=for-the-badge&logo=SWIFT)

[![Build & Test](https://github.com/allexks/FuzzyKit/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/allexks/FuzzyKit/actions/workflows/build-and-test.yml)
![License](https://img.shields.io/github/license/allexks/FuzzyKit)

## Example Usage

```swift
import FuzzyKit

enum Funding { case adequate, marginal, inadequate }
enum Staffing { case small, large }
enum Risk { case low, normal, high }

let funding: SimpleLinguisticVariable = [
.inadequate: .init(membershipFunction: .leftOpen(slopeStart: 15, slopeEnd: 35)),
.marginal: .init(membershipFunction: .triangular(minimum: 21, peak: 41, maximum: 61)),
.adequate: .init(membershipFunction: .rightOpen(slopeStart: 55, slopeEnd: 75)),
]

let staffing: SimpleLinguisticVariable = [
.small: .init(membershipFunction: .leftOpen(slopeStart: 29, slopeEnd: 69)),
.large: .init(membershipFunction: .rightOpen(slopeStart: 37, slopeEnd: 77)),
]

let risk: SimpleLinguisticVariable = [
.low: .init(membershipFunction: .leftOpen(slopeStart: 20, slopeEnd: 40)),
.normal: .init(membershipFunction: .triangular(minimum: 20, peak: 50, maximum: 80)),
.high: .init(membershipFunction: .rightOpen(slopeStart: 60, slopeEnd: 80)),
]

let Ø = AnyFuzzySet.empty

let ruleBase = FuzzyRuleBase {
funding.is(.adequate) || staffing.is(.small) --> risk.is(.low)
funding.is(.marginal) && staffing.is(.large) --> risk.is(.normal)
funding.is(.inadequate) || Ø --> risk.is(.high)
}

let flc = FuzzyLogicController(rules: ruleBase, settings: .init(implication: .mamdani))

flc.consequenceGrade(for: 50, usingSingletonFact: (8.8, 42)) // result is 0.675
```

## Modules

Using the Swift Package Manager, don't forget to add the package as a dependency to your `Package.swift` file:

```diff
dependencies: [
+ .package(url: "https://github.com/allexks/FuzzyKit", .upToNextMajor(from: "0.1.0")),
],
```

To be able to use everything from this package, you can import everything at once using this helper module:

```diff
.target(
name: "...",
dependencies: [
+ .product(name: "FuzzyKit", package: "FuzzyKit"),
]
),
```

```swift
import FuzzyKit
```

Or alternatively, import only the specific modules needed:

```diff
.target(
name: "...",
dependencies: [
+ .product(name: "FuzzySets", package: "FuzzyKit"),
+ .product(name: "FuzzyNumbers", package: "FuzzyKit"),
+ .product(name: "FuzzyRelations", package: "FuzzyKit"),
+ .product(name: "FuzzyLogic", package: "FuzzyKit"),
]
),
```

```swift
import FuzzySets
import FuzzyNumbers
import FuzzyRelations
import FuzzyLogic
```

## API Reference

API Reference automatically collected with `jazzy` is published [here](https://allexks.github.io/FuzzyKit) with each new release.

## `FuzzySets` Module

### `protocol FuzzySet`
This abstraction requires a fuzzy set to provide a `grade(forElement:)` method which accepts a parameter of an `associatedtype Universe` and returns its membership `Grade` in the set. There are 3 provided concrete implementations in this module:

1. `struct AnyFuzzySet` - allows type erasure. It only stores a `MembershipFunction` and has non-mutable methods.

2. `struct IterableFuzzySet` - stores a `MembershipFunction` as well as a `Sequence` of elements of the associated type `Universe`. Implements `Sequence` so that it can easily be iterated over them. The elements of the iteration over an `IterableFuzzySet` are `struct`s containing `grade` and `element` properties. It has non-mutable methods only. Includes `support`, `core` and `height` computed properties.

3. `struct DiscreteMutableFuzzySet` - it is "discrete" because it doesn't stores a `MembershipFunction` but instead keeps its elements and their grade in a `Dictionary`, and it is "mutable" because it contains mutable equivalents of all other methods that operate over the set (including `subscript`). A default value of `0` is returned for the grade of an element that is not in the dictionary (a different default value can be provided as well). Includes `support`, `core` and `height` computed properties. A bonus feature is its debug print using Zadeh's notation.

Convertions between the 3 types are easy and possible using the `eraseToAnyFuzzySet`, `makeIterable` and `makeDiscreteMutable` methods defined on them.

### `protocol FuzzySetOperations`
All 3 concrete types implement it. It requires the following methods that operate on fuzzy sets:

* `alphaCut(_:alpha:)`

* `complement(method:)`

* `intersection(_:method:)`

* `union(_:method:)`

* `difference(_:method:)`

* `symmetricDifference(_:method:)`

* `power(_:n:)`

* `appliedCustomFunction(_:function:)`

## License

[MIT](LICENSE)

[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fallexks%2FFuzzyKit.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fallexks%2FFuzzyKit?ref=badge_large)