From 52269d767ccd5b35e5f42586ac2862d42e192754 Mon Sep 17 00:00:00 2001 From: Mihai Date: Sun, 10 Nov 2024 16:31:15 +0200 Subject: [PATCH] Issue:Creating band matrices #1160, implemented initial version for from_bands method, but couldnt test it --- src/base/matrix.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/base/matrix.rs b/src/base/matrix.rs index 77f6c1c88..8d3c31708 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -13,6 +13,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "rkyv-serialize-no-std")] use super::rkyv_wrappers::CustomPhantom; +use super::Dynamic; #[cfg(feature = "rkyv-serialize")] use rkyv::bytecheck; #[cfg(feature = "rkyv-serialize-no-std")] @@ -2368,3 +2369,54 @@ impl super::alias::Matrix1 { scalar } } + +impl> Matrix { + /// Takes variant number of bands + /// The central band becomes the main diagonal + pub fn from_bands(args: &[&Vec]) -> Self + where + T: Zero + Clone, + DefaultAllocator: Allocator, + { + + // Consider the central band as the main diagonal + assert!( + args.len() % 2 == 1, + "Number of bands should be odd" + ); + + // Retrieves the index and the length of the longest band to calculate the size of the matrix + let (n, ind) = args.iter() + .enumerate() + .map(|(index, v)| (index, v.len())) + .max_by_key(|(_, len)| *len) + .unwrap_or((0, 0)); + + // The size is considered as the length of the longest band and the distance from the main diagonal + n = n + ind - args.len()/2; + + // Create a zeroed matrix with the specified generic size. + let mut mat = Matrix::::zeros_generic(R::from_usize(n), C::from_usize(n)); + + // Set the main diagonal band + for i in 0..args[args.len()/2].len()-1 { + unsafe {*mat.get_unchecked_mut((i, i)) = args[args.len()/2][i].clone(); } + } + + // set lower diagonal bands + for band in 0..args.len()/2 - 1 { + for i in 0..args[band].len() - 1 { + unsafe {*mat.get_unchecked_mut((i, 0)) = args[band][i].clone(); } + } + } + + // set upper diagonal bands + for band in args.len()/2 + 1..args.len()-1 { + for j in 0..args[band].len() - 1 { + unsafe {*mat.get_unchecked_mut((0, j)) = args[band][j].clone(); } + } + } + + mat + } +}