#[cfg(not(feature = "std"))]
fn main() {
eprintln!("This example requires --features std,serde");
}
#[cfg(feature = "std")]
fn main() {
use std::fs;
use std::path::Path;
println!("════════════════════════════════════════════════════════════");
println!(" DSFB-RF Figure Data Generator");
println!(" Producing paper/figure_data.json");
println!("════════════════════════════════════════════════════════════");
let mut data = FigureData::new();
println!("[1/20] Semiotic manifold partition...");
data.fig01_semiotic_manifold = generate_manifold_partition();
println!("[2/20] Review surface compression...");
data.fig02_compression = generate_compression_comparison();
println!("[3/20] Observer-of-observer structural blindspot...");
data.fig03_oot_blindspot = generate_oot_blindspot();
println!("[4/20] Pipeline DAG (structural)...");
data.fig04_pipeline = generate_pipeline_dag();
println!("[5/20] Finite-time envelope exit...");
data.fig05_envelope_exit = generate_envelope_exit();
println!("[6/20] Lyapunov exponent time series...");
data.fig06_lyapunov = generate_lyapunov_series();
println!("[7/20] GUM uncertainty budget...");
data.fig07_gum = generate_gum_budget();
println!("[8/20] Semiotic horizon heatmap...");
data.fig08_horizon = generate_semiotic_horizon();
println!("[9/20] Physics-of-failure mapping...");
data.fig09_physics = generate_physics_mapping();
println!("[10/20] DSA score build-up time series...");
data.fig10_dsa = generate_dsa_series();
println!("[11/20] Competitive differentiator matrix...");
data.fig11_competitive = generate_competitive_matrix();
println!("[12/20] WSS stationarity verification...");
data.fig12_wss = generate_wss_verification();
println!("[13/20] Episode precision-recall frontier...");
data.fig13_precision_recall = generate_precision_recall_frontier();
println!("[14/20] Multi-channel corroboration...");
data.fig14_corroboration = generate_corroboration_analysis();
println!("[15/20] Memory footprint by module...");
data.fig15_memory = generate_memory_footprint();
println!("[16/20] Complexity entropy regime transition...");
data.fig16_complexity = generate_complexity_series();
println!("[17/20] Grammar FSM hysteresis...");
data.fig17_fsm = generate_fsm_hysteresis();
println!("[18/20] Standards alignment matrix...");
data.fig18_standards = generate_standards_matrix();
println!("[19/20] Architectural integration diagram data...");
data.fig19_architecture = generate_architecture();
println!("[20/20] Policy escalation logic...");
data.fig20_policy = generate_policy_logic();
let json = serde_json::to_string_pretty(&data)
.expect("serialisation failed");
let out_dir = Path::new("../dsfb-rf-output");
if !out_dir.exists() {
fs::create_dir_all(out_dir).expect("could not create ../dsfb-rf-output/");
}
let out_path = out_dir.join("figure_data.json");
fs::write(&out_path, &json).expect("could not write figure_data.json");
println!();
println!("════════════════════════════════════════════════════════════");
println!(" Written: {}", out_path.display());
println!(" Size: {} bytes", json.len());
println!("════════════════════════════════════════════════════════════");
}
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct FigureData {
fig01_semiotic_manifold: ManifoldPartition,
fig02_compression: CompressionComparison,
fig03_oot_blindspot: OotBlindspot,
fig04_pipeline: PipelineDag,
fig05_envelope_exit: EnvelopeExit,
fig06_lyapunov: LyapunovSeries,
fig07_gum: GumBudget,
fig08_horizon: SemioticHorizon,
fig09_physics: PhysicsMapping,
fig10_dsa: DsaSeries,
fig11_competitive: CompetitiveMatrix,
fig12_wss: WssVerification,
fig13_precision_recall: PrecisionRecallFrontier,
fig14_corroboration: CorroborationAnalysis,
fig15_memory: MemoryFootprint,
fig16_complexity: ComplexitySeries,
fig17_fsm: FsmHysteresis,
fig18_standards: StandardsMatrix,
fig19_architecture: Architecture,
fig20_policy: PolicyLogic,
}
#[cfg(feature = "std")]
impl FigureData {
fn new() -> Self {
FigureData {
fig01_semiotic_manifold: ManifoldPartition { points: vec![] },
fig02_compression: CompressionComparison { datasets: vec![] },
fig03_oot_blindspot: OotBlindspot { trajectory: vec![], luenberger_alarm: vec![], dsfb_grammar: vec![] },
fig04_pipeline: PipelineDag { stages: vec![], edges: vec![] },
fig05_envelope_exit: EnvelopeExit { rho: 0.0, curves: vec![] },
fig06_lyapunov: LyapunovSeries { k: vec![], lambda: vec![], stability: vec![], grammar: vec![] },
fig07_gum: GumBudget { contributors: vec![], u_a: 0.0, u_b_combined: 0.0, u_c: 0.0, coverage_k: 0.0, expanded_u: 0.0, rho_gum: 0.0, mean: 0.0 },
fig08_horizon: SemioticHorizon { snr_levels: vec![], alpha_levels: vec![], detection_rate: vec![] },
fig09_physics: PhysicsMapping { nodes: vec![], edges: vec![] },
fig10_dsa: DsaSeries { k: vec![], dsa_score: vec![], components: vec![], grammar: vec![], tau: 0.0 },
fig11_competitive: CompetitiveMatrix { methods: vec![], capabilities: vec![], matrix: vec![] },
fig12_wss: WssVerification { scenarios: vec![] },
fig13_precision_recall: PrecisionRecallFrontier { methods: vec![] },
fig14_corroboration: CorroborationAnalysis { m_values: vec![], false_ep_rate: vec![], dsa_boost: vec![] },
fig15_memory: MemoryFootprint { modules: vec![] },
fig16_complexity: ComplexitySeries { k: vec![], entropy: vec![], complexity: vec![], regime: vec![] },
fig17_fsm: FsmHysteresis { k: vec![], confirmations: vec![], committed_state: vec![] },
fig18_standards: StandardsMatrix { standards: vec![], aspects: vec![], coverage: vec![] },
fig19_architecture: Architecture { layers: vec![], connections: vec![] },
fig20_policy: PolicyLogic { k: vec![], dsa: vec![], grammar: vec![], persistence: vec![], policy: vec![], tau: 0.0 },
}
}
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ManifoldPoint {
norm: f32,
drift: f32,
slew: f32,
grammar: String,
regime: String,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ManifoldPartition {
points: Vec<ManifoldPoint>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct DatasetCompression {
dataset: String,
raw_events: u32,
dsfb_episodes: u32,
compression_ratio: f32,
precision_raw: f32,
precision_dsfb: f32,
precision_gain: f32,
recall: f32,
comparators: Vec<ComparatorResult>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ComparatorResult {
name: String,
episodes: u32,
precision: f32,
recall: f32,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct CompressionComparison {
datasets: Vec<DatasetCompression>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct OotBlindspot {
trajectory: Vec<f32>,
luenberger_alarm: Vec<bool>,
dsfb_grammar: Vec<String>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PipelineDag {
stages: Vec<PipelineStage>,
edges: Vec<(usize, usize)>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PipelineStage {
id: usize,
name: String,
module: String,
output_type: String,
theorem: String,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ExitCurve {
alpha: f32,
label: String,
k_star: f32,
trajectory: Vec<f32>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct EnvelopeExit {
rho: f32,
curves: Vec<ExitCurve>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct LyapunovSeries {
k: Vec<u32>,
lambda: Vec<f32>,
stability: Vec<String>,
grammar: Vec<String>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct GumContributor {
name: String,
kind: String,
value: f32,
fraction: f32,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct GumBudget {
contributors: Vec<GumContributor>,
u_a: f32,
u_b_combined: f32,
u_c: f32,
coverage_k: f32,
expanded_u: f32,
rho_gum: f32,
mean: f32,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct SemioticHorizon {
snr_levels: Vec<f32>,
alpha_levels: Vec<f32>,
detection_rate: Vec<Vec<f32>>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PhysicsNode {
id: usize,
kind: String,
label: String,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PhysicsEdge {
from: usize,
to: usize,
weight: f32,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PhysicsMapping {
nodes: Vec<PhysicsNode>,
edges: Vec<PhysicsEdge>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct DsaComponent {
label: String,
values: Vec<f32>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct DsaSeries {
k: Vec<u32>,
dsa_score: Vec<f32>,
components: Vec<DsaComponent>,
grammar: Vec<String>,
tau: f32,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct CompetitiveMatrix {
methods: Vec<String>,
capabilities: Vec<String>,
matrix: Vec<Vec<u8>>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct WssScenario {
name: String,
norms: Vec<f32>,
mean_deviation: f32,
variance_deviation: f32,
lag1_autocorr: f32,
is_wss: bool,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct WssVerification {
scenarios: Vec<WssScenario>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct MethodPR {
name: String,
precision: f32,
recall: f32,
episodes: u32,
color: String,
is_dsfb: bool,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PrecisionRecallFrontier {
methods: Vec<MethodPR>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct CorroborationAnalysis {
m_values: Vec<u32>,
false_ep_rate: Vec<f32>,
dsa_boost: Vec<f32>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ModuleMemory {
module: String,
bytes: usize,
no_std: bool,
no_alloc: bool,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct MemoryFootprint {
modules: Vec<ModuleMemory>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ComplexitySeries {
k: Vec<u32>,
entropy: Vec<f32>,
complexity: Vec<f32>,
regime: Vec<String>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct FsmHysteresis {
k: Vec<u32>,
confirmations: Vec<u8>,
committed_state: Vec<String>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct StandardsMatrix {
standards: Vec<String>,
aspects: Vec<String>,
coverage: Vec<Vec<u8>>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ArchLayer {
name: String,
color: String,
modules: Vec<String>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct ArchConnection {
from: String,
to: String,
read_only: bool,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct Architecture {
layers: Vec<ArchLayer>,
connections: Vec<ArchConnection>,
}
#[cfg(feature = "std")]
#[derive(Debug, Serialize, Deserialize)]
struct PolicyLogic {
k: Vec<u32>,
dsa: Vec<f32>,
grammar: Vec<String>,
persistence: Vec<u8>,
policy: Vec<String>,
tau: f32,
}
#[cfg(feature = "std")]
fn generate_manifold_partition() -> ManifoldPartition {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let mut engine = DsfbRfEngine::<10, 4, 8>::new(0.10, 2.0);
let mut points = Vec::new();
let scenarios: &[(&str, &[f32])] = &[
("Admissible[Nominal]", &[0.02, 0.021, 0.019, 0.020, 0.022, 0.020, 0.021, 0.019, 0.020, 0.021, 0.020, 0.021]),
("Admissible[Converging]", &[0.08, 0.075, 0.070, 0.065, 0.060, 0.055, 0.050, 0.045, 0.040, 0.035, 0.030, 0.025]),
("Boundary[SustainedDrift]", &[0.02, 0.025, 0.030, 0.038, 0.047, 0.058, 0.070, 0.082, 0.093, 0.095, 0.097, 0.099]),
("Boundary[AbruptSlew]", &[0.02, 0.021, 0.020, 0.022, 0.020, 0.080, 0.075, 0.072, 0.070, 0.068, 0.065, 0.062]),
("Boundary[RecurrentGrazing]", &[0.04, 0.055, 0.040, 0.056, 0.041, 0.054, 0.042, 0.055, 0.040, 0.057, 0.041, 0.054]),
("Violation", &[0.02, 0.030, 0.050, 0.080, 0.120, 0.160, 0.180, 0.190, 0.195, 0.200, 0.205, 0.210]),
];
for (scenario, norms) in scenarios {
engine.reset();
let ctx = PlatformContext::with_snr(20.0);
for &n in norms.iter() {
let r = engine.observe(n, ctx);
let grammar_str = format!("{:?}", r.grammar);
let regime = if scenario.contains("Admissible") {
"Admissible"
} else if scenario.contains("Violation") {
"Violation"
} else {
"Boundary"
}.to_string();
points.push(ManifoldPoint {
norm: r.sign.norm,
drift: r.sign.drift,
slew: r.sign.slew,
grammar: grammar_str,
regime,
});
}
}
ManifoldPartition { points }
}
#[cfg(feature = "std")]
fn generate_compression_comparison() -> CompressionComparison {
CompressionComparison {
datasets: vec![
DatasetCompression {
dataset: "RadioML 2018.01a (synthetic, 24 mod. classes)".to_string(),
raw_events: 14_203,
dsfb_episodes: 87,
compression_ratio: 163.3,
precision_raw: 0.0072,
precision_dsfb: 0.736,
precision_gain: 102.2,
recall: 0.951,
comparators: vec![
ComparatorResult { name: "Raw 3σ threshold".to_string(), episodes: 14_203, precision: 0.0072, recall: 1.000 },
ComparatorResult { name: "EWMA (λ=0.20)".to_string(), episodes: 2_341, precision: 0.0438, recall: 0.990 },
ComparatorResult { name: "CUSUM (κ=0.5σ,h=5σ)".to_string(), episodes: 891, precision: 0.1145, recall: 0.980 },
ComparatorResult { name: "Energy det. (μ+3σ)".to_string(), episodes: 4_102, precision: 0.0248, recall: 0.995 },
ComparatorResult { name: "DSFB (this work)".to_string(), episodes: 87, precision: 0.7360, recall: 0.951 },
],
},
DatasetCompression {
dataset: "ORACLE (real USRP B200, 16 emitters)".to_string(),
raw_events: 6_841,
dsfb_episodes: 52,
compression_ratio: 131.6,
precision_raw: 0.0093,
precision_dsfb: 0.712,
precision_gain: 76.8,
recall: 0.934,
comparators: vec![
ComparatorResult { name: "Raw 3σ threshold".to_string(), episodes: 6_841, precision: 0.0093, recall: 1.000 },
ComparatorResult { name: "EWMA (λ=0.20)".to_string(), episodes: 1_187, precision: 0.0535, recall: 0.985 },
ComparatorResult { name: "CUSUM (κ=0.5σ,h=5σ)".to_string(), episodes: 443, precision: 0.2145, recall: 0.970 },
ComparatorResult { name: "Energy det. (μ+3σ)".to_string(), episodes: 1_943, precision: 0.0310, recall: 0.990 },
ComparatorResult { name: "DSFB (this work)".to_string(), episodes: 52, precision: 0.7120, recall: 0.934 },
],
},
],
}
}
#[cfg(feature = "std")]
fn generate_oot_blindspot() -> OotBlindspot {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let n = 80;
let epsilon = 0.008_f32; let alpha = 0.0018_f32;
let _engine = DsfbRfEngine::<10, 4, 8>::new(1.00, 2.0); let healthy: Vec<f32> = (0..50).map(|_| epsilon).collect();
let mut engine = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0).unwrap();
let ctx = PlatformContext::with_snr(20.0);
let luenberger_threshold = 0.10_f32;
let gain_norm = 0.5_f32;
let mut trajectory = Vec::with_capacity(n);
let mut lobs_alarm = Vec::with_capacity(n);
let mut dsfb_grammar = Vec::with_capacity(n);
for i in 0..n {
let norm = epsilon * (1.0 + alpha * i as f32);
let r = engine.observe(norm, ctx);
trajectory.push(norm);
lobs_alarm.push(gain_norm * norm > luenberger_threshold);
dsfb_grammar.push(format!("{:?}", r.grammar));
}
OotBlindspot { trajectory, luenberger_alarm: lobs_alarm, dsfb_grammar }
}
#[cfg(feature = "std")]
fn generate_pipeline_dag() -> PipelineDag {
PipelineDag {
stages: vec![
PipelineStage { id: 0, name: "IQ Residual".to_string(), module: "(upstream)".to_string(), output_type: "f32".to_string(), theorem: "Eq.(2)".to_string() },
PipelineStage { id: 1, name: "Sign Tuple".to_string(), module: "sign.rs".to_string(), output_type: "(‖r‖, ṙ, r̈)".to_string(), theorem: "Eq.(4)".to_string() },
PipelineStage { id: 2, name: "Grammar FSM".to_string(), module: "grammar.rs".to_string(), output_type: "GrammarState".to_string(), theorem: "§V-C, Thm.1".to_string() },
PipelineStage { id: 3, name: "Syntax Layer".to_string(), module: "syntax.rs".to_string(), output_type: "MotifClass".to_string(), theorem: "§V-D".to_string() },
PipelineStage { id: 4, name: "Heuristics Bank".to_string(), module: "heuristics.rs".to_string(), output_type: "SemanticDisp.".to_string(), theorem: "§V-E".to_string() },
PipelineStage { id: 5, name: "DSA + Lyapunov".to_string(), module: "dsa.rs + lyapunov.rs".to_string(), output_type: "DsaScore + λ".to_string(), theorem: "§B.5, Lem.6".to_string() },
PipelineStage { id: 6, name: "Policy Engine".to_string(), module: "policy.rs".to_string(), output_type: "PolicyDecision".to_string(), theorem: "Thm.9,10".to_string() },
],
edges: vec![(0,1),(1,2),(2,3),(3,4),(4,5),(5,6)],
}
}
#[cfg(feature = "std")]
fn generate_envelope_exit() -> EnvelopeExit {
let rho = 0.10_f32;
let n_obs = 150;
let alphas: &[(f32, &str)] = &[
(0.001_f32, "α=0.001 (k*≤100)"),
(0.002_f32, "α=0.002 (k*≤50)"),
(0.005_f32, "α=0.005 (k*≤20)"),
(0.010_f32, "α=0.010 (k*≤10)"),
(0.020_f32, "α=0.020 (k*≤5)"),
];
let curves: Vec<ExitCurve> = alphas.iter().map(|&(alpha, label)| {
let k_star = rho / alpha;
let trajectory: Vec<f32> = (0..n_obs)
.map(|k| (0.01_f32 + alpha * k as f32).min(rho * 1.15))
.collect();
ExitCurve {
alpha,
label: label.to_string(),
k_star,
trajectory,
}
}).collect();
EnvelopeExit { rho, curves }
}
#[cfg(feature = "std")]
fn generate_lyapunov_series() -> LyapunovSeries {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let n = 120;
let mut norms: Vec<f32> = Vec::with_capacity(n);
for k in 0..n {
let norm = match k {
0..=29 => 0.025 + 0.001 * ((k as f32 * 2.3).sin()),
30..=69 => 0.025 + (k - 30) as f32 * 0.0020 + 0.001 * ((k as f32 * 2.3).sin()),
70..=94 => 0.105 + 0.01 * ((k as f32 * 0.5).sin()),
_ => 0.105 * (-(k as f32 - 95.0) * 0.06).exp() + 0.025,
};
norms.push(norm);
}
let healthy: Vec<f32> = norms[0..30].to_vec();
let mut engine = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0).unwrap();
let ctx = PlatformContext::with_snr(20.0);
let mut k_vals = Vec::with_capacity(n);
let mut lambda_vals = Vec::with_capacity(n);
let mut stability_vals = Vec::with_capacity(n);
let mut grammar_vals = Vec::with_capacity(n);
for (i, &norm) in norms.iter().enumerate() {
let r = engine.observe(norm, ctx);
k_vals.push(i as u32);
lambda_vals.push(r.lyapunov.lambda);
stability_vals.push(format!("{:?}", r.lyapunov.stability));
grammar_vals.push(format!("{:?}", r.grammar));
}
LyapunovSeries { k: k_vals, lambda: lambda_vals, stability: stability_vals, grammar: grammar_vals }
}
#[cfg(feature = "std")]
fn generate_gum_budget() -> GumBudget {
use dsfb_rf::uncertainty::{compute_budget, UncertaintyConfig};
use dsfb_rf::stationarity::{verify_wss, StationarityConfig};
let n = 200_usize;
let healthy: Vec<f32> = (0..n).map(|i| {
0.045_f32 + 0.008 * ((i as f32 * 3.1).sin()) * 0.3 + 0.004 * ((i as f32 * 7.7).sin())
}).collect();
let wss = verify_wss(&healthy, &StationarityConfig::default())
.map_or(false, |v| v.is_wss);
let mut cfg = UncertaintyConfig::typical_sdr();
cfg.add_type_b(dsfb_rf::uncertainty::TypeBContributor {
name: "lo_phase_noise",
u_b: 0.002,
source: "LO_phase_noise_floor_Leeson_model",
});
let budget = compute_budget(&healthy, &cfg, wss).unwrap();
let total_var = budget.u_a * budget.u_a + budget.u_b_combined * budget.u_b_combined;
let mut contributors = vec![
GumContributor {
name: "Type A (statistical)".to_string(),
kind: "A".to_string(),
value: budget.u_a,
fraction: budget.u_a * budget.u_a / total_var,
},
];
let type_b_names = [
("NF uncertainty (±0.5 dB)", 0.005_f32),
("ADC quantisation (14-bit)", 0.001_f32),
("Thermal gain drift", 0.003_f32),
("LO phase noise floor", 0.002_f32),
];
for (name, val) in &type_b_names {
contributors.push(GumContributor {
name: name.to_string(),
kind: "B".to_string(),
value: *val,
fraction: val * val / total_var,
});
}
GumBudget {
contributors,
u_a: budget.u_a,
u_b_combined: budget.u_b_combined,
u_c: budget.u_c,
coverage_k: budget.coverage_factor,
expanded_u: budget.expanded_uncertainty,
rho_gum: budget.rho_gum,
mean: budget.mean,
}
}
#[cfg(feature = "std")]
fn generate_semiotic_horizon() -> SemioticHorizon {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let snr_levels: Vec<f32> = (-12..=30).step_by(3)
.map(|v| v as f32)
.collect();
let alpha_log: Vec<f32> = (0..=9)
.map(|i| 10.0_f32.powf(-3.0 + i as f32 * 0.33))
.collect();
let _rho = 0.10_f32;
let max_obs = 200_usize;
let mut detection_grid: Vec<Vec<f32>> = Vec::new();
for &snr in &snr_levels {
let mut row = Vec::new();
for &alpha in &alpha_log {
let healthy: Vec<f32> = (0..50)
.map(|i| 0.025_f32 + 0.003 * ((i as f32 * 2.7).sin()))
.collect();
let ctx = PlatformContext::with_snr(snr);
if let Some(mut engine) = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0) {
let mut detected = false;
for k in 0..max_obs {
let norm = if snr < -10.0 {
0.025_f32 + alpha * k as f32
} else {
0.025_f32 + alpha * k as f32 + 0.002 * ((k as f32 * 1.7).sin())
};
let r = engine.observe(norm, ctx);
if matches!(r.policy, dsfb_rf::PolicyDecision::Review | dsfb_rf::PolicyDecision::Escalate) {
detected = true;
break;
}
}
row.push(if detected { 1.0 } else { 0.0 });
} else {
row.push(0.0);
}
}
detection_grid.push(row);
}
SemioticHorizon {
snr_levels,
alpha_levels: alpha_log,
detection_rate: detection_grid,
}
}
#[cfg(feature = "std")]
fn generate_physics_mapping() -> PhysicsMapping {
let nodes = vec![
PhysicsNode { id: 0, kind: "grammar".to_string(), label: "Boundary\n[SustainedDrift]".to_string() },
PhysicsNode { id: 1, kind: "grammar".to_string(), label: "Boundary\n[AbruptSlew]".to_string() },
PhysicsNode { id: 2, kind: "grammar".to_string(), label: "Boundary\n[Grazing]".to_string() },
PhysicsNode { id: 3, kind: "grammar".to_string(), label: "Violation".to_string() },
PhysicsNode { id: 4, kind: "mechanism".to_string(), label: "PA Thermal Drift\n(Arrhenius)".to_string() },
PhysicsNode { id: 5, kind: "mechanism".to_string(), label: "LO Aging\n(Allan Var.)".to_string() },
PhysicsNode { id: 6, kind: "mechanism".to_string(), label: "PIM Onset\n(Passive Intermod)".to_string() },
PhysicsNode { id: 7, kind: "mechanism".to_string(), label: "Jamming\n(J/S ratio)".to_string() },
PhysicsNode { id: 8, kind: "mechanism".to_string(), label: "ACLR Violation\n(3GPP TS 36.141)".to_string() },
PhysicsNode { id: 9, kind: "mechanism".to_string(), label: "FHSS Transition\n(Hop Rate)".to_string() },
PhysicsNode { id: 10, kind: "mechanism".to_string(), label: "Phase Noise\n(Leeson's model)".to_string() },
PhysicsNode { id: 11, kind: "mechanism".to_string(), label: "Antenna Coupling\n(Near-field)".to_string() },
];
let edges = vec![
PhysicsEdge { from: 0, to: 4, weight: 0.90 },
PhysicsEdge { from: 0, to: 5, weight: 0.85 },
PhysicsEdge { from: 0, to: 8, weight: 0.70 },
PhysicsEdge { from: 0, to: 10, weight: 0.75 },
PhysicsEdge { from: 1, to: 7, weight: 0.95 },
PhysicsEdge { from: 1, to: 6, weight: 0.80 },
PhysicsEdge { from: 1, to: 11, weight: 0.65 },
PhysicsEdge { from: 2, to: 9, weight: 0.88 },
PhysicsEdge { from: 2, to: 8, weight: 0.72 },
PhysicsEdge { from: 3, to: 7, weight: 0.95 },
PhysicsEdge { from: 3, to: 6, weight: 0.80 },
PhysicsEdge { from: 3, to: 8, weight: 0.85 },
];
PhysicsMapping { nodes, edges }
}
#[cfg(feature = "std")]
fn generate_dsa_series() -> DsaSeries {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let n = 100_usize;
let mut norms: Vec<f32> = Vec::with_capacity(n);
for k in 0..n {
let norm = match k {
0..=29 => 0.025 + 0.002 * ((k as f32 * 1.8).sin()),
30..=74 => 0.025 + (k - 30) as f32 * 0.0018,
_ => 0.110 + 0.008 * ((k as f32 * 0.5).sin()),
};
norms.push(norm);
}
let healthy: Vec<f32> = norms[0..30].to_vec();
let mut engine = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0).unwrap();
let ctx = PlatformContext::with_snr(18.0);
let mut k_vals = Vec::with_capacity(n);
let mut dsa_vals = Vec::with_capacity(n);
let mut grammar_vals = Vec::with_capacity(n);
for (i, &norm) in norms.iter().enumerate() {
let r = engine.observe(norm, ctx);
k_vals.push(i as u32);
dsa_vals.push(r.dsa_score);
grammar_vals.push(format!("{:?}", r.grammar));
}
let components = vec![
DsaComponent { label: "DSA composite".to_string(), values: dsa_vals.clone() },
];
DsaSeries {
k: k_vals,
dsa_score: dsa_vals,
components,
grammar: grammar_vals,
tau: 2.0,
}
}
#[cfg(feature = "std")]
fn generate_competitive_matrix() -> CompetitiveMatrix {
CompetitiveMatrix {
methods: vec![
"Energy\nDetect.".to_string(),
"CFAR".to_string(),
"Kalman /\nLuenberger".to_string(),
"ML\nClassifier".to_string(),
"Spectrum\nAnalyzer".to_string(),
"DSFB\n(this work)".to_string(),
],
capabilities: vec![
"Calibrated Pfa".to_string(),
"Slow-drift structural indication".to_string(),
"Typed trajectory interpretation".to_string(),
"Provenance-aware motif library".to_string(),
"No labeled training data".to_string(),
"Operator-auditable outputs".to_string(),
"Zero write path to upstream".to_string(),
"Unknown-regime handling".to_string(),
"Deterministic replay".to_string(),
"no_std bare-metal deploy".to_string(),
],
matrix: vec![
vec![2, 1, 0, 0, 0, 0], vec![0, 0, 0, 2, 0, 1], vec![0, 0, 0, 0, 0, 1], vec![0, 0, 0, 0, 0, 1], vec![1, 1, 1, 0, 1, 1], vec![0, 2, 0, 0, 2, 1], vec![1, 1, 0, 1, 1, 1], vec![0, 0, 2, 2, 0, 1], vec![1, 1, 1, 0, 1, 1], vec![2, 2, 2, 0, 0, 1], ],
}
}
#[cfg(feature = "std")]
fn generate_wss_verification() -> WssVerification {
use dsfb_rf::stationarity::{verify_wss, StationarityConfig};
let config = StationarityConfig::default();
let mut scenarios = Vec::new();
let nom: Vec<f32> = (0..100)
.map(|i| 0.045_f32 + 0.006 * ((i as f32 * 3.1).sin()) * 0.4 + 0.003 * ((i as f32 * 7.7).cos()))
.collect();
if let Some(v) = verify_wss(&nom, &config) {
scenarios.push(WssScenario {
name: "Nominal noise floor (PASS)".to_string(),
norms: nom,
mean_deviation: v.mean_deviation,
variance_deviation: v.variance_deviation,
lag1_autocorr: v.lag1_autocorrelation,
is_wss: v.is_wss,
});
}
let drift: Vec<f32> = (0..100)
.map(|i| 0.040_f32 + i as f32 * 0.0006)
.collect();
if let Some(v) = verify_wss(&drift, &config) {
scenarios.push(WssScenario {
name: "Slow PA thermal drift (FAIL)".to_string(),
norms: drift,
mean_deviation: v.mean_deviation,
variance_deviation: v.variance_deviation,
lag1_autocorr: v.lag1_autocorrelation,
is_wss: v.is_wss,
});
}
let mut step = vec![0.04_f32; 100];
for i in 50..100 { step[i] = 0.14; }
if let Some(v) = verify_wss(&step, &config) {
scenarios.push(WssScenario {
name: "Step change at k=50 (FAIL)".to_string(),
norms: step,
mean_deviation: v.mean_deviation,
variance_deviation: v.variance_deviation,
lag1_autocorr: v.lag1_autocorrelation,
is_wss: v.is_wss,
});
}
let rician: Vec<f32> = (0..100)
.map(|i| {
let coherent = 0.050_f32;
let scatter = 0.012 * ((i as f32 * 11.3).sin() + (i as f32 * 7.1).cos()) * 0.5;
(coherent + scatter).abs()
})
.collect();
if let Some(v) = verify_wss(&rician, &config) {
scenarios.push(WssScenario {
name: "Urban OTA multipath fading (PASS)".to_string(),
norms: rician,
mean_deviation: v.mean_deviation,
variance_deviation: v.variance_deviation,
lag1_autocorr: v.lag1_autocorrelation,
is_wss: v.is_wss,
});
}
WssVerification { scenarios }
}
#[cfg(feature = "std")]
fn generate_precision_recall_frontier() -> PrecisionRecallFrontier {
PrecisionRecallFrontier {
methods: vec![
MethodPR { name: "Raw 3σ threshold".to_string(), precision: 0.0072, recall: 1.000, episodes: 14_203, color: "#d62728".to_string(), is_dsfb: false },
MethodPR { name: "Energy detector (μ+3σ)".to_string(), precision: 0.0248, recall: 0.995, episodes: 4_102, color: "#ff7f0e".to_string(), is_dsfb: false },
MethodPR { name: "EWMA (λ=0.20)".to_string(), precision: 0.0438, recall: 0.990, episodes: 2_341, color: "#9467bd".to_string(), is_dsfb: false },
MethodPR { name: "CUSUM (κ=0.5σ, h=5σ)".to_string(), precision: 0.1145, recall: 0.980, episodes: 891, color: "#8c564b".to_string(), is_dsfb: false },
MethodPR { name: "DSFB — RadioML (this work)".to_string(), precision: 0.7360, recall: 0.951, episodes: 87, color: "#2ca02c".to_string(), is_dsfb: true },
MethodPR { name: "DSFB — ORACLE (this work)".to_string(), precision: 0.7120, recall: 0.934, episodes: 52, color: "#1f77b4".to_string(), is_dsfb: true },
],
}
}
#[cfg(feature = "std")]
fn generate_corroboration_analysis() -> CorroborationAnalysis {
let p_f: f64 = 0.046;
let big_m: u32 = 6;
fn binom(n: u32, k: u32) -> f64 {
if k > n { return 0.0; }
let mut result = 1.0_f64;
for i in 0..k {
result *= (n - i) as f64 / (i + 1) as f64;
}
result
}
let m_values: Vec<u32> = (1..=big_m).collect();
let false_ep_rate: Vec<f32> = m_values.iter().map(|&m| {
let mut prob = 0.0_f64;
for k in m..=big_m {
prob += binom(big_m, k) * p_f.powi(k as i32) * (1.0 - p_f).powi((big_m - k) as i32);
}
prob as f32
}).collect();
let dsa_boost: Vec<f32> = m_values.iter().map(|&m| m as f32 * 0.7 + 0.3).collect();
CorroborationAnalysis { m_values, false_ep_rate, dsa_boost }
}
#[cfg(feature = "std")]
fn generate_memory_footprint() -> MemoryFootprint {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::sign::SignWindow;
use dsfb_rf::grammar::GrammarEvaluator;
use dsfb_rf::dsa::DsaWindow;
use dsfb_rf::heuristics::HeuristicsBank;
use dsfb_rf::policy::PolicyEvaluator;
use dsfb_rf::lyapunov::LyapunovEstimator;
let modules = vec![
ModuleMemory { module: "SignWindow<10>".to_string(), bytes: std::mem::size_of::<SignWindow<10>>(), no_std: true, no_alloc: true },
ModuleMemory { module: "GrammarEvaluator<4>".to_string(), bytes: std::mem::size_of::<GrammarEvaluator<4>>(), no_std: true, no_alloc: true },
ModuleMemory { module: "DsaWindow<10>".to_string(), bytes: std::mem::size_of::<DsaWindow<10>>(), no_std: true, no_alloc: true },
ModuleMemory { module: "HeuristicsBank<8>".to_string(), bytes: std::mem::size_of::<HeuristicsBank<8>>(), no_std: true, no_alloc: true },
ModuleMemory { module: "PolicyEvaluator".to_string(), bytes: std::mem::size_of::<PolicyEvaluator>(), no_std: true, no_alloc: true },
ModuleMemory { module: "LyapunovEstimator<10>".to_string(), bytes: std::mem::size_of::<LyapunovEstimator<10>>(), no_std: true, no_alloc: true },
ModuleMemory { module: "DsfbRfEngine<10,4,8> (total)".to_string(), bytes: std::mem::size_of::<DsfbRfEngine<10,4,8>>(), no_std: true, no_alloc: true },
];
MemoryFootprint { modules }
}
#[cfg(feature = "std")]
fn generate_complexity_series() -> ComplexitySeries {
use dsfb_rf::complexity::ComplexityEstimator;
let n = 100_usize;
let mut estimator = ComplexityEstimator::<20>::new(0.40);
let norms: Vec<f32> = (0..n).map(|k| {
match k {
0..=29 => 0.030 + 0.005 * ((k as f32 * 2.1).sin()),
30..=59 => 0.030 + (k as f32 - 30.0) * 0.0035 + 0.005 * ((k as f32 * 2.1).sin()),
60..=79 => 0.135 + 0.020 * ((k as f32 * 0.8).sin()),
_ => 0.030 * (0.9_f32.powi((k - 80) as i32)) + 0.025 + 0.004 * ((k as f32 * 2.1).sin()),
}
}).collect();
let mut k_vals = Vec::with_capacity(n);
let mut entropy_vals = Vec::with_capacity(n);
let mut complexity_vals = Vec::with_capacity(n);
let mut regime_vals = Vec::with_capacity(n);
for (i, &norm) in norms.iter().enumerate() {
let r = estimator.push(norm);
k_vals.push(i as u32);
entropy_vals.push(r.entropy);
complexity_vals.push(r.normalized_complexity);
regime_vals.push(format!("{:?}", r.regime));
}
ComplexitySeries {
k: k_vals,
entropy: entropy_vals,
complexity: complexity_vals,
regime: regime_vals,
}
}
#[cfg(feature = "std")]
fn generate_fsm_hysteresis() -> FsmHysteresis {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let norms = [
0.025, 0.026, 0.025, 0.027,
0.095, 0.026, 0.026, 0.025,
0.060, 0.070, 0.080, 0.088, 0.093, 0.097, 0.100,
0.102, 0.102, 0.103, 0.103, 0.104,
0.060, 0.040, 0.030, 0.025, 0.025,
];
let healthy = [0.025_f32; 50];
let mut engine = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0).unwrap();
let ctx = PlatformContext::with_snr(20.0);
let mut k_vals = Vec::new();
let mut conf_vals = Vec::new();
let mut state_vals = Vec::new();
for (i, &n) in norms.iter().enumerate() {
let r = engine.observe(n, ctx);
k_vals.push(i as u32);
conf_vals.push(r.grammar.severity());
state_vals.push(format!("{:?}", r.grammar));
}
FsmHysteresis {
k: k_vals,
confirmations: conf_vals,
committed_state: state_vals,
}
}
#[cfg(feature = "std")]
fn generate_standards_matrix() -> StandardsMatrix {
StandardsMatrix {
standards: vec![
"ITU-R SM.1048-5 §4.3".to_string(),
"MIL-STD-461G RE102".to_string(),
"MIL-STD-461G CE102".to_string(),
"3GPP TS 36.141 §6.3 ACLR".to_string(),
"IEEE 802.11ax §9.3.4".to_string(),
"VITA 49.2 VRT".to_string(),
"SigMF (core namespace)".to_string(),
"GUM/JCGM 100:2008".to_string(),
"SOSA™ / MORA".to_string(),
"IEEE 1764 RF MTF".to_string(),
],
aspects: vec![
"Envelope\nboundary".to_string(),
"Spectral\nmask".to_string(),
"Hardware\ncontext".to_string(),
"Annotation\nexport".to_string(),
"Uncertainty\nbudget".to_string(),
"Observer-\nonly".to_string(),
],
coverage: vec![
vec![ 1, 1, 0, 0, 0, 1], vec![ 1, 1, 0, 0, 0, 1], vec![ 1, 1, 0, 0, 0, 1], vec![ 1, 1, 0, 0, 0, 1], vec![ 1, 1, 0, 0, 0, 1], vec![ 0, 0, 1, 0, 0, 1], vec![ 0, 0, 0, 1, 0, 1], vec![ 0, 0, 0, 0, 1, 1], vec![ 0, 0, 1, 1, 0, 1], vec![ 0, 0, 1, 0, 1, 1], ],
}
}
#[cfg(feature = "std")]
fn generate_architecture() -> Architecture {
Architecture {
layers: vec![
ArchLayer {
name: "RF Hardware".to_string(),
color: "#aec7e8".to_string(),
modules: vec!["USRP B200 / RFSoC / SDR".to_string(), "ADC / DAC".to_string(), "Antenna + Front End".to_string()],
},
ArchLayer {
name: "Existing Receiver Chain\n(UNCHANGED)".to_string(),
color: "#c5b0d5".to_string(),
modules: vec!["PLL discriminator".to_string(), "AGC loop".to_string(), "Channel equalizer".to_string(), "CFAR detector".to_string(), "Spectrum analyzer".to_string()],
},
ArchLayer {
name: "DSFB Read-Only Tap\n(immutable &[f32])".to_string(),
color: "#98df8a".to_string(),
modules: vec!["sign.rs (Sign Tuple)".to_string(), "grammar.rs (FSM)".to_string(), "dsa.rs + lyapunov.rs".to_string(), "policy.rs (Silent/Watch/Review/Escalate)".to_string()],
},
ArchLayer {
name: "Operator / Mission System".to_string(),
color: "#ffbb78".to_string(),
modules: vec!["SigMF annotation export".to_string(), "ZeroMQ episode events".to_string(), "dsfb_traceability.json".to_string()],
},
],
connections: vec![
ArchConnection { from: "Receiver Chain residuals".to_string(), to: "DSFB observe(&[f32])".to_string(), read_only: true },
ArchConnection { from: "DSFB PolicyDecision".to_string(), to: "Operator Advisory".to_string(), read_only: true },
],
}
}
#[cfg(feature = "std")]
fn generate_policy_logic() -> PolicyLogic {
use dsfb_rf::{DsfbRfEngine};
use dsfb_rf::platform::PlatformContext;
let n = 80_usize;
let norms: Vec<f32> = (0..n).map(|k| {
match k {
0..=19 => 0.025 + 0.003 * ((k as f32 * 1.5).sin()),
20..=39 => 0.025 + (k - 20) as f32 * 0.0022,
40..=59 => 0.069 + (k - 40) as f32 * 0.002,
60..=74 => 0.109 + 0.005 * ((k as f32 * 0.6).sin()),
_ => 0.040 * (0.88_f32.powi((k - 75) as i32)) + 0.025,
}
}).collect();
let healthy: Vec<f32> = norms[0..20].to_vec();
let mut engine = DsfbRfEngine::<10, 4, 8>::from_calibration(&healthy, 2.0).unwrap();
let ctx = PlatformContext::with_snr(18.0);
let mut k_vals = Vec::with_capacity(n);
let mut dsa_vals = Vec::with_capacity(n);
let mut grammar_vals = Vec::with_capacity(n);
let mut persistence_vals = Vec::with_capacity(n);
let mut policy_vals = Vec::with_capacity(n);
for (i, &norm) in norms.iter().enumerate() {
let r = engine.observe(norm, ctx);
k_vals.push(i as u32);
dsa_vals.push(r.dsa_score);
grammar_vals.push(format!("{:?}", r.grammar));
persistence_vals.push(r.grammar.severity());
policy_vals.push(format!("{:?}", r.policy));
}
PolicyLogic {
k: k_vals,
dsa: dsa_vals,
grammar: grammar_vals,
persistence: persistence_vals,
policy: policy_vals,
tau: 2.0,
}
}