Skip to content

MatZ Mul, Cmp, Transpose#115

Merged
jnsiemer merged 16 commits intodevfrom
MatZ_cmp_transpose
Mar 29, 2023
Merged

MatZ Mul, Cmp, Transpose#115
jnsiemer merged 16 commits intodevfrom
MatZ_cmp_transpose

Conversation

@jnsiemer
Copy link
Member

@jnsiemer jnsiemer commented Mar 27, 2023

This PR implements

  • Compare
  • Tranpose
  • Multiplication
    including tests for MatZ.

@jnsiemer jnsiemer self-assigned this Mar 27, 2023
@jnsiemer jnsiemer changed the title MatZ Compare + Transpose MatZ Mul, Cmp, Transpose Mar 27, 2023
type Output = MatZ;

/// Implements the [`Mul`] trait for two [`MatZ`] values.
/// [`Mul`] is implemented for any combination of owned and borrowed [`MatZ`] and any kind of [`VecZ`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VecZ?

Suggested change
/// [`Mul`] is implemented for any combination of owned and borrowed [`MatZ`] and any kind of [`VecZ`].
/// [`Mul`] is implemented for any combination of owned and borrowed [`MatZ`].

Copy link
Member Author

@jnsiemer jnsiemer Mar 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc-comment is correct. It's about all the combinations of Multiplication of that type that are implemented.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change

@jnsiemer jnsiemer force-pushed the MatZ_cmp_transpose branch from a97d74a to 58631ab Compare March 27, 2023 16:12
@jnsiemer jnsiemer changed the title MatZ Mul, Cmp, Transpose VecZ + MatZ Mul, Cmp, Transpose Mar 27, 2023

use super::MatZ;
use std::str::FromStr;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the tests are all 2x2 matrices, please also add one for different sizes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now one 3x3 test was included

Comment on lines +23 to +45
/// Creates a new row-vector with `num_rows` rows and
/// zeros as entries.
///
/// Parameters:
/// - `num_rows`: number of columns the new vector should have
///
/// Returns a [`VecZ`] or an error, if the number of rows is
/// less or equal to `0`.
///
/// # Example
/// ```
/// use math::integer::VecZ;
/// use math::utils::VectorDirection;
///
/// let vector = VecZ::new(5, VectorDirection::ColumnVector).unwrap();
/// ```
///
/// # Errors and Failures
/// - Returns a [`MathError`] of type
/// [`InvalidMatrix`](MathError::InvalidMatrix)
/// if the number of rows is `0`.
/// - Returns a [`MathError`] of type [`OutOfBounds`](MathError::OutOfBounds)
/// if the number of rows is negative or it does not fit into an [`i64`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not fit to definition with vector direction

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now updated

Comment on lines +64 to +66
/// Creates a [`VecZ`] row-vector with entries in [`Z`] from a [`String`].
/// The format of that string looks like this `[1,2,3]` for a row vector
/// with three entries (`1` in the first row, `2` in the second one, ...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does not fit to direction

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now fits again

Comment on lines +131 to +132
assert_eq!(Z::from_i64(0), entry1);
assert_eq!(Z::from_i64(0), entry2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert_eq!(Z::from_i64(0), entry1);
assert_eq!(Z::from_i64(0), entry2);
assert_eq!(Z::ZERO entry1);
assert_eq!(Z::ZERO, entry2);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +131 to +132
assert_eq!(Z::from_i64(0), entry1);
assert_eq!(Z::from_i64(0), entry2);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though i prefer using the constant

Suggested change
assert_eq!(Z::from_i64(0), entry1);
assert_eq!(Z::from_i64(0), entry2);
assert_eq!(Z::from(0), entry1);
assert_eq!(Z::from(0), entry2);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to Z::ZERO

let cmp = VecZ::from_str("[[1],[2],[3]]").unwrap();

assert_eq!(cmp, vec.transpose());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also test with large entries and with negative entries and different sizes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

several kinds of entries (large, negative etc) are tested in MatZ::transpose, which this function uses. Different sized matrices were now added (4 and 5 entries) to the ones in MatZ:: transpose by these tests

Comment on lines +60 to +62
pub fn is_row_vector(&self) -> bool {
self.matrix.get_num_columns() > 1
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this be more intuitiv?:

Suggested change
pub fn is_row_vector(&self) -> bool {
self.matrix.get_num_columns() > 1
}
pub fn is_row_vector(&self) -> bool {
self.matrix.get_num_rows() == 1
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now done this way. get_direction changed appropriately

Comment on lines +64 to +66
/// Creates a [`VecZ`] row-vector with entries in [`Z`] from a [`String`].
/// The format of that string looks like this `[1,2,3]` for a row vector
/// with three entries (`1` in the first row, `2` in the second one, ...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format does not fit anymore

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should now fit, again

Comment on lines +95 to +113
let entries_string = parse_matrix_string(string)?;
let (num_rows, num_cols) = find_matrix_dimensions(&entries_string)?;
let mut vector: VecZ;
match (num_rows, num_cols) {
(1, _) => vector = VecZ::new(num_cols, VectorDirection::RowVector)?,
(_, 1) => vector = VecZ::new(num_rows, VectorDirection::ColumnVector)?,
(_, _) => return Err(MathError::InvalidStringToVectorInput(String::from(
"The string either contained more than one column or row, or did have zero entries",
))),
}

// fill entries of matrix according to entries in string_matrix
for (row_num, row) in entries_string.iter().enumerate() {
for (col_num, entry) in row.iter().enumerate() {
let z_entry = Z::from_str(entry)?;
vector.matrix.set_entry(row_num, col_num, z_entry)?;
}
}
Ok(vector)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, what I would prefer:

Suggested change
let entries_string = parse_matrix_string(string)?;
let (num_rows, num_cols) = find_matrix_dimensions(&entries_string)?;
let mut vector: VecZ;
match (num_rows, num_cols) {
(1, _) => vector = VecZ::new(num_cols, VectorDirection::RowVector)?,
(_, 1) => vector = VecZ::new(num_rows, VectorDirection::ColumnVector)?,
(_, _) => return Err(MathError::InvalidStringToVectorInput(String::from(
"The string either contained more than one column or row, or did have zero entries",
))),
}
// fill entries of matrix according to entries in string_matrix
for (row_num, row) in entries_string.iter().enumerate() {
for (col_num, entry) in row.iter().enumerate() {
let z_entry = Z::from_str(entry)?;
vector.matrix.set_entry(row_num, col_num, z_entry)?;
}
}
Ok(vector)
let matrix = MatZ::from_str(str)?;
match (matrix.get_num_rows(), matrix.get_num_cols()) {
(a,b) if a ==1 || b== 1 => Ok(VecZ{matrix})}
_ => Err(MathError::InvalidStringToVectorInput(String::from(
"The string either contained more than one column or row, or did have zero entries",
))),
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in slightly different way

/// # Examples
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct VecZ {
pub(crate) matrix: MatZ,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matrix might be misleading

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to vector

@@ -1,4 +1,4 @@
// Copyright © 2023 Marcel Luca Schmidt
// Copyright © 2023 Marcel Luca Schmidt, Niklas Siemer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Copyright © 2023 Marcel Luca Schmidt, Niklas Siemer
// Copyright © 2023 Marcel Luca Schmidt

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// assert_eq!(mat.transpose(), cmp);
/// ```
pub fn transpose(&self) -> Self {
let mut out = Self::new(self.get_num_columns(), self.get_num_rows()).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better use "expect" with a simple message that the number of rows or columns was saved wrongly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we know that this can not fail, it's ok to use unwrap

/// [`InvalidMatrix`](MathError::InvalidMatrix)
/// if the number of rows is `0`.
/// - Returns a [`MathError`] of type [`OutOfBounds`](MathError::OutOfBounds)
/// if the number of rows is negative or it does not fit into an [`i64`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// if the number of rows is negative or it does not fit into an [`i64`].
/// if the number of rows/columns is negative or it does not fit into an [`i64`].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added at several points

/// # Errors and Failures
/// - Returns a [`MathError`] of type
/// [`InvalidMatrix`](MathError::InvalidMatrix)
/// if the number of rows is `0`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// if the number of rows is `0`.
/// if the number of rows/columns is `0`.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +64 to +66
/// Creates a [`VecZ`] row-vector with entries in [`Z`] from a [`String`].
/// The format of that string looks like this `[1,2,3]` for a row vector
/// with three entries (`1` in the first row, `2` in the second one, ...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Creates a [`VecZ`] row-vector with entries in [`Z`] from a [`String`].
/// The format of that string looks like this `[1,2,3]` for a row vector
/// with three entries (`1` in the first row, `2` in the second one, ...)
/// Creates a [`VecZ`] vector with entries in [`Z`] from a [`String`].
/// The format of that string looks like this `[[1,2,3]]` for a row vector
/// with three entries (`1` in the first row, `2` in the second one, ...)
/// and like this `[[1],[2],[3]]` for a column vector with the same entries.
/// A string containing a single value (`[[1]]`) is always a row vector.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, but left out the comment about a 1x1 string as this is the wrong place to put it.

/// assert!(row.is_row_vector());
/// ```
pub fn is_row_vector(&self) -> bool {
self.matrix.get_num_columns() > 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.matrix.get_num_columns() > 1
self.matrix.get_num_rows() == 1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, now it's done like this and commented accordingly

/// assert!(col.is_column_vector());
/// ```
pub fn is_column_vector(&self) -> bool {
self.matrix.get_num_rows() > 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.matrix.get_num_rows() > 1
self.matrix.get_num_rows() != 1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a nice solution, the one above is way more appropriate

self.matrix.get_num_columns() > 1
}

/// Returns `true` if the vector is a column vector with more than one row.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns `true` if the vector is a column vector with more than one row.
/// Returns `true` if the vector is a column vector.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed according to new implementation

Comment on lines +79 to +80
/// Returns [`VectorDirection::ColumnVector`] if the vector is a column vector with more than one row.
/// Otherwise, returns [`VectorDirection::RowVector`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns [`VectorDirection::ColumnVector`] if the vector is a column vector with more than one row.
/// Otherwise, returns [`VectorDirection::RowVector`].
/// Returns [`VectorDirection::ColumnVector`] if the vector is a column vector.
/// Otherwise, returns [`VectorDirection::RowVector`].

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed up completely

Comment on lines +35 to +38
pub fn set_entry<S: TryInto<i64> + Display + Copy, T: Into<Z>>(
&mut self,
entry: S,
value: T,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use updated version with impl instead of S and T

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I'm not able to use the trait and this is the way it is done in MatZ, I do not see what to do differently here. But I also opened an issue for the set_entry and get_entry trait for Vectors.

@jnsiemer jnsiemer reopened this Mar 29, 2023
@jnsiemer jnsiemer changed the title VecZ + MatZ Mul, Cmp, Transpose MatZ Mul, Cmp, Transpose Mar 29, 2023
type Output = MatZ;

/// Implements the [`Mul`] trait for two [`MatZ`] values.
/// [`Mul`] is implemented for any combination of owned and borrowed [`MatZ`] and any kind of [`VecZ`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change

@jnsiemer jnsiemer merged commit 1569864 into dev Mar 29, 2023
@jnsiemer jnsiemer deleted the MatZ_cmp_transpose branch March 29, 2023 11:41
3pmile pushed a commit that referenced this pull request Apr 2, 2023
* Add macros for cross type arithmetics

* Implement multiplication for MatZ

* Implement PartialEq for MatZ

* Implement transpose for MatZ

* Add VecZ

* Implement MatZ * VecZ + tests

* Add instantiation methods for VecZ

* Add getter and transpose to VecZ

* Implement multiplication for VecZ in combination with MatZ

* Apply requested PR changes and add from_str tests for VecZ

* Apply rustfmt + add import of GetEntry for VecZ

* Make vector viable as Column and RowVector

* Apply requested PR changes to VecZ

* Remove vectors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants