Skip to content

Commit 3aba580

Browse files
committed
fixed bugs when order of system is zero
1 parent b12d114 commit 3aba580

2 files changed

Lines changed: 56 additions & 9 deletions

File tree

src/analysis/system_properties.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ fn h2_norm<U: Time + 'static>(
5050
let m = b.ncols();
5151
let p = c.nrows();
5252

53+
assert!(m > 0);
54+
assert!(p > 0);
55+
56+
if n == 0 {
57+
let d_all_zero = d.iter().all(|&x| x == 0.0);
58+
if d_all_zero {
59+
return Ok(0.);
60+
}
61+
return Err("Order of system is zero and D matrix is not zero".into());
62+
}
63+
5364
let lda = a.nrows();
5465
let ldb = b.nrows();
5566
let ldc = c.nrows();
@@ -66,6 +77,7 @@ fn h2_norm<U: Time + 'static>(
6677
let mut iwarn = -1 as c_int;
6778
let mut info = -1 as c_int;
6879

80+
// println!("lda: {}", lda);
6981
let h2_norm = unsafe {
7082
ab13bd_(
7183
time_domain.as_ptr(),
@@ -122,6 +134,21 @@ fn hinf_norm<U: Time + 'static>(
122134
) -> Result<f64, String> {
123135
Ss::<U>::verify_dimensions(&a, &b, &c, &d).map_err(|e| e.to_string())?;
124136

137+
let n = a.nrows();
138+
let m = b.ncols();
139+
let p = c.nrows();
140+
141+
assert!(p > 0);
142+
assert!(m > 0);
143+
144+
if n == 0 {
145+
// The gain is constant and equal to D
146+
// H-inf norm is the largest singular value
147+
let singular_values = d.singular_values();
148+
let max_singular_value = singular_values.max();
149+
return Ok(max_singular_value);
150+
}
151+
125152
let time_domain = if std::any::TypeId::of::<U>()
126153
== std::any::TypeId::of::<Continuous>()
127154
{
@@ -137,10 +164,6 @@ fn hinf_norm<U: Time + 'static>(
137164
let equilibration = CString::new("S").unwrap(); // Perform scaling
138165
let d_is_nonzero = CString::new("D").unwrap();
139166

140-
let n = a.nrows();
141-
let m = b.ncols();
142-
let p = c.nrows();
143-
144167
let mut e = DMatrix::identity(n, n);
145168

146169
let mut f_peak = [0.0, 1.0]; // initial guess not active
@@ -446,6 +469,7 @@ impl<U: Time + 'static> Ss<U> {
446469
/// - `Ok(f64)`: The H2 norm of the system.
447470
/// - `Err(String)`: An error message if the computation fails.
448471
pub fn norm_h2(&self) -> Result<f64, String> {
472+
// println!("before h2: {}", self);
449473
h2_norm::<U>(
450474
self.a().clone(),
451475
self.b().clone(),
@@ -510,6 +534,7 @@ impl<U: Time + 'static> Ss<U> {
510534
#[cfg(test)]
511535
mod tests {
512536
use crate::{
537+
Continuous, Ss,
513538
systems::Tf,
514539
transformations::SsRealization::{ControllableCF, ObservableCF},
515540
};
@@ -546,6 +571,13 @@ mod tests {
546571
epsilon = 1e-2
547572
);
548573
}
574+
575+
let sys = Ss::<Continuous>::new_from_scalar(-2.0);
576+
assert_abs_diff_eq!(sys.norm_hinf().unwrap(), 2.0);
577+
578+
assert!(sys.norm_h2().is_err());
579+
let sys = Ss::<Continuous>::new_from_scalar(0.0);
580+
assert_eq!(sys.norm_h2().unwrap(), 0.0);
549581
}
550582

551583
#[test]

src/transformations.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,18 +155,24 @@ impl<U: Time + 'static> Tf<f64, U> {
155155
let (_, den_deg) = tf.degree_num_den();
156156
let nx = den_deg;
157157

158+
let mut d = DMatrix::zeros(1, 1);
159+
if !tf.is_strictly_proper() {
160+
assert!(tf.numerator().coeffs().len() > nx);
161+
d[(0, 0)] = tf.numerator().coeffs()[nx];
162+
}
163+
164+
if nx == 0 {
165+
assert_eq!(tf.relative_degree(), 0);
166+
return Ok(Ss::new_from_scalar(d[(0, 0)]));
167+
}
168+
158169
let mut a = DMatrix::zeros(nx, nx);
159170
a.view_mut((1, 0), (nx - 1, nx - 1))
160171
.copy_from(&DMatrix::identity(nx - 1, nx - 1));
161172
for row in 0..nx {
162173
a[(row, nx - 1)] = -tf.denominator().coeffs()[row];
163174
}
164175

165-
let mut d = DMatrix::zeros(1, 1);
166-
if !tf.is_strictly_proper() {
167-
assert!(tf.numerator().coeffs().len() > nx);
168-
d[(0, 0)] = tf.numerator().coeffs()[nx];
169-
}
170176

171177
let mut num_extended = tf.numerator().coeffs().to_vec();
172178
num_extended.resize(nx, 0.);
@@ -659,6 +665,15 @@ mod tests {
659665
assert_abs_diff_eq!(ss.d(), &d_ans);
660666

661667
assert_abs_diff_eq!(tf_ret.normalize(), tf.normalize());
668+
669+
let tf = Tf::<_, Continuous>::new_from_scalar(1.0);
670+
let ss = tf.to_ss().unwrap();
671+
assert_eq!(ss.order(), 0);
672+
assert_eq!(ss.d()[(0, 0)], 1.0);
673+
674+
assert_eq!(tf.is_strictly_proper(), false);
675+
assert_eq!(tf.is_proper(), true);
676+
662677
}
663678

664679
#[test]

0 commit comments

Comments
 (0)