@@ -3,8 +3,16 @@ use crypto_bigint::rand_core::RngCore;
33use serde:: Serialize ;
44use std:: ops:: { Add , Index , IndexMut , Mul , Sub } ;
55
6+ #[ derive( thiserror:: Error , Debug ) ]
7+ pub enum Error {
8+ #[ error( "the operands do not have the same dimension: {0:?} and {1:?}" ) ]
9+ IncompatibleDimension ( usize , usize ) ,
10+ }
11+
12+ pub type Result < T > = std:: result:: Result < T , Error > ;
13+
614/// Vector whose elements belong to a ring.
7- #[ derive( Serialize , PartialEq , Eq , Debug ) ]
15+ #[ derive( Serialize , PartialEq , Eq , Debug , Clone ) ]
816pub struct Vector < T : Ring > ( Vec < T > ) ;
917
1018impl < T > Vector < T >
1624 self . 0 . len ( )
1725 }
1826
27+ /// Returns whether the vector has no elements.
1928 pub fn is_empty ( & self ) -> bool {
20- self . len ( ) == 0
29+ self . 0 . is_empty ( )
2130 }
2231
2332 /// Generates a vector of zeroes.
@@ -40,12 +49,15 @@ where
4049 }
4150
4251 /// Computes the dot product between two vectors.
43- pub fn dot ( & self , other : & Vector < T > ) -> T {
52+ pub fn dot ( & self , other : & Vector < T > ) -> Result < T > {
53+ if self . len ( ) != other. len ( ) {
54+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
55+ }
4456 let mut result = T :: ZERO ;
4557 for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
4658 result = result + & ( * self_elem * other_elem) ;
4759 }
48- result
60+ Ok ( result)
4961 }
5062}
5163
@@ -82,43 +94,106 @@ impl<T> Add<&Vector<T>> for Vector<T>
8294where
8395 T : Ring ,
8496{
85- type Output = Self ;
97+ type Output = Result < Self > ;
8698
8799 fn add ( self , other : & Vector < T > ) -> Self :: Output {
100+ if self . len ( ) != other. len ( ) {
101+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
102+ }
88103 let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
89104 for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
90105 output. push ( * self_elem + other_elem) ;
91106 }
92- Self ( output)
107+ Ok ( Self ( output) )
108+ }
109+ }
110+
111+ impl < T > Add < & Vector < T > > for & Vector < T >
112+ where
113+ T : Ring ,
114+ {
115+ type Output = Result < Vector < T > > ;
116+
117+ fn add ( self , other : & Vector < T > ) -> Self :: Output {
118+ if self . len ( ) != other. len ( ) {
119+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
120+ }
121+ let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
122+ for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
123+ output. push ( * self_elem + other_elem) ;
124+ }
125+ Ok ( Vector ( output) )
93126 }
94127}
95128
96129impl < T > Sub < & Vector < T > > for Vector < T >
97130where
98131 T : Ring ,
99132{
100- type Output = Self ;
133+ type Output = Result < Self > ;
134+
135+ fn sub ( self , other : & Vector < T > ) -> Self :: Output {
136+ if self . len ( ) != other. len ( ) {
137+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
138+ }
139+ let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
140+ for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
141+ output. push ( * self_elem - other_elem) ;
142+ }
143+ Ok ( Self ( output) )
144+ }
145+ }
146+
147+ impl < T > Sub < & Vector < T > > for & Vector < T >
148+ where
149+ T : Ring ,
150+ {
151+ type Output = Result < Vector < T > > ;
101152
102153 fn sub ( self , other : & Vector < T > ) -> Self :: Output {
154+ if self . len ( ) != other. len ( ) {
155+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
156+ }
103157 let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
104158 for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
105159 output. push ( * self_elem - other_elem) ;
106160 }
107- Self ( output)
161+ Ok ( Vector ( output) )
108162 }
109163}
110164
111165impl < T > Mul < & Vector < T > > for Vector < T >
112166where
113167 T : Ring ,
114168{
115- type Output = Self ;
169+ type Output = Result < Self > ;
116170
117171 fn mul ( self , other : & Vector < T > ) -> Self :: Output {
172+ if self . len ( ) != other. len ( ) {
173+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
174+ }
175+ let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
176+ for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
177+ output. push ( * self_elem * other_elem) ;
178+ }
179+ Ok ( Self ( output) )
180+ }
181+ }
182+
183+ impl < T > Mul < & Vector < T > > for & Vector < T >
184+ where
185+ T : Ring ,
186+ {
187+ type Output = Result < Vector < T > > ;
188+
189+ fn mul ( self , other : & Vector < T > ) -> Self :: Output {
190+ if self . len ( ) != other. len ( ) {
191+ return Err ( Error :: IncompatibleDimension ( self . len ( ) , other. len ( ) ) ) ;
192+ }
118193 let mut output = Vec :: with_capacity ( other. 0 . len ( ) ) ;
119194 for ( self_elem, other_elem) in self . 0 . iter ( ) . zip ( other. 0 . iter ( ) ) {
120195 output. push ( * self_elem * other_elem) ;
121196 }
122- Self ( output)
197+ Ok ( Vector ( output) )
123198 }
124199}
0 commit comments