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}