@@ -139,6 +139,103 @@ class Tensor(T)
139
139
self .range(start, stop, T .new(1 ))
140
140
end
141
141
142
+ # Return evenly spaced numbers over a specified interval.
143
+ # Returns `num` evenly spaced samples, calculated over the
144
+ # interval [`start`, `stop`].
145
+ # The endpoint of the interval can optionally be excluded.
146
+ #
147
+ # ```
148
+ # B.linspace(0, 1, 5) # => Tensor[0.0, 0.25, 0.5, 0.75, 1.0]
149
+ #
150
+ # B.linspace(0, 1, 5, endpoint: false) # => Tensor[0.0, 0.2, 0.4, 0.6, 0.8]
151
+ # ```
152
+ def self.linear_space (start : T , stop : T , num : Int = 50 , endpoint = true )
153
+ unless num > 0
154
+ raise Num ::Internal ::ValueError .new(
155
+ " Number of samples must be non-negative"
156
+ )
157
+ end
158
+ divisor = endpoint ? num - 1 : num
159
+ result = Tensor .range(T .new(num))
160
+ delta = stop - start
161
+
162
+ if num > 1
163
+ step = delta / divisor
164
+ if step == 0
165
+ raise Num ::Internal ::ValueError .new(
166
+ " Step cannot be 0"
167
+ )
168
+ end
169
+ else
170
+ step = delta
171
+ end
172
+
173
+ result.map! do |i |
174
+ i * step + start
175
+ end
176
+
177
+ if endpoint && num > 1
178
+ result[result.shape[0 ] - 1 ] = stop
179
+ end
180
+
181
+ result
182
+ end
183
+
184
+ # Return numbers spaced evenly on a log scale.
185
+ # In linear space, the sequence starts at ``base ** start``
186
+ # (`base` to the power of `start`) and ends with ``base ** stop``
187
+ # (see `endpoint` below).
188
+ #
189
+ # ```
190
+ # B.logspace(2.0, 3.0, num = 4) # => Tensor[100.0, 215.44346900318845, 464.15888336127773, 1000.0]
191
+ # ```
192
+ def self.logarithmic_space (
193
+ start : T ,
194
+ stop : T ,
195
+ num = 50 ,
196
+ endpoint = true ,
197
+ base : T = T .new(10.0 )
198
+ )
199
+ result = Tensor .linear_space(start, stop, num: num, endpoint: endpoint)
200
+ result.map! do |i |
201
+ base ** i
202
+ end
203
+ result
204
+ end
205
+
206
+ # Return numbers spaced evenly on a log scale (a geometric progression).
207
+ # This is similar to `logspace`, but with endpoints specified directly.
208
+ # Each output sample is a constant multiple of the previous.
209
+ #
210
+ # ```
211
+ # geomspace(1, 1000, 4) # => Tensor[1.0, 10.0, 100.0, 1000.0]
212
+ # ```
213
+ def self.geometric_space (start : T , stop : T , num = 50 , endpoint = true )
214
+ if start == 0 || stop == 0
215
+ raise Num ::Internal ::ValueError .new(
216
+ " Geometric sequence cannot include zero"
217
+ )
218
+ end
219
+
220
+ out_sign = T .new(1.0 )
221
+
222
+ if start < 0 && stop < 0
223
+ start, stop = - start, - stop
224
+ out_sign = - out_sign
225
+ end
226
+
227
+ log_start = Math .log(start, T .new(10.0 ))
228
+ log_stop = Math .log(stop, T .new(10.0 ))
229
+
230
+ Tensor .logarithmic_space(
231
+ log_start,
232
+ log_stop,
233
+ num: num,
234
+ endpoint: endpoint,
235
+ base: T .new(10.0 )
236
+ ) * out_sign
237
+ end
238
+
142
239
# Return a two-dimensional `Tensor` with ones along the diagonal,
143
240
# and zeros elsewhere
144
241
#
0 commit comments