Add all operator functions

This commit is contained in:
Alexander Ignatov 2021-12-22 23:52:36 +02:00
parent 09c3b5bc56
commit 3fb313bd4e
1 changed files with 111 additions and 15 deletions

View File

@ -1,44 +1,121 @@
import RealModule
/// Describes a T-norm function, usually used for forming an intersection of fuzzy sets.
///
/// A function `T` must satisfy the following axioms in order to be T-normed:
/// 1. Boundary condition: `T(1, 1) = 1`, `T(1, 0) = 0`, `T(0, 1) = 0`, `T(0, 0) = 0`
/// 2. Commutativity: `T(a, b) = T(b, a)`
/// 3. Monotonic: `If a <= a' and b <= b' Then T(a, b) <= T(a', b')`
/// 4. Associativity: `T(T(a, b), c) = T(a, T(b, c))`
public enum TNormFunction { public enum TNormFunction {
case minimum case minimum
case lukasiewicz case lukasiewicz
case product case product
case weak case weak
case hamacher case hamacher(gamma: Double)
case duboisAndPrade case duboisAndPrade(alpha: Double)
case yager case yager(p: Double)
case frank case frank(lambda: Double)
case custom((Grade, Grade) -> Grade) case custom((Grade, Grade) -> Grade)
var function: (Grade, Grade) -> Grade { var function: (Grade, Grade) -> Grade {
min switch self {
// TODO case .minimum:
return min
case .lukasiewicz:
return { max($0 + $1, 1) }
case .product:
return { $0 * $1 }
case .weak:
return { max($0, $1) == 1 ? min($0, $1) : 0 }
case .hamacher(gamma: let g):
return { $0 * $1 / (g + (1 - g)*($0 + $1 - $0*$1)) }
case .duboisAndPrade(alpha: let a):
return { $0 * $1 / max($0, $1, a) }
case .yager(p: let p):
return {
1 - min(1.0, ((1-$0).pow(p) + (1-$1).pow(p)).root(p))
}
case .frank(lambda: let l):
switch l {
case 0:
return TNormFunction.minimum.function
case 1:
return TNormFunction.product.function
case .infinity:
return TNormFunction.lukasiewicz.function
default:
return {
1 - (1 + (l.pow($0) - 1)*(l.pow($1) - 1) / (l - 1)).log(base: l)
}
}
case .custom(let function):
return function
}
} }
} }
/// Describes a S-norm (T-conorm) function, usually used for forming a union of fuzzy sets.
///
/// A function `S` must satisfy the following axioms in order to be S-normed (T-conormed):
/// 1. Boundary condition: `S(1, 1) = 1`, `S(1, 0) = 1`, `S(0, 1) = 1`, `S(0, 0) = 0`
/// 2. Commutativity: `S(a, b) = S(b, a)`
/// 3. Monotonic: `If a <= a' and b <= b' Then S(a, b) <= S(a', b')`
/// 4. Associativity: `S(T(a, b), c) = S(a, T(b, c))`
public enum SNormFunction { public enum SNormFunction {
case maximum case maximum
case lukasiewicz case lukasiewicz
case probabilistic case probabilistic
case strong case strong
case hamacher case hamacher(gamma: Double)
case yager case yager(p: Double)
case custom((Grade, Grade) -> Grade) case custom((Grade, Grade) -> Grade)
var function: (Grade, Grade) -> Grade { var function: (Grade, Grade) -> Grade {
max switch self {
// TODO case .maximum:
return max
case .lukasiewicz:
return { min($0 + $1, 1) }
case .probabilistic:
return { $0 + $1 - $0*$1 }
case .strong:
return { min($0, $1) == 0 ? max($0, $1) : 1 }
case .hamacher(gamma: let g):
return { ($0 + $1 - (2 - g)*$0*$1) / (1 - (1 - g)*$0*$1) }
case .yager(p: let p):
return { min(1, ($0.pow(p) + $1.pow(p)).root(p)) }
case .custom(let function):
return function
}
} }
} }
/// Describes a complement (negation) function, usually used for forming a complement (negation) of a fuzzy set.
///
/// A function `c` must satisfy the following axioms in order to be capable of negating a fuzzy set:
/// 1. Boundary condition: `c(0) = 1`, `c(1) = 0`
/// 2. Monotonic nonincreasing: `a < b -> c(a) >= c(b)`
/// 3. Involution: `c(c(a)) = a`
public enum ComplementFunction { public enum ComplementFunction {
case standard case standard
case yager case yager(w: Double)
case sugeno case sugeno(s: Double)
case custom((Grade) -> Grade) case custom((Grade) -> Grade)
var function: (Grade) -> Grade { var function: (Grade) -> Grade {
{ 1 - $0 } switch self {
// TODO case .standard:
return { 1 - $0 }
case .yager(w: let w):
return { (1 - $0.pow(w)).root(w) }
case .sugeno(s: let s):
return { (1 - $0) / (1 - s * $0) }
case .custom(let function):
return function
}
} }
} }
@ -75,9 +152,28 @@ public enum SymmetricDifferenceFunction {
case .minMaxAndStandardComplement: case .minMaxAndStandardComplement:
return { max(min($0, 1 - $1), min($1, 1 - $0)) } return { max(min($0, 1 - $1), min($1, 1 - $0)) }
case .tNormSNormAndComplement(let t, let s, let c): case .tNormSNormAndComplement(let t, let s, let c):
return { s.function(t.function($0, c.function($1)), t.function($1, c.function($0))) } return {
s.function(
t.function($0, c.function($1)),
t.function($1, c.function($0))
)
}
case .custom(let function): case .custom(let function):
return function return function
} }
} }
} }
internal extension Double {
func pow(_ x: Double) -> Double {
Double.pow(self, x)
}
func log(base: Double) -> Double {
Double.log(self) / Double.log(base)
}
func root(_ x: Double) -> Double {
Double.pow(self, 1/x)
}
}