qfall_math/rational/mat_q/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::MatQ;
16use crate::traits::MatrixDimensions;
17
18impl MatQ {
19 /// Returns `true` if the provided [`MatQ`] has only one row,
20 /// i.e. is a row vector. Otherwise, returns `false`.
21 ///
22 /// # Examples
23 /// ```
24 /// use qfall_math::rational::MatQ;
25 /// use std::str::FromStr;
26 ///
27 /// let row_vec = MatQ::from_str("[[1, 2, 3/2]]").unwrap();
28 /// let col_vec = MatQ::from_str("[[1/4],[2],[3]]").unwrap();
29 ///
30 /// assert!(row_vec.is_row_vector());
31 /// assert!(!col_vec.is_row_vector());
32 /// ```
33 pub fn is_row_vector(&self) -> bool {
34 self.get_num_rows() == 1
35 }
36
37 /// Returns `true` if the provided [`MatQ`] has only one column,
38 /// i.e. is a column vector. Otherwise, returns `false`.
39 ///
40 /// # Examples
41 /// ```
42 /// use qfall_math::rational::MatQ;
43 /// use std::str::FromStr;
44 ///
45 /// let row_vec = MatQ::from_str("[[1/1, 2, 3]]").unwrap();
46 /// let col_vec = MatQ::from_str("[[1],[2/3],[3]]").unwrap();
47 ///
48 /// assert!(col_vec.is_column_vector());
49 /// assert!(!row_vec.is_column_vector());
50 /// ```
51 pub fn is_column_vector(&self) -> bool {
52 self.get_num_columns() == 1
53 }
54
55 /// Returns `true` if the provided [`MatQ`] has only one column or one row,
56 /// i.e. is a vector. Otherwise, returns `false`.
57 ///
58 /// # Examples
59 /// ```
60 /// use qfall_math::rational::MatQ;
61 /// use std::str::FromStr;
62 ///
63 /// let row_vec = MatQ::from_str("[[1, 2/2, 3/1]]").unwrap();
64 /// let col_vec = MatQ::from_str("[[1],[2],[3/2]]").unwrap();
65 ///
66 /// assert!(row_vec.is_vector());
67 /// assert!(col_vec.is_vector());
68 /// ```
69 pub fn is_vector(&self) -> bool {
70 self.is_column_vector() || self.is_row_vector()
71 }
72
73 /// Returns `true` if the provided [`MatQ`] has only one entry,
74 /// i.e. is a 1x1 matrix. Otherwise, returns `false`.
75 ///
76 /// # Examples
77 /// ```
78 /// use qfall_math::rational::MatQ;
79 /// use std::str::FromStr;
80 ///
81 /// let vec = MatQ::from_str("[[1/2]]").unwrap();
82 ///
83 /// assert!(vec.has_single_entry());
84 /// ```
85 pub fn has_single_entry(&self) -> bool {
86 self.is_column_vector() && self.is_row_vector()
87 }
88}
89
90#[cfg(test)]
91mod test_is_vector {
92 use super::*;
93 use std::str::FromStr;
94
95 /// Check whether matrices with `1` row or one column
96 /// get recognized as (row or column) vectors
97 #[test]
98 fn vectors_detected() {
99 let row = MatQ::from_str(&format!("[[1/1, {}]]", i64::MIN)).unwrap();
100 let col = MatQ::from_str(&format!("[[1/1],[2/1],[{}/1],[4/1]]", i64::MAX)).unwrap();
101
102 assert!(row.is_row_vector());
103 assert!(!row.is_column_vector());
104 assert!(row.is_vector());
105
106 assert!(!col.is_row_vector());
107 assert!(col.is_column_vector());
108 assert!(col.is_vector());
109 }
110
111 /// Check whether matrices with more than one row or column
112 /// don't get recognized as (row or column) vector
113 #[test]
114 fn non_vectors_detected() {
115 let mat_1 = MatQ::from_str(&format!("[[1, {}/1],[2, 3]]", i64::MIN)).unwrap();
116 let mat_2 = MatQ::from_str(&format!("[[1, {}, 3/3],[4/1, 5/1, 6/1]]", i64::MAX)).unwrap();
117 let mat_3 =
118 MatQ::from_str(&format!("[[1/1, {}/1],[2/1, 3/1],[4/1, 5/1]]", i64::MIN)).unwrap();
119 let mat_4 = MatQ::from_str("[[1/1, 0],[2, 0],[4, 0]]").unwrap();
120 let mat_5 = MatQ::from_str("[[1, 2/1, 4],[0, 0, 0]]").unwrap();
121
122 assert!(!mat_1.is_column_vector());
123 assert!(!mat_1.is_row_vector());
124 assert!(!mat_1.is_vector());
125
126 assert!(!mat_2.is_column_vector());
127 assert!(!mat_2.is_row_vector());
128 assert!(!mat_2.is_vector());
129
130 assert!(!mat_3.is_column_vector());
131 assert!(!mat_3.is_row_vector());
132 assert!(!mat_3.is_vector());
133
134 assert!(!mat_4.is_column_vector());
135 assert!(!mat_4.is_row_vector());
136 assert!(!mat_4.is_vector());
137
138 assert!(!mat_5.is_column_vector());
139 assert!(!mat_5.is_row_vector());
140 assert!(!mat_5.is_vector());
141 }
142
143 /// Check whether matrices with only one entry get recognized as single entry matrices
144 #[test]
145 fn single_entry_detected() {
146 let small = MatQ::from_str("[[1]]").unwrap();
147 let large = MatQ::from_str(&format!("[[{}/1]]", i64::MIN)).unwrap();
148
149 // check whether single entry is correctly detected
150 assert!(small.has_single_entry());
151 assert!(large.has_single_entry());
152
153 // check whether single entry is correctly detected as row and column vector
154 assert!(small.is_row_vector());
155 assert!(small.is_column_vector());
156 assert!(small.is_vector());
157
158 assert!(large.is_row_vector());
159 assert!(large.is_column_vector());
160 assert!(large.is_vector());
161 }
162
163 /// Check whether matrices with more than one entry
164 /// don't get recognized as single entry matrices
165 #[test]
166 fn non_single_entry_detected() {
167 let row = MatQ::from_str(&format!("[[1, {}]]", i64::MIN)).unwrap();
168 let col = MatQ::from_str(&format!("[[1],[{}],[3/1]]", i64::MIN)).unwrap();
169 let mat = MatQ::from_str("[[1/1, 2],[3, 4],[5, 6]]").unwrap();
170
171 assert!(!row.has_single_entry());
172 assert!(!col.has_single_entry());
173 assert!(!mat.has_single_entry());
174 }
175}