diff --git a/rust/.gitignore b/rust/.gitignore new file mode 100644 index 0000000..1de5659 --- /dev/null +++ b/rust/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 0000000..20af5cf --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "NeuralNetwork" +version = "0.1.0" diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 0000000..3489657 --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,2 @@ +pub mod matrix_layout; +pub mod matrix; \ No newline at end of file diff --git a/rust/src/main.rs b/rust/src/main.rs index e7a11a9..93c124a 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,3 +1,7 @@ +use NeuralNetwork::matrix; +use NeuralNetwork::matrix_layout::{ColumnMajor, RowMajor}; + fn main() { - println!("Hello, world!"); -} + let mtx = matrix::Matrix::::with_size(3, 4); + println!("{}", mtx); +} \ No newline at end of file diff --git a/rust/src/matrix.rs b/rust/src/matrix.rs new file mode 100644 index 0000000..43bb9d6 --- /dev/null +++ b/rust/src/matrix.rs @@ -0,0 +1,55 @@ +use core::fmt; +use crate::matrix_layout::{ RowMajor, MatrixLayout}; + +pub struct Matrix { + data: Vec, + row: usize, + col: usize, + _marker: std::marker::PhantomData, +} + +impl Matrix { + pub fn with_size(row: usize, col: usize) -> Self + where + T: Default + Clone, + { + Self { + data: vec![T::default(); row * col], + row, + col, + _marker: std::marker::PhantomData, + } + } + + pub fn get(&self, row: usize, col: usize) -> Option<&T> { + if row >= self.row || col >= self.col { return None; } + + let idx = L::get_index(row, col, self.row, self.col)?; + self.data.get(idx) + } + + pub fn get_row(&self, row: usize) -> Option> { + let (start, step) = L::row_stride(row, self.row, self.col)?; + Some(self.data.iter().skip(start).step_by(step).take(self.col)) + } + + pub fn get_column(&self, col: usize) -> Option> { + let (start, step) = L::col_stride(col, self.row, self.col)?; + Some(self.data.iter().skip(start).step_by(step).take(self.row)) + } +} + +impl std::fmt::Display for Matrix { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (0..self.row).for_each(|r| { + if let Some(row_iter) = self.get_row(r) { + row_iter.for_each(|c| { + _ = write!(f, "{}\t", c); + }); + } + _ = write!(f, "\n"); + }); + + Ok(()) + } +} \ No newline at end of file diff --git a/rust/src/matrix_layout.rs b/rust/src/matrix_layout.rs new file mode 100644 index 0000000..0678a2b --- /dev/null +++ b/rust/src/matrix_layout.rs @@ -0,0 +1,75 @@ +pub trait MatrixLayout { + /// row, colから一次元配列のindexを取得する + /// # 引数 + /// - `row`: 行番号 + /// - `col`: 列番号 + /// - `matrix_row`: 行数 + /// - `matrix_col`: 列数 + /// # 戻り値 + /// - 一次元配列のindex + fn get_index(row: usize, col: usize, matrix_row: usize, matrix_col: usize) -> Option; + + /// row, colから行・列のstrideを取得する + /// # 引数 + /// - `row`: 行番号 + /// - `matrix_row`: 行数 + /// - `matrix_col`: 列数 + /// # 戻り値 + /// - (開始位置, ステップ)のタプル + fn row_stride(row: usize, matrix_row: usize, matrix_col: usize) -> Option<(usize, usize)>; + + /// row, colから行・列のstrideを取得する + /// # 引数 + /// - `col`: 列番号 + /// - `matrix_row`: 行数 + /// - `matrix_col`: 列数 + /// # 戻り値 + /// - (開始位置, ステップ)のタプル + fn col_stride(col: usize, matrix_row: usize, matrix_col: usize) -> Option<(usize, usize)>; +} + +pub struct RowMajor; +impl MatrixLayout for RowMajor { + fn get_index(row: usize, col: usize, _m_row: usize, m_col: usize) -> Option { + if _m_row == 0 || m_col == 0 || row >= _m_row || col >= m_col { + return None; + } + + Some(row * m_col + col) + } + fn row_stride(row: usize, _m_row: usize, m_col: usize) -> Option<(usize, usize)> { + if _m_row == 0 || m_col == 0 || row >= _m_row { + return None; + } + + Some((row * m_col, 1)) + } + fn col_stride(col: usize, _m_row: usize, m_col: usize) -> Option<(usize, usize)> { + if _m_row == 0 || m_col == 0 || col >= m_col { + return None; + } + + Some((col, m_col)) + } +} +pub struct ColumnMajor; +impl MatrixLayout for ColumnMajor { + fn get_index(row: usize, col: usize, m_row: usize, _m_col: usize) -> Option { + if m_row == 0 || _m_col == 0 || row >= m_row || col >= _m_col { + return None; + } + Some(col * m_row + row) + } + fn row_stride(row: usize, m_row: usize, _m_col: usize) -> Option<(usize, usize)> { + if m_row == 0 || _m_col == 0 || row >= m_row { + return None; + } + Some((row, m_row)) + } + fn col_stride(col: usize, m_row: usize, _m_col: usize) -> Option<(usize, usize)> { + if m_row == 0 || _m_col == 0 || col >= _m_col { + return None; + } + Some((col * m_row, 1)) + } +} \ No newline at end of file