1+ #pragma once
2+ #include < iostream>
3+ #include < cstddef>
4+ #include < stdexcept>
5+ #include < algorithm>
6+ #include < initializer_list>
7+ #include < valarray>
8+ namespace user ;
9+ template <typename T>
10+ class matrix {
11+ public:
12+ using value_type = T;
13+ using reference = T&;
14+ class index_error :public std ::out_of_range{
15+ public:
16+ index_error (const char *msg=" Index error" ):out_of_range{msg}{}
17+ };
18+ class invalid_plus :public std ::logic_error{
19+ public:
20+ invalid_plus (const char *msg=" The number of rows or columns of the two matrices to be added is not equal" ):logic_error{msg}{}
21+ };
22+ class invalid_multiplies :public std ::logic_error{
23+ public:
24+ invalid_multiplies (const char *msg=" The number of rows or columns of the two matrices to be multiplied is not equal" ):logic_error{msg}{}
25+ };
26+ class invalid_concatenate :public std ::logic_error{
27+ public:
28+ invalid_concatenate (const char *msg=" Concatenate error" ):logic_error{msg}{}
29+ };
30+ class cannot_compare :public std ::logic_error{
31+ public:
32+ cannot_compare (const char *msg=" The size of two matricies are not equal. Cannot compare" ):logic_error{msg}{}
33+ };
34+ matrix (std::size_t , std::size_t );
35+ matrix (const std::initializer_list<std::initializer_list<value_type>>&);
36+ value_type operator ()(std::size_t x,std::size_t y)const noexcept {return element_[x][y];}
37+ value_type operator ()(std::size_t x,std::size_t y,bool value)noexcept {return element_[x][y]=value;}
38+ friend matrix operator +(const matrix&,const matrix&);
39+ friend matrix operator *(const matrix&,const matrix&);
40+ friend bool operator ==(const matrix&,const matrix&);
41+ friend bool operator !=(const matrix&,const matrix&);
42+ friend bool operator <(const matrix&,const matrix&);
43+ inline iterator begin ()noexcept {return element_.begin ();}
44+ inline const_iterator begin ()const noexcept {return element_.begin ();}
45+ inline iterator end ()noexcept {return element_.end ();}
46+ inline const_iterator end ()const noexcept {return element_.end ();}
47+ inline reverse_iterator rbegin ()noexcept {return element_.rbegin ();}
48+ inline const_reverse_iterator rbegin ()const noexcept {return element_.rbegin ();}
49+ inline reverse_iterator rend ()noexcept {return element_.rend ();}
50+ inline const_reverse_iterator rend ()const noexcept {return element_.rend ();}
51+ inline std::pair<std::size_t ,std::size_t > size ()const noexcept {return std::make_pair (n_,m_);}
52+ matrix transpose ()const noexcept ;
53+ template <concatenate_direction direction>
54+ friend matrix concatenate (const matrix&,const matrix&);
55+ friend std::ostream& operator <<(std::ostream&,const matrix&);
56+ private:
57+ const std::size_t n_;
58+ const std::size_t m_;
59+ std::vector<std::vector<bool >> element_;
60+ };
61+ matrix::matrix (std::size_t n,std::size_t m)noexcept :n_{n},m_{m},element_{}{
62+ element_.resize (n_);
63+ for (auto &row:element_)
64+ row.resize (m_);
65+ }
66+ matrix::matrix (const std::initializer_list<std::initializer_list<bool >> &init):n_{init.size ()},m_{init.begin ()->size ()},element_{}{
67+ element_.resize (n_);
68+ std::size_t i=0 ;
69+ for (auto &row:init){
70+ element_[i].resize (m_);
71+ if (row.size ()!=m_)
72+ throw std::out_of_range{" All rows in the initializer list must have the same size." };
73+ std::copy (row.begin (),row.end (),element_[i++].begin ());
74+ }
75+ }
76+ matrix operator +(const matrix &lhs,const matrix &rhs){
77+ if (lhs.n_ !=rhs.n_ ||lhs.m_ !=rhs.m_ )
78+ throw matrix::invalid_plus{};
79+ matrix result (lhs.n_ ,lhs.m_ );
80+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
81+ for (std::size_t j=0 ;j<lhs.m_ ;j++)
82+ result (i,j,lhs (i,j)^rhs (i,j));
83+ return result;
84+ }
85+ matrix operator *(const matrix &lhs,const matrix &rhs){
86+ if (lhs.m_ !=rhs.n_ )
87+ throw matrix::invalid_multiplies{};
88+ matrix result (lhs.n_ ,rhs.m_ );
89+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
90+ for (std::size_t j=0 ;j<rhs.m_ ;j++)
91+ for (std::size_t k=0 ;k<lhs.m_ ;k++)
92+ result (i,j,result (i,j)^lhs (i,k)&rhs (k,j));
93+ return result;
94+ }
95+ bool operator ==(const matrix &lhs,const matrix &rhs){
96+ if (lhs.m_ !=rhs.m_ ||lhs.n_ !=rhs.n_ )
97+ throw matrix::cannot_compare{};
98+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
99+ for (std::size_t j=0 ;j<lhs.m_ ;j++)
100+ if (lhs (i,j)!=rhs (i,j))
101+ return false ;
102+ return true ;
103+ }
104+ bool operator !=(const matrix &lhs,const matrix &rhs){
105+ if (lhs.m_ !=rhs.m_ ||lhs.n_ !=rhs.n_ )
106+ throw matrix::cannot_compare{};
107+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
108+ for (std::size_t j=0 ;j<lhs.m_ ;j++)
109+ if (lhs (i,j)!=rhs (i,j))
110+ return true ;
111+ return false ;
112+ }
113+ bool operator <(const matrix &lhs,const matrix &rhs){
114+ if (lhs.m_ !=rhs.m_ ||lhs.n_ !=rhs.n_ )
115+ throw matrix::cannot_compare{};
116+ std::size_t l_weight{0 },r_weight{0 };
117+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
118+ for (std::size_t j=0 ;j<lhs.m_ ;j++){
119+ if (lhs (i,j))
120+ l_weight++;
121+ if (rhs (i,j))
122+ r_weight++;
123+ }
124+ if (l_weight<r_weight)
125+ return true ;
126+ else if (l_weight>r_weight)
127+ return false ;
128+ for (std::size_t i=0 ;i<lhs.n_ ;i++)
129+ for (std::size_t j=0 ;j<lhs.m_ ;j++){
130+ if (lhs (i,j)<rhs (i,j))
131+ return true ;
132+ else if (lhs (i,j)>rhs (i,j))
133+ return false ;
134+ }
135+ return false ;
136+ }
137+ matrix matrix::transpose ()const noexcept {
138+ matrix result (m_,n_);
139+ for (std::size_t i=0 ;i<m_;i++)
140+ for (std::size_t j=0 ;j<n_;j++)
141+ result (i,j,element_[j][i]);
142+ return result;
143+ }
144+ template <concatenate_direction direction>
145+ matrix concatenate (const matrix&,const matrix&);
146+ template <>
147+ matrix concatenate<vertical>(const matrix &uhs,const matrix &dhs){
148+ if (uhs.m_ !=dhs.m_ )
149+ throw matrix::invalid_concatenate{" Two matrices to be concatenated have different number of columns" };
150+ matrix result (uhs.n_ +dhs.n_ ,uhs.m_ );
151+ for (std::size_t j=0 ;j<uhs.m_ ;j++){
152+ for (std::size_t i=0 ;i<uhs.n_ ;i++)
153+ result (i,j,uhs (i,j));
154+ for (std::size_t i=0 ;i<dhs.n_ ;i++)
155+ result (uhs.n_ +i,j,dhs (i,j));
156+ }
157+ return result;
158+ }
159+ template <>
160+ matrix concatenate<horizontal>(const matrix &lhs,const matrix &rhs){
161+ if (lhs.n_ !=rhs.n_ )
162+ throw matrix::invalid_concatenate{" Two matrices to be concatenated have different number of rows." };
163+ matrix result (lhs.n_ ,lhs.m_ +rhs.m_ );
164+ for (std::size_t i=0 ;i<lhs.n_ ;i++){
165+ for (std::size_t j=0 ;j<lhs.m_ ;j++)
166+ result (i,j,lhs (i,j));
167+ for (std::size_t j=0 ;j<rhs.m_ ;j++)
168+ result (i,lhs.m_ +j,rhs (i,j));
169+ }
170+ return result;
171+ }
172+ inline matrix transpose (const matrix &mat){
173+ return mat.transpose ();
174+ }
175+ matrix Identity (std::size_t size){
176+ matrix result (size,size);
177+ for (std::size_t i=0 ;i<size;i++)
178+ result (i,i,true );
179+ return result;
180+ }
181+ matrix ItoB (unsigned x,std::size_t len){
182+ matrix result (1 ,len);
183+ for (std::size_t i=0 ;i<len;i++)
184+ result (0 ,len-1 -i,1 <<i&x);
185+ return result;
186+ }
187+ inline std::ostream& operator <<(std::ostream &out,const output_method &style){
188+ outstyle=style;
189+ return out;
190+ }
191+ std::ostream& operator <<(std::ostream &out,const matrix &mat){
192+ for (auto row:mat){
193+ for (auto x:row){
194+ out<<x;
195+ if (outstyle==as_matrix)
196+ out<<' ' ;
197+ }
198+ }
199+ return out;
200+ }
201+ // ~code
202+ };
0 commit comments