@@ -71,21 +71,17 @@ impl<F> ExactSizeIterator for Geomspace<F> where Geomspace<F>: Iterator {}
71
71
///
72
72
/// Iterator element type is `F`, where `F` must be either `f32` or `f64`.
73
73
///
74
- /// **Panics** if the interval `[a, b]` contains zero (including the end points).
74
+ /// Returns `None` if `start` and `end` have different signs or if either one
75
+ /// is zero. Conceptually, this means that in order to obtain a `Some` result,
76
+ /// `end / start` must be positive.
75
77
#[ inline]
76
- pub fn geomspace < F > ( a : F , b : F , n : usize ) -> Geomspace < F >
78
+ pub fn geomspace < F > ( a : F , b : F , n : usize ) -> Option < Geomspace < F > >
77
79
where
78
80
F : Float ,
79
81
{
80
- assert ! (
81
- a != F :: zero( ) && b != F :: zero( ) ,
82
- "Start and/or end of geomspace cannot be zero." ,
83
- ) ;
84
- assert ! (
85
- a. is_sign_negative( ) == b. is_sign_negative( ) ,
86
- "Logarithmic interval cannot cross 0."
87
- ) ;
88
-
82
+ if a == F :: zero ( ) || b == F :: zero ( ) || a. is_sign_negative ( ) != b. is_sign_negative ( ) {
83
+ return None ;
84
+ }
89
85
let log_a = a. abs ( ) . ln ( ) ;
90
86
let log_b = b. abs ( ) . ln ( ) ;
91
87
let step = if n > 1 {
@@ -94,13 +90,13 @@ where
94
90
} else {
95
91
F :: zero ( )
96
92
} ;
97
- Geomspace {
93
+ Some ( Geomspace {
98
94
sign : a. signum ( ) ,
99
95
start : log_a,
100
96
step : step,
101
97
index : 0 ,
102
98
len : n,
103
- }
99
+ } )
104
100
}
105
101
106
102
#[ cfg( test) ]
@@ -113,22 +109,22 @@ mod tests {
113
109
use approx:: assert_abs_diff_eq;
114
110
use crate :: { arr1, Array1 } ;
115
111
116
- let array: Array1 < _ > = geomspace ( 1e0 , 1e3 , 4 ) . collect ( ) ;
112
+ let array: Array1 < _ > = geomspace ( 1e0 , 1e3 , 4 ) . unwrap ( ) . collect ( ) ;
117
113
assert_abs_diff_eq ! ( array, arr1( & [ 1e0 , 1e1 , 1e2 , 1e3 ] ) , epsilon = 1e-12 ) ;
118
114
119
- let array: Array1 < _ > = geomspace ( 1e3 , 1e0 , 4 ) . collect ( ) ;
115
+ let array: Array1 < _ > = geomspace ( 1e3 , 1e0 , 4 ) . unwrap ( ) . collect ( ) ;
120
116
assert_abs_diff_eq ! ( array, arr1( & [ 1e3 , 1e2 , 1e1 , 1e0 ] ) , epsilon = 1e-12 ) ;
121
117
122
- let array: Array1 < _ > = geomspace ( -1e3 , -1e0 , 4 ) . collect ( ) ;
118
+ let array: Array1 < _ > = geomspace ( -1e3 , -1e0 , 4 ) . unwrap ( ) . collect ( ) ;
123
119
assert_abs_diff_eq ! ( array, arr1( & [ -1e3 , -1e2 , -1e1 , -1e0 ] ) , epsilon = 1e-12 ) ;
124
120
125
- let array: Array1 < _ > = geomspace ( -1e0 , -1e3 , 4 ) . collect ( ) ;
121
+ let array: Array1 < _ > = geomspace ( -1e0 , -1e3 , 4 ) . unwrap ( ) . collect ( ) ;
126
122
assert_abs_diff_eq ! ( array, arr1( & [ -1e0 , -1e1 , -1e2 , -1e3 ] ) , epsilon = 1e-12 ) ;
127
123
}
128
124
129
125
#[ test]
130
126
fn iter_forward ( ) {
131
- let mut iter = geomspace ( 1.0f64 , 1e3 , 4 ) ;
127
+ let mut iter = geomspace ( 1.0f64 , 1e3 , 4 ) . unwrap ( ) ;
132
128
133
129
assert ! ( iter. size_hint( ) == ( 4 , Some ( 4 ) ) ) ;
134
130
@@ -143,7 +139,7 @@ mod tests {
143
139
144
140
#[ test]
145
141
fn iter_backward ( ) {
146
- let mut iter = geomspace ( 1.0f64 , 1e3 , 4 ) ;
142
+ let mut iter = geomspace ( 1.0f64 , 1e3 , 4 ) . unwrap ( ) ;
147
143
148
144
assert ! ( iter. size_hint( ) == ( 4 , Some ( 4 ) ) ) ;
149
145
@@ -157,20 +153,17 @@ mod tests {
157
153
}
158
154
159
155
#[ test]
160
- #[ should_panic]
161
156
fn zero_lower ( ) {
162
- geomspace ( 0.0 , 1.0 , 4 ) ;
157
+ assert ! ( geomspace( 0.0 , 1.0 , 4 ) . is_none ( ) ) ;
163
158
}
164
159
165
160
#[ test]
166
- #[ should_panic]
167
161
fn zero_upper ( ) {
168
- geomspace ( 1.0 , 0.0 , 4 ) ;
162
+ assert ! ( geomspace( 1.0 , 0.0 , 4 ) . is_none ( ) ) ;
169
163
}
170
164
171
165
#[ test]
172
- #[ should_panic]
173
166
fn zero_included ( ) {
174
- geomspace ( -1.0 , 1.0 , 4 ) ;
167
+ assert ! ( geomspace( -1.0 , 1.0 , 4 ) . is_none ( ) ) ;
175
168
}
176
169
}
0 commit comments