Compare commits
2 Commits
c721daab89
...
479eed439f
| Author | SHA1 | Date |
|---|---|---|
|
|
479eed439f | |
|
|
ec37ab1674 |
|
|
@ -84,9 +84,35 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Run Rust tests
|
||||
# wifi-densepose-core, -config, and -mat have no system library dependencies
|
||||
# and can be tested in a bare CI environment.
|
||||
#
|
||||
# Other workspace crates (desktop, nn, signal, hardware, wifiscan) require
|
||||
# system libraries (Tauri/glib, libtorch, OpenBLAS, libpcap, serialport) that
|
||||
# are not available on a stock ubuntu runner without additional setup steps.
|
||||
#
|
||||
# Previous config used `--workspace --no-default-features` which had two bugs:
|
||||
# 1. Stripping --no-default-features removes the `std` feature, breaking
|
||||
# String/format!/etc. in crates that put std behind a feature flag.
|
||||
# 2. Tauri (wifi-densepose-desktop) pulls in glib unconditionally regardless
|
||||
# of feature flags, so --workspace always fails without libglib2.0-dev.
|
||||
|
||||
- name: Run Rust tests — core (default features)
|
||||
working-directory: rust-port/wifi-densepose-rs
|
||||
run: cargo test --workspace --no-default-features
|
||||
run: cargo test -p wifi-densepose-core -p wifi-densepose-config -p wifi-densepose-mat
|
||||
|
||||
- name: Run Rust tests — core (no optional features)
|
||||
working-directory: rust-port/wifi-densepose-rs
|
||||
# Keep std enabled — it's required, not optional. Only strip truly optional features.
|
||||
run: cargo test -p wifi-densepose-core -p wifi-densepose-config -p wifi-densepose-mat --no-default-features --features std
|
||||
|
||||
- name: Clippy — core crates
|
||||
working-directory: rust-port/wifi-densepose-rs
|
||||
run: cargo clippy -p wifi-densepose-core -p wifi-densepose-config -p wifi-densepose-mat -- -D warnings
|
||||
|
||||
- name: Check optional ternlang feature
|
||||
working-directory: rust-port/wifi-densepose-rs
|
||||
run: cargo check -p wifi-densepose-core --features ternlang
|
||||
|
||||
# Unit and Integration Tests
|
||||
test:
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ default = ["std"]
|
|||
std = []
|
||||
serde = ["dep:serde", "ndarray/serde"]
|
||||
async = ["dep:async-trait"]
|
||||
ternlang = ["dep:ternlang-core"]
|
||||
|
||||
[dependencies]
|
||||
# Error handling
|
||||
|
|
@ -38,8 +39,8 @@ chrono = { version = "0.4", features = ["serde"] }
|
|||
# UUID for unique identifiers
|
||||
uuid = { version = "1.6", features = ["v4", "serde"] }
|
||||
|
||||
# Ternary Intelligence Stack
|
||||
ternlang-core = { path = "/home/eri-irfos/Desktop/Ternary Intelligence Stack (TIS)/ternlang-root/ternlang-core", version = "0.1.0" }
|
||||
# Ternary Intelligence Stack (optional — enable with feature "ternlang")
|
||||
ternlang-core = { version = "0.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json.workspace = true
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use chrono::{DateTime, Utc};
|
|||
use ndarray::{Array1, Array2, Array3};
|
||||
use num_complex::Complex64;
|
||||
use uuid::Uuid;
|
||||
#[cfg(feature = "ternlang")]
|
||||
use ternlang_core::Trit;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
|
|
@ -151,57 +152,82 @@ impl Default for Timestamp {
|
|||
}
|
||||
}
|
||||
|
||||
/// Confidence score represented as a Triadic Field {-1, 0, +1}.
|
||||
/// Aligned with RFI-IRFOS TIS standards for high-fidelity pose resolution.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
/// Confidence score in the range [0.0, 1.0].
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct Confidence(Trit);
|
||||
pub struct Confidence(f32);
|
||||
|
||||
impl Confidence {
|
||||
/// Creates a new triadic confidence from a raw f32 value.
|
||||
/// Aligned with ISO/IEC TIS-9000 uncertainty mapping.
|
||||
/// Creates a new confidence value.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the value is not in the range [0.0, 1.0].
|
||||
pub fn new(value: f32) -> CoreResult<Self> {
|
||||
if value > 0.6 {
|
||||
Ok(Self(Trit::Affirm))
|
||||
} else if value < 0.3 {
|
||||
Ok(Self(Trit::Reject))
|
||||
} else {
|
||||
Ok(Self(Trit::Tend))
|
||||
if !(0.0..=1.0).contains(&value) {
|
||||
return Err(CoreError::validation(format!(
|
||||
"Confidence must be in [0.0, 1.0], got {value}"
|
||||
)));
|
||||
}
|
||||
Ok(Self(value))
|
||||
}
|
||||
|
||||
/// Returns the raw scalar representation of the triadic field.
|
||||
/// Creates a confidence value without validation (for internal use).
|
||||
///
|
||||
/// Returns the raw confidence value.
|
||||
#[must_use]
|
||||
pub fn value(&self) -> f32 {
|
||||
match self.0 {
|
||||
Trit::Affirm => 1.0,
|
||||
Trit::Reject => -1.0,
|
||||
Trit::Tend => 0.0,
|
||||
}
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns `true` if the signal is triadic-affirmative.
|
||||
/// Returns `true` if the confidence exceeds the default threshold.
|
||||
#[must_use]
|
||||
pub fn is_high(&self) -> bool {
|
||||
self.0 == Trit::Affirm
|
||||
self.0 >= 0.5
|
||||
}
|
||||
|
||||
/// Returns `true` if the confidence exceeds the given threshold.
|
||||
#[must_use]
|
||||
pub fn exceeds(&self, threshold: f32) -> bool {
|
||||
self.value() >= threshold
|
||||
self.0 >= threshold
|
||||
}
|
||||
|
||||
/// Maximum confidence (Affirm).
|
||||
pub const MAX: Self = Self(Trit::Affirm);
|
||||
/// Maximum confidence value (1.0).
|
||||
pub const MAX: Self = Self(1.0);
|
||||
|
||||
/// Minimum confidence (Reject).
|
||||
pub const MIN: Self = Self(Trit::Reject);
|
||||
/// Minimum confidence value (0.0).
|
||||
pub const MIN: Self = Self(0.0);
|
||||
|
||||
/// Maps this confidence score to a ternary trit signal.
|
||||
///
|
||||
/// Useful for integrating with ternary reasoning pipelines
|
||||
/// (e.g. [`ternlang`](https://ternlang.com)) where decisions must
|
||||
/// express not just high/low but an explicit "hold — gather more data"
|
||||
/// state.
|
||||
///
|
||||
/// | Range | Trit | Meaning |
|
||||
/// |--------------|---------|----------------------------------|
|
||||
/// | `>= 0.65` | Affirm | High confidence — act |
|
||||
/// | `0.35..0.65` | Tend | Uncertain — defer or review |
|
||||
/// | `< 0.35` | Reject | Low confidence — discard/retry |
|
||||
///
|
||||
/// Requires the `ternlang` feature flag.
|
||||
#[cfg(feature = "ternlang")]
|
||||
#[must_use]
|
||||
pub fn trit_signal(&self) -> Trit {
|
||||
if self.0 >= 0.65 {
|
||||
Trit::Affirm
|
||||
} else if self.0 < 0.35 {
|
||||
Trit::Reject
|
||||
} else {
|
||||
Trit::Tend
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Confidence {
|
||||
fn default() -> Self {
|
||||
Self(Trit::Tend)
|
||||
Self(0.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue