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_push(p: *mut float, n: usize, x: float);
92 fn a_float_roll(p: *mut float, n: usize);
93 fn a_float_sum(p: *const float, n: usize) -> float;
94 fn a_float_sum1(p: *const float, n: usize) -> float;
95 fn a_float_sum2(p: *const float, n: usize) -> float;
96 fn a_float_mean(p: *const float, n: usize) -> float;
99 /// roll back the elements of a float array and save the value
101 pub fn float_push(x: &mut [float], v: float) {
102 unsafe { a_float_push(x.as_mut_ptr(), x.len(), v) }
104 /// roll back the elements of a float array circularly
106 pub fn float_roll(x: &mut [float]) {
107 unsafe { a_float_roll(x.as_mut_ptr(), x.len()) }
109 /// calculate the sum of a float array
111 pub fn float_sum(x: &[float]) -> float {
112 unsafe { a_float_sum(x.as_ptr(), x.len()) }
114 /// calculate the absolute sum of a float array
116 pub fn float_sum1(x: &[float]) -> float {
117 unsafe { a_float_sum1(x.as_ptr(), x.len()) }
119 /// calculate the sum of squares of a float array
121 pub fn float_sum2(x: &[float]) -> float {
122 unsafe { a_float_sum2(x.as_ptr(), x.len()) }
124 /// calculate the mean of a float array
126 pub fn float_mean(x: &[float]) -> float {
127 unsafe { a_float_mean(x.as_ptr(), x.len()) }
131 fn a_hash_bkdr_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
132 fn a_hash_sdbm_(pdata: *const u8, nbyte: usize, value: u32) -> u32;
135 /// a hash function whose prime number is 131
137 pub fn hash_bkdr(block: &[u8], value: u32) -> u32 {
138 unsafe { a_hash_bkdr_(block.as_ptr(), block.len(), value) }
140 /// a hash function whose prime number is 65599
142 pub fn hash_sdbm(block: &[u8], value: u32) -> u32 {
143 unsafe { a_hash_sdbm_(block.as_ptr(), block.len(), value) }
146 /// Cyclic Redundancy Check for 8 bits
149 /// Cyclic Redundancy Check comparison table
150 pub table: [u8; 0x100],
154 fn a_crc8m_init(table: *mut u8, poly: u8);
155 fn a_crc8l_init(table: *mut u8, poly: u8);
156 fn a_crc8(table: *const u8, pdate: *const u8, nbyte: usize, value: u8) -> u8;
160 /// initialize for MSB CRC-8
162 pub fn new_msb(poly: u8) -> Self {
163 let mut ctx: Self = Self { table: [0; 0x100] };
164 unsafe { a_crc8m_init(ctx.table.as_mut_ptr(), poly) };
167 /// initialize for LSB CRC-8
169 pub fn new_lsb(poly: u8) -> Self {
170 let mut ctx: Self = Self { table: [0; 0x100] };
171 unsafe { a_crc8l_init(ctx.table.as_mut_ptr(), poly) };
174 /// generate for MSB CRC-8
176 pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
177 unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
180 /// generate for LSB CRC-8
182 pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
183 unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
186 /// calculate for CRC-8
188 pub fn eval(self, block: &[u8], value: u8) -> u8 {
189 unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
193 /// Cyclic Redundancy Check for 16 bits
196 /// Cyclic Redundancy Check comparison table
197 pub table: [u16; 0x100],
198 eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
202 fn a_crc16m_init(table: *mut u16, poly: u16);
203 fn a_crc16l_init(table: *mut u16, poly: u16);
204 fn a_crc16m(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
205 fn a_crc16l(table: *const u16, pdate: *const u8, nbyte: usize, value: u16) -> u16;
209 /// initialize for MSB CRC-16
211 pub fn new_msb(poly: u16) -> Self {
212 let mut ctx: Self = Self {
216 unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
219 /// initialize for LSB CRC-16
221 pub fn new_lsb(poly: u16) -> Self {
222 let mut ctx: Self = Self {
226 unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
229 /// generate for MSB CRC-16
231 pub fn gen_msb(&mut self, poly: u16) -> &mut Self {
232 unsafe { a_crc16m_init(self.table.as_mut_ptr(), poly) };
233 self.eval = a_crc16m;
236 /// generate for LSB CRC-16
238 pub fn gen_lsb(&mut self, poly: u16) -> &mut Self {
239 unsafe { a_crc16l_init(self.table.as_mut_ptr(), poly) };
240 self.eval = a_crc16l;
243 /// calculate for CRC-16
245 pub fn eval(self, block: &[u8], value: u16) -> u16 {
246 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
250 /// Cyclic Redundancy Check for 32 bits
253 /// Cyclic Redundancy Check comparison table
254 pub table: [u32; 0x100],
255 eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
259 fn a_crc32m_init(table: *mut u32, poly: u32);
260 fn a_crc32l_init(table: *mut u32, poly: u32);
261 fn a_crc32m(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
262 fn a_crc32l(table: *const u32, pdate: *const u8, nbyte: usize, value: u32) -> u32;
266 /// initialize for MSB CRC-32
268 pub fn new_msb(poly: u32) -> Self {
269 let mut ctx: Self = Self {
273 unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
276 /// initialize for LSB CRC-32
278 pub fn new_lsb(poly: u32) -> Self {
279 let mut ctx: Self = Self {
283 unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
286 /// generate for MSB CRC-32
288 pub fn gen_msb(&mut self, poly: u32) -> &mut Self {
289 unsafe { a_crc32m_init(self.table.as_mut_ptr(), poly) };
290 self.eval = a_crc32m;
293 /// generate for LSB CRC-32
295 pub fn gen_lsb(&mut self, poly: u32) -> &mut Self {
296 unsafe { a_crc32l_init(self.table.as_mut_ptr(), poly) };
297 self.eval = a_crc32l;
300 /// calculate for CRC-32
302 pub fn eval(self, block: &[u8], value: u32) -> u32 {
303 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
307 /// Cyclic Redundancy Check for 64 bits
310 /// Cyclic Redundancy Check comparison table
311 pub table: [u64; 0x100],
312 eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
316 fn a_crc64m_init(table: *mut u64, poly: u64);
317 fn a_crc64l_init(table: *mut u64, poly: u64);
318 fn a_crc64m(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
319 fn a_crc64l(table: *const u64, pdate: *const u8, nbyte: usize, value: u64) -> u64;
323 /// initialize for MSB CRC-64
325 pub fn new_msb(poly: u64) -> Self {
326 let mut ctx: Self = Self {
330 unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
333 /// initialize for LSB CRC-64
335 pub fn new_lsb(poly: u64) -> Self {
336 let mut ctx: Self = Self {
340 unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
343 /// generate for MSB CRC-64
345 pub fn gen_msb(&mut self, poly: u64) -> &mut Self {
346 unsafe { a_crc64m_init(self.table.as_mut_ptr(), poly) };
347 self.eval = a_crc64m;
350 /// generate for LSB CRC-64
352 pub fn gen_lsb(&mut self, poly: u64) -> &mut Self {
353 unsafe { a_crc64l_init(self.table.as_mut_ptr(), poly) };
354 self.eval = a_crc64l;
357 /// calculate for CRC-64
359 pub fn eval(self, block: &[u8], value: u64) -> u64 {
360 unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
364 #[allow(clippy::excessive_precision)]
365 const TAU: float = 6.28318530717958647692528676655900577;
370 /// filter coefficient
379 /// initialize for High Pass Filter
381 pub fn new(fc: float, ts: float) -> Self {
383 alpha: 1.0 / (TAU * fc * ts + 1.0),
388 /// generate for High Pass Filter
390 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
391 self.alpha = 1.0 / (TAU * fc * ts + 1.0);
394 /// calculate for High Pass Filter
396 pub fn iter(&mut self, x: float) -> float {
397 self.output = self.alpha * (self.output + x - self.input);
401 /// zeroing for High Pass Filter
403 pub fn zero(&mut self) -> &mut Self {
410 #[allow(clippy::excessive_precision)]
411 const _1_TAU: float = 0.159154943091895335768883763372514362;
416 /// filter coefficient
423 /// initialize for Low Pass Filter
425 pub fn new(fc: float, ts: float) -> Self {
427 alpha: ts / (_1_TAU / fc + ts),
431 /// generate for Low Pass Filter
433 pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
434 self.alpha = ts / (_1_TAU / fc + ts);
437 /// calculate for Low Pass Filter
439 pub fn iter(&mut self, x: float) -> float {
440 self.output *= 1.0 - self.alpha;
441 self.output += x * self.alpha;
444 /// zeroing for Low Pass Filter
446 pub fn zero(&mut self) -> &mut Self {
452 /// membership function
456 pub const NUL: c_int = 0;
457 /// gaussian membership function
458 pub const GAUSS: c_int = 1;
459 /// gaussian combination membership function
460 pub const GAUSS2: c_int = 2;
461 /// generalized bell-shaped membership function
462 pub const GBELL: c_int = 3;
463 /// sigmoidal membership function
464 pub const SIG: c_int = 4;
465 /// difference between two sigmoidal membership functions
466 pub const DSIG: c_int = 5;
467 /// product of two sigmoidal membership functions
468 pub const PSIG: c_int = 6;
469 /// trapezoidal membership function
470 pub const TRAP: c_int = 7;
471 /// triangular membership function
472 pub const TRI: c_int = 8;
473 /// linear s-shaped saturation membership function
474 pub const LINS: c_int = 9;
475 /// linear z-shaped saturation membership function
476 pub const LINZ: c_int = 10;
477 /// s-shaped membership function
478 pub const S: c_int = 11;
479 /// z-shaped membership function
480 pub const Z: c_int = 12;
481 /// pi-shaped membership function
482 pub const PI: c_int = 13;
486 fn a_mf_gauss(x: float, sigma: float, c: float) -> float;
487 fn a_mf_gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float;
488 fn a_mf_gbell(x: float, a: float, b: float, c: float) -> float;
489 fn a_mf_sig(x: float, a: float, c: float) -> float;
490 fn a_mf_dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
491 fn a_mf_psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float;
492 fn a_mf_trap(x: float, a: float, b: float, c: float, d: float) -> float;
493 fn a_mf_tri(x: float, a: float, b: float, c: float) -> float;
494 fn a_mf_lins(x: float, a: float, b: float) -> float;
495 fn a_mf_linz(x: float, a: float, b: float) -> float;
496 fn a_mf_s(x: float, a: float, b: float) -> float;
497 fn a_mf_z(x: float, a: float, b: float) -> float;
498 fn a_mf_pi(x: float, a: float, b: float, c: float, d: float) -> float;
501 /// gaussian membership function
503 pub fn gauss(x: float, sigma: float, c: float) -> float {
504 unsafe { a_mf_gauss(x, sigma, c) }
506 /// gaussian combination membership function
508 pub fn gauss2(x: float, sigma1: float, c1: float, sigma2: float, c2: float) -> float {
509 unsafe { a_mf_gauss2(x, sigma1, c1, sigma2, c2) }
511 /// generalized bell-shaped membership function
513 pub fn gbell(x: float, a: float, b: float, c: float) -> float {
514 unsafe { a_mf_gbell(x, a, b, c) }
516 /// sigmoidal membership function
518 pub fn sig(x: float, a: float, c: float) -> float {
519 unsafe { a_mf_sig(x, a, c) }
521 /// difference between two sigmoidal membership functions
523 pub fn dsig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
524 unsafe { a_mf_dsig(x, a1, c1, a2, c2) }
526 /// product of two sigmoidal membership functions
528 pub fn psig(x: float, a1: float, c1: float, a2: float, c2: float) -> float {
529 unsafe { a_mf_psig(x, a1, c1, a2, c2) }
531 /// trapezoidal membership function
533 pub fn trap(x: float, a: float, b: float, c: float, d: float) -> float {
534 unsafe { a_mf_trap(x, a, b, c, d) }
536 /// triangular membership function
538 pub fn tri(x: float, a: float, b: float, c: float) -> float {
539 unsafe { a_mf_tri(x, a, b, c) }
541 /// linear s-shaped saturation membership function
543 pub fn lins(x: float, a: float, b: float) -> float {
544 unsafe { a_mf_lins(x, a, b) }
546 /// linear z-shaped saturation membership function
548 pub fn linz(x: float, a: float, b: float) -> float {
549 unsafe { a_mf_linz(x, a, b) }
551 /// s-shaped membership function
553 pub fn s(x: float, a: float, b: float) -> float {
554 unsafe { a_mf_s(x, a, b) }
556 /// z-shaped membership function
558 pub fn z(x: float, a: float, b: float) -> float {
559 unsafe { a_mf_z(x, a, b) }
561 /// pi-shaped membership function
563 pub fn pi(x: float, a: float, b: float, c: float, d: float) -> float {
564 unsafe { a_mf_pi(x, a, b, c, d) }
568 /// proportional integral derivative controller
571 /// proportional constant
573 /// integral constant
575 /// derivative constant
577 /// maximum integral output
579 /// minimum integral output
581 /// controller integral output
583 /// maximum final output
585 /// minimum final output
587 /// controller final output
597 impl Default for pid {
599 fn default() -> Self {
604 summax: float::INFINITY,
605 summin: -float::INFINITY,
607 outmax: float::INFINITY,
608 outmin: -float::INFINITY,
618 fn a_pid_set_kpid(ctx: *mut pid, kp: float, ki: float, kd: float);
619 fn a_pid_run(ctx: *mut pid, set: float, fdb: float) -> float;
620 fn a_pid_pos(ctx: *mut pid, set: float, fdb: float) -> float;
621 fn a_pid_inc(ctx: *mut pid, set: float, fdb: float) -> float;
622 fn a_pid_zero(ctx: *mut pid);
626 /// initialize for PID controller
628 pub fn new() -> Self {
631 /// set proportional integral derivative constant for PID controller
633 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
634 unsafe { a_pid_set_kpid(self, kp, ki, kd) };
637 /// calculate for PID controller
639 pub fn run(&mut self, set: float, fdb: float) -> float {
640 unsafe { a_pid_run(self, set, fdb) }
642 /// calculate for positional PID controller
644 pub fn pos(&mut self, set: float, fdb: float) -> float {
645 unsafe { a_pid_pos(self, set, fdb) }
647 /// calculate for incremental PID controller
649 pub fn inc(&mut self, set: float, fdb: float) -> float {
650 unsafe { a_pid_inc(self, set, fdb) }
652 /// zeroing for PID controller
654 pub fn zero(&mut self) -> &mut Self {
655 unsafe { a_pid_zero(self) };
660 /// fuzzy PID controller operator
664 pub const CAP: c_uint = 1;
666 pub const CAP_ALGEBRA: c_uint = 2;
668 pub const CAP_BOUNDED: c_uint = 3;
670 pub const CUP: c_uint = 4;
672 pub const CUP_ALGEBRA: c_uint = 5;
674 pub const CUP_BOUNDED: c_uint = 6;
675 /// sqrt(a,b)*sqrt(1-(1-a)*(1-b))
676 pub const EQU: c_uint = 0;
679 /// fuzzy proportional integral derivative controller
681 pub struct pid_fuzzy {
682 /// proportional integral derivative controller
691 /// fuzzy relational operator
692 opr: extern "C" fn(float, float) -> float,
693 /// base proportional constant
695 /// base integral constant
697 /// base derivative constant
699 /// number of order in the square matrix
701 /// maximum number triggered by the rule
705 impl Default for pid_fuzzy {
707 fn default() -> Self {
717 opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
728 fn a_pid_fuzzy_opr(opr: c_uint) -> extern "C" fn(float, float) -> float;
729 fn a_pid_fuzzy_set_opr(ctx: *mut pid_fuzzy, opr: c_uint);
730 fn a_pid_fuzzy_bfuzz(ctx: *const pid_fuzzy) -> *mut u8;
731 fn a_pid_fuzzy_set_bfuzz(ctx: *mut pid_fuzzy, ptr: *mut u8, num: usize);
732 fn a_pid_fuzzy_set_rule(
741 fn a_pid_fuzzy_set_kpid(ctx: *mut pid_fuzzy, kp: float, ki: float, kd: float);
742 fn a_pid_fuzzy_run(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
743 fn a_pid_fuzzy_pos(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
744 fn a_pid_fuzzy_inc(ctx: *mut pid_fuzzy, set: float, fdb: float) -> float;
745 fn a_pid_fuzzy_zero(ctx: *mut pid_fuzzy);
749 /// initialize for fuzzy PID controller
751 pub fn new() -> Self {
754 /// set fuzzy relational operator for fuzzy PID controller
756 pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
757 unsafe { a_pid_fuzzy_set_opr(self, opr) };
760 /// compute size of memory block for fuzzy PID controller
762 #[allow(non_snake_case)]
763 pub const fn BFUZZ(n: usize) -> usize {
764 size_of::<c_uint>() * n * 2 + size_of::<float>() * n * (2 + n)
766 /// get memory block for fuzzy PID controller
768 pub fn bfuzz(&mut self) -> &mut [u8] {
769 unsafe { from_raw_parts_mut(a_pid_fuzzy_bfuzz(self), Self::BFUZZ(self.nfuzz as usize)) }
771 /// set memory block for fuzzy PID controller
773 pub fn set_bfuzz(&mut self, ptr: &mut [u8], num: usize) -> &mut Self {
774 unsafe { a_pid_fuzzy_set_bfuzz(self, ptr.as_mut_ptr(), num) };
777 /// set rule base for fuzzy PID controller
789 a_pid_fuzzy_set_rule(
801 /// set proportional integral derivative constant for fuzzy PID controller
803 pub fn set_kpid(&mut self, kp: float, ki: float, kd: float) -> &mut Self {
804 unsafe { a_pid_fuzzy_set_kpid(self, kp, ki, kd) };
807 /// calculate for fuzzy PID controller
809 pub fn run(&mut self, set: float, fdb: float) -> float {
810 unsafe { a_pid_fuzzy_run(self, set, fdb) }
812 /// calculate for positional fuzzy PID controller
814 pub fn pos(&mut self, set: float, fdb: float) -> float {
815 unsafe { a_pid_fuzzy_pos(self, set, fdb) }
817 /// calculate for incremental fuzzy PID controller
819 pub fn inc(&mut self, set: float, fdb: float) -> float {
820 unsafe { a_pid_fuzzy_inc(self, set, fdb) }
822 /// zeroing for fuzzy PID controller
824 pub fn zero(&mut self) -> &mut Self {
825 unsafe { a_pid_fuzzy_zero(self) };
830 /// single neuron proportional integral derivative controller
832 pub struct pid_neuro {
833 /// proportional integral derivative controller
835 /// proportional coefficient
837 /// proportional weight
841 /// derivative weight
847 impl Default for pid_neuro {
849 fn default() -> Self {
862 fn a_pid_neuro_set_kpid(ctx: *mut pid_neuro, k: float, kp: float, ki: float, kd: float);
863 fn a_pid_neuro_set_wpid(ctx: *mut pid_neuro, wp: float, wi: float, wd: float);
864 fn a_pid_neuro_run(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
865 fn a_pid_neuro_inc(ctx: *mut pid_neuro, set: float, fdb: float) -> float;
866 fn a_pid_neuro_zero(ctx: *mut pid_neuro);
870 /// initialize for single neuron PID controller
872 pub fn new() -> Self {
875 /// set proportional integral derivative constant for single neuron PID controller
877 pub fn set_kpid(&mut self, k: float, kp: float, ki: float, kd: float) -> &mut Self {
878 unsafe { a_pid_neuro_set_kpid(self, k, kp, ki, kd) };
881 /// set proportional integral derivative weight for single neuron PID controller
883 pub fn set_wpid(&mut self, wp: float, wi: float, wd: float) -> &mut Self {
884 unsafe { a_pid_neuro_set_wpid(self, wp, wi, wd) };
887 /// calculate for single neuron PID controller
889 pub fn run(&mut self, set: float, fdb: float) -> float {
890 unsafe { a_pid_neuro_run(self, set, fdb) }
892 /// calculate for incremental single neuron PID controller
894 pub fn inc(&mut self, set: float, fdb: float) -> float {
895 unsafe { a_pid_neuro_inc(self, set, fdb) }
897 /// zeroing for single neuron PID controller
899 pub fn zero(&mut self) -> &mut Self {
900 unsafe { a_pid_neuro_zero(self) };
905 /// simple linear regression
907 pub struct regress_simple {
908 /// regression coefficient
915 fn a_regress_simple_eval(ctx: *const regress_simple, val: float) -> float;
916 fn a_regress_simple_evar(ctx: *const regress_simple, val: float) -> float;
917 fn a_regress_simple_ols_(
918 ctx: *mut regress_simple,
925 fn a_regress_simple_olsx(
926 ctx: *mut regress_simple,
932 fn a_regress_simple_olsy(
933 ctx: *mut regress_simple,
939 fn a_regress_simple_ols(ctx: *mut regress_simple, n: usize, x: *const float, y: *const float);
940 fn a_regress_simple_zero(ctx: *mut regress_simple);
943 impl regress_simple {
944 /// initialize for simple linear regression
946 pub fn new(coef: float, bias: float) -> Self {
949 /// calculate predicted value for simple linear regression
951 pub fn eval(&self, val: float) -> float {
952 unsafe { a_regress_simple_eval(self, val) }
954 /// calculate predicted value for simple linear regression
956 pub fn evar(&self, val: float) -> float {
957 unsafe { a_regress_simple_evar(self, val) }
959 /// ordinary least squares for simple linear regression
961 pub fn ols_(&mut self, x: &[float], y: &[float], x_mean: float, y_mean: float) -> &mut Self {
962 unsafe { a_regress_simple_ols_(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean, y_mean) };
965 /// ordinary least squares for simple linear regression
967 pub fn olsx(&mut self, x: &[float], y: &[float], x_mean: float) -> &mut Self {
968 unsafe { a_regress_simple_olsx(self, x.len(), x.as_ptr(), y.as_ptr(), x_mean) };
971 /// ordinary least squares for simple linear regression
973 pub fn olsy(&mut self, x: &[float], y: &[float], y_mean: float) -> &mut Self {
974 unsafe { a_regress_simple_olsy(self, x.len(), x.as_ptr(), y.as_ptr(), y_mean) };
977 /// ordinary least squares for simple linear regression
979 pub fn ols(&mut self, x: &[float], y: &[float]) -> &mut Self {
980 unsafe { a_regress_simple_ols(self, x.len(), x.as_ptr(), y.as_ptr()) };
983 /// zeroing for simple linear regression
985 pub fn zero(&mut self) -> &mut Self {
986 unsafe { a_regress_simple_zero(self) };
991 /// transfer function
1001 den_p: *const float,
1002 /// numerator number
1004 /// denominator number
1009 fn a_tf_set_num(ctx: *mut tf, num_n: c_uint, num_p: *const float, input: *mut float);
1010 fn a_tf_set_den(ctx: *mut tf, den_n: c_uint, den_p: *const float, output: *mut float);
1014 num_p: *const float,
1017 den_p: *const float,
1020 fn a_tf_iter(ctx: *const tf, x: float) -> float;
1021 fn a_tf_zero(ctx: *const tf);
1025 /// initialize for transfer function
1027 pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
1028 let mut ctx: Self = Self {
1039 num.len() as c_uint,
1042 den.len() as c_uint,
1044 output.as_mut_ptr(),
1049 /// calculate for transfer function
1051 pub fn iter(&mut self, x: float) -> float {
1052 unsafe { a_tf_iter(self, x) }
1054 /// zeroing for transfer function
1056 pub fn zero(&mut self) -> &mut Self {
1057 unsafe { a_tf_zero(self) };
1060 /// get input for transfer function
1062 pub fn input(&self) -> &[float] {
1063 unsafe { from_raw_parts(self.input, self.num_n as usize) }
1065 /// get numerator for transfer function
1067 pub fn num(&self) -> &[float] {
1068 unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
1070 /// set numerator for transfer function
1072 pub fn set_num(&mut self, num: &[float], input: &mut [float]) -> &mut Self {
1073 unsafe { a_tf_set_num(self, num.len() as c_uint, num.as_ptr(), input.as_mut_ptr()) };
1076 /// get output for transfer function
1078 pub fn output(&self) -> &[float] {
1079 unsafe { from_raw_parts(self.output, self.den_n as usize) }
1081 /// get denominator for transfer function
1083 pub fn den(&self) -> &[float] {
1084 unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
1086 /// set denominator for transfer function
1088 pub fn set_den(&mut self, den: &[float], output: &mut [float]) -> &mut Self {
1089 unsafe { a_tf_set_den(self, den.len() as c_uint, den.as_ptr(), output.as_mut_ptr()) };
1094 /// bell-shaped velocity trajectory
1096 pub struct trajbell {
1099 /// constant velocity phase
1101 /// acceleration phase
1103 /// deceleration phase
1105 /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
1107 /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
1109 /// initial position
1113 /// initial velocity
1117 /// maximum velocity
1121 /// maximum acceleration
1123 /// maximum deceleration
1127 impl Default for trajbell {
1129 fn default() -> Self {
1160 fn a_trajbell_pos(ctx: *const trajbell, x: float) -> float;
1161 fn a_trajbell_vel(ctx: *const trajbell, x: float) -> float;
1162 fn a_trajbell_acc(ctx: *const trajbell, x: float) -> float;
1163 fn a_trajbell_jer(ctx: *const trajbell, x: float) -> float;
1167 /// initialize for bell-shaped velocity trajectory
1169 pub fn new() -> Self {
1172 /// generate for bell-shaped velocity trajectory
1173 #[allow(clippy::too_many_arguments)]
1185 unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1187 /// calculate position for bell-shaped velocity trajectory
1189 pub fn pos(&mut self, x: float) -> float {
1190 unsafe { a_trajbell_pos(self, x) }
1192 /// calculate velocity for bell-shaped velocity trajectory
1194 pub fn vel(&mut self, x: float) -> float {
1195 unsafe { a_trajbell_vel(self, x) }
1197 /// calculate acceleration for bell-shaped velocity trajectory
1199 pub fn acc(&mut self, x: float) -> float {
1200 unsafe { a_trajbell_acc(self, x) }
1202 /// calculate jerk for bell-shaped velocity trajectory
1204 pub fn jer(&mut self, x: float) -> float {
1205 unsafe { a_trajbell_jer(self, x) }
1209 /// cubic polynomial trajectory
1211 pub struct trajpoly3 {
1212 /// coefficients of position
1214 /// coefficients of velocity
1216 /// coefficients of acceleration
1221 fn a_trajpoly3_gen(ctx: *mut trajpoly3, ts: float, p0: float, p1: float, v0: float, v1: float);
1222 fn a_trajpoly3_pos(ctx: *const trajpoly3, x: float) -> float;
1223 fn a_trajpoly3_vel(ctx: *const trajpoly3, x: float) -> float;
1224 fn a_trajpoly3_acc(ctx: *const trajpoly3, x: float) -> float;
1228 /// initialize for cubic polynomial trajectory
1230 pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1231 let mut ctx: Self = Self {
1236 unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1239 /// generate for cubic polynomial trajectory
1241 pub fn gen(&mut self, ts: float, p0: float, p1: float, v0: float, v1: float) -> &mut Self {
1242 unsafe { a_trajpoly3_gen(self, ts, p0, p1, v0, v1) };
1245 /// calculate position for cubic polynomial trajectory
1247 pub fn pos(&mut self, x: float) -> float {
1248 unsafe { a_trajpoly3_pos(self, x) }
1250 /// calculate velocity for cubic polynomial trajectory
1252 pub fn vel(&mut self, x: float) -> float {
1253 unsafe { a_trajpoly3_vel(self, x) }
1255 /// calculate acceleration for cubic polynomial trajectory
1257 pub fn acc(&mut self, x: float) -> float {
1258 unsafe { a_trajpoly3_acc(self, x) }
1262 /// quintic polynomial trajectory
1264 pub struct trajpoly5 {
1265 /// coefficients of position
1267 /// coefficients of velocity
1269 /// coefficients of acceleration
1275 ctx: *mut trajpoly5,
1284 fn a_trajpoly5_pos(ctx: *const trajpoly5, x: float) -> float;
1285 fn a_trajpoly5_vel(ctx: *const trajpoly5, x: float) -> float;
1286 fn a_trajpoly5_acc(ctx: *const trajpoly5, x: float) -> float;
1290 /// initialize for quintic polynomial trajectory
1291 #[allow(clippy::too_many_arguments)]
1302 let mut ctx: Self = Self {
1307 unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1310 /// generate for quintic polynomial trajectory
1311 #[allow(clippy::too_many_arguments)]
1323 unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1326 /// calculate position for quintic polynomial trajectory
1328 pub fn pos(&mut self, x: float) -> float {
1329 unsafe { a_trajpoly5_pos(self, x) }
1331 /// calculate velocity for quintic polynomial trajectory
1333 pub fn vel(&mut self, x: float) -> float {
1334 unsafe { a_trajpoly5_vel(self, x) }
1336 /// calculate acceleration for quintic polynomial trajectory
1338 pub fn acc(&mut self, x: float) -> float {
1339 unsafe { a_trajpoly5_acc(self, x) }
1343 /// hepta polynomial trajectory
1345 pub struct trajpoly7 {
1346 /// coefficients of position
1348 /// coefficients of velocity
1350 /// coefficients of acceleration
1352 /// coefficients of jerk
1358 ctx: *mut trajpoly7,
1369 fn a_trajpoly7_pos(ctx: *const trajpoly7, x: float) -> float;
1370 fn a_trajpoly7_vel(ctx: *const trajpoly7, x: float) -> float;
1371 fn a_trajpoly7_acc(ctx: *const trajpoly7, x: float) -> float;
1372 fn a_trajpoly7_jer(ctx: *const trajpoly7, x: float) -> float;
1376 /// initialize for hepta polynomial trajectory
1377 #[allow(clippy::too_many_arguments)]
1390 let mut ctx: Self = Self {
1396 unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1399 /// generate for hepta polynomial trajectory
1400 #[allow(clippy::too_many_arguments)]
1414 unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1417 /// calculate position for hepta polynomial trajectory
1419 pub fn pos(&mut self, x: float) -> float {
1420 unsafe { a_trajpoly7_pos(self, x) }
1422 /// calculate velocity for hepta polynomial trajectory
1424 pub fn vel(&mut self, x: float) -> float {
1425 unsafe { a_trajpoly7_vel(self, x) }
1427 /// calculate acceleration for hepta polynomial trajectory
1429 pub fn acc(&mut self, x: float) -> float {
1430 unsafe { a_trajpoly7_acc(self, x) }
1432 /// calculate jerk for hepta polynomial trajectory
1434 pub fn jer(&mut self, x: float) -> float {
1435 unsafe { a_trajpoly7_jer(self, x) }
1439 /// trapezoidal velocity trajectory
1441 pub struct trajtrap {
1444 /// initial position
1448 /// initial velocity
1452 /// constant velocity
1454 /// time before constant velocity
1456 /// time after constant velocity
1458 /// position before constant velocity
1460 /// position after constant velocity
1462 /// acceleration before constant velocity
1464 /// acceleration after constant velocity
1468 impl Default for trajtrap {
1470 fn default() -> Self {
1499 fn a_trajtrap_pos(ctx: *const trajtrap, x: float) -> float;
1500 fn a_trajtrap_vel(ctx: *const trajtrap, x: float) -> float;
1501 fn a_trajtrap_acc(ctx: *const trajtrap, x: float) -> float;
1505 /// initialize for trapezoidal velocity trajectory
1507 pub fn new() -> Self {
1510 /// generate for trapezoidal velocity trajectory
1511 #[allow(clippy::too_many_arguments)]
1523 unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1525 /// calculate position for trapezoidal velocity trajectory
1527 pub fn pos(&mut self, x: float) -> float {
1528 unsafe { a_trajtrap_pos(self, x) }
1530 /// calculate velocity for trapezoidal velocity trajectory
1532 pub fn vel(&mut self, x: float) -> float {
1533 unsafe { a_trajtrap_vel(self, x) }
1535 /// calculate acceleration for trapezoidal velocity trajectory
1537 pub fn acc(&mut self, x: float) -> float {
1538 unsafe { a_trajtrap_acc(self, x) }
1544 pub struct version {
1557 impl Default for version {
1559 fn default() -> Self {
1565 alpha: [b'.', 0, 0, 0],
1571 static a_version_major: c_uint;
1572 static a_version_minor: c_uint;
1573 static a_version_patch: c_uint;
1574 static a_version_tweak: u32;
1575 fn a_version_set_alpha(ctx: *mut version, alpha: *const u8);
1576 fn a_version_alpha(ctx: *const version, alpha: &mut [u8; 5]);
1577 fn a_version_parse(ctx: *mut version, ver: *const u8) -> c_uint;
1578 fn a_version_tostr(ctx: *const version, p: *mut u8, n: usize) -> c_int;
1579 fn a_version_cmp(ctx: *const version, rhs: *const version) -> c_int;
1580 fn a_version_lt(ctx: *const version, rhs: *const version) -> bool;
1581 fn a_version_gt(ctx: *const version, rhs: *const version) -> bool;
1582 fn a_version_le(ctx: *const version, rhs: *const version) -> bool;
1583 fn a_version_ge(ctx: *const version, rhs: *const version) -> bool;
1584 fn a_version_eq(ctx: *const version, rhs: *const version) -> bool;
1585 fn a_version_check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int;
1589 /// initialize for version
1591 pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1596 ..Default::default()
1599 /// set alphabet for version
1601 pub fn set_alpha(&mut self, alpha: &[u8]) {
1602 unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1604 /// get alphabet for version
1606 pub fn alpha(&self, alpha: &mut [u8; 5]) {
1607 unsafe { a_version_alpha(self, alpha) }
1609 /// parse version string to version
1611 pub fn parse(&mut self, ver: &str) -> c_uint {
1612 unsafe { a_version_parse(self, ver.as_ptr()) }
1614 /// convert version to string
1616 pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1617 unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1619 /// algorithm library version check
1621 pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1622 unsafe { a_version_check(major, minor, patch) }
1624 /// algorithm library version major
1626 pub fn major() -> c_uint {
1627 unsafe { a_version_major }
1629 /// algorithm library version minor
1631 pub fn minor() -> c_uint {
1632 unsafe { a_version_minor }
1634 /// algorithm library version patch
1636 pub fn patch() -> c_uint {
1637 unsafe { a_version_patch }
1639 /// algorithm library version tweak
1641 pub fn tweak() -> u32 {
1642 unsafe { a_version_tweak }
1646 impl PartialOrd for version {
1648 fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1649 let ok: c_int = unsafe { a_version_cmp(self, other) };
1651 return Some(Ordering::Greater);
1654 return Some(Ordering::Less);
1656 Some(Ordering::Equal)
1659 fn lt(&self, other: &version) -> bool {
1660 unsafe { a_version_lt(self, other) }
1663 fn gt(&self, other: &version) -> bool {
1664 unsafe { a_version_gt(self, other) }
1667 fn le(&self, other: &version) -> bool {
1668 unsafe { a_version_le(self, other) }
1671 fn ge(&self, other: &version) -> bool {
1672 unsafe { a_version_ge(self, other) }
1676 impl PartialEq for version {
1678 fn eq(&self, other: &version) -> bool {
1679 unsafe { a_version_eq(self, other) }