| 475 | } |
| 476 | |
| 477 | fn mul_dgemv(&self, trans: bool, alpha: f64, x: &[f64], beta: f64, y: &[f64]) -> Vec<f64> { |
| 478 | |
| 479 | if !trans { |
| 480 | if self.cols() != x.len() || self.rows() != y.len() { |
| 481 | panic!("Invalid dimensions."); |
| 482 | } |
| 483 | } else { |
| 484 | if self.rows() != x.len() || self.cols() != y.len() { |
| 485 | panic!("Invalid dimensions."); |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | let transpose = if trans { Transpose::Trans } else { Transpose::NoTrans }; |
| 490 | // this will be modified by cblas_dgemv |
| 491 | let r = y.to_vec(); |
| 492 | |
| 493 | unsafe { |
| 494 | cblas_dgemv( |
| 495 | Order::RowMajor, |
| 496 | transpose, |
| 497 | self.rows() as c_int, |
| 498 | self.cols() as c_int, |
| 499 | alpha as c_double, |
| 500 | self.buf().as_ptr() as *const c_double, |
| 501 | self.cols() as c_int, |
| 502 | x.as_ptr() as *const c_double, |
| 503 | 1 as c_int, |
| 504 | beta as c_double, // beta |
| 505 | r.as_ptr() as *mut c_double, |
| 506 | 1 as c_int |
| 507 | ); |
| 508 | } |
| 509 | r |
| 510 | } |
| 511 | |
| 512 | /// Computes (alhpa * Xv) or (alpha * X^T * v) |
| 513 | fn mul_scalar_vec(&self, trans: bool, alpha: f64, x: &[f64]) -> Vec<f64> { |