Added append_row, append_column, append_row_zeroes and append_column_zeroes methods to math::matrix::Matrix + some tests
Minor index.scss styles changes Added prototype implementation for MatrixComponent in web crate
This commit is contained in:
parent
199805aafc
commit
e4e17953e2
4 changed files with 186 additions and 2 deletions
|
@ -36,6 +36,14 @@ impl<T: Num + Clone> Matrix<T> {
|
|||
pub fn column(&self, j: usize) -> Vec<T> {
|
||||
self.iter_column(j).cloned().collect()
|
||||
}
|
||||
|
||||
pub fn append_row_zeroes(&mut self) {
|
||||
self.append_row(vec![T::zero(); self.width])
|
||||
}
|
||||
|
||||
pub fn append_column_zeroes(&mut self) {
|
||||
self.append_column(vec![T::zero(); self.height()])
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num> Matrix<T> {
|
||||
|
@ -75,6 +83,25 @@ impl<T: Num> Matrix<T> {
|
|||
pub fn can_mul(&self, other: &Self) -> bool {
|
||||
self.width == other.height()
|
||||
}
|
||||
|
||||
pub fn append_row(&mut self, mut row: Vec<T>) {
|
||||
if row.len() != self.width {
|
||||
panic!("Unable to append row with len {} to matrix with width {}", row.len(), self.width);
|
||||
}
|
||||
self.data.append(&mut row);
|
||||
}
|
||||
|
||||
pub fn append_column(&mut self, column: Vec<T>) {
|
||||
let height = self.height();
|
||||
if column.len() != height {
|
||||
panic!("Unable to append row with len {} to matrix with width {}", column.len(), height);
|
||||
}
|
||||
for (i, e) in column.into_iter().enumerate() {
|
||||
let insert_at = (i + 1) * self.width + i;
|
||||
self.data.insert(insert_at, e);
|
||||
}
|
||||
self.width += 1;
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num> Index<usize> for Matrix<T> {
|
||||
|
@ -175,4 +202,62 @@ mod tests {
|
|||
assert_eq!(matrix.column(1), vec![2, 5, 8]);
|
||||
assert_eq!(matrix.column(2), vec![3, 6, 9]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_row_and_column() {
|
||||
let mut matrix = matrix![2;
|
||||
1, 2,
|
||||
3, 4
|
||||
];
|
||||
matrix.append_row(vec![5, 6]);
|
||||
assert_eq!(matrix, matrix![2;
|
||||
1, 2,
|
||||
3, 4,
|
||||
5, 6
|
||||
]);
|
||||
matrix.append_column(vec![7, 8, 9]);
|
||||
assert_eq!(matrix, matrix![3;
|
||||
1, 2, 7,
|
||||
3, 4, 8,
|
||||
5, 6, 9
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn append_row_and_column_zeroes() {
|
||||
let mut matrix = matrix![2;
|
||||
1, 2,
|
||||
3, 4
|
||||
];
|
||||
matrix.append_row_zeroes();
|
||||
assert_eq!(matrix, matrix![2;
|
||||
1, 2,
|
||||
3, 4,
|
||||
0, 0
|
||||
]);
|
||||
matrix.append_column_zeroes();
|
||||
assert_eq!(matrix, matrix![3;
|
||||
1, 2, 0,
|
||||
3, 4, 0,
|
||||
0, 0, 0
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Unable to append")]
|
||||
fn append_row_wrong_width() {
|
||||
matrix![2;
|
||||
1, 2,
|
||||
3, 4
|
||||
].append_row(vec![1, 2, 3]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Unable to append")]
|
||||
fn append_column_wrong_height() {
|
||||
matrix![2;
|
||||
1, 2,
|
||||
3, 4
|
||||
].append_column(vec![1, 2, 3]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mathematical</title>
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
$bg-color: #2b2927;
|
||||
$text-color: #e2e19c;
|
||||
$cell-color: #473b34;
|
||||
|
||||
html, body {
|
||||
background-color: $bg-color;
|
||||
color: $text-color;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.matrix-cell {
|
||||
background-color: $cell-color;
|
||||
color: $text-color;
|
||||
border: solid 1px black;
|
||||
width: 30pt;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,95 @@
|
|||
use math::matrix::Matrix;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct MatrixComponent {
|
||||
matrix: Matrix<f64>
|
||||
}
|
||||
|
||||
pub enum MatrixMsg {
|
||||
CellChange(Cell),
|
||||
AddRow,
|
||||
AddColumn
|
||||
}
|
||||
|
||||
impl Component for MatrixComponent {
|
||||
type Message = MatrixMsg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(_ctx: &Context<Self>) -> Self {
|
||||
Self { matrix: Matrix::new_zeroes(3, 3) }
|
||||
}
|
||||
|
||||
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool {
|
||||
match msg {
|
||||
MatrixMsg::CellChange(cell) => self.matrix[cell.i][cell.j] = cell.value,
|
||||
MatrixMsg::AddRow => self.matrix.append_row_zeroes(),
|
||||
MatrixMsg::AddColumn => self.matrix.append_column_zeroes()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
let on_cell_change = ctx.link().callback(MatrixMsg::CellChange);
|
||||
html! {
|
||||
<table> {
|
||||
self.matrix.iter_rows().enumerate().map(|(i, row)| html! {
|
||||
<tr> {
|
||||
row.iter().enumerate().map(|(j, e)| {
|
||||
let cell = Cell { i, j, value: *e };
|
||||
html! {
|
||||
<td>
|
||||
<MatrixCellComponent cell={cell} on_cell_change={on_cell_change.clone()} />
|
||||
</td>
|
||||
}
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</tr>
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</table>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MatrixCellComponent;
|
||||
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct MatrixCellProps {
|
||||
pub cell: Cell,
|
||||
pub on_cell_change: Callback<Cell>
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
pub struct Cell {
|
||||
i: usize, j: usize, value: f64
|
||||
}
|
||||
|
||||
impl Component for MatrixCellComponent {
|
||||
type Message = ();
|
||||
type Properties = MatrixCellProps;
|
||||
|
||||
fn create(_ctx: &Context<Self>) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
let cell = ctx.props().cell.clone();
|
||||
let oninput = ctx.props().on_cell_change
|
||||
.reform(move |e: InputEvent|
|
||||
Cell { i: cell.i, j: cell.j, value: e.as_f64().unwrap_or_default() }
|
||||
);
|
||||
html! {
|
||||
<input class="matrix-cell" type="text" {oninput}/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<p>{"Hello World!"}</p>
|
||||
<>
|
||||
<MatrixComponent />
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue