Expand description
Pure-Rust relaxed vector fitting for rational approximation of frequency-domain data. Fits scalar, vector, and matrix-valued responses.
§API overview
Model— fitted rational approximation (poles, residues, evaluation)Options— solver configuration (pole count, convergence, weighting)CsvandTouchstone— parse sampled data from common file formatshz,rad,real,complex— axis wrappers for unit conversionShapeandLayout— describe the structure of flattened response data
§Examples
Fit sampled data from CSV:
use vecfit::{Csv, Options};
let csv = "freq_Hz,re_f1,im_f1\n1,0.95,-0.31\n5,0.35,-0.72\n10,0.10,-0.98\n50,0.02,-1.0\n100,0.01,-1.0\n";
let model = Csv::from_csv(csv)?.fit(Options::new().poles(2))?;
assert!(model.shape().is_scalar());Fit an analytic transfer function via closure:
use num_complex::Complex64;
use vecfit::{Options, Model, complex};
let s: Vec<Complex64> = (0..80)
.map(|k| Complex64::new(0.0, 1.0 + k as f64))
.collect();
let model = Model::fit(
complex(&s),
|s| 0.05 + 1.2 / (s + 3.0) + 0.4 / (s + 15.0),
Options::new().poles(4),
)?;
let fitted = model.eval_scalar(&s)?;
assert_eq!(fitted.len(), s.len());Multi-channel vector fit using the hz axis wrapper:
use vecfit::{Options, Model, hz};
let freq: Vec<f64> = (1..60).map(|k| k as f64).collect();
let model = Model::fit(
hz(&freq),
|f| {
let w = 2.0 * std::f64::consts::PI * f;
[1.0 / (1.0 + w), 0.6 / (3.0 + w), 0.3 / (9.0 + w)]
},
Options::new().poles(4),
)?;
assert_eq!(model.channels(), 3);JSON round-trip:
use num_complex::Complex64;
use vecfit::{Options, Model, complex};
let s: Vec<Complex64> = (0..48)
.map(|k| Complex64::new(0.0, 2.0 + k as f64))
.collect();
let model = Model::fit(
complex(&s),
|s| vec![1.0 / (s + 2.0), 0.5 / (s + 8.0)],
Options::new().poles(3),
)?;
let json = model.to_json()?;
let loaded = Model::from_json(&json)?;
assert_eq!(loaded.channels(), model.channels());Re-exports§
pub use crate::axis::AsComplexAxis;pub use crate::axis::Axis;pub use crate::axis::ComplexAxis;pub use crate::axis::Hz;pub use crate::axis::IntoAxis;pub use crate::axis::RadPerSec;pub use crate::axis::RealAxis;pub use crate::axis::c;pub use crate::axis::complex;pub use crate::axis::hz;pub use crate::axis::rad;pub use crate::axis::real;pub use crate::emt::ChannelStateSpace;pub use crate::emt::DiscreteChannelStateSpace;pub use crate::emt::DiscreteStateSpaceModel;pub use crate::emt::DiscretizationMethod;pub use crate::emt::RealSection;pub use crate::emt::RealSectionChannel;pub use crate::emt::RealSectionModel;pub use crate::emt::StateSpaceModel;pub use crate::error::Result;pub use crate::error::VecfitError;pub use crate::fit::AutoPoles;pub use crate::fit::Options;pub use crate::fit::ProblemRef;pub use crate::fit::Report;pub use crate::fit::SampleMatrix;pub use crate::fit::SampleMatrixRef;pub use crate::fit::SolverPolicy;pub use crate::fit::SolverUsed;pub use crate::fit::WeightStrategy;pub use crate::io::ComplexModelJson;pub use crate::io::Csv;pub use crate::io::ParsedSamples;pub use crate::io::RealKernelJsonModel;pub use crate::io::RealKernelPoleJson;pub use crate::model::ChannelErrors;pub use crate::model::Model;pub use crate::model::ModelParts;pub use crate::shape::FlatResponse;pub use crate::shape::IntoResponse;pub use crate::shape::Layout;pub use crate::shape::ResponseSample;pub use crate::shape::ResponseScalar;pub use crate::shape::Shape;pub use crate::touchstone::DataFormat;pub use crate::touchstone::FrequencyUnit;pub use crate::touchstone::ParameterType;pub use crate::touchstone::Touchstone;pub use crate::touchstone::TouchstoneOptions;