qfall_math/integer/mat_z/vector/
is_vector.rs

1// Copyright © 2023 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module includes all functionality to check
10//! whether a matrix represents a vector, i.e. has only one row
11//! or one column.
12//! These methods should be used to ensure that vector functions
13//! can only be called on suitably formed vector/matrices.
14
15use super::super::MatZ;
16use crate::traits::MatrixDimensions;
17
18impl MatZ {
19    /// Returns `true` if the provided [`MatZ`] has only one row,
20    /// i.e. is a row vector. Otherwise, returns `false`.
21    ///
22    /// # Examples
23    /// ```
24    /// use qfall_math::integer::MatZ;
25    /// use std::str::FromStr;
26    ///
27    /// let vec = MatZ::from_str("[[1, 2, 3]]").unwrap();
28    ///
29    /// assert!(vec.is_row_vector());
30    /// assert!(!vec.transpose().is_row_vector());
31    /// ```
32    pub fn is_row_vector(&self) -> bool {
33        self.get_num_rows() == 1
34    }
35
36    /// Returns `true` if the provided [`MatZ`] has only one column,
37    /// i.e. is a column vector. Otherwise, returns `false`.
38    ///
39    /// # Examples
40    /// ```
41    /// use qfall_math::integer::MatZ;
42    /// use std::str::FromStr;
43    ///
44    /// let vec = MatZ::from_str("[[1],[2],[3]]").unwrap();
45    ///
46    /// assert!(vec.is_column_vector());
47    /// assert!(!vec.transpose().is_column_vector());
48    /// ```
49    pub fn is_column_vector(&self) -> bool {
50        self.get_num_columns() == 1
51    }
52
53    /// Returns `true` if the provided [`MatZ`] has only one column or one row,
54    /// i.e. is a vector. Otherwise, returns `false`.
55    ///
56    /// # Examples
57    /// ```
58    /// use qfall_math::integer::MatZ;
59    /// use std::str::FromStr;
60    ///
61    /// let vec = MatZ::from_str("[[1],[2],[3]]").unwrap();
62    ///
63    /// assert!(vec.is_vector());
64    /// assert!(vec.transpose().is_vector());
65    /// ```
66    pub fn is_vector(&self) -> bool {
67        self.is_column_vector() || self.is_row_vector()
68    }
69
70    /// Returns `true` if the provided [`MatZ`] has only one entry,
71    /// i.e. is a 1x1 matrix. Otherwise, returns `false`.
72    ///
73    /// # Examples
74    /// ```
75    /// use qfall_math::integer::MatZ;
76    /// use std::str::FromStr;
77    ///
78    /// let vec = MatZ::from_str("[[1]]").unwrap();
79    ///
80    /// assert!(vec.has_single_entry());
81    /// ```
82    pub fn has_single_entry(&self) -> bool {
83        self.is_column_vector() && self.is_row_vector()
84    }
85}
86
87#[cfg(test)]
88mod test_is_vector {
89    use super::*;
90    use std::str::FromStr;
91
92    /// Check whether matrices with `1` row or one column
93    /// get recognized as (row or column) vectors
94    #[test]
95    fn vectors_detected() {
96        let row = MatZ::from_str(&format!("[[1, {}]]", i64::MIN)).unwrap();
97        let col = MatZ::from_str(&format!("[[1],[2],[{}],[4]]", i64::MAX)).unwrap();
98
99        assert!(row.is_row_vector());
100        assert!(!row.is_column_vector());
101        assert!(row.is_vector());
102
103        assert!(!col.is_row_vector());
104        assert!(col.is_column_vector());
105        assert!(col.is_vector());
106    }
107
108    /// Check whether matrices with more than one row or column
109    /// don't get recognized as (row or column) vector
110    #[test]
111    fn non_vectors_detected() {
112        let mat_1 = MatZ::from_str(&format!("[[1, {}],[2, 3]]", i64::MIN)).unwrap();
113        let mat_2 = MatZ::from_str(&format!("[[1, {}, 3],[4, 5, 6]]", i64::MAX)).unwrap();
114        let mat_3 = MatZ::from_str(&format!("[[1, {}],[2, 3],[4, 5]]", i64::MIN)).unwrap();
115        let mat_4 = MatZ::from_str("[[1, 0],[2, 0],[4, 0]]").unwrap();
116        let mat_5 = MatZ::from_str("[[1, 2, 4],[0, 0, 0]]").unwrap();
117
118        assert!(!mat_1.is_column_vector());
119        assert!(!mat_1.is_row_vector());
120        assert!(!mat_1.is_vector());
121
122        assert!(!mat_2.is_column_vector());
123        assert!(!mat_2.is_row_vector());
124        assert!(!mat_2.is_vector());
125
126        assert!(!mat_3.is_column_vector());
127        assert!(!mat_3.is_row_vector());
128        assert!(!mat_3.is_vector());
129
130        assert!(!mat_4.is_column_vector());
131        assert!(!mat_4.is_row_vector());
132        assert!(!mat_4.is_vector());
133
134        assert!(!mat_5.is_column_vector());
135        assert!(!mat_5.is_row_vector());
136        assert!(!mat_5.is_vector());
137    }
138
139    /// Check whether matrices with only one entry get recognized as single entry matrices
140    #[test]
141    fn single_entry_detected() {
142        let small = MatZ::from_str("[[1]]").unwrap();
143        let large = MatZ::from_str(&format!("[[{}]]", i64::MIN)).unwrap();
144
145        // check whether single entry is correctly detected
146        assert!(small.has_single_entry());
147        assert!(large.has_single_entry());
148
149        // check whether single entry is correctly detected as row and column vector
150        assert!(small.is_row_vector());
151        assert!(small.is_column_vector());
152        assert!(small.is_vector());
153
154        assert!(large.is_row_vector());
155        assert!(large.is_column_vector());
156        assert!(large.is_vector());
157    }
158
159    /// Check whether matrices with more than one entry
160    /// don't get recognized as single entry matrices
161    #[test]
162    fn non_single_entry_detected() {
163        let row = MatZ::from_str(&format!("[[1, {}]]", i64::MIN)).unwrap();
164        let col = MatZ::from_str(&format!("[[1],[{}],[3]]", i64::MIN)).unwrap();
165        let mat = MatZ::from_str("[[1, 2],[3, 4],[5, 6]]").unwrap();
166
167        assert!(!row.has_single_entry());
168        assert!(!col.has_single_entry());
169        assert!(!mat.has_single_entry());
170    }
171}