Skip to main content

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}