Moved yew web project into another repo, removed sq_matrix module

This commit is contained in:
Egor 2024-05-26 22:57:00 +03:00
parent 8c1272fa9c
commit 65bb1f1823
17 changed files with 64 additions and 1439 deletions

1143
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,7 @@
[workspace]
resolver = "2"
members = [
"math", "web"
]
[package]
name = "mathematical"
version = "0.1.0"
edition = "2021"
[dependencies]
num = "0.4.3"

View file

@ -1,6 +0,0 @@
[build]
target = "web/index.html"
[serve]
address = "127.0.0.1"
port = 8080

View file

@ -1,7 +0,0 @@
[package]
name = "math"
version = "0.1.0"
edition = "2021"
[dependencies]
num = "0.4.3"

View file

@ -1,2 +0,0 @@
pub mod matrix;
pub mod sq_matrix;

View file

@ -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
View file

@ -0,0 +1 @@
pub mod matrix;

View file

@ -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);

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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>
}
}