实用 API 示例¶
完整场景解释完整计算过程。这里的较小示例涵盖域验证、采样性质、其他运算选择、有限比较和错误处理。每个 Python 代码块均可独立运行,并在 CI 中针对已安装的 wheel 和 sdist 产物执行。
积分前验证域¶
from fuzzyroutines import ContinuousUniverse, DiscreteUniverse, IntegrationDomain
universe = ContinuousUniverse(0, 10, leftClosed=True, rightClosed=True)
domain = IntegrationDomain.FromLegacyInterval((2, 8)).ValidateWithin(universe)
assert universe.isBounded and universe.Contains(0)
assert domain.Contains(2) and domain.ToLegacyInterval() == (2, 8)
discrete = DiscreteUniverse((1, 3, 5))
assert discrete.Contains(3) and not discrete.Contains(2)
print(domain.ToLegacyInterval(), discrete.points)
积分窗口是有限闭区间,不是数学上的支集。论域可以无界或具有开端点;请求的积分窗口必须遵守这些端点限制。
读取精确与采样性质¶
from fuzzyroutines import (
ContinuousInterval, ContinuousRegion, ContinuousUniverse, DeriveProperties,
DiscreteRegion, IntegrationDomain, IsNormal, SampleProperties,
ScalarFuzzySet, Triangle,
)
model = Triangle(0, 2, 4)
universe = ContinuousUniverse(0, 4, leftClosed=True, rightClosed=True)
properties = DeriveProperties(model, universe)
sampled = SampleProperties(model, IntegrationDomain(0, 4), sampleCount=5)
assert properties.isExact and properties.height == 1
assert properties.core.Contains(2) and not properties.positiveSupport.Contains(0)
assert not sampled.isExact and sampled.heightEstimate == 1
assert sampled.coreSamples.points == (2,)
assert IsNormal(ScalarFuzzySet(universe, model))
interval = ContinuousInterval(1, 3, leftClosed=True, rightClosed=False)
region = ContinuousRegion((interval,))
assert region.Contains(1) and not region.Contains(3) and not region.isEmpty
assert not interval.isSingleton and not DiscreteRegion((1, 3)).isEmpty
print(properties.height, sampled.coordinates)
对于内置解析函数族,DeriveProperties 计算限制在论域内的精确几何性质。SampleProperties 报告指定网格上观察到的支集、核、边界和高度估计。本例恰好采到峰值,因此估计为一;其他模型若漏掉窄峰,就可能低估高度。一般连续模型的精确高度不会从采样推断。IsNormal 使用精确高度和显式容差,默认容差为 \(10^{-12}\)。
有意识地选择标量运算族¶
from math import isclose
from fuzzyroutines import NegationPolicy, SNormPolicy, TNormPolicy
expectedAnd = {"logic": 0.4, "algebraic": 0.28, "boundary": 0.1, "drastic": 0}
expectedOr = {"logic": 0.7, "algebraic": 0.82, "boundary": 1, "drastic": 1}
for family in expectedAnd:
assert isclose(TNormPolicy(family).Evaluate(0.4, 0.7), expectedAnd[family], abs_tol=1e-12)
assert isclose(SNormPolicy(family).Evaluate(0.4, 0.7), expectedOr[family], abs_tol=1e-12)
assert NegationPolicy("standard").Evaluate(0.4) == 0.6
assert NegationPolicy("parametric", alpha=0.5).Evaluate(0.5) == 0.5
assert NegationPolicy("parabolic", alpha=0.5).Evaluate(0.5) == 0.5
print(expectedAnd, expectedOr)
参数化否定要求 \(0<\alpha<1\);抛物线否定要求 \(1/4\leq\alpha\leq3/4\)。这里的 α 是否定参数,不是 α-截集阈值。有界与剧烈策略是显式备选;端点处的突变行为可能影响模型。
在显式坐标处比较连续模型¶
from fuzzyroutines import (
ComparisonDomain, ComparisonPolicy, ContinuousUniverse,
EqualOnDomain, IncludedOnDomain, ScalarFuzzySet, Triangle,
)
universe = ContinuousUniverse(0, 4, leftClosed=True, rightClosed=True)
left = ScalarFuzzySet(universe, Triangle(0, 2, 4))
right = ScalarFuzzySet(universe, Triangle(0, 2, 4))
coordinates = ComparisonDomain((0, 1, 2, 3, 4)).ValidateWithin(universe)
policy = ComparisonPolicy("tolerance", absoluteTolerance=1e-12, relativeTolerance=1e-10)
assert policy.Equal(0.5, 0.5 + 1e-13)
assert policy.Included(0.4, 0.5)
assert EqualOnDomain(left, right, policy, coordinates)
assert IncludedOnDomain(left, right, policy, coordinates)
print(coordinates.points)
结果只证明五个声明的观测处的关系。即使独立解析论证能说明这两个特定定义相同,该结果本身也不是全局连续等价性的证明。
处理数学上未定义的结果¶
from fuzzyroutines import (
Centroid, CentroidPolicy, ContinuousUniverse, IntegrationDomain,
MembershipScalar, ScalarFuzzySet,
)
from fuzzyroutines.exceptions import UndefinedResultError
def ZeroGrade(coordinate: MembershipScalar) -> MembershipScalar:
"""Return zero area on every allowed coordinate."""
return 0
empty = ScalarFuzzySet(
ContinuousUniverse(0, 1, leftClosed=True, rightClosed=True), ZeroGrade,
)
try:
Centroid(empty, IntegrationDomain(0, 1), CentroidPolicy(maximumDepth=20))
except UndefinedResultError:
print("No centroid: the membership area is zero")
else:
raise AssertionError("zero-area membership unexpectedly had a centroid")
应选择符合领域语义的后备行为,或继续传播此错误。静默返回零会凭空指定一个代表性坐标。无效类型、参数和域具有各自的异常类别;自适应细化达到上限时抛出 CentroidConvergenceError。应捕获应用确实能够处理的具体类别,而不是抑制全部错误。