Write vector multiplication

This commit is contained in:
Austen Adler 2021-06-02 18:50:06 -04:00
parent 0405d25998
commit e3b5457fe6
3 changed files with 52 additions and 7 deletions

View File

@ -5,7 +5,7 @@ pub mod types;
use crate::calc::entries::CalculatorEntry;
use confy::{load, store};
use entries::{Entry, Number, Vector};
use entries::{Entry, Number, Vector, VectorDirection};
use errors::{CalculatorError, CalculatorResult};
use operations::{
ArithmeticOperation, CalculatorOperation, CalculatorStateChange, MacroState, OpArgs,
@ -552,7 +552,7 @@ impl Calculator {
.unzip();
let entry = Entry::Vector(Vector {
values,
direction: true,
direction: VectorDirection::Row,
});
entries.push_front(count_entry);
Ok(CalculatorStateChange {

View File

@ -30,9 +30,31 @@ impl PartialEq for Number {
}
}
#[derive(PartialEq, Copy, Clone, Debug, Serialize, Deserialize)]
pub enum VectorDirection {
Row,
Column,
}
impl VectorDirection {
pub fn swap(&self) -> Self {
match self {
Self::Row => Self::Column,
Self::Column => Self::Row,
}
}
pub fn get_separator(&self) -> &str {
match self {
Self::Row => " ",
Self::Column => "; ",
}
}
}
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Vector {
pub direction: bool,
pub direction: VectorDirection,
pub values: Vec<Number>,
}
@ -41,7 +63,7 @@ pub struct Vector {
pub enum Entry {
Number(Number),
Vector(Vector),
// Matrix(Vec<Vec<Number>>),
// Matrix(Vec<Vector>),
}
// macro_rules! op_child_call {
@ -297,7 +319,7 @@ impl CalculatorEntry for Vector {
.iter()
.map(|number| number.format_entry(display_mode))
.collect::<Vec<String>>()
.join(if self.direction { "; " } else { " " })
.join(self.direction.get_separator())
)
}
// Mathematical operations
@ -316,7 +338,7 @@ impl CalculatorEntry for Vector {
fn inverse(&self) -> CalculatorResult<Entry> {
Ok(Entry::Vector(Vector {
values: self.values.clone(),
direction: !self.direction,
direction: self.direction.swap(),
}))
}
fn sin(&self, angle_mode: CalculatorAngleMode) -> CalculatorResult<Entry> {
@ -397,7 +419,27 @@ impl CalculatorEntry for Vector {
self.iterated_binary_vec(arg, Number::sub_num)
}
fn mul_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
self.iterated_binary_vec(arg, Number::mul_num)
if self.values.len() != arg.values.len() {
return Err(CalculatorError::DimensionMismatch);
}
match (self.direction, arg.direction) {
(VectorDirection::Row, VectorDirection::Column) => {
// Row by column -- will produce a scalar
self.values
.iter()
.zip(arg.values.iter())
.try_fold(Entry::Number(Number::ZERO), |acc, (n1, n2)| {
acc.add(&n1.mul_num(n2)?)
})
}
(VectorDirection::Column, VectorDirection::Row) => {
Err(CalculatorError::NotYetImplemented)
}
(VectorDirection::Row, VectorDirection::Row)
| (VectorDirection::Column, VectorDirection::Column) => {
Err(CalculatorError::DimensionMismatch)
}
}
}
fn div_vec(&self, arg: &Self) -> CalculatorResult<Entry> {
self.iterated_binary_vec(arg, Number::div_num)

View File

@ -15,6 +15,8 @@ pub enum CalculatorError {
TypeMismatch,
/// Dimensions must match
DimensionMismatch,
/// Plans are in place to implement, but we are not there yet
NotYetImplemented,
/// Thrown when an undo or redo cannot be performed
CorruptStateChange(String),
/// Cannot undo or redo
@ -50,6 +52,7 @@ impl fmt::Display for CalculatorError {
Self::NotEnoughStackEntries => write!(f, "Not enough items in the stack"),
Self::TypeMismatch => write!(f, "Type mismatch"),
Self::DimensionMismatch => write!(f, "Dimension mismatch"),
Self::NotYetImplemented => write!(f, "Not yet implemented"),
Self::CorruptStateChange(msg) => {
write!(f, "Corrupt state change: {}", msg)
}