1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
//! An interface to the [Linear Algebra PACKage][1].
//!
//! [1]: http://en.wikipedia.org/wiki/LAPACK

extern crate libc;
extern crate liblapack_sys as raw;

use libc::{c_char, c_int};

#[derive(Clone, Copy)]
pub enum Jobu {
    A = b'A' as isize,
    S = b'S' as isize,
    O = b'O' as isize,
    N = b'N' as isize,
}

#[derive(Clone, Copy)]
pub enum Jobvt {
    A = b'A' as isize,
    S = b'S' as isize,
    O = b'O' as isize,
    N = b'N' as isize,
}

#[derive(Clone, Copy)]
pub enum Jobz {
    N = b'N' as isize,
    V = b'V' as isize,
}

#[derive(Clone, Copy)]
pub enum Uplo {
    U = b'U' as isize,
    L = b'L' as isize,
}

#[inline]
pub fn dsyev(jobz: Jobz, uplo: Uplo, n: usize, a: &mut [f64], lda: usize, w: &mut [f64],
             work: &mut [f64], lwork: usize, info: &mut isize) {

    unsafe {
        raw::dsyev_(&(jobz as c_char) as *const _ as *mut _,
                    &(uplo as c_char) as *const _ as *mut _,
                    &(n as c_int) as *const _ as *mut _,
                    a.as_mut_ptr(),
                    &(lda as c_int) as *const _ as *mut _,
                    w.as_mut_ptr(),
                    work.as_mut_ptr(),
                    &(lwork as c_int) as *const _ as *mut _,
                    info as *mut _ as *mut _);
    }
}

#[inline]
pub fn dgesvd(jobu: Jobu, jobvt: Jobvt, m: usize, n: usize, a: &mut [f64], lda: usize,
              s: &mut [f64], u: &mut [f64], ldu: usize, vt: &mut [f64], ldvt: usize,
              work: &mut [f64], lwork: usize, info: &mut isize) {

    unsafe {
        raw::dgesvd_(&(jobu as c_char) as *const _ as *mut _,
                     &(jobvt as c_char) as *const _ as *mut _,
                     &(m as c_int) as *const _ as *mut _,
                     &(n as c_int) as *const _ as *mut _,
                     a.as_mut_ptr(),
                     &(lda as c_int) as *const _ as *mut _,
                     s.as_mut_ptr(),
                     u.as_mut_ptr(),
                     &(ldu as c_int) as *const _ as *mut _,
                     vt.as_mut_ptr(),
                     &(ldvt as c_int) as *const _ as *mut _,
                     work.as_mut_ptr(),
                     &(lwork as c_int) as *const _ as *mut _,
                     info as *mut _ as *mut _);
    }
}

#[inline]
pub fn dgetrf(m: usize, n: usize, a: &mut [f64], lda: usize, ipiv: &mut [i32], info: &mut isize) {
    unsafe {
        raw::dgetrf_(&(m as c_int) as *const _ as *mut _,
                     &(n as c_int) as *const _ as *mut _,
                     a.as_mut_ptr(),
                     &(lda as c_int) as *const _ as *mut _,
                     ipiv.as_mut_ptr(),
                     info as *mut _ as *mut _);
    }
}

#[inline]
pub fn dgetri(n: usize, a: &mut [f64], lda: usize, ipiv: &mut [i32], work: &mut [f64],
              lwork: usize, info: &mut isize) {

    unsafe {
        raw::dgetri_(&(n as c_int) as *const _ as *mut _,
                     a.as_mut_ptr(),
                     &(lda as c_int) as *const _ as *mut _,
                     ipiv.as_mut_ptr(),
                     work.as_mut_ptr(),
                     &(lwork as c_int) as *const _ as *mut _,
                     info as *mut _ as *mut _);
    }
}