2 An algorithm library based on C/C++
6 Add this to your `Cargo.toml`:
14 #![warn(missing_docs)]
15 #![allow(non_camel_case_types)]
16 #![cfg_attr(not(feature = "std"), no_std)]
18 /// floating-point number stored using `f64`
19 #[cfg(not(feature = "float"))]
21 /// floating-point number stored using `f32`
22 #[cfg(feature = "float")]
25 #[cfg(feature = "std")]
28 #[cfg(not(feature = "std"))]
29 pub use core::ffi::c_int;
30 #[cfg(feature = "std")]
31 pub use std::os::raw::c_int;
33 #[cfg(not(feature = "std"))]
34 pub use core::ffi::c_uint;
35 #[cfg(feature = "std")]
36 pub use std::os::raw::c_uint;
38 #[cfg(not(feature = "std"))]
39 use core::mem::size_of;
40 #[cfg(feature = "std")]
41 use std::mem::size_of;
43 #[cfg(not(feature = "std"))]
44 use core::cmp::Ordering;
45 #[cfg(feature = "std")]
46 use std::cmp::Ordering;
48 #[cfg(not(feature = "std"))]
49 use core::ptr::{null, null_mut};
50 #[cfg(feature = "std")]
51 use std::ptr::{null, null_mut};
53 #[cfg(not(feature = "std"))]
54 use core::slice::{from_raw_parts, from_raw_parts_mut};
55 #[cfg(feature = "std")]
56 use std::slice::{from_raw_parts, from_raw_parts_mut};
59 fn a_u32_sqrt(x: u32) -> u16;
60 fn a_u64_sqrt(x: u64) -> u32;
63 /// square root of an unsigned integer
65 pub fn u32_sqrt(x: u32) -> u16 {
66 unsafe { a_u32_sqrt(x) }
68 /// square root of an unsigned integer
70 pub fn u64_sqrt(x: u64) -> u32 {
71 unsafe { a_u64_sqrt(x) }
75 fn a_f32_rsqrt(x: f32) -> f32;
76 fn a_f64_rsqrt(x: f64) -> f64;
79 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
81 pub fn f32_rsqrt(x: f32) -> f32 {
82 unsafe { a_f32_rsqrt(x) }
84 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
86 pub fn f64_rsqrt(x: f64) -> f64 {
87 unsafe { a_f64_rsqrt(x) }
91 fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
92 fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
95 /// a hash function whose prime number is 131
97 pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
98 unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
100 /// a hash function whose prime number is 65599
102 pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
103 unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
106 /// Cyclic Redundancy Check for 8 bits
109 /// Cyclic Redundancy Check comparison table
110 pub table: [u8; 0x100],
114 fn a_crc8m_init(table: *mut u8, poly: u8);
115 fn a_crc8l_init(table: *mut u8, poly: u8);
116 fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
120 /// initialize for MSB CRC-8
122 pub fn new_msb(poly: u8) -> Self {
123 let mut ctx: Self = Self { table: [0; 0x100] };
124 unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
127 /// initialize for LSB CRC-8
129 pub fn new_lsb(poly: u8) -> Self {
130 let mut ctx: Self = Self { table: [0; 0x100] };
131 unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
134 /// generate for MSB CRC-8
136 pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
137 unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
140 /// generate for LSB CRC-8
142 pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
143 unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
146 /// calculate for CRC-8
148 pub fn eval(self, block: &[u8], value: u8) -> u8 {
149 unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
153 /// Cyclic Redundancy Check for 16 bits
156 /// Cyclic Redundancy Check comparison table
157 pub table: [u16; 0x100],
158 eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
162 fn a_crc16m_init(table: *mut u16, poly: u16);
163 fn a_crc16l_init(table: *mut u16, poly: u16);
164 fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
165 fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
169 /// initialize for MSB CRC-16
171 pub fn new_msb(poly: u16) -> Self {
172 let mut ctx: Self = Self {
176 unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
179 /// initialize for LSB CRC-16
181 pub fn new_lsb(poly: u16) -> Self {
182 let mut ctx: Self = Self {
186 unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
189 /// generate for MSB CRC-16
191 pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
192 unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
193 self.eval = a_crc16m;
196 /// generate for LSB CRC-16
198 pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
199 unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
200 self.eval = a_crc16l;
203 /// calculate for CRC-16
205 pub fn eval(self, block: &[u8], value: u16) -> u16 {
206 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
210 /// Cyclic Redundancy Check for 32 bits
213 /// Cyclic Redundancy Check comparison table
214 pub table: [u32; 0x100],
215 eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
219 fn a_crc32m_init(table: *mut u32, poly: u32);
220 fn a_crc32l_init(table: *mut u32, poly: u32);
221 fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
222 fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
226 /// initialize for MSB CRC-32
228 pub fn new_msb(poly: u32) -> Self {
229 let mut ctx: Self = Self {
233 unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
236 /// initialize for LSB CRC-32
238 pub fn new_lsb(poly: u32) -> Self {
239 let mut ctx: Self = Self {
243 unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
246 /// generate for MSB CRC-32
248 pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
249 unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
250 self.eval = a_crc32m;
253 /// generate for LSB CRC-32
255 pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
256 unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
257 self.eval = a_crc32l;
260 /// calculate for CRC-32
262 pub fn eval(self, block: &[u8], value: u32) -> u32 {
263 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
267 /// Cyclic Redundancy Check for 64 bits
270 /// Cyclic Redundancy Check comparison table
271 pub table: [u64; 0x100],
272 eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
276 fn a_crc64m_init(table: *mut u64, poly: u64);
277 fn a_crc64l_init(table: *mut u64, poly: u64);
278 fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
279 fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
283 /// initialize for MSB CRC-64
285 pub fn new_msb(poly: u64) -> Self {
286 let mut ctx: Self = Self {
290 unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
293 /// initialize for LSB CRC-64
295 pub fn new_lsb(poly: u64) -> Self {
296 let mut ctx: Self = Self {
300 unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
303 /// generate for MSB CRC-64
305 pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
306 unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
307 self.eval = a_crc64m;
310 /// generate for LSB CRC-64
312 pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
313 unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
314 self.eval = a_crc64l;
317 /// calculate for CRC-64
319 pub fn eval(self, block: &[u8], value: u64) -> u64 {
320 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
324 #[allow(clippy::excessive_precision)]
325 const TAU: float = 6.28318530717958647692528676655900577;
330 /// filter coefficient
339 /// initialize for High Pass Filter
341 pub fn new(fc: float, ts: float) -> Self {
343 alpha: 1.0 / (TAU * fc * ts + 1.0),
348 /// generate for High Pass Filter
350 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
351 self.alpha = 1.0 / (TAU * fc * ts + 1.0);
354 /// calculate for High Pass Filter
356 pub fn iter(&mut self, x: float) -> float {
357 self.output = self.alpha * (self.output + x - self.input);
361 /// zeroing for High Pass Filter
363 pub fn zero(&mut self) -> &mut Self {
370 #[allow(clippy::excessive_precision)]
371 const _1_TAU: float = 0.159154943091895335768883763372514362;
376 /// filter coefficient
383 /// initialize for Low Pass Filter
385 pub fn new(fc: float, ts: float) -> Self {
387 alpha: ts / (_1_TAU / fc + ts),
391 /// generate for Low Pass Filter
393 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
394 self.alpha = ts / (_1_TAU / fc + ts);
397 /// calculate for Low Pass Filter
399 pub fn iter(&mut self, x: float) -> float {
400 self.output *= 1.0 - self.alpha;
401 self.output += x * self.alpha;
404 /// zeroing for Low Pass Filter
406 pub fn zero(&mut self) -> &mut Self {
412 /// membership function
416 pub const NUL: c_int = 0;
417 /// gaussian membership function
418 pub const GAUSS: c_int = 1;
419 /// gaussian combination membership function
420 pub const GAUSS2: c_int = 2;
421 /// generalized bell-shaped membership function
422 pub const GBELL: c_int = 3;
423 /// sigmoidal membership function
424 pub const SIG: c_int = 4;
425 /// difference between two sigmoidal membership functions
426 pub const DSIG: c_int = 5;
427 /// product of two sigmoidal membership functions
428 pub const PSIG: c_int = 6;
429 /// trapezoidal membership function
430 pub const TRAP: c_int = 7;
431 /// triangular membership function
432 pub const TRI: c_int = 8;
433 /// linear s-shaped saturation membership function
434 pub const LINS: c_int = 9;
435 /// linear z-shaped saturation membership function
436 pub const LINZ: c_int = 10;
437 /// s-shaped membership function
438 pub const S: c_int = 11;
439 /// z-shaped membership function
440 pub const Z: c_int = 12;
441 /// pi-shaped membership function
442 pub const PI: c_int = 13;
446 fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
447 fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
448 fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
449 fn a_mf_sig(x: float, a: float, c: float) -> float;
450 fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
451 fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
452 fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
453 fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
454 fn a_mf_lins(x: float, a: float, b: float) -> float;
455 fn a_mf_linz(x: float, a: float, b: float) -> float;
456 fn a_mf_s(x: float, a: float, b: float) -> float;
457 fn a_mf_z(x: float, a: float, b: float) -> float;
458 fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
461 /// gaussian membership function
463 pub fn gauss(x: float, sigma: float, c: float) -> float {
464 unsafe { a_mf_gauss(x, sigma, c) }
466 /// gaussian combination membership function
468 pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
469 unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
471 /// generalized bell-shaped membership function
473 pub fn gbell(x: float, a: float, b: float, c: float) -> float {
474 unsafe { a_mf_gbell(x, a, b, c) }
476 /// sigmoidal membership function
478 pub fn sig(x: float, a: float, c: float) -> float {
479 unsafe { a_mf_sig(x, a, c) }
481 /// difference between two sigmoidal membership functions
483 pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
484 unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
486 /// product of two sigmoidal membership functions
488 pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
489 unsafe { a_mf_psig(x, a1, c1, a2, c2) }
491 /// trapezoidal membership function
493 pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
494 unsafe { a_mf_trap(x, a, b, c, d) }
496 /// triangular membership function
498 pub fn tri(x: float, a: float, b: float, c: float) -> float {
499 unsafe { a_mf_tri(x, a, b, c) }
501 /// linear s-shaped saturation membership function
503 pub fn lins(x: float, a: float, b: float) -> float {
504 unsafe { a_mf_lins(x, a, b) }
506 /// linear z-shaped saturation membership function
508 pub fn linz(x: float, a: float, b: float) -> float {
509 unsafe { a_mf_linz(x, a, b) }
511 /// s-shaped membership function
513 pub fn s(x: float, a: float, b: float) -> float {
514 unsafe { a_mf_s(x, a, b) }
516 /// z-shaped membership function
518 pub fn z(x: float, a: float, b: float) -> float {
519 unsafe { a_mf_z(x, a, b) }
521 /// pi-shaped membership function
523 pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
524 unsafe { a_mf_pi(x, a, b, c, d) }
528 /// proportional integral derivative controller
531 /// proportional constant
533 /// integral constant
535 /// derivative constant
537 /// maximum integral output
539 /// minimum integral output
541 /// controller integral output
543 /// maximum final output
545 /// minimum final output
547 /// controller final output
557 impl Default for pid {
559 fn default() -> Self {
564 summax: float::INFINITY,
565 summin: -float::INFINITY,
567 outmax: float::INFINITY,
568 outmin: -float::INFINITY,
578 fn a_pid_set_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
579 fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
580 fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
581 fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
582 fn a_pid_zero(ctx: *mut pid);
586 /// initialize for PID controller
588 pub fn new() -> Self {
591 /// set proportional integral derivative constant for PID controller
593 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
594 unsafe { a_pid_set_kpid(self, kp, ki, kd) };
597 /// calculate for PID controller
599 pub fn run(&mut self, set: float, fdb: float) -> float {
600 unsafe { a_pid_run(self, set, fdb) }
602 /// calculate for positional PID controller
604 pub fn pos(&mut self, set: float, fdb: float) -> float {
605 unsafe { a_pid_pos(self, set, fdb) }
607 /// calculate for incremental PID controller
609 pub fn inc(&mut self, set: float, fdb: float) -> float {
610 unsafe { a_pid_inc(self, set, fdb) }
612 /// zeroing for PID controller
614 pub fn zero(&mut self) -> &mut Self {
615 unsafe { a_pid_zero(self) };
620 /// fuzzy PID controller operator
624 pub const CAP: c_uint = 1;
626 pub const CAP_ALGEBRA: c_uint = 2;
628 pub const CAP_BOUNDED: c_uint = 3;
630 pub const CUP: c_uint = 4;
632 pub const CUP_ALGEBRA: c_uint = 5;
634 pub const CUP_BOUNDED: c_uint = 6;
635 /// sqrt(a,b)*sqrt(1-(1-a)*(1-b))
636 pub const EQU: c_uint = 0;
639 /// fuzzy proportional integral derivative controller
641 pub struct pid_fuzzy {
642 /// proportional integral derivative controller
651 /// fuzzy relational operator
652 opr: extern "C" fn(float, float) -> float,
653 /// base proportional constant
655 /// base integral constant
657 /// base derivative constant
659 /// number of order in the square matrix
661 /// maximum number triggered by the rule
665 impl Default for pid_fuzzy {
667 fn default() -> Self {
677 opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
688 fn a_pid_fuzzy_opr(opr: c_uint) -> extern "C" fn(float, float) -> float;
689 fn a_pid_fuzzy_set_opr(ctx: *mut pid_fuzzy, opr: c_uint);
690 fn a_pid_fuzzy_bfuzz(ctx: *const pid_fuzzy) -> *mut u8;
691 fn a_pid_fuzzy_set_bfuzz(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
692 fn a_pid_fuzzy_set_rule(
701 fn a_pid_fuzzy_set_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
702 fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
703 fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
704 fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
705 fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
709 /// initialize for fuzzy PID controller
711 pub fn new() -> Self {
714 /// set fuzzy relational operator for fuzzy PID controller
716 pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
717 unsafe { a_pid_fuzzy_set_opr(self, opr) };
720 /// compute size of memory block for fuzzy PID controller
722 #[allow(non_snake_case)]
723 pub const fn BFUZZ(n: usize) -> usize {
724 size_of::<c_uint>() * n * 2 + size_of::<float>() * n * (2 + n)
726 /// get memory block for fuzzy PID controller
728 pub fn bfuzz(&mut self) -> &mut [u8] {
729 unsafe { from_raw_parts_mut(a_pid_fuzzy_bfuzz(self), Self::BFUZZ(self.nfuzz as usize)) }
731 /// set memory block for fuzzy PID controller
733 pub fn set_bfuzz(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
734 unsafe { a_pid_fuzzy_set_bfuzz(self, ptr.as_mut_ptr(), num) };
737 /// set rule base for fuzzy PID controller
749 a_pid_fuzzy_set_rule(
761 /// set proportional integral derivative constant for fuzzy PID controller
763 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
764 unsafe { a_pid_fuzzy_set_kpid(self, kp, ki, kd) };
767 /// calculate for fuzzy PID controller
769 pub fn run(&mut self, set: float, fdb: float) -> float {
770 unsafe { a_pid_fuzzy_run(self, set, fdb) }
772 /// calculate for positional fuzzy PID controller
774 pub fn pos(&mut self, set: float, fdb: float) -> float {
775 unsafe { a_pid_fuzzy_pos(self, set, fdb) }
777 /// calculate for incremental fuzzy PID controller
779 pub fn inc(&mut self, set: float, fdb: float) -> float {
780 unsafe { a_pid_fuzzy_inc(self, set, fdb) }
782 /// zeroing for fuzzy PID controller
784 pub fn zero(&mut self) -> &mut Self {
785 unsafe { a_pid_fuzzy_zero(self) };
790 /// single neuron proportional integral derivative controller
792 pub struct pid_neuro {
793 /// proportional integral derivative controller
795 /// proportional coefficient
797 /// proportional weight
801 /// derivative weight
807 impl Default for pid_neuro {
809 fn default() -> Self {
822 fn a_pid_neuro_set_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
823 fn a_pid_neuro_set_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
824 fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
825 fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
826 fn a_pid_neuro_zero(ctx: *mut pid_neuro);
830 /// initialize for single neuron PID controller
832 pub fn new() -> Self {
835 /// set proportional integral derivative constant for single neuron PID controller
837 pub fn set_kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
838 unsafe { a_pid_neuro_set_kpid(self, k, kp, ki, kd) };
841 /// set proportional integral derivative weight for single neuron PID controller
843 pub fn set_wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
844 unsafe { a_pid_neuro_set_wpid(self, wp, wi, wd) };
847 /// calculate for single neuron PID controller
849 pub fn run(&mut self, set: float, fdb: float) -> float {
850 unsafe { a_pid_neuro_run(self, set, fdb) }
852 /// calculate for incremental single neuron PID controller
854 pub fn inc(&mut self, set: float, fdb: float) -> float {
855 unsafe { a_pid_neuro_inc(self, set, fdb) }
857 /// zeroing for single neuron PID controller
859 pub fn zero(&mut self) -> &mut Self {
860 unsafe { a_pid_neuro_zero(self) };
865 /// simple linear regression
867 pub struct regress_simple {
868 /// regression coefficient
875 fn a_regress_simple_eval(ctx: *const regress_simple, val: float) -> float;
876 fn a_regress_simple_evar(ctx: *const regress_simple, val: float) -> float;
877 fn a_regress_simple_ols_(
878 ctx: *mut regress_simple,
885 fn a_regress_simple_olsx(
886 ctx: *mut regress_simple,
892 fn a_regress_simple_olsy(
893 ctx: *mut regress_simple,
899 fn a_regress_simple_ols(ctx: *mut regress_simple, n: usize, x: *const float, y: *const float);
900 fn a_regress_simple_zero(ctx: *mut regress_simple);
903 impl regress_simple {
904 /// initialize for simple linear regression
906 pub fn new(coef: float, bias: float) -> Self {
909 /// calculate predicted value for simple linear regression
911 pub fn eval(&self, val: float) -> float {
912 unsafe { a_regress_simple_eval(self, val) }
914 /// calculate predicted value for simple linear regression
916 pub fn evar(&self, val: float) -> float {
917 unsafe { a_regress_simple_evar(self, val) }
919 /// ordinary least squares for simple linear regression
921 pub fn ols_(&mut self, x: &[float], y: &[float], x_mean: float, y_mean: float) -> &mut Self {
922 unsafe { a_regress_simple_ols_(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean, y_mean) };
925 /// ordinary least squares for simple linear regression
927 pub fn olsx(&mut self, x: &[float], y: &[float], x_mean: float) -> &mut Self {
928 unsafe { a_regress_simple_olsx(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean) };
931 /// ordinary least squares for simple linear regression
933 pub fn olsy(&mut self, x: &[float], y: &[float], y_mean: float) -> &mut Self {
934 unsafe { a_regress_simple_olsy(self, x.len(), x.as_ptr(), y.as_ptr(), y_mean) };
937 /// ordinary least squares for simple linear regression
939 pub fn ols(&mut self, x: &[float], y: &[float]) -> &mut Self {
940 unsafe { a_regress_simple_ols(self, x.len(), x.as_ptr(), y.as_ptr()) };
943 /// zeroing for simple linear regression
945 pub fn zero(&mut self) -> &mut Self {
946 unsafe { a_regress_simple_zero(self) };
951 /// transfer function
964 /// denominator number
969 fn a_tf_set_num(ctx: *mut tf, num_n: c_uint, num_p: *const float, input: *mut float);
970 fn a_tf_set_den(ctx: *mut tf, den_n: c_uint, den_p: *const float, output: *mut float);
980 fn a_tf_iter(ctx: *const tf, x: float) -> float;
981 fn a_tf_zero(ctx: *const tf);
985 /// initialize for transfer function
987 pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
988 let mut ctx: Self = Self {
1002 den.len() as c_uint,
1004 output.as_mut_ptr(),
1009 /// calculate for transfer function
1011 pub fn iter(&mut self, x: float) -> float {
1012 unsafe { a_tf_iter(self, x) }
1014 /// zeroing for transfer function
1016 pub fn zero(&mut self) -> &mut Self {
1017 unsafe { a_tf_zero(self) };
1020 /// get input for transfer function
1022 pub fn input(&self) -> &[float] {
1023 unsafe { from_raw_parts(self.input, self.num_n as usize) }
1025 /// get numerator for transfer function
1027 pub fn num(&self) -> &[float] {
1028 unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
1030 /// set numerator for transfer function
1032 pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
1033 unsafe { a_tf_set_num(self, num.len() as c_uint, num.as_ptr(), input.as_mut_ptr()) };
1036 /// get output for transfer function
1038 pub fn output(&self) -> &[float] {
1039 unsafe { from_raw_parts(self.output, self.den_n as usize) }
1041 /// get denominator for transfer function
1043 pub fn den(&self) -> &[float] {
1044 unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
1046 /// set denominator for transfer function
1048 pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
1049 unsafe { a_tf_set_den(self, den.len() as c_uint, den.as_ptr(), output.as_mut_ptr()) };
1054 /// bell-shaped velocity trajectory
1056 pub struct trajbell {
1059 /// constant velocity phase
1061 /// acceleration phase
1063 /// deceleration phase
1065 /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
1067 /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
1069 /// initial position
1073 /// initial velocity
1077 /// maximum velocity
1081 /// maximum acceleration
1083 /// maximum deceleration
1087 impl Default for trajbell {
1089 fn default() -> Self {
1120 fn a_trajbell_pos(ctx: *const trajbell, x: float) -> float;
1121 fn a_trajbell_vel(ctx: *const trajbell, x: float) -> float;
1122 fn a_trajbell_acc(ctx: *const trajbell, x: float) -> float;
1123 fn a_trajbell_jer(ctx: *const trajbell, x: float) -> float;
1127 /// initialize for bell-shaped velocity trajectory
1129 pub fn new() -> Self {
1132 /// generate for bell-shaped velocity trajectory
1133 #[allow(clippy::too_many_arguments)]
1145 unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1147 /// calculate position for bell-shaped velocity trajectory
1149 pub fn pos(&mut self, x: float) -> float {
1150 unsafe { a_trajbell_pos(self, x) }
1152 /// calculate velocity for bell-shaped velocity trajectory
1154 pub fn vel(&mut self, x: float) -> float {
1155 unsafe { a_trajbell_vel(self, x) }
1157 /// calculate acceleration for bell-shaped velocity trajectory
1159 pub fn acc(&mut self, x: float) -> float {
1160 unsafe { a_trajbell_acc(self, x) }
1162 /// calculate jerk for bell-shaped velocity trajectory
1164 pub fn jer(&mut self, x: float) -> float {
1165 unsafe { a_trajbell_jer(self, x) }
1169 /// cubic polynomial trajectory
1171 pub struct trajpoly3 {
1172 /// coefficients of position
1174 /// coefficients of velocity
1176 /// coefficients of acceleration
1181 fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, p0: float, p1: float, v0: float, v1: float);
1182 fn a_trajpoly3_pos(ctx: *const trajpoly3, x: float) -> float;
1183 fn a_trajpoly3_vel(ctx: *const trajpoly3, x: float) -> float;
1184 fn a_trajpoly3_acc(ctx: *const trajpoly3, x: float) -> float;
1188 /// initialize for cubic polynomial trajectory
1190 pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1191 let mut ctx: Self = Self {
1196 unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1199 /// generate for cubic polynomial trajectory
1201 pub fn gen(&mut self, ts: float, p0: float, p1: float, v0: float, v1: float) -> &mut Self {
1202 unsafe { a_trajpoly3_gen(self, ts, p0, p1, v0, v1) };
1205 /// calculate position for cubic polynomial trajectory
1207 pub fn pos(&mut self, x: float) -> float {
1208 unsafe { a_trajpoly3_pos(self, x) }
1210 /// calculate velocity for cubic polynomial trajectory
1212 pub fn vel(&mut self, x: float) -> float {
1213 unsafe { a_trajpoly3_vel(self, x) }
1215 /// calculate acceleration for cubic polynomial trajectory
1217 pub fn acc(&mut self, x: float) -> float {
1218 unsafe { a_trajpoly3_acc(self, x) }
1222 /// quintic polynomial trajectory
1224 pub struct trajpoly5 {
1225 /// coefficients of position
1227 /// coefficients of velocity
1229 /// coefficients of acceleration
1235 ctx: *mut trajpoly5,
1244 fn a_trajpoly5_pos(ctx: *const trajpoly5, x: float) -> float;
1245 fn a_trajpoly5_vel(ctx: *const trajpoly5, x: float) -> float;
1246 fn a_trajpoly5_acc(ctx: *const trajpoly5, x: float) -> float;
1250 /// initialize for quintic polynomial trajectory
1251 #[allow(clippy::too_many_arguments)]
1262 let mut ctx: Self = Self {
1267 unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1270 /// generate for quintic polynomial trajectory
1271 #[allow(clippy::too_many_arguments)]
1283 unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1286 /// calculate position for quintic polynomial trajectory
1288 pub fn pos(&mut self, x: float) -> float {
1289 unsafe { a_trajpoly5_pos(self, x) }
1291 /// calculate velocity for quintic polynomial trajectory
1293 pub fn vel(&mut self, x: float) -> float {
1294 unsafe { a_trajpoly5_vel(self, x) }
1296 /// calculate acceleration for quintic polynomial trajectory
1298 pub fn acc(&mut self, x: float) -> float {
1299 unsafe { a_trajpoly5_acc(self, x) }
1303 /// hepta polynomial trajectory
1305 pub struct trajpoly7 {
1306 /// coefficients of position
1308 /// coefficients of velocity
1310 /// coefficients of acceleration
1312 /// coefficients of jerk
1318 ctx: *mut trajpoly7,
1329 fn a_trajpoly7_pos(ctx: *const trajpoly7, x: float) -> float;
1330 fn a_trajpoly7_vel(ctx: *const trajpoly7, x: float) -> float;
1331 fn a_trajpoly7_acc(ctx: *const trajpoly7, x: float) -> float;
1332 fn a_trajpoly7_jer(ctx: *const trajpoly7, x: float) -> float;
1336 /// initialize for hepta polynomial trajectory
1337 #[allow(clippy::too_many_arguments)]
1350 let mut ctx: Self = Self {
1356 unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1359 /// generate for hepta polynomial trajectory
1360 #[allow(clippy::too_many_arguments)]
1374 unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1377 /// calculate position for hepta polynomial trajectory
1379 pub fn pos(&mut self, x: float) -> float {
1380 unsafe { a_trajpoly7_pos(self, x) }
1382 /// calculate velocity for hepta polynomial trajectory
1384 pub fn vel(&mut self, x: float) -> float {
1385 unsafe { a_trajpoly7_vel(self, x) }
1387 /// calculate acceleration for hepta polynomial trajectory
1389 pub fn acc(&mut self, x: float) -> float {
1390 unsafe { a_trajpoly7_acc(self, x) }
1392 /// calculate jerk for hepta polynomial trajectory
1394 pub fn jer(&mut self, x: float) -> float {
1395 unsafe { a_trajpoly7_jer(self, x) }
1399 /// trapezoidal velocity trajectory
1401 pub struct trajtrap {
1404 /// initial position
1408 /// initial velocity
1412 /// constant velocity
1414 /// time before constant velocity
1416 /// time after constant velocity
1418 /// position before constant velocity
1420 /// position after constant velocity
1422 /// acceleration before constant velocity
1424 /// acceleration after constant velocity
1428 impl Default for trajtrap {
1430 fn default() -> Self {
1459 fn a_trajtrap_pos(ctx: *const trajtrap, x: float) -> float;
1460 fn a_trajtrap_vel(ctx: *const trajtrap, x: float) -> float;
1461 fn a_trajtrap_acc(ctx: *const trajtrap, x: float) -> float;
1465 /// initialize for trapezoidal velocity trajectory
1467 pub fn new() -> Self {
1470 /// generate for trapezoidal velocity trajectory
1471 #[allow(clippy::too_many_arguments)]
1483 unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1485 /// calculate position for trapezoidal velocity trajectory
1487 pub fn pos(&mut self, x: float) -> float {
1488 unsafe { a_trajtrap_pos(self, x) }
1490 /// calculate velocity for trapezoidal velocity trajectory
1492 pub fn vel(&mut self, x: float) -> float {
1493 unsafe { a_trajtrap_vel(self, x) }
1495 /// calculate acceleration for trapezoidal velocity trajectory
1497 pub fn acc(&mut self, x: float) -> float {
1498 unsafe { a_trajtrap_acc(self, x) }
1504 pub struct version {
1517 impl Default for version {
1519 fn default() -> Self {
1525 alpha: [b'.', 0, 0, 0],
1531 static a_version_major: c_uint;
1532 static a_version_minor: c_uint;
1533 static a_version_patch: c_uint;
1534 static a_version_tweak: u32;
1535 fn a_version_set_alpha(ctx: *mut version, alpha: *const u8);
1536 fn a_version_alpha(ctx: *const version, alpha: &mut [u8; 5]);
1537 fn a_version_parse(ctx: *mut version, ver: *const u8) -> c_uint;
1538 fn a_version_tostr(ctx: *const version, p: *mut u8, n: usize) -> c_int;
1539 fn a_version_cmp(ctx: *const version, rhs: *const version) -> c_int;
1540 fn a_version_lt(ctx: *const version, rhs: *const version) -> bool;
1541 fn a_version_gt(ctx: *const version, rhs: *const version) -> bool;
1542 fn a_version_le(ctx: *const version, rhs: *const version) -> bool;
1543 fn a_version_ge(ctx: *const version, rhs: *const version) -> bool;
1544 fn a_version_eq(ctx: *const version, rhs: *const version) -> bool;
1545 fn a_version_check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int;
1549 /// initialize for version
1551 pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1556 ..Default::default()
1559 /// set alphabet for version
1561 pub fn set_alpha(&mut self, alpha: &[u8]) {
1562 unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1564 /// get alphabet for version
1566 pub fn alpha(&self, alpha: &mut [u8; 5]) {
1567 unsafe { a_version_alpha(self, alpha) }
1569 /// parse version string to version
1571 pub fn parse(&mut self, ver: &str) -> c_uint {
1572 unsafe { a_version_parse(self, ver.as_ptr()) }
1574 /// convert version to string
1576 pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1577 unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1579 /// algorithm library version check
1581 pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1582 unsafe { a_version_check(major, minor, patch) }
1584 /// algorithm library version major
1586 pub fn major() -> c_uint {
1587 unsafe { a_version_major }
1589 /// algorithm library version minor
1591 pub fn minor() -> c_uint {
1592 unsafe { a_version_minor }
1594 /// algorithm library version patch
1596 pub fn patch() -> c_uint {
1597 unsafe { a_version_patch }
1599 /// algorithm library version tweak
1601 pub fn tweak() -> u32 {
1602 unsafe { a_version_tweak }
1606 impl PartialOrd for version {
1608 fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1609 let ok: c_int = unsafe { a_version_cmp(self, other) };
1611 return Some(Ordering::Greater);
1614 return Some(Ordering::Less);
1616 Some(Ordering::Equal)
1619 fn lt(&self, other: &version) -> bool {
1620 unsafe { a_version_lt(self, other) }
1623 fn gt(&self, other: &version) -> bool {
1624 unsafe { a_version_gt(self, other) }
1627 fn le(&self, other: &version) -> bool {
1628 unsafe { a_version_le(self, other) }
1631 fn ge(&self, other: &version) -> bool {
1632 unsafe { a_version_ge(self, other) }
1636 impl PartialEq for version {
1638 fn eq(&self, other: &version) -> bool {
1639 unsafe { a_version_eq(self, other) }