peroxide/macros/r_macro.rs
1//! R like macros
2//!
3//! # List
4//!
5//! * `c`
6//! * `seq`
7//! * `matrix`
8//! * `cbind`
9//! * `rbind`
10//! * `runif`
11//! * `rnorm`
12//! * `dnorm`
13//! * `pnorm`
14//! * `rt`
15//! * `dt`
16//! * `pt`
17//! * `lm`
18
19/// R like concatenate (Type: Vec\<f64\>)
20///
21/// # Examples
22/// ```
23/// #[macro_use]
24/// extern crate peroxide;
25/// use peroxide::fuga::*;
26///
27/// fn main() {
28/// let a = c!(1,2,3,4);
29/// let b = c![5,6,7,8];
30/// let c = c![a; b];
31/// println!("{:?}", a); // [1,2,3,4]
32/// println!("{:?}", b); // [5,6,7,8]
33/// println!("{:?}", c); // [1,2,3,4,5,6,7,8]
34/// }
35/// ```
36#[macro_export]
37macro_rules! c {
38 ( $( $x:expr ),* ) => {
39 {
40 let mut v: Vec<f64> = Vec::new();
41 let mut l: usize = 0;
42 $(
43 v.push($x as f64);
44 l += 1;
45 )*
46 v
47 }
48 };
49 ( $( $x:expr );* ) => {
50 {
51 let mut v: Vec<f64> = Vec::new();
52 $(
53 v.extend(&$x);
54 )*
55 v
56 }
57 }
58}
59
60/// R like seq macro
61///
62/// # Examples
63/// ```
64/// #[macro_use]
65/// extern crate peroxide;
66/// use peroxide::fuga::*;
67///
68/// fn main() {
69/// assert_eq!(seq!(1,10,1), c!(1,2,3,4,5,6,7,8,9,10));
70/// assert_eq!(seq!(1,10,1), seq!(1;10;1));
71/// }
72/// ```
73#[macro_export]
74macro_rules! seq {
75 ( $start:expr, $end:expr, $step:expr ) => {{
76 let s = $start as f64;
77 let e = $end as f64;
78 let step = $step as f64;
79
80 assert!(e > s);
81
82 let factor: f64 = (e - s) / step;
83 let l: usize = factor as usize + 1;
84 let mut v: Vec<f64> = Vec::new();
85
86 for i in 0..l {
87 v.push(s + step * (i as f64));
88 }
89 v
90 }};
91 ( $start:expr; $end:expr; $step:expr ) => {
92 seq!($start, $end, $step)
93 };
94}
95
96/// More R like Matrix constructor (Macro)
97///
98/// # Examples
99/// ```
100/// #[macro_use]
101/// extern crate peroxide;
102/// use peroxide::fuga::*;
103///
104/// fn main() {
105/// let a = matrix!(1;4;1, 2, 2, Row); // start;end;step
106/// let b = matrix(c!(1,2,3,4), 2, 2, Row);
107/// let c = matrix(vec![1,2,3,4], 2, 2, Row); // Normal function
108/// assert!(a == b && b == c);
109///
110/// let m = matrix!(0, 2, 2, Row);
111/// assert_eq!(m, zeros!(2, 2));
112/// }
113/// ```
114#[macro_export]
115macro_rules! matrix {
116 ( $start:expr;$end:expr;$step:expr, $row:expr, $col:expr, $shape:expr ) => {{
117 matrix(seq!($start, $end, $step), $row, $col, $shape)
118 }};
119
120 ( $value:expr, $row:expr, $col:expr, $shape:expr ) => {{
121 matrix(vec![$value as f64; $row * $col], $row, $col, $shape)
122 }};
123}
124
125/// R like cbind
126///
127/// # Examples
128/// ```
129/// #[macro_use]
130/// extern crate peroxide;
131/// use peroxide::fuga::*;
132///
133/// fn main() {
134/// let a = matrix!(1;4;1, 2, 2, Col);
135/// let b = matrix(c!(5,6),2, 1, Col);
136/// let c = matrix(c!(7,8),2,1,Col);
137/// assert_eq!(cbind!(a.clone(),b.clone()), matrix!(1;6;1,2,3,Col));
138/// assert_eq!(cbind!(a,b,c), matrix!(1;8;1, 2, 4, Col));
139/// }
140/// ```
141#[macro_export]
142macro_rules! cbind {
143 // Two
144 ( $x:expr, $y:expr ) => {
145 {
146 let mut temp = $x;
147 if temp.shape != Col {
148 temp = temp.change_shape();
149 }
150
151 let mut v: Vec<f64> = temp.data;
152 let mut c: usize = temp.col;
153 let r: usize = temp.row;
154
155 assert_eq!(r, $y.row);
156 v.extend(&$y.data.clone());
157 c += &$y.col;
158 matrix(v, r, c, Col)
159 }
160 };
161
162 // Multi
163 ( $x0:expr, $( $x: expr ),* ) => {
164 {
165 let mut temp0 = $x0;
166 if temp0.shape != Col {
167 temp0 = temp0.change_shape();
168 }
169 let mut v: Vec<f64> = temp0.data;
170 let mut c: usize = temp0.col;
171 let r: usize = temp0.row;
172 $(
173 let mut temp = $x;
174 if temp.shape != Col {
175 temp = temp.change_shape();
176 }
177 // Must equal row
178 assert_eq!(r, temp.row);
179 // Add column
180 c += temp.col;
181 v.extend(&temp.data.clone());
182 )*
183 matrix(v, r, c, Col)
184 }
185 };
186}
187
188/// R like rbind
189///
190/// # Examples
191/// ```
192/// #[macro_use]
193/// extern crate peroxide;
194/// use peroxide::fuga::*;
195///
196/// fn main() {
197/// let a = matrix!(1;4;1, 2, 2, Row);
198/// let b = matrix(c!(5,6),1, 2, Row);
199/// let c = matrix(c!(7,8),1, 2, Row);
200/// assert_eq!(rbind!(a.clone(),b.clone()), matrix!(1;6;1, 3, 2, Row));
201/// assert_eq!(rbind!(a,b,c), matrix!(1;8;1, 4, 2, Row));
202/// }
203/// ```
204#[macro_export]
205macro_rules! rbind {
206 // Two
207 ( $x:expr, $y:expr ) => {
208 {
209 let mut temp = $x;
210 if temp.shape != Row {
211 temp = temp.change_shape();
212 }
213
214 let mut temp2 = $y;
215 if temp2.shape != Row {
216 temp2 = temp2.change_shape();
217 }
218
219 let mut v: Vec<f64> = temp.data;
220 let c: usize = temp.col;
221 let mut r: usize = temp.row;
222
223 assert_eq!(c, temp2.col);
224 v.extend(&temp2.data.clone());
225 r += temp2.row;
226 matrix(v, r, c, Row)
227 }
228 };
229
230 // Multi
231 ( $x0:expr, $( $x: expr ),* ) => {
232 {
233 let mut temp0 = $x0;
234 if temp0.shape != Row {
235 temp0 = temp0.change_shape();
236 }
237 let mut v: Vec<f64> = temp0.data;
238 let c: usize = temp0.col;
239 let mut r: usize = temp0.row;
240 $(
241 let mut temp = $x;
242 if temp.shape != Row {
243 temp = temp.change_shape();
244 }
245 // Must equal row
246 assert_eq!(c, temp.col);
247 // Add column
248 r += temp.row;
249 v.extend(&temp.data.clone());
250 )*
251 matrix(v, r, c, Row)
252 }
253 };
254}
255
256/// R like random uniform
257///
258/// # Examples
259/// ```
260/// #[macro_use]
261/// extern crate peroxide;
262/// use peroxide::fuga::*;
263///
264/// fn main() {
265/// let a = runif!(5, -1, 1);
266/// println!("{:?}", a);
267///
268/// let b = runif!(5); // same as runif!(5,0,1)
269/// println!("{:?}", b);
270/// }
271/// ```
272#[macro_export]
273macro_rules! runif {
274 ( $x0:expr, $start:expr, $end:expr ) => {{
275 let n: usize = $x0;
276 let mut v = vec![0f64; n];
277
278 let mut rng = rand::rng();
279
280 for i in 0..n {
281 v[i] = rng.random_range($start as f64..=$end as f64);
282 }
283 v
284 }};
285
286 ( $x0:expr ) => {{
287 runif!($x0, 0, 1)
288 }};
289}
290
291/// R like random normal
292///
293/// # Examples
294/// ```
295/// #[macro_use]
296/// extern crate peroxide;
297/// use peroxide::fuga::*;
298///
299/// fn main() {
300/// let a = rnorm!(5, 2, 1);
301/// println!("{:?}", a);
302///
303/// let b = rnorm!(5); // same as rnorm!(5,0,1)
304/// println!("{:?}", b);
305/// }
306/// ```
307#[macro_export]
308macro_rules! rnorm {
309 ( $n:expr, $mean:expr, $sd:expr ) => {{
310 let n: usize = $n;
311 let normal = Normal($mean as f64, $sd as f64);
312 normal.sample(n)
313 }};
314
315 ( $n:expr ) => {{
316 rnorm!($n, 0, 1)
317 }};
318}
319
320/// R like `dnorm`
321///
322/// # Examples
323/// ```
324/// #[macro_use]
325/// extern crate peroxide;
326/// use peroxide::fuga::*;
327///
328/// fn main() {
329/// let a = dnorm!(2, 2, 1);
330/// println!("{:?}", a); // 0.3989422804014327
331///
332/// let b = dnorm!(0); // same as dnorm!(0,0,1)
333/// println!("{:?}", b);
334/// }
335/// ```
336#[macro_export]
337macro_rules! dnorm {
338 ( $x:expr, $mean: expr, $sd:expr ) => {{
339 let x = $x as f64;
340 let mean = $mean as f64;
341 let sd = $sd as f64;
342 let normal = Normal(mean, sd);
343 normal.pdf(x)
344 }};
345
346 ( $x:expr ) => {{
347 dnorm!($x, 0, 1)
348 }};
349}
350
351/// R like `pnorm`
352///
353/// # Examples
354/// ```
355/// #[macro_use]
356/// extern crate peroxide;
357/// use peroxide::fuga::*;
358///
359/// fn main() {
360/// let a = pnorm!(2, 2, 1);
361/// println!("{:?}", a); // 0.5
362///
363/// let b = pnorm!(0); // same as pnorm!(0,0,1)
364/// println!("{:?}", b);
365/// }
366/// ```
367#[macro_export]
368macro_rules! pnorm {
369 ( $x:expr, $mean:expr, $sd:expr ) => {{
370 let x = $x as f64;
371 let mean = $mean as f64;
372 let sd = $sd as f64;
373 let normal = Normal(mean, sd);
374 normal.cdf(x)
375 }};
376
377 ( $x:expr ) => {
378 pnorm!($x, 0, 1)
379 };
380}
381
382/// R like random Student's t
383///
384/// # Examples
385/// ```
386/// #[macro_use]
387/// extern crate peroxide;
388/// use peroxide::fuga::*;
389///
390/// fn main() {
391/// let a = rt!(5, 1);
392/// println!("{:?}", a);
393/// }
394/// ```
395#[macro_export]
396macro_rules! rt {
397 ( $n:expr, $df:expr ) => {{
398 let n: usize = $n;
399 let t = StudentT($df as f64);
400 t.sample(n)
401 }};
402}
403
404/// R like `dt`
405///
406/// # Examples
407/// ```
408/// #[macro_use]
409/// extern crate peroxide;
410/// use peroxide::fuga::*;
411///
412/// fn main() {
413/// let a = dt!(1, 1);
414/// println!("{:?}", a);
415/// }
416/// ```
417#[macro_export]
418macro_rules! dt {
419 ( $x:expr, $df:expr ) => {{
420 let x = $x as f64;
421 let df = $df as f64;
422 let t = StudentT(df);
423 t.pdf(x)
424 }};
425}
426
427/// R like `pt`
428///
429/// # Examples
430/// ```
431/// #[macro_use]
432/// extern crate peroxide;
433/// use peroxide::fuga::*;
434///
435/// fn main() {
436/// let a = pt!(1, 1);
437/// println!("{:?}", a); // 0.5
438/// }
439/// ```
440#[macro_export]
441macro_rules! pt {
442 ( $x:expr, $df:expr ) => {{
443 let x = $x as f64;
444 let df = $df as f64;
445 let t = StudentT(df);
446 t.cdf(x)
447 }};
448}
449
450/// R like lm
451///
452/// # Caution
453/// Should use single token to use this macro
454/// * `lm(y ~ x)` can be accepted
455/// * `lm(c!(1,2,3,4) ~ c!(1,2,3,4))` is not allowed!
456///
457/// # Examples
458/// ```
459/// #[macro_use]
460/// extern crate peroxide;
461/// use peroxide::fuga::*;
462///
463/// fn main() {
464/// let a = matrix!(1;5;1, 5, 1, Col);
465/// let b = matrix(c!(3.7, 4.2, 4.9, 5.7, 6.0), 5, 1, Col);
466///
467/// assert_eq!(lm!(b ~ a), matrix(c!(3.0700, 0.6100), 2, 1, Col));
468/// }
469/// ```
470#[macro_export]
471macro_rules! lm {
472 ( $y:tt ~ $x:tt ) => {
473 lm(&$x, &$y)
474 };
475}