Moved yew web project into another repo, removed sq_matrix module
This commit is contained in:
parent
8c1272fa9c
commit
65bb1f1823
17 changed files with 64 additions and 1439 deletions
1143
Cargo.lock
generated
1143
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
12
Cargo.toml
12
Cargo.toml
|
@ -1,5 +1,7 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"math", "web"
|
||||
]
|
||||
[package]
|
||||
name = "mathematical"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.3"
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[build]
|
||||
target = "web/index.html"
|
||||
|
||||
[serve]
|
||||
address = "127.0.0.1"
|
||||
port = 8080
|
|
@ -1,7 +0,0 @@
|
|||
[package]
|
||||
name = "math"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.3"
|
|
@ -1,2 +0,0 @@
|
|||
pub mod matrix;
|
||||
pub mod sq_matrix;
|
|
@ -1,48 +0,0 @@
|
|||
use num::Num;
|
||||
use super::matrix::Matrix;
|
||||
|
||||
pub struct SquareMatrix<T: Num> {
|
||||
matrix: Matrix<T>
|
||||
}
|
||||
|
||||
impl<T: Num> SquareMatrix<T> {
|
||||
pub fn order(&self) -> usize {
|
||||
self.matrix.width()
|
||||
}
|
||||
|
||||
pub fn new(mut data: Vec<T>, order: usize) -> Self {
|
||||
let size = check_size(order);
|
||||
data.truncate(size);
|
||||
Self {
|
||||
matrix: Matrix::new_unchecked(data, order)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> SquareMatrix<T> {
|
||||
pub fn new_filled(val: T, order: usize) -> Self {
|
||||
let size = check_size(order);
|
||||
let data = vec![val; size];
|
||||
Self {
|
||||
matrix: Matrix::new_unchecked(data, order)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_size(order: usize) -> usize {
|
||||
if order < 2 {
|
||||
panic!("Square matrix must have at least order of 2, but got {}", order)
|
||||
}
|
||||
let Some(size) = order.checked_mul(order)
|
||||
else {
|
||||
panic!("Total matrix size for order {} exceeds usize limit", order)
|
||||
};
|
||||
return size;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! sq_matrix {
|
||||
[ $o:expr; $( $x:expr ),+ ] => {
|
||||
$crate::matrix::SquareMatrix::new(vec![$( $x, )+], $o)
|
||||
};
|
||||
}
|
1
src/lib.rs
Normal file
1
src/lib.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod matrix;
|
|
@ -1,6 +1,6 @@
|
|||
mod iter;
|
||||
mod arithemtic;
|
||||
mod ops;
|
||||
mod arithemtic;
|
||||
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
|
@ -12,7 +12,7 @@ pub struct Matrix<T: Num> {
|
|||
data: Box<Vec<T>>
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Matrix<T> {
|
||||
impl<T: Num + Clone> Matrix<T> {
|
||||
pub fn new_filled(val: T, width: usize, height: usize) -> Self {
|
||||
let Some(size) = width.checked_mul(height)
|
||||
else {
|
||||
|
@ -34,7 +34,7 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
}
|
||||
|
||||
pub fn column(&self, j: usize) -> Vec<T> {
|
||||
self.iter_column(j).copied().collect()
|
||||
self.iter_column(j).cloned().collect()
|
||||
}
|
||||
|
||||
pub fn append_row_zeroes(&mut self) {
|
||||
|
@ -44,19 +44,6 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
pub fn append_column_zeroes(&mut self) {
|
||||
self.append_column(vec![T::zero(); self.height()])
|
||||
}
|
||||
|
||||
pub fn remove_row(&mut self, i: usize) {
|
||||
if self.height() <= 2 {
|
||||
panic!("Unable to remove row of a matrix with height {}", self.height());
|
||||
}
|
||||
let row_start = i * self.width;
|
||||
self.data.copy_within(row_start+self.width.., row_start);
|
||||
self.data.truncate(self.data.len() - self.width);
|
||||
}
|
||||
|
||||
pub fn remove_last_row(&mut self) {
|
||||
self.remove_row(self.height() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num> Matrix<T> {
|
||||
|
@ -73,10 +60,6 @@ impl<T: Num> Matrix<T> {
|
|||
Self { width, data: Box::new(data) }
|
||||
}
|
||||
|
||||
pub(super) fn new_unchecked(data: Vec<T>, width: usize) -> Self {
|
||||
Self { width, data: Box::new(data) }
|
||||
}
|
||||
|
||||
pub fn width(&self) -> usize {
|
||||
self.width
|
||||
}
|
||||
|
@ -116,6 +99,21 @@ impl<T: Num> Matrix<T> {
|
|||
self.width += 1;
|
||||
}
|
||||
|
||||
pub fn remove_row(&mut self, i: usize) {
|
||||
if self.height() <= 2 {
|
||||
panic!("Unable to remove row of a matrix with height {}", self.height());
|
||||
}
|
||||
let row_start = i * self.width;
|
||||
self.data.drain(row_start..row_start+self.width);
|
||||
}
|
||||
|
||||
pub fn remove_last_row(&mut self) {
|
||||
if self.height() <= 2 {
|
||||
panic!("Unable to remove row of a matrix with height {}", self.height());
|
||||
}
|
||||
self.data.truncate(self.data.len() - self.width);
|
||||
}
|
||||
|
||||
pub fn remove_column(&mut self, j: usize) {
|
||||
if self.width <= 2 {
|
||||
panic!("Unable to remove column of a matrix with height {}", self.width);
|
|
@ -4,7 +4,7 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi
|
|||
|
||||
use num::{traits::NumAssign, Num, Signed};
|
||||
|
||||
impl<T: Num + Copy> Matrix<T> {
|
||||
impl<T: Num + Clone> Matrix<T> {
|
||||
pub fn multiply(&self, rhs: &Self) -> Self {
|
||||
if !self.can_mul(&rhs) {
|
||||
panic!("Unable to multiply matrices with sizes {}x{} and {}x{}",
|
||||
|
@ -12,9 +12,9 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
}
|
||||
let mut new = Matrix::new_zeroes(rhs.width, self.height());
|
||||
for (i, j) in new.indices() {
|
||||
let new_elem = self.row(i).into_iter()
|
||||
.zip(rhs.column(j).into_iter())
|
||||
.map(|(e1, e2)| e1 * e2)
|
||||
let new_elem = self[i].iter()
|
||||
.zip(rhs.iter_column(j))
|
||||
.map(|(e1, e2)| e1.clone() * e2.clone())
|
||||
.reduce(|acc, e| acc + e);
|
||||
new[i][j] = new_elem.unwrap();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Add for Matrix<T> {
|
||||
impl<T: Num> Add for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
if !self.same_size(&rhs) {
|
||||
|
@ -38,7 +38,7 @@ impl<T: Num + Copy> Add for Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: NumAssign + Copy> AddAssign for Matrix<T> {
|
||||
impl<T: NumAssign> AddAssign for Matrix<T> {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
if !self.same_size(&rhs) {
|
||||
panic!("Unable to add matrices with different sizes {}x{} and {}x{}",
|
||||
|
@ -50,17 +50,18 @@ impl<T: NumAssign + Copy> AddAssign for Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Signed + Copy> Neg for Matrix<T> {
|
||||
impl<T: Num + Signed> Neg for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn neg(mut self) -> Self::Output {
|
||||
for e in self.iter_mut() {
|
||||
*e = -*e;
|
||||
}
|
||||
return self;
|
||||
fn neg(self) -> Self::Output {
|
||||
let width = self.width;
|
||||
let data = self.into_iter()
|
||||
.map(|e| -e)
|
||||
.collect();
|
||||
return Self { data: Box::new(data), width };
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Sub for Matrix<T> {
|
||||
impl<T: Num> Sub for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
if !self.same_size(&rhs) {
|
||||
|
@ -76,7 +77,7 @@ impl<T: Num + Copy> Sub for Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: NumAssign + Copy> SubAssign for Matrix<T> {
|
||||
impl<T: NumAssign> SubAssign for Matrix<T> {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
if !self.same_size(&rhs) {
|
||||
panic!("Unable to subtract matrices with different sizes {}x{} and {}x{}",
|
||||
|
@ -88,43 +89,45 @@ impl<T: NumAssign + Copy> SubAssign for Matrix<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Mul<T> for Matrix<T> {
|
||||
impl<T: Num + Clone> Mul<T> for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn mul(mut self, rhs: T) -> Self::Output {
|
||||
for e in self.iter_mut() {
|
||||
*e = *e * rhs;
|
||||
}
|
||||
return self;
|
||||
fn mul(self, rhs: T) -> Self::Output {
|
||||
let width = self.width;
|
||||
let data = self.into_iter()
|
||||
.map(|e| e * rhs.clone())
|
||||
.collect();
|
||||
return Self { data: Box::new(data), width };
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NumAssign + Copy> MulAssign<T> for Matrix<T> {
|
||||
impl<T: NumAssign + Clone> MulAssign<T> for Matrix<T> {
|
||||
fn mul_assign(&mut self, rhs: T) {
|
||||
for e in self.iter_mut() {
|
||||
*e *= rhs;
|
||||
*e *= rhs.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Div<T> for Matrix<T> {
|
||||
impl<T: Num + Clone> Div<T> for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn div(mut self, rhs: T) -> Self::Output {
|
||||
for e in self.iter_mut() {
|
||||
*e = *e / rhs;
|
||||
}
|
||||
return self;
|
||||
fn div(self, rhs: T) -> Self::Output {
|
||||
let width = self.width;
|
||||
let data = self.into_iter()
|
||||
.map(|e| e / rhs.clone())
|
||||
.collect();
|
||||
return Self { data: Box::new(data), width };
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NumAssign + Copy> DivAssign<T> for Matrix<T> {
|
||||
impl<T: NumAssign + Clone> DivAssign<T> for Matrix<T> {
|
||||
fn div_assign(&mut self, rhs: T) {
|
||||
for e in self.iter_mut() {
|
||||
*e /= rhs;
|
||||
*e /= rhs.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Copy> Mul for Matrix<T> {
|
||||
impl<T: Num + Clone> Mul for Matrix<T> {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
self.multiply(&rhs)
|
|
@ -2,7 +2,7 @@ use super::*;
|
|||
|
||||
use num::Num;
|
||||
|
||||
impl<T: Num + Copy> Matrix<T> {
|
||||
impl<T: Num + Clone> Matrix<T> {
|
||||
pub fn minor(&self, row_index: usize, column_index: usize) -> Self {
|
||||
if self.width < 2 {
|
||||
panic!("Matrix width must be greater than 1 to form its minor, but got {}", self.width)
|
||||
|
@ -18,7 +18,7 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
let mut minor_data = Box::new(Vec::with_capacity(minor_width * (height - 1)));
|
||||
for (i, j, e) in self.iter_indexed() {
|
||||
if i == row_index || j == column_index { continue; }
|
||||
minor_data.push(*e);
|
||||
minor_data.push(e.clone());
|
||||
}
|
||||
Self { width: minor_width, data: minor_data }
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ impl<T: Num + Copy> Matrix<T> {
|
|||
for j in 0..self.width {
|
||||
let mut row_start = 0usize;
|
||||
for _ in 0..height {
|
||||
transposed_data.push(self.data[row_start + j]);
|
||||
transposed_data.push(self.data[row_start + j].clone());
|
||||
row_start += self.width;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
[package]
|
||||
name = "web"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
math = { path = "../math" }
|
||||
log = "0.4.21"
|
||||
wasm-bindgen = "0.2.92"
|
||||
wasm-logger = "0.2.0"
|
||||
web-sys = "0.3.69"
|
||||
yew = { git = "https://github.com/yewstack/yew/", features = ["csr"] }
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
|
@ -1,11 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Mathematical</title>
|
||||
<link data-trunk rel="rust" />
|
||||
<link data-trunk rel="scss" href="index.scss" />
|
||||
<link data-trunk rel="icon" href="assets/favicon.ico" />
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
$bg-color: #2b2927;
|
||||
$text-color: #e2e19c;
|
||||
$cell-color: #473b34;
|
||||
|
||||
body {
|
||||
background-color: $bg-color;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.matrix {
|
||||
display: grid;
|
||||
gap: 50px;
|
||||
grid-template-columns: auto 100px;
|
||||
grid-template-rows: auto 100px;
|
||||
justify-content: start;
|
||||
|
||||
input {
|
||||
background-color: $cell-color;
|
||||
color: $text-color;
|
||||
border: solid 1px black;
|
||||
width: 30pt;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: $cell-color;
|
||||
color: $text-color;
|
||||
border: solid 1px black;
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
mod matrix;
|
||||
|
||||
use yew::prelude::*;
|
||||
use matrix::MatrixComponent;
|
||||
|
||||
#[function_component]
|
||||
fn App() -> Html {
|
||||
html! {
|
||||
<>
|
||||
<MatrixComponent />
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
wasm_logger::init(wasm_logger::Config::default());
|
||||
yew::Renderer::<App>::new().render();
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
use math::matrix::Matrix;
|
||||
use yew::prelude::*;
|
||||
use web_sys::HtmlInputElement;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
pub enum MatrixMsg {
|
||||
CellChange(Cell),
|
||||
AddRow,
|
||||
AddColumn,
|
||||
RemoveRow,
|
||||
RemoveColumn
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
pub struct Cell {
|
||||
i: usize, j: usize, value: i32
|
||||
}
|
||||
|
||||
pub struct MatrixComponent {
|
||||
matrix: Matrix<i32>
|
||||
}
|
||||
|
||||
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(),
|
||||
MatrixMsg::RemoveRow => {
|
||||
if self.matrix.height() > 2 {
|
||||
self.matrix.remove_last_row();
|
||||
}
|
||||
},
|
||||
MatrixMsg::RemoveColumn => {
|
||||
if self.matrix.width() > 2 {
|
||||
self.matrix.remove_last_column();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
let on_size_change = ctx.link().callback(|msg| msg);
|
||||
log::info!("{:?}", &self.matrix);
|
||||
html! {
|
||||
<div class={classes!("matrix")}>
|
||||
<table> {
|
||||
self.matrix.iter_rows().enumerate().map(|(i, row)| html! {
|
||||
<tr> {
|
||||
row.iter().enumerate().map(|(j, e)| {
|
||||
let oninput = ctx.link().callback(move |e: InputEvent| {
|
||||
let input = e.target().unwrap().unchecked_into::<HtmlInputElement>();
|
||||
let value = input.value().trim().parse::<i32>().unwrap_or_default();
|
||||
log::info!("{}", value);
|
||||
MatrixMsg::CellChange(Cell { i, j, value })
|
||||
});
|
||||
html! {
|
||||
<td>
|
||||
<input type="text" value={e.to_string()} {oninput}/>
|
||||
</td>
|
||||
}
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</tr>
|
||||
}).collect::<Html>()
|
||||
}
|
||||
</table>
|
||||
<MatrixSizeControls {on_size_change} />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct MatrixSizeControlsProps {
|
||||
on_size_change: Callback<MatrixMsg>
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn MatrixSizeControls(props: &MatrixSizeControlsProps) -> Html {
|
||||
let on_click_add_row = props.on_size_change.reform(|_| MatrixMsg::AddRow);
|
||||
let on_click_add_column = props.on_size_change.reform(|_| MatrixMsg::AddColumn);
|
||||
let on_click_remove_row = props.on_size_change.reform(|_|MatrixMsg::RemoveRow);
|
||||
let on_click_remove_column = props.on_size_change.reform(|_| MatrixMsg::RemoveColumn);
|
||||
html! {
|
||||
<div class={classes!("matrix-size-controls")}>
|
||||
<div>
|
||||
<button onclick={on_click_add_row}>{"Add row"}</button>
|
||||
<button onclick={on_click_remove_row}>{"Remove row"}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onclick={on_click_add_column}>{"Add column"}</button>
|
||||
<button onclick={on_click_remove_column}>{"Remove column"}</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue