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_float_sum(p: *const float, n: usize) -> float;
92 fn a_float_sum1(p: *const float, n: usize) -> float;
93 fn a_float_sum2(p: *const float, n: usize) -> float;
94 fn a_float_mean(p: *const float, n: usize) -> float;
97 /// calculate the sum of a float array
99 pub fn float_sum(x: &[float]) -> float {
100 unsafe { a_float_sum(x.as_ptr(), x.len()) }
102 /// calculate the absolute sum of a float array
104 pub fn float_sum1(x: &[float]) -> float {
105 unsafe { a_float_sum1(x.as_ptr(), x.len()) }
107 /// calculate the sum of squares of a float array
109 pub fn float_sum2(x: &[float]) -> float {
110 unsafe { a_float_sum2(x.as_ptr(), x.len()) }
112 /// calculate the mean of a float array
114 pub fn float_mean(x: &[float]) -> float {
115 unsafe { a_float_mean(x.as_ptr(), x.len()) }
119 fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
120 fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
123 /// a hash function whose prime number is 131
125 pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
126 unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
128 /// a hash function whose prime number is 65599
130 pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
131 unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
134 /// Cyclic Redundancy Check for 8 bits
137 /// Cyclic Redundancy Check comparison table
138 pub table: [u8; 0x100],
142 fn a_crc8m_init(table: *mut u8, poly: u8);
143 fn a_crc8l_init(table: *mut u8, poly: u8);
144 fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
148 /// initialize for MSB CRC-8
150 pub fn new_msb(poly: u8) -> Self {
151 let mut ctx: Self = Self { table: [0; 0x100] };
152 unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
155 /// initialize for LSB CRC-8
157 pub fn new_lsb(poly: u8) -> Self {
158 let mut ctx: Self = Self { table: [0; 0x100] };
159 unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
162 /// generate for MSB CRC-8
164 pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
165 unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
168 /// generate for LSB CRC-8
170 pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
171 unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
174 /// calculate for CRC-8
176 pub fn eval(self, block: &[u8], value: u8) -> u8 {
177 unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
181 /// Cyclic Redundancy Check for 16 bits
184 /// Cyclic Redundancy Check comparison table
185 pub table: [u16; 0x100],
186 eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
190 fn a_crc16m_init(table: *mut u16, poly: u16);
191 fn a_crc16l_init(table: *mut u16, poly: u16);
192 fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
193 fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
197 /// initialize for MSB CRC-16
199 pub fn new_msb(poly: u16) -> Self {
200 let mut ctx: Self = Self {
204 unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
207 /// initialize for LSB CRC-16
209 pub fn new_lsb(poly: u16) -> Self {
210 let mut ctx: Self = Self {
214 unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
217 /// generate for MSB CRC-16
219 pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
220 unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
221 self.eval = a_crc16m;
224 /// generate for LSB CRC-16
226 pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
227 unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
228 self.eval = a_crc16l;
231 /// calculate for CRC-16
233 pub fn eval(self, block: &[u8], value: u16) -> u16 {
234 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
238 /// Cyclic Redundancy Check for 32 bits
241 /// Cyclic Redundancy Check comparison table
242 pub table: [u32; 0x100],
243 eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
247 fn a_crc32m_init(table: *mut u32, poly: u32);
248 fn a_crc32l_init(table: *mut u32, poly: u32);
249 fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
250 fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
254 /// initialize for MSB CRC-32
256 pub fn new_msb(poly: u32) -> Self {
257 let mut ctx: Self = Self {
261 unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
264 /// initialize for LSB CRC-32
266 pub fn new_lsb(poly: u32) -> Self {
267 let mut ctx: Self = Self {
271 unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
274 /// generate for MSB CRC-32
276 pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
277 unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
278 self.eval = a_crc32m;
281 /// generate for LSB CRC-32
283 pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
284 unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
285 self.eval = a_crc32l;
288 /// calculate for CRC-32
290 pub fn eval(self, block: &[u8], value: u32) -> u32 {
291 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
295 /// Cyclic Redundancy Check for 64 bits
298 /// Cyclic Redundancy Check comparison table
299 pub table: [u64; 0x100],
300 eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
304 fn a_crc64m_init(table: *mut u64, poly: u64);
305 fn a_crc64l_init(table: *mut u64, poly: u64);
306 fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
307 fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
311 /// initialize for MSB CRC-64
313 pub fn new_msb(poly: u64) -> Self {
314 let mut ctx: Self = Self {
318 unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
321 /// initialize for LSB CRC-64
323 pub fn new_lsb(poly: u64) -> Self {
324 let mut ctx: Self = Self {
328 unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
331 /// generate for MSB CRC-64
333 pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
334 unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
335 self.eval = a_crc64m;
338 /// generate for LSB CRC-64
340 pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
341 unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
342 self.eval = a_crc64l;
345 /// calculate for CRC-64
347 pub fn eval(self, block: &[u8], value: u64) -> u64 {
348 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
352 #[allow(clippy::excessive_precision)]
353 const TAU: float = 6.28318530717958647692528676655900577;
358 /// filter coefficient
367 /// initialize for High Pass Filter
369 pub fn new(fc: float, ts: float) -> Self {
371 alpha: 1.0 / (TAU * fc * ts + 1.0),
376 /// generate for High Pass Filter
378 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
379 self.alpha = 1.0 / (TAU * fc * ts + 1.0);
382 /// calculate for High Pass Filter
384 pub fn iter(&mut self, x: float) -> float {
385 self.output = self.alpha * (self.output + x - self.input);
389 /// zeroing for High Pass Filter
391 pub fn zero(&mut self) -> &mut Self {
398 #[allow(clippy::excessive_precision)]
399 const _1_TAU: float = 0.159154943091895335768883763372514362;
404 /// filter coefficient
411 /// initialize for Low Pass Filter
413 pub fn new(fc: float, ts: float) -> Self {
415 alpha: ts / (_1_TAU / fc + ts),
419 /// generate for Low Pass Filter
421 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
422 self.alpha = ts / (_1_TAU / fc + ts);
425 /// calculate for Low Pass Filter
427 pub fn iter(&mut self, x: float) -> float {
428 self.output *= 1.0 - self.alpha;
429 self.output += x * self.alpha;
432 /// zeroing for Low Pass Filter
434 pub fn zero(&mut self) -> &mut Self {
440 /// membership function
444 pub const NUL: c_int = 0;
445 /// gaussian membership function
446 pub const GAUSS: c_int = 1;
447 /// gaussian combination membership function
448 pub const GAUSS2: c_int = 2;
449 /// generalized bell-shaped membership function
450 pub const GBELL: c_int = 3;
451 /// sigmoidal membership function
452 pub const SIG: c_int = 4;
453 /// difference between two sigmoidal membership functions
454 pub const DSIG: c_int = 5;
455 /// product of two sigmoidal membership functions
456 pub const PSIG: c_int = 6;
457 /// trapezoidal membership function
458 pub const TRAP: c_int = 7;
459 /// triangular membership function
460 pub const TRI: c_int = 8;
461 /// linear s-shaped saturation membership function
462 pub const LINS: c_int = 9;
463 /// linear z-shaped saturation membership function
464 pub const LINZ: c_int = 10;
465 /// s-shaped membership function
466 pub const S: c_int = 11;
467 /// z-shaped membership function
468 pub const Z: c_int = 12;
469 /// pi-shaped membership function
470 pub const PI: c_int = 13;
474 fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
475 fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
476 fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
477 fn a_mf_sig(x: float, a: float, c: float) -> float;
478 fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
479 fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
480 fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
481 fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
482 fn a_mf_lins(x: float, a: float, b: float) -> float;
483 fn a_mf_linz(x: float, a: float, b: float) -> float;
484 fn a_mf_s(x: float, a: float, b: float) -> float;
485 fn a_mf_z(x: float, a: float, b: float) -> float;
486 fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
489 /// gaussian membership function
491 pub fn gauss(x: float, sigma: float, c: float) -> float {
492 unsafe { a_mf_gauss(x, sigma, c) }
494 /// gaussian combination membership function
496 pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
497 unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
499 /// generalized bell-shaped membership function
501 pub fn gbell(x: float, a: float, b: float, c: float) -> float {
502 unsafe { a_mf_gbell(x, a, b, c) }
504 /// sigmoidal membership function
506 pub fn sig(x: float, a: float, c: float) -> float {
507 unsafe { a_mf_sig(x, a, c) }
509 /// difference between two sigmoidal membership functions
511 pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
512 unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
514 /// product of two sigmoidal membership functions
516 pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
517 unsafe { a_mf_psig(x, a1, c1, a2, c2) }
519 /// trapezoidal membership function
521 pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
522 unsafe { a_mf_trap(x, a, b, c, d) }
524 /// triangular membership function
526 pub fn tri(x: float, a: float, b: float, c: float) -> float {
527 unsafe { a_mf_tri(x, a, b, c) }
529 /// linear s-shaped saturation membership function
531 pub fn lins(x: float, a: float, b: float) -> float {
532 unsafe { a_mf_lins(x, a, b) }
534 /// linear z-shaped saturation membership function
536 pub fn linz(x: float, a: float, b: float) -> float {
537 unsafe { a_mf_linz(x, a, b) }
539 /// s-shaped membership function
541 pub fn s(x: float, a: float, b: float) -> float {
542 unsafe { a_mf_s(x, a, b) }
544 /// z-shaped membership function
546 pub fn z(x: float, a: float, b: float) -> float {
547 unsafe { a_mf_z(x, a, b) }
549 /// pi-shaped membership function
551 pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
552 unsafe { a_mf_pi(x, a, b, c, d) }
556 /// proportional integral derivative controller
559 /// proportional constant
561 /// integral constant
563 /// derivative constant
565 /// maximum integral output
567 /// minimum integral output
569 /// controller integral output
571 /// maximum final output
573 /// minimum final output
575 /// controller final output
585 impl Default for pid {
587 fn default() -> Self {
592 summax: float::INFINITY,
593 summin: -float::INFINITY,
595 outmax: float::INFINITY,
596 outmin: -float::INFINITY,
606 fn a_pid_set_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
607 fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
608 fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
609 fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
610 fn a_pid_zero(ctx: *mut pid);
614 /// initialize for PID controller
616 pub fn new() -> Self {
619 /// set proportional integral derivative constant for PID controller
621 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
622 unsafe { a_pid_set_kpid(self, kp, ki, kd) };
625 /// calculate for PID controller
627 pub fn run(&mut self, set: float, fdb: float) -> float {
628 unsafe { a_pid_run(self, set, fdb) }
630 /// calculate for positional PID controller
632 pub fn pos(&mut self, set: float, fdb: float) -> float {
633 unsafe { a_pid_pos(self, set, fdb) }
635 /// calculate for incremental PID controller
637 pub fn inc(&mut self, set: float, fdb: float) -> float {
638 unsafe { a_pid_inc(self, set, fdb) }
640 /// zeroing for PID controller
642 pub fn zero(&mut self) -> &mut Self {
643 unsafe { a_pid_zero(self) };
648 /// fuzzy PID controller operator
652 pub const CAP: c_uint = 1;
654 pub const CAP_ALGEBRA: c_uint = 2;
656 pub const CAP_BOUNDED: c_uint = 3;
658 pub const CUP: c_uint = 4;
660 pub const CUP_ALGEBRA: c_uint = 5;
662 pub const CUP_BOUNDED: c_uint = 6;
663 /// sqrt(a,b)*sqrt(1-(1-a)*(1-b))
664 pub const EQU: c_uint = 0;
667 /// fuzzy proportional integral derivative controller
669 pub struct pid_fuzzy {
670 /// proportional integral derivative controller
679 /// fuzzy relational operator
680 opr: extern "C" fn(float, float) -> float,
681 /// base proportional constant
683 /// base integral constant
685 /// base derivative constant
687 /// number of order in the square matrix
689 /// maximum number triggered by the rule
693 impl Default for pid_fuzzy {
695 fn default() -> Self {
705 opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
716 fn a_pid_fuzzy_opr(opr: c_uint) -> extern "C" fn(float, float) -> float;
717 fn a_pid_fuzzy_set_opr(ctx: *mut pid_fuzzy, opr: c_uint);
718 fn a_pid_fuzzy_bfuzz(ctx: *const pid_fuzzy) -> *mut u8;
719 fn a_pid_fuzzy_set_bfuzz(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
720 fn a_pid_fuzzy_set_rule(
729 fn a_pid_fuzzy_set_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
730 fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
731 fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
732 fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
733 fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
737 /// initialize for fuzzy PID controller
739 pub fn new() -> Self {
742 /// set fuzzy relational operator for fuzzy PID controller
744 pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
745 unsafe { a_pid_fuzzy_set_opr(self, opr) };
748 /// compute size of memory block for fuzzy PID controller
750 #[allow(non_snake_case)]
751 pub const fn BFUZZ(n: usize) -> usize {
752 size_of::<c_uint>() * n * 2 + size_of::<float>() * n * (2 + n)
754 /// get memory block for fuzzy PID controller
756 pub fn bfuzz(&mut self) -> &mut [u8] {
757 unsafe { from_raw_parts_mut(a_pid_fuzzy_bfuzz(self), Self::BFUZZ(self.nfuzz as usize)) }
759 /// set memory block for fuzzy PID controller
761 pub fn set_bfuzz(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
762 unsafe { a_pid_fuzzy_set_bfuzz(self, ptr.as_mut_ptr(), num) };
765 /// set rule base for fuzzy PID controller
777 a_pid_fuzzy_set_rule(
789 /// set proportional integral derivative constant for fuzzy PID controller
791 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
792 unsafe { a_pid_fuzzy_set_kpid(self, kp, ki, kd) };
795 /// calculate for fuzzy PID controller
797 pub fn run(&mut self, set: float, fdb: float) -> float {
798 unsafe { a_pid_fuzzy_run(self, set, fdb) }
800 /// calculate for positional fuzzy PID controller
802 pub fn pos(&mut self, set: float, fdb: float) -> float {
803 unsafe { a_pid_fuzzy_pos(self, set, fdb) }
805 /// calculate for incremental fuzzy PID controller
807 pub fn inc(&mut self, set: float, fdb: float) -> float {
808 unsafe { a_pid_fuzzy_inc(self, set, fdb) }
810 /// zeroing for fuzzy PID controller
812 pub fn zero(&mut self) -> &mut Self {
813 unsafe { a_pid_fuzzy_zero(self) };
818 /// single neuron proportional integral derivative controller
820 pub struct pid_neuro {
821 /// proportional integral derivative controller
823 /// proportional coefficient
825 /// proportional weight
829 /// derivative weight
835 impl Default for pid_neuro {
837 fn default() -> Self {
850 fn a_pid_neuro_set_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
851 fn a_pid_neuro_set_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
852 fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
853 fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
854 fn a_pid_neuro_zero(ctx: *mut pid_neuro);
858 /// initialize for single neuron PID controller
860 pub fn new() -> Self {
863 /// set proportional integral derivative constant for single neuron PID controller
865 pub fn set_kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
866 unsafe { a_pid_neuro_set_kpid(self, k, kp, ki, kd) };
869 /// set proportional integral derivative weight for single neuron PID controller
871 pub fn set_wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
872 unsafe { a_pid_neuro_set_wpid(self, wp, wi, wd) };
875 /// calculate for single neuron PID controller
877 pub fn run(&mut self, set: float, fdb: float) -> float {
878 unsafe { a_pid_neuro_run(self, set, fdb) }
880 /// calculate for incremental single neuron PID controller
882 pub fn inc(&mut self, set: float, fdb: float) -> float {
883 unsafe { a_pid_neuro_inc(self, set, fdb) }
885 /// zeroing for single neuron PID controller
887 pub fn zero(&mut self) -> &mut Self {
888 unsafe { a_pid_neuro_zero(self) };
893 /// simple linear regression
895 pub struct regress_simple {
896 /// regression coefficient
903 fn a_regress_simple_eval(ctx: *const regress_simple, val: float) -> float;
904 fn a_regress_simple_evar(ctx: *const regress_simple, val: float) -> float;
905 fn a_regress_simple_ols_(
906 ctx: *mut regress_simple,
913 fn a_regress_simple_olsx(
914 ctx: *mut regress_simple,
920 fn a_regress_simple_olsy(
921 ctx: *mut regress_simple,
927 fn a_regress_simple_ols(ctx: *mut regress_simple, n: usize, x: *const float, y: *const float);
928 fn a_regress_simple_zero(ctx: *mut regress_simple);
931 impl regress_simple {
932 /// initialize for simple linear regression
934 pub fn new(coef: float, bias: float) -> Self {
937 /// calculate predicted value for simple linear regression
939 pub fn eval(&self, val: float) -> float {
940 unsafe { a_regress_simple_eval(self, val) }
942 /// calculate predicted value for simple linear regression
944 pub fn evar(&self, val: float) -> float {
945 unsafe { a_regress_simple_evar(self, val) }
947 /// ordinary least squares for simple linear regression
949 pub fn ols_(&mut self, x: &[float], y: &[float], x_mean: float, y_mean: float) -> &mut Self {
950 let n = x.len().min(y.len());
951 unsafe { a_regress_simple_ols_(self, n, x.as_ptr(), y.as_ptr(), x_mean, y_mean) };
954 /// ordinary least squares for simple linear regression
956 pub fn olsx(&mut self, x: &[float], y: &[float], x_mean: float) -> &mut Self {
957 let n = x.len().min(y.len());
958 unsafe { a_regress_simple_olsx(self, n, x.as_ptr(), y.as_ptr(), x_mean) };
961 /// ordinary least squares for simple linear regression
963 pub fn olsy(&mut self, x: &[float], y: &[float], y_mean: float) -> &mut Self {
964 let n = x.len().min(y.len());
965 unsafe { a_regress_simple_olsy(self, n, x.as_ptr(), y.as_ptr(), y_mean) };
968 /// ordinary least squares for simple linear regression
970 pub fn ols(&mut self, x: &[float], y: &[float]) -> &mut Self {
971 let n = x.len().min(y.len());
972 unsafe { a_regress_simple_ols(self, n, x.as_ptr(), y.as_ptr()) };
975 /// zeroing for simple linear regression
977 pub fn zero(&mut self) -> &mut Self {
978 unsafe { a_regress_simple_zero(self) };
983 /// transfer function
996 /// denominator number
1001 fn a_tf_set_num(ctx: *mut tf, num_n: c_uint, num_p: *const float, input: *mut float);
1002 fn a_tf_set_den(ctx: *mut tf, den_n: c_uint, den_p: *const float, output: *mut float);
1006 num_p: *const float,
1009 den_p: *const float,
1012 fn a_tf_iter(ctx: *const tf, x: float) -> float;
1013 fn a_tf_zero(ctx: *const tf);
1017 /// initialize for transfer function
1019 pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
1020 let mut ctx: Self = Self {
1031 num.len() as c_uint,
1034 den.len() as c_uint,
1036 output.as_mut_ptr(),
1041 /// calculate for transfer function
1043 pub fn iter(&mut self, x: float) -> float {
1044 unsafe { a_tf_iter(self, x) }
1046 /// zeroing for transfer function
1048 pub fn zero(&mut self) -> &mut Self {
1049 unsafe { a_tf_zero(self) };
1052 /// get input for transfer function
1054 pub fn input(&self) -> &[float] {
1055 unsafe { from_raw_parts(self.input, self.num_n as usize) }
1057 /// get numerator for transfer function
1059 pub fn num(&self) -> &[float] {
1060 unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
1062 /// set numerator for transfer function
1064 pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
1065 unsafe { a_tf_set_num(self, num.len() as c_uint, num.as_ptr(), input.as_mut_ptr()) };
1068 /// get output for transfer function
1070 pub fn output(&self) -> &[float] {
1071 unsafe { from_raw_parts(self.output, self.den_n as usize) }
1073 /// get denominator for transfer function
1075 pub fn den(&self) -> &[float] {
1076 unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
1078 /// set denominator for transfer function
1080 pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
1081 unsafe { a_tf_set_den(self, den.len() as c_uint, den.as_ptr(), output.as_mut_ptr()) };
1086 /// bell-shaped velocity trajectory
1088 pub struct trajbell {
1091 /// constant velocity phase
1093 /// acceleration phase
1095 /// deceleration phase
1097 /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
1099 /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
1101 /// initial position
1105 /// initial velocity
1109 /// maximum velocity
1113 /// maximum acceleration
1115 /// maximum deceleration
1119 impl Default for trajbell {
1121 fn default() -> Self {
1152 fn a_trajbell_pos(ctx: *const trajbell, x: float) -> float;
1153 fn a_trajbell_vel(ctx: *const trajbell, x: float) -> float;
1154 fn a_trajbell_acc(ctx: *const trajbell, x: float) -> float;
1155 fn a_trajbell_jer(ctx: *const trajbell, x: float) -> float;
1159 /// initialize for bell-shaped velocity trajectory
1161 pub fn new() -> Self {
1164 /// generate for bell-shaped velocity trajectory
1165 #[allow(clippy::too_many_arguments)]
1177 unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1179 /// calculate position for bell-shaped velocity trajectory
1181 pub fn pos(&mut self, x: float) -> float {
1182 unsafe { a_trajbell_pos(self, x) }
1184 /// calculate velocity for bell-shaped velocity trajectory
1186 pub fn vel(&mut self, x: float) -> float {
1187 unsafe { a_trajbell_vel(self, x) }
1189 /// calculate acceleration for bell-shaped velocity trajectory
1191 pub fn acc(&mut self, x: float) -> float {
1192 unsafe { a_trajbell_acc(self, x) }
1194 /// calculate jerk for bell-shaped velocity trajectory
1196 pub fn jer(&mut self, x: float) -> float {
1197 unsafe { a_trajbell_jer(self, x) }
1201 /// cubic polynomial trajectory
1203 pub struct trajpoly3 {
1204 /// coefficients of position
1206 /// coefficients of velocity
1208 /// coefficients of acceleration
1213 fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, p0: float, p1: float, v0: float, v1: float);
1214 fn a_trajpoly3_pos(ctx: *const trajpoly3, x: float) -> float;
1215 fn a_trajpoly3_vel(ctx: *const trajpoly3, x: float) -> float;
1216 fn a_trajpoly3_acc(ctx: *const trajpoly3, x: float) -> float;
1220 /// initialize for cubic polynomial trajectory
1222 pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1223 let mut ctx: Self = Self {
1228 unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1231 /// generate for cubic polynomial trajectory
1233 pub fn gen(&mut self, ts: float, p0: float, p1: float, v0: float, v1: float) -> &mut Self {
1234 unsafe { a_trajpoly3_gen(self, ts, p0, p1, v0, v1) };
1237 /// calculate position for cubic polynomial trajectory
1239 pub fn pos(&mut self, x: float) -> float {
1240 unsafe { a_trajpoly3_pos(self, x) }
1242 /// calculate velocity for cubic polynomial trajectory
1244 pub fn vel(&mut self, x: float) -> float {
1245 unsafe { a_trajpoly3_vel(self, x) }
1247 /// calculate acceleration for cubic polynomial trajectory
1249 pub fn acc(&mut self, x: float) -> float {
1250 unsafe { a_trajpoly3_acc(self, x) }
1254 /// quintic polynomial trajectory
1256 pub struct trajpoly5 {
1257 /// coefficients of position
1259 /// coefficients of velocity
1261 /// coefficients of acceleration
1267 ctx: *mut trajpoly5,
1276 fn a_trajpoly5_pos(ctx: *const trajpoly5, x: float) -> float;
1277 fn a_trajpoly5_vel(ctx: *const trajpoly5, x: float) -> float;
1278 fn a_trajpoly5_acc(ctx: *const trajpoly5, x: float) -> float;
1282 /// initialize for quintic polynomial trajectory
1283 #[allow(clippy::too_many_arguments)]
1294 let mut ctx: Self = Self {
1299 unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1302 /// generate for quintic polynomial trajectory
1303 #[allow(clippy::too_many_arguments)]
1315 unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1318 /// calculate position for quintic polynomial trajectory
1320 pub fn pos(&mut self, x: float) -> float {
1321 unsafe { a_trajpoly5_pos(self, x) }
1323 /// calculate velocity for quintic polynomial trajectory
1325 pub fn vel(&mut self, x: float) -> float {
1326 unsafe { a_trajpoly5_vel(self, x) }
1328 /// calculate acceleration for quintic polynomial trajectory
1330 pub fn acc(&mut self, x: float) -> float {
1331 unsafe { a_trajpoly5_acc(self, x) }
1335 /// hepta polynomial trajectory
1337 pub struct trajpoly7 {
1338 /// coefficients of position
1340 /// coefficients of velocity
1342 /// coefficients of acceleration
1344 /// coefficients of jerk
1350 ctx: *mut trajpoly7,
1361 fn a_trajpoly7_pos(ctx: *const trajpoly7, x: float) -> float;
1362 fn a_trajpoly7_vel(ctx: *const trajpoly7, x: float) -> float;
1363 fn a_trajpoly7_acc(ctx: *const trajpoly7, x: float) -> float;
1364 fn a_trajpoly7_jer(ctx: *const trajpoly7, x: float) -> float;
1368 /// initialize for hepta polynomial trajectory
1369 #[allow(clippy::too_many_arguments)]
1382 let mut ctx: Self = Self {
1388 unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1391 /// generate for hepta polynomial trajectory
1392 #[allow(clippy::too_many_arguments)]
1406 unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1409 /// calculate position for hepta polynomial trajectory
1411 pub fn pos(&mut self, x: float) -> float {
1412 unsafe { a_trajpoly7_pos(self, x) }
1414 /// calculate velocity for hepta polynomial trajectory
1416 pub fn vel(&mut self, x: float) -> float {
1417 unsafe { a_trajpoly7_vel(self, x) }
1419 /// calculate acceleration for hepta polynomial trajectory
1421 pub fn acc(&mut self, x: float) -> float {
1422 unsafe { a_trajpoly7_acc(self, x) }
1424 /// calculate jerk for hepta polynomial trajectory
1426 pub fn jer(&mut self, x: float) -> float {
1427 unsafe { a_trajpoly7_jer(self, x) }
1431 /// trapezoidal velocity trajectory
1433 pub struct trajtrap {
1436 /// initial position
1440 /// initial velocity
1444 /// constant velocity
1446 /// time before constant velocity
1448 /// time after constant velocity
1450 /// position before constant velocity
1452 /// position after constant velocity
1454 /// acceleration before constant velocity
1456 /// acceleration after constant velocity
1460 impl Default for trajtrap {
1462 fn default() -> Self {
1491 fn a_trajtrap_pos(ctx: *const trajtrap, x: float) -> float;
1492 fn a_trajtrap_vel(ctx: *const trajtrap, x: float) -> float;
1493 fn a_trajtrap_acc(ctx: *const trajtrap, x: float) -> float;
1497 /// initialize for trapezoidal velocity trajectory
1499 pub fn new() -> Self {
1502 /// generate for trapezoidal velocity trajectory
1503 #[allow(clippy::too_many_arguments)]
1515 unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1517 /// calculate position for trapezoidal velocity trajectory
1519 pub fn pos(&mut self, x: float) -> float {
1520 unsafe { a_trajtrap_pos(self, x) }
1522 /// calculate velocity for trapezoidal velocity trajectory
1524 pub fn vel(&mut self, x: float) -> float {
1525 unsafe { a_trajtrap_vel(self, x) }
1527 /// calculate acceleration for trapezoidal velocity trajectory
1529 pub fn acc(&mut self, x: float) -> float {
1530 unsafe { a_trajtrap_acc(self, x) }
1536 pub struct version {
1549 impl Default for version {
1551 fn default() -> Self {
1557 alpha: [b'.', 0, 0, 0],
1563 static a_version_major: c_uint;
1564 static a_version_minor: c_uint;
1565 static a_version_patch: c_uint;
1566 static a_version_tweak: u32;
1567 fn a_version_set_alpha(ctx: *mut version, alpha: *const u8);
1568 fn a_version_alpha(ctx: *const version, alpha: &mut [u8; 5]);
1569 fn a_version_parse(ctx: *mut version, ver: *const u8) -> c_uint;
1570 fn a_version_tostr(ctx: *const version, p: *mut u8, n: usize) -> c_int;
1571 fn a_version_cmp(ctx: *const version, rhs: *const version) -> c_int;
1572 fn a_version_lt(ctx: *const version, rhs: *const version) -> bool;
1573 fn a_version_gt(ctx: *const version, rhs: *const version) -> bool;
1574 fn a_version_le(ctx: *const version, rhs: *const version) -> bool;
1575 fn a_version_ge(ctx: *const version, rhs: *const version) -> bool;
1576 fn a_version_eq(ctx: *const version, rhs: *const version) -> bool;
1577 fn a_version_check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int;
1581 /// initialize for version
1583 pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1588 ..Default::default()
1591 /// set alphabet for version
1593 pub fn set_alpha(&mut self, alpha: &[u8]) {
1594 unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1596 /// get alphabet for version
1598 pub fn alpha(&self, alpha: &mut [u8; 5]) {
1599 unsafe { a_version_alpha(self, alpha) }
1601 /// parse version string to version
1603 pub fn parse(&mut self, ver: &str) -> c_uint {
1604 unsafe { a_version_parse(self, ver.as_ptr()) }
1606 /// convert version to string
1608 pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1609 unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1611 /// algorithm library version check
1613 pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1614 unsafe { a_version_check(major, minor, patch) }
1616 /// algorithm library version major
1618 pub fn major() -> c_uint {
1619 unsafe { a_version_major }
1621 /// algorithm library version minor
1623 pub fn minor() -> c_uint {
1624 unsafe { a_version_minor }
1626 /// algorithm library version patch
1628 pub fn patch() -> c_uint {
1629 unsafe { a_version_patch }
1631 /// algorithm library version tweak
1633 pub fn tweak() -> u32 {
1634 unsafe { a_version_tweak }
1638 impl PartialOrd for version {
1640 fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1641 let ok: c_int = unsafe { a_version_cmp(self, other) };
1643 return Some(Ordering::Greater);
1646 return Some(Ordering::Less);
1648 Some(Ordering::Equal)
1651 fn lt(&self, other: &version) -> bool {
1652 unsafe { a_version_lt(self, other) }
1655 fn gt(&self, other: &version) -> bool {
1656 unsafe { a_version_gt(self, other) }
1659 fn le(&self, other: &version) -> bool {
1660 unsafe { a_version_le(self, other) }
1663 fn ge(&self, other: &version) -> bool {
1664 unsafe { a_version_ge(self, other) }
1668 impl PartialEq for version {
1670 fn eq(&self, other: &version) -> bool {
1671 unsafe { a_version_eq(self, other) }