Skip to content

Commit f1ed32a

Browse files
committed
Improved docs.
1 parent a490245 commit f1ed32a

File tree

3 files changed

+18
-59
lines changed

3 files changed

+18
-59
lines changed

lax/src/eig.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ impl_eig_work_r!(f64, lapack_sys::dgeev_);
404404
///
405405
/// In the C-layout case, we need the conjugates of the left
406406
/// eigenvectors, so the signs should be reversed.
407-
fn reconstruct_eigenvectors<T: Scalar>(
407+
pub(crate) fn reconstruct_eigenvectors<T: Scalar>(
408408
take_hermite_conjugate: bool,
409409
eig_im: &[T],
410410
vr: &[T],

lax/src/eig_generalized.rs

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use std::mem::MaybeUninit;
1111

1212
use crate::{error::*, layout::MatrixLayout, *};
13+
use crate::eig::reconstruct_eigenvectors;
1314
use cauchy::*;
1415
use num_traits::{ToPrimitive, Zero};
1516

@@ -22,16 +23,17 @@ pub struct EigGeneralizedWork<T: Scalar> {
2223
/// Compute left eigenvectors or not
2324
pub jobvl: JobEv,
2425

25-
/// Eigenvalues
26+
/// Eigenvalues: alpha (numerators)
2627
pub alpha: Vec<MaybeUninit<T::Complex>>,
28+
/// Eigenvalues: beta (denominators)
2729
pub beta: Vec<MaybeUninit<T::Complex>>,
28-
/// Real part of eigenvalues used in real routines
30+
/// Real part of alpha (eigenvalue numerators) used in real routines
2931
pub alpha_re: Option<Vec<MaybeUninit<T::Real>>>,
30-
/// Imaginary part of eigenvalues used in real routines
32+
/// Imaginary part of alpha (eigenvalue numerators) used in real routines
3133
pub alpha_im: Option<Vec<MaybeUninit<T::Real>>>,
32-
/// Real part of eigenvalues used in real routines
34+
/// Real part of beta (eigenvalue denominators) used in real routines
3335
pub beta_re: Option<Vec<MaybeUninit<T::Real>>>,
34-
/// Imaginary part of eigenvalues used in real routines
36+
/// Imaginary part of beta (eigenvalue denominators) used in real routines
3537
pub beta_im: Option<Vec<MaybeUninit<T::Real>>>,
3638

3739
/// Left eigenvectors
@@ -397,8 +399,8 @@ macro_rules! impl_eig_generalized_work_r {
397399
.as_ref()
398400
.map(|e| unsafe { e.slice_assume_init_ref() })
399401
.unwrap();
400-
reconstruct_eigs(alpha_re, Some(alpha_im), &mut self.alpha);
401-
reconstruct_eigs(beta_re, None, &mut self.beta);
402+
reconstruct_eigs_optional_im(alpha_re, Some(alpha_im), &mut self.alpha);
403+
reconstruct_eigs_optional_im(beta_re, None, &mut self.beta);
402404

403405
if let Some(v) = self.vr_l.as_ref() {
404406
let v = unsafe { v.slice_assume_init_ref() };
@@ -466,8 +468,8 @@ macro_rules! impl_eig_generalized_work_r {
466468
impl_eig_generalized_work_r!(f32, c32, lapack_sys::sggev_);
467469
impl_eig_generalized_work_r!(f64, c64, lapack_sys::dggev_);
468470

469-
/// Create complex eigenvalues from real and imaginary parts.
470-
fn reconstruct_eigs<T: Scalar>(
471+
/// Create complex eigenvalues from real and optional imaginary parts.
472+
fn reconstruct_eigs_optional_im<T: Scalar>(
471473
re: &[T],
472474
im_opt: Option<&[T]>,
473475
eigs: &mut [MaybeUninit<T::Complex>],
@@ -486,52 +488,3 @@ fn reconstruct_eigs<T: Scalar>(
486488
}
487489
}
488490
}
489-
490-
/// Reconstruct eigenvectors into complex-array
491-
///
492-
/// From LAPACK API https://software.intel.com/en-us/node/469230
493-
///
494-
/// - If the j-th eigenvalue is real,
495-
/// - v(j) = VR(:,j), the j-th column of VR.
496-
///
497-
/// - If the j-th and (j+1)-st eigenvalues form a complex conjugate pair,
498-
/// - v(j) = VR(:,j) + i*VR(:,j+1)
499-
/// - v(j+1) = VR(:,j) - i*VR(:,j+1).
500-
///
501-
/// In the C-layout case, we need the conjugates of the left
502-
/// eigenvectors, so the signs should be reversed.
503-
fn reconstruct_eigenvectors<T: Scalar>(
504-
take_hermite_conjugate: bool,
505-
eig_im: &[T],
506-
vr: &[T],
507-
vc: &mut [MaybeUninit<T::Complex>],
508-
) {
509-
let n = eig_im.len();
510-
assert_eq!(vr.len(), n * n);
511-
assert_eq!(vc.len(), n * n);
512-
513-
let mut col = 0;
514-
while col < n {
515-
if eig_im[col].is_zero() {
516-
// The corresponding eigenvalue is real.
517-
for row in 0..n {
518-
let re = vr[row + col * n];
519-
vc[row + col * n].write(T::complex(re, T::zero()));
520-
}
521-
col += 1;
522-
} else {
523-
// This is a complex conjugate pair.
524-
assert!(col + 1 < n);
525-
for row in 0..n {
526-
let re = vr[row + col * n];
527-
let mut im = vr[row + (col + 1) * n];
528-
if take_hermite_conjugate {
529-
im = -im;
530-
}
531-
vc[row + col * n].write(T::complex(re, im));
532-
vc[row + (col + 1) * n].write(T::complex(re, -im));
533-
}
534-
col += 2;
535-
}
536-
}
537-
}

ndarray-linalg/src/eig.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ pub trait EigGeneralized {
119119
/// }
120120
/// }
121121
/// ```
122+
///
123+
/// # Arguments
124+
///
125+
/// * `thresh_opt` - An optional threshold for determining approximate zero |β| values when
126+
/// computing the eigenvalues as α/β. If `None`, no approximate comparisons to zero will be
127+
/// made.
122128
fn eig_generalized(
123129
&self,
124130
thresh_opt: Option<Self::Real>,

0 commit comments

Comments
 (0)