@@ -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) ]
511535mod 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]
0 commit comments