hpt_traits/ops/random.rs
1use hpt_common::{error::base::TensorError, shape::shape::Shape};
2use hpt_types::into_scalar::Cast;
3use rand_distr::uniform::SampleUniform;
4
5/// A trait for generating random numbers.
6pub trait Random
7where
8 Self: Sized,
9{
10 /// Associated type for meta-information or parameters relevant to distributions.
11 type Meta;
12
13 /// create a Tensor with data in normal distribution. `mean = 0.0`, `std_dev = 1.0`.
14 ///
15 /// ## Parameters:
16 /// `shape`: shape of the output
17 ///
18 /// ## Example:
19 /// ```rust
20 /// let a = Tensor::<f32>::randn([10, 10])?;
21 /// ```
22 #[track_caller]
23 fn randn<S: Into<Shape>>(shape: S) -> Result<Self, TensorError>;
24
25 /// same as `randn` but the shape will be based on `x`.
26 ///
27 /// ## Parameters:
28 /// `shape`: shape of the output
29 ///
30 /// ## Example:
31 /// ```rust
32 /// let a = Tensor::<f32>::randn([10, 10])?;
33 /// let b = a.randn_like()?; // shape: [10, 10]
34 /// ```
35 #[track_caller]
36 fn randn_like(&self) -> Result<Self, TensorError>;
37
38 /// create a Tensor with data uniformly distributed between `low` and `high`.
39 ///
40 /// ## Parameters:
41 /// `shape`: shape of the output
42 ///
43 /// `low`: the lowest value
44 ///
45 /// `high`: the highest value
46 ///
47 /// ## Example:
48 /// ```rust
49 /// let a = Tensor::<f32>::rand([10, 10], 0.0, 10.0)?;
50 /// ```
51 #[track_caller]
52 fn rand<S: Into<Shape>>(
53 shape: S,
54 low: Self::Meta,
55 high: Self::Meta,
56 ) -> Result<Self, TensorError>;
57
58 /// same as `rand` but the shape will be based on `x`.
59 ///
60 /// ## Parameters:
61 /// `shape`: shape of the output
62 ///
63 /// ## Example:
64 /// ```rust
65 /// let a = Tensor::<f32>::rand([10, 10], 0.0, 10.0)?;
66 /// let b = a.rand_like(0.0, 10.0)?; // shape: [10, 10]
67 /// ```
68 #[track_caller]
69 fn rand_like(&self, low: Self::Meta, high: Self::Meta) -> Result<Self, TensorError>;
70
71 /// Create a Tensor with values drawn from a beta distribution with parameters `alpha` and `beta`.
72 /// The beta distribution is a continuous probability distribution defined on the interval [0, 1].
73 ///
74 /// ## Parameters:
75 /// `alpha`: Shape parameter alpha (α) of the beta distribution. Must be positive.
76 ///
77 /// `beta`: Shape parameter beta (β) of the beta distribution. Must be positive.
78 ///
79 /// `shape`: shape of the output
80 ///
81 /// ## Example:
82 /// ```rust
83 /// let a = Tensor::<f32>::beta(2.0, 5.0, &[10, 10])?;
84 /// ```
85 #[track_caller]
86 fn beta<S: Into<Shape>>(a: Self::Meta, b: Self::Meta, shape: S) -> Result<Self, TensorError>;
87
88 /// Same as `beta` but the shape will be based on `x`.
89 /// Creates a Tensor with values drawn from a beta distribution with parameters `alpha` and `beta`.
90 ///
91 /// ## Parameters:
92 /// `alpha`: Shape parameter alpha (α) of the beta distribution. Must be positive.
93 ///
94 /// `beta`: Shape parameter beta (β) of the beta distribution. Must be positive.
95 ///
96 /// ## Example:
97 /// ```rust
98 /// let x = Tensor::<f32>::randn(&[10, 10])?;
99 /// let b = x.beta_like(2.0, 5.0)?; // shape: [10, 10]
100 /// ```
101 #[track_caller]
102 fn beta_like(&self, a: Self::Meta, b: Self::Meta) -> Result<Self, TensorError>;
103
104 /// Create a Tensor with values drawn from a chi-square distribution with `df` degrees of freedom.
105 /// The chi-square distribution is a continuous probability distribution of the sum of squares of `df` independent standard normal random variables.
106 ///
107 /// ## Parameters:
108 /// `df`: Degrees of freedom parameter. Must be positive.
109 ///
110 /// `shape`: shape of the output
111 ///
112 /// ## Example:
113 /// ```rust
114 /// let a = Tensor::<f32>::chisquare(5.0, &[10, 10])?;
115 /// ```
116 #[track_caller]
117 fn chisquare<S: Into<Shape>>(df: Self::Meta, shape: S) -> Result<Self, TensorError>;
118
119 /// Same as `chisquare` but the shape will be based on `x`.
120 /// Creates a Tensor with values drawn from a chi-square distribution with `df` degrees of freedom.
121 ///
122 /// ## Parameters:
123 /// `df`: Degrees of freedom parameter. Must be positive.
124 ///
125 /// ## Example:
126 /// ```rust
127 /// let x = Tensor::<f32>::randn(&[10, 10])?;
128 /// let b = x.chisquare_like(5.0)?; // shape: [10, 10]
129 /// ```
130 #[track_caller]
131 fn chisquare_like(&self, df: Self::Meta) -> Result<Self, TensorError>;
132
133 /// Create a Tensor with values drawn from an exponential distribution with rate parameter `lambda`.
134 /// The exponential distribution describes the time between events in a Poisson point process.
135 ///
136 /// ## Parameters:
137 /// `lambda`: Rate parameter (λ) of the exponential distribution. Must be positive.
138 ///
139 /// `shape`: shape of the output
140 ///
141 /// ## Example:
142 /// ```rust
143 /// let a = Tensor::<f32>::exponential(2.0, &[10, 10])?;
144 /// ```
145 #[track_caller]
146 fn exponential<S: Into<Shape>>(lambda: Self::Meta, shape: S) -> Result<Self, TensorError>;
147
148 /// Same as `exponential` but the shape will be based on `x`.
149 /// Creates a Tensor with values drawn from an exponential distribution with rate parameter `lambda`.
150 ///
151 /// ## Parameters:
152 /// `lambda`: Rate parameter (λ) of the exponential distribution. Must be positive.
153 ///
154 /// ## Example:
155 /// ```rust
156 /// let x = Tensor::<f32>::randn(&[10, 10])?;
157 /// let b = x.exponential_like(2.0)?; // shape: [10, 10]
158 /// ```
159 #[track_caller]
160 fn exponential_like(&self, lambda: Self::Meta) -> Result<Self, TensorError>;
161
162 /// Create a Tensor with values drawn from a gamma distribution with shape parameter `shape_param` (often denoted as k or α) and scale parameter `scale` (often denoted as θ).
163 /// The gamma distribution is a continuous probability distribution that generalizes the exponential distribution.
164 ///
165 /// ## Parameters:
166 /// `shape_param`: Shape parameter (k or α) of the gamma distribution. Must be positive.
167 ///
168 /// `scale`: Scale parameter (θ) of the gamma distribution. Must be positive.
169 ///
170 /// `shape`: shape of the output
171 ///
172 /// ## Example:
173 /// ```rust
174 /// let a = Tensor::<f32>::gamma(2.0, 2.0, &[10, 10])?;
175 /// ```
176 #[track_caller]
177 fn gamma<S: Into<Shape>>(
178 shape: Self::Meta,
179 scale: Self::Meta,
180 shape: S,
181 ) -> Result<Self, TensorError>;
182
183 /// Same as `gamma` but the shape will be based on `x`.
184 /// Creates a Tensor with values drawn from a gamma distribution with shape parameter `shape_param` and scale parameter `scale`.
185 ///
186 /// ## Parameters:
187 /// `shape_param`: Shape parameter (k or α) of the gamma distribution. Must be positive.
188 ///
189 /// `scale`: Scale parameter (θ) of the gamma distribution. Must be positive.
190 ///
191 /// ## Example:
192 /// ```rust
193 /// let x = Tensor::<f32>::randn(&[10, 10])?;
194 /// let g = x.gamma_like(2.0, 2.0)?; // shape: [10, 10]
195 /// ```
196 #[track_caller]
197 fn gamma_like(&self, shape: Self::Meta, scale: Self::Meta) -> Result<Self, TensorError>;
198
199 /// Create a Tensor with values drawn from a Gumbel distribution (also known as the Extreme Value Type I distribution) with location parameter `mu` and scale parameter `beta`.
200 /// The Gumbel distribution is commonly used to model the distribution of extreme values.
201 ///
202 /// ## Parameters:
203 /// `mu`: Location parameter (μ) of the Gumbel distribution.
204 ///
205 /// `beta`: Scale parameter (β) of the Gumbel distribution. Must be positive.
206 ///
207 /// `shape`: shape of the output
208 ///
209 /// ## Example:
210 /// ```rust
211 /// let a = Tensor::<f32>::gumbel(0.0, 1.0, &[10, 10])?;
212 /// ```
213 #[track_caller]
214 fn gumbel<S: Into<Shape>>(
215 mu: Self::Meta,
216 beta: Self::Meta,
217 shape: S,
218 ) -> Result<Self, TensorError>;
219
220 /// Same as `gumbel` but the shape will be based on `x`.
221 /// Creates a Tensor with values drawn from a Gumbel distribution with location parameter `mu` and scale parameter `beta`.
222 ///
223 /// ## Parameters:
224 /// `mu`: Location parameter (μ) of the Gumbel distribution.
225 ///
226 /// `beta`: Scale parameter (β) of the Gumbel distribution. Must be positive.
227 ///
228 /// ## Example:
229 /// ```rust
230 /// let x = Tensor::<f32>::randn(&[10, 10])?;
231 /// let g = x.gumbel_like(0.0, 1.0)?; // shape: [10, 10]
232 /// ```
233 #[track_caller]
234 fn gumbel_like(&self, mu: Self::Meta, beta: Self::Meta) -> Result<Self, TensorError>;
235
236 /// Create a Tensor with values drawn from a log-normal distribution. A random variable is log-normally distributed if the logarithm of the random variable is normally distributed.
237 /// The parameters `mean` and `std` are the mean and standard deviation of the underlying normal distribution.
238 ///
239 /// ## Parameters:
240 /// `mean`: Mean (μ) of the underlying normal distribution.
241 ///
242 /// `std`: Standard deviation (σ) of the underlying normal distribution. Must be positive.
243 ///
244 /// `shape`: shape of the output
245 ///
246 /// ## Example:
247 /// ```rust
248 /// let a = Tensor::<f32>::lognormal(0.0, 1.0, &[10, 10])?;
249 /// ```
250 #[track_caller]
251 fn lognormal<S: Into<Shape>>(
252 mean: Self::Meta,
253 std: Self::Meta,
254 shape: S,
255 ) -> Result<Self, TensorError>;
256
257 /// Same as `lognormal` but the shape will be based on `x`.
258 /// Creates a Tensor with values drawn from a log-normal distribution with parameters `mean` and `std` of the underlying normal distribution.
259 ///
260 /// ## Parameters:
261 /// `mean`: Mean (μ) of the underlying normal distribution.
262 ///
263 /// `std`: Standard deviation (σ) of the underlying normal distribution. Must be positive.
264 ///
265 /// ## Example:
266 /// ```rust
267 /// let x = Tensor::<f32>::randn(&[10, 10])?;
268 /// let l = x.lognormal_like(0.0, 1.0)?; // shape: [10, 10]
269 /// ```
270 #[track_caller]
271 fn lognormal_like(&self, mean: Self::Meta, std: Self::Meta) -> Result<Self, TensorError>;
272
273 /// Create a Tensor with values drawn from a normal (Gaussian) distribution with specified mean and standard deviation.
274 /// The normal distribution is a continuous probability distribution that is symmetric around its mean, showing the familiar bell-shaped curve.
275 ///
276 /// ## Parameters:
277 /// `mean`: Mean (μ) of the distribution, determining the center of the bell curve.
278 ///
279 /// `std`: Standard deviation (σ) of the distribution, determining the spread. Must be positive.
280 ///
281 /// `shape`: shape of the output
282 ///
283 /// ## Example:
284 /// ```rust
285 /// let a = Tensor::<f32>::normal_gaussian(0.0, 1.0, &[10, 10])?;
286 /// ```
287 #[track_caller]
288 fn normal_gaussian<S: Into<Shape>>(
289 mean: Self::Meta,
290 std: Self::Meta,
291 shape: S,
292 ) -> Result<Self, TensorError>;
293
294 /// Same as `normal_gaussian` but the shape will be based on `x`.
295 /// Creates a Tensor with values drawn from a normal distribution with specified mean and standard deviation.
296 ///
297 /// ## Parameters:
298 /// `mean`: Mean (μ) of the distribution, determining the center of the bell curve.
299 ///
300 /// `std`: Standard deviation (σ) of the distribution, determining the spread. Must be positive.
301 ///
302 /// ## Example:
303 /// ```rust
304 /// let x = Tensor::<f32>::randn(&[10, 10])?;
305 /// let n = x.normal_gaussian_like(0.0, 1.0)?; // shape: [10, 10]
306 /// ```
307 #[track_caller]
308 fn normal_gaussian_like(&self, mean: Self::Meta, std: Self::Meta) -> Result<Self, TensorError>;
309
310 /// Create a Tensor with values drawn from a Pareto distribution.
311 /// The Pareto distribution is a power-law probability distribution often used to describe the distribution of wealth, population sizes, and many other natural and social phenomena.
312 ///
313 /// ## Parameters:
314 /// `scale`: Scale parameter (xₘ), also known as the minimum possible value. Must be positive.
315 ///
316 /// `shape`: Shape parameter (α), also known as the Pareto index. Must be positive.
317 ///
318 /// `tensor_shape`: Shape of the output tensor.
319 ///
320 /// ## Example:
321 /// ```rust
322 /// let a = Tensor::<f32>::pareto(1.0, 3.0, &[10, 10])?;
323 /// ```
324 #[track_caller]
325 fn pareto<S: Into<Shape>>(
326 pareto_shape: Self::Meta,
327 a: Self::Meta,
328 shape: S,
329 ) -> Result<Self, TensorError>;
330
331 /// Same as `pareto` but the shape will be based on `x`.
332 /// Creates a Tensor with values drawn from a Pareto distribution with specified scale and shape parameters.
333 ///
334 /// ## Parameters:
335 /// `scale`: Scale parameter (xₘ), also known as the minimum possible value. Must be positive.
336 ///
337 /// `shape`: Shape parameter (α), also known as the Pareto index. Must be positive.
338 ///
339 /// ## Example:
340 /// ```rust
341 /// let x = Tensor::<f32>::randn(&[10, 10])?;
342 /// let p = x.pareto_like(1.0, 3.0)?; // shape: [10, 10]
343 /// ```
344 #[track_caller]
345 fn pareto_like(&self, pareto_shape: Self::Meta, a: Self::Meta) -> Result<Self, TensorError>;
346
347 /// Create a Tensor with values drawn from a Poisson distribution.
348 /// The Poisson distribution is a discrete probability distribution that expresses the probability of a given number of events occurring in a fixed interval of time or space, assuming these events occur with a known constant mean rate (λ) and independently of the time since the last event.
349 ///
350 /// ## Parameters:
351 /// `lambda`: Rate parameter (λ) of the Poisson distribution. Must be positive.
352 ///
353 /// `shape`: Shape of the output tensor.
354 ///
355 /// ## Example:
356 /// ```rust
357 /// let a = Tensor::<f32>::poisson(5.0, &[10, 10])?;
358 /// ```
359 #[track_caller]
360 fn poisson<S: Into<Shape>>(lambda: Self::Meta, shape: S) -> Result<Self, TensorError>;
361
362 /// Same as `poisson` but the shape will be based on `x`.
363 /// Creates a Tensor with values drawn from a Poisson distribution with specified rate parameter.
364 ///
365 /// ## Parameters:
366 /// `lambda`: Rate parameter (λ) of the Poisson distribution. Must be positive.
367 ///
368 /// ## Example:
369 /// ```rust
370 /// let x = Tensor::<f32>::randn(&[10, 10])?;
371 /// let p = x.poisson_like(5.0)?; // shape: [10, 10]
372 /// ```
373 #[track_caller]
374 fn poisson_like(&self, lambda: Self::Meta) -> Result<Self, TensorError>;
375
376 /// Create a Tensor with values drawn from a Weibull distribution.
377 /// The Weibull distribution is a continuous probability distribution commonly used in reliability engineering, survival analysis, and extreme value theory.
378 ///
379 /// ## Parameters:
380 /// `shape`: Shape parameter (k), determines the shape of the distribution. Must be positive.
381 ///
382 /// `scale`: Scale parameter (λ), determines the spread of the distribution. Must be positive.
383 ///
384 /// `tensor_shape`: Shape of the output tensor.
385 ///
386 /// ## Example:
387 /// ```rust
388 /// let a = Tensor::<f32>::weibull(2.0, 1.0, &[10, 10])?;
389 /// ```
390 #[track_caller]
391 fn weibull<S: Into<Shape>>(a: Self::Meta, b: Self::Meta, shape: S)
392 -> Result<Self, TensorError>;
393
394 /// Same as `weibull` but the shape will be based on `x`.
395 /// Creates a Tensor with values drawn from a Weibull distribution with specified shape and scale parameters.
396 ///
397 /// ## Parameters:
398 /// `shape`: Shape parameter (k), determines the shape of the distribution. Must be positive.
399 ///
400 /// `scale`: Scale parameter (λ), determines the spread of the distribution. Must be positive.
401 ///
402 /// ## Example:
403 /// ```rust
404 /// let x = Tensor::<f32>::randn(&[10, 10])?;
405 /// let w = x.weibull_like(2.0, 1.0)?; // shape: [10, 10]
406 /// ```
407 #[track_caller]
408 fn weibull_like(&self, a: Self::Meta, b: Self::Meta) -> Result<Self, TensorError>;
409
410 /// Create a Tensor with values drawn from a Zipf distribution.
411 /// The Zipf distribution is a discrete probability distribution commonly used to model frequency distributions of ranked data in various physical and social phenomena, where the frequency of any element is inversely proportional to its rank.
412 ///
413 /// ## Parameters:
414 /// `n`: Number of elements (N). Defines the range of possible values [1, N].
415 ///
416 /// `s`: Exponent parameter (s). Controls the skewness of the distribution. Must be greater than 1.
417 ///
418 /// `shape`: Shape of the output tensor.
419 ///
420 /// ## Example:
421 /// ```rust
422 /// let a = Tensor::<f32>::zipf(1000.0, 2.0, &[10, 10])?;
423 /// ```
424 #[track_caller]
425 fn zipf<S: Into<Shape>>(n: Self::Meta, a: Self::Meta, shape: S) -> Result<Self, TensorError>;
426
427 /// Same as `zipf` but the shape will be based on `x`.
428 /// Creates a Tensor with values drawn from a Zipf distribution with specified number of elements and exponent parameter.
429 ///
430 /// ## Parameters:
431 /// `n`: Number of elements (N). Defines the range of possible values [1, N].
432 ///
433 /// `s`: Exponent parameter (s). Controls the skewness of the distribution. Must be greater than 1.
434 ///
435 /// ## Example:
436 /// ```rust
437 /// let x = Tensor::<f32>::randn(&[10, 10])?;
438 /// let z = x.zipf_like(1000.0, 2.0)?; // shape: [10, 10]
439 /// ```
440 #[track_caller]
441 fn zipf_like(&self, n: Self::Meta, a: Self::Meta) -> Result<Self, TensorError>;
442
443 /// Create a Tensor with values drawn from a triangular distribution.
444 /// The triangular distribution is a continuous probability distribution with a lower limit `low`, upper limit `high`, and mode `mode`. It forms a triangular shape in its probability density function.
445 ///
446 /// ## Parameters:
447 /// `low`: Lower limit (a) of the distribution.
448 ///
449 /// `high`: Upper limit (b) of the distribution. Must be greater than `low`.
450 ///
451 /// `mode`: Mode (c) of the distribution. Must be between `low` and `high`.
452 ///
453 /// `shape`: Shape of the output tensor.
454 ///
455 /// ## Example:
456 /// ```rust
457 /// let a = Tensor::<f32>::triangular(0.0, 10.0, 5.0, &[10, 10])?;
458 /// ```
459 #[track_caller]
460 fn triangular<S: Into<Shape>>(
461 low: Self::Meta,
462 high: Self::Meta,
463 mode: Self::Meta,
464 shape: S,
465 ) -> Result<Self, TensorError>;
466
467 /// Same as `triangular` but the shape will be based on `x`.
468 /// Creates a Tensor with values drawn from a triangular distribution with specified lower limit, upper limit, and mode.
469 ///
470 /// ## Parameters:
471 /// `low`: Lower limit (a) of the distribution.
472 ///
473 /// `high`: Upper limit (b) of the distribution. Must be greater than `low`.
474 ///
475 /// `mode`: Mode (c) of the distribution. Must be between `low` and `high`.
476 ///
477 /// ## Example:
478 /// ```rust
479 /// let x = Tensor::<f32>::randn(&[10, 10])?;
480 /// let t = x.triangular_like(0.0, 10.0, 5.0)?; // shape: [10, 10]
481 /// ```
482 #[track_caller]
483 fn triangular_like(
484 &self,
485 low: Self::Meta,
486 high: Self::Meta,
487 mode: Self::Meta,
488 ) -> Result<Self, TensorError>;
489
490 /// Create a Tensor with values drawn from a Bernoulli distribution.
491 /// The Bernoulli distribution is a discrete probability distribution of a random variable which takes the value 1 with probability p and the value 0 with probability q = 1 - p.
492 ///
493 /// ## Parameters:
494 /// `shape`: Shape of the output tensor.
495 ///
496 /// `p`: Success probability (p). Must be in the interval [0, 1].
497 ///
498 /// ## Example:
499 /// ```rust
500 /// let a = Tensor::<f32>::bernoulli(&[10, 10], 0.7)?;
501 /// ```
502 #[track_caller]
503 fn bernoulli<S: Into<Shape>>(shape: S, p: Self::Meta) -> Result<Self, TensorError>
504 where
505 Self::Meta: Cast<f64>,
506 bool: Cast<Self::Meta>;
507}
508
509/// A trait for generating random integers.
510pub trait RandomInt
511where
512 Self: Sized,
513{
514 /// Associated type for meta-information or parameters relevant to distributions.
515 type Meta;
516
517 /// Create a Tensor with random integers drawn uniformly from the half-open interval `[low, high)`.
518 /// The distribution is uniform, meaning each integer in the range has an equal probability of being drawn.
519 ///
520 /// ## Parameters:
521 /// `low`: Lower bound (inclusive) of the range.
522 ///
523 /// `high`: Upper bound (exclusive) of the range.
524 ///
525 /// `shape`: Shape of the output tensor.
526 ///
527 /// ## Example:
528 /// ```rust
529 /// let a = Tensor::<i32>::randint(0, 100, &[10, 10])?;
530 /// ```
531 #[track_caller]
532 fn randint<S: Into<Shape>>(
533 low: Self::Meta,
534 high: Self::Meta,
535 shape: S,
536 ) -> Result<Self, TensorError>
537 where
538 Self::Meta: SampleUniform,
539 <Self::Meta as SampleUniform>::Sampler: Sync;
540
541 /// Same as `randint` but the shape will be based on `x`.
542 /// Creates a Tensor with random integers drawn uniformly from the half-open interval `[low, high)`.
543 ///
544 /// ## Parameters:
545 /// `low`: Lower bound (inclusive) of the range.
546 ///
547 /// `high`: Upper bound (exclusive) of the range.
548 ///
549 /// ## Example:
550 /// ```rust
551 /// let x = Tensor::<i32>::randn(&[10, 10])?;
552 /// let r = x.randint_like(0, 100)?; // shape: [10, 10]
553 /// ```
554 #[track_caller]
555 fn randint_like(&self, low: Self::Meta, high: Self::Meta) -> Result<Self, TensorError>
556 where
557 Self::Meta: SampleUniform,
558 <Self::Meta as SampleUniform>::Sampler: Sync;
559}