1 unstable release
Uses new Rust 2024
| new 0.1.0 | Jan 5, 2026 |
|---|
#494 in Algorithms
51KB
957 lines
Fuzzy Control
A type-safe, production-ready fuzzy logic control library for Rust.
Features
- Type-safe membership degrees: Enforces the [0, 1] constraint at the type level
- Generic numeric types: Use
f64,f32, or custom numeric types for both domain and membership values - Comprehensive membership functions: Triangular, Trapezoidal, Gaussian, and extensible
- Mamdani inference: Complete implementation with configurable operators
- Multiple defuzzification methods: Centroid, Bisector, Mean/Smallest/Largest of Maximum, Weighted Average
- Flexible rule system: Support for AND/OR operators and rule weights
- SVG visualization: Built-in plotting for membership functions, fuzzification, aggregation, and control surfaces
- No external dependencies: Only requires
num-traitsfor numeric abstractions
Installation
Add this to your Cargo.toml:
[dependencies]
fuzzy_control = "0.1.0"
Quick Start
use fuzzy_control::*;
use fuzzy_control::membership_functions::*;
use fuzzy_control::defuzzification::*;
use std::collections::HashMap;
fn main() -> Result<(), MembershipError> {
// Create input variable: Temperature (0-100°C)
let mut temperature = LinguisticVariable::new("temperature", (0.0, 100.0));
temperature.add_set(FuzzySet::new(
"cold",
Box::new(Triangular::new(0.0, 0.0, 50.0)?)
));
temperature.add_set(FuzzySet::new(
"hot",
Box::new(Triangular::new(50.0, 100.0, 100.0)?)
));
// Create output variable: Fan Speed (0-100%)
let mut fan_speed = LinguisticVariable::new("fan_speed", (0.0, 100.0));
fan_speed.add_set(FuzzySet::new(
"low",
Box::new(Triangular::new(0.0, 0.0, 50.0)?)
));
fan_speed.add_set(FuzzySet::new(
"high",
Box::new(Triangular::new(50.0, 100.0, 100.0)?)
));
// Create rules
let rules = vec![
FuzzyRule::new(
vec![Condition::new("temperature", "cold")],
RuleOperator::And,
vec![Consequent::new("fan_speed", "low")],
),
FuzzyRule::new(
vec![Condition::new("temperature", "hot")],
RuleOperator::And,
vec![Consequent::new("fan_speed", "high")],
),
];
// Build controller
let controller = FuzzyController::builder()
.add_input(temperature)
.add_output(fan_speed)
.add_rules(rules)
.build();
// Evaluate with input
let inputs = HashMap::from([("temperature".to_string(), 75.0)]);
let outputs = controller.evaluate_centroid(&inputs)?;
println!("Temperature: 75°C → Fan Speed: {:.1}%", outputs["fan_speed"]);
Ok(())
}
Core Concepts
Membership Functions
Define how crisp values map to fuzzy membership degrees:
// Triangular membership function
let cold = Triangular::new(0.0, 0.0, 50.0)?;
// Trapezoidal for flat peaks
let comfortable = Trapezoidal::new(15.0, 20.0, 25.0, 30.0)?;
// Gaussian for smooth transitions
let warm = Gaussian::new(25.0, 5.0)?;
Linguistic Variables
Group fuzzy sets under a named variable:
let mut temperature = LinguisticVariable::new("temperature", (0.0, 100.0));
temperature.add_set(cold_set);
temperature.add_set(warm_set);
temperature.add_set(hot_set);
Fuzzy Rules
Express control logic in IF-THEN format:
// Simple rule
let rule = FuzzyRule::new(
vec![Condition::new("temperature", "hot")],
RuleOperator::And,
vec![Consequent::new("fan_speed", "high")],
);
// Rule with multiple conditions
let rule = FuzzyRule::new(
vec![
Condition::new("temperature", "hot"),
Condition::new("humidity", "high"),
],
RuleOperator::And,
vec![Consequent::new("fan_speed", "max")],
);
// Rule with weight
let rule = rule.with_weight(MembershipDegree::new(0.8)?);
Defuzzification
Convert fuzzy outputs to crisp values:
// Centroid (most common)
let defuzz = Centroid::new(200)?;
let outputs = controller.evaluate(&inputs, &defuzz)?;
// Or use the convenience method
let outputs = controller.evaluate_centroid(&inputs)?;
// Other methods available:
// - Bisector
// - MeanOfMaximum
// - SmallestOfMaximum
// - LargestOfMaximum
// - WeightedAverage
Visualization
Generate SVG visualizations for analysis and debugging:
use fuzzy_control::visualization::*;
// Plot membership functions
let svg = plot_membership_functions(&temperature, None)?;
std::fs::write("membership.svg", svg)?;
// Visualize fuzzification
let svg = plot_fuzzification(&temperature, 35.0, None)?;
std::fs::write("fuzzification.svg", svg)?;
// Show rule firing strengths
let inputs = HashMap::from([("temperature".to_string(), 35.0)]);
let svg = plot_rule_evaluation(&controller, &inputs, None)?;
std::fs::write("rules.svg", svg)?;
// Visualize output aggregation
let defuzz = Centroid::new(200)?;
let svg = plot_output_aggregation(
&controller,
"fan_speed",
&inputs,
&defuzz,
None
)?;
std::fs::write("aggregation.svg", svg)?;
// Generate control surface (2-input systems)
let svg = plot_control_surface(
&controller,
"temperature",
"humidity",
"fan_speed",
&defuzz,
30,
None
)?;
std::fs::write("surface.svg", svg)?;
Advanced Usage
Custom Numeric Types
Use different numeric types for domain and membership:
// f32 for memory efficiency
let controller = FuzzyController::<f32, f32>::builder()
.add_input(temp)
.build();
// Mix types: f64 domain, f32 membership
let controller = FuzzyController::<f64, f32>::builder()
.add_input(temp)
.build();
Custom Operators
Provide custom T-norms and S-norms:
use fuzzy_control::operators::*;
let controller = FuzzyController::builder()
.with_t_norm(Box::new(ProductTNorm))
.with_s_norm(Box::new(ProbabilisticSumSNorm))
.add_input(temp)
.build();
Batch Operations
Add multiple variables and rules at once:
let controller = FuzzyController::builder()
.add_inputs(vec![temp, humidity, pressure])
.add_outputs(vec![fan, heater, ventilation])
.add_rules(vec![rule1, rule2, rule3])
.build();
Examples
See the examples/ directory for complete examples:
temperature_control.rs- Simple temperature control systemhvac_system.rs- Multi-input HVAC controllervisualizations.rs- Generate all visualization types
Run examples with:
cargo run --example temperature_control
cargo run --example hvac_system
cargo run --example visualizations
Testing
Run the comprehensive test suite:
cargo test
Run tests with output:
cargo test -- --nocapture
Architecture
The library is organized into several modules:
- Core types:
MembershipDegree,Floattrait - Membership functions:
membership_functionsmodule - Fuzzy sets:
FuzzySet,LinguisticVariable - Rules:
FuzzyRule,Condition,Consequent - Operators:
TNorm,SNormtraits and implementations - Controller:
FuzzyControllerand builder - Defuzzification: Multiple defuzzification methods
- Visualization: SVG plotting utilities
Contributing
Contributions are welcome! Please feel free to submit pull requests or open issues.
License
This project is dual-licensed under MIT or Apache-2.0. You may choose either license.
References
- Zadeh, L.A. (1965). "Fuzzy Sets". Information and Control.
- Mamdani, E.H. (1974). "Application of fuzzy algorithms for control of simple dynamic plant"
- Takagi, T. and Sugeno, M. (1985). "Fuzzy identification of systems"
Roadmap
- Sugeno-style inference
- Additional membership function types (Sigmoid, Bell, etc.)
- Performance optimizations
- Serialization support
- WASM support for web applications
Dependencies
~145KB