create regress_simple for Rust
[liba.git] / src / lib.rs
blobe7047f361542edf3b16359d911e0e8b87fd0f0d8
1 /*!
2 An algorithm library based on C/C++
4 ## Installation
6 Add this to your `Cargo.toml`:
8 ```toml
9 [dependencies]
10 liba = "0.1"
11 ```
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"))]
20 pub type float = f64;
21 /// floating-point number stored using `f32`
22 #[cfg(feature = "float")]
23 pub type float = f32;
25 #[cfg(feature = "std")]
26 extern crate 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};
58 extern "C" {
59     fn a_u32_sqrt(x: u32) -> u16;
60     fn a_u64_sqrt(x: u64) -> u32;
63 /// square root of an unsigned integer
64 #[inline(always)]
65 pub fn u32_sqrt(x: u32) -> u16 {
66     unsafe { a_u32_sqrt(x) }
68 /// square root of an unsigned integer
69 #[inline(always)]
70 pub fn u64_sqrt(x: u64) -> u32 {
71     unsafe { a_u64_sqrt(x) }
74 extern "C" {
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}}`
80 #[inline(always)]
81 pub fn f32_rsqrt(x: f32) -> f32 {
82     unsafe { a_f32_rsqrt(x) }
84 /// reciprocal of square-root, `\frac{1}{\sqrt{x}}`
85 #[inline(always)]
86 pub fn f64_rsqrt(x: f64) -> f64 {
87     unsafe { a_f64_rsqrt(x) }
90 extern "C" {
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
96 #[inline(always)]
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
101 #[inline(always)]
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
107 #[repr(C)]
108 pub struct crc8 {
109     /// Cyclic Redundancy Check comparison table
110     pub table: [u8; 0x100],
113 extern "C" {
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;
119 impl crc8 {
120     /// initialize for MSB CRC-8
121     #[inline(always)]
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) };
125         ctx
126     }
127     /// initialize for LSB CRC-8
128     #[inline(always)]
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) };
132         ctx
133     }
134     /// generate for MSB CRC-8
135     #[inline(always)]
136     pub fn gen_msb(&mut self, poly: u8) -> &mut Self {
137         unsafe { a_crc8m_init(self.table.as_mut_ptr(), poly) };
138         self
139     }
140     /// generate for LSB CRC-8
141     #[inline(always)]
142     pub fn gen_lsb(&mut self, poly: u8) -> &mut Self {
143         unsafe { a_crc8l_init(self.table.as_mut_ptr(), poly) };
144         self
145     }
146     /// calculate for CRC-8
147     #[inline(always)]
148     pub fn eval(self, block: &[u8], value: u8) -> u8 {
149         unsafe { a_crc8(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
150     }
153 /// Cyclic Redundancy Check for 16 bits
154 #[repr(C)]
155 pub struct crc16 {
156     /// Cyclic Redundancy Check comparison table
157     pub table: [u16; 0x100],
158     eval: unsafe extern "C" fn(*const u16, *const u8, usize, u16) -> u16,
161 extern "C" {
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;
168 impl crc16 {
169     /// initialize for MSB CRC-16
170     #[inline(always)]
171     pub fn new_msb(poly: u16) -> Self {
172         let mut ctx: Self = Self {
173             table: [0; 0x100],
174             eval: a_crc16m,
175         };
176         unsafe { a_crc16m_init(ctx.table.as_mut_ptr(), poly) };
177         ctx
178     }
179     /// initialize for LSB CRC-16
180     #[inline(always)]
181     pub fn new_lsb(poly: u16) -> Self {
182         let mut ctx: Self = Self {
183             table: [0; 0x100],
184             eval: a_crc16l,
185         };
186         unsafe { a_crc16l_init(ctx.table.as_mut_ptr(), poly) };
187         ctx
188     }
189     /// generate for MSB CRC-16
190     #[inline(always)]
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;
194         self
195     }
196     /// generate for LSB CRC-16
197     #[inline(always)]
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;
201         self
202     }
203     /// calculate for CRC-16
204     #[inline(always)]
205     pub fn eval(self, block: &[u8], value: u16) -> u16 {
206         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
207     }
210 /// Cyclic Redundancy Check for 32 bits
211 #[repr(C)]
212 pub struct crc32 {
213     /// Cyclic Redundancy Check comparison table
214     pub table: [u32; 0x100],
215     eval: unsafe extern "C" fn(*const u32, *const u8, usize, u32) -> u32,
218 extern "C" {
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;
225 impl crc32 {
226     /// initialize for MSB CRC-32
227     #[inline(always)]
228     pub fn new_msb(poly: u32) -> Self {
229         let mut ctx: Self = Self {
230             table: [0; 0x100],
231             eval: a_crc32m,
232         };
233         unsafe { a_crc32m_init(ctx.table.as_mut_ptr(), poly) };
234         ctx
235     }
236     /// initialize for LSB CRC-32
237     #[inline(always)]
238     pub fn new_lsb(poly: u32) -> Self {
239         let mut ctx: Self = Self {
240             table: [0; 0x100],
241             eval: a_crc32l,
242         };
243         unsafe { a_crc32l_init(ctx.table.as_mut_ptr(), poly) };
244         ctx
245     }
246     /// generate for MSB CRC-32
247     #[inline(always)]
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;
251         self
252     }
253     /// generate for LSB CRC-32
254     #[inline(always)]
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;
258         self
259     }
260     /// calculate for CRC-32
261     #[inline(always)]
262     pub fn eval(self, block: &[u8], value: u32) -> u32 {
263         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
264     }
267 /// Cyclic Redundancy Check for 64 bits
268 #[repr(C)]
269 pub struct crc64 {
270     /// Cyclic Redundancy Check comparison table
271     pub table: [u64; 0x100],
272     eval: unsafe extern "C" fn(*const u64, *const u8, usize, u64) -> u64,
275 extern "C" {
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;
282 impl crc64 {
283     /// initialize for MSB CRC-64
284     #[inline(always)]
285     pub fn new_msb(poly: u64) -> Self {
286         let mut ctx: Self = Self {
287             table: [0; 0x100],
288             eval: a_crc64m,
289         };
290         unsafe { a_crc64m_init(ctx.table.as_mut_ptr(), poly) };
291         ctx
292     }
293     /// initialize for LSB CRC-64
294     #[inline(always)]
295     pub fn new_lsb(poly: u64) -> Self {
296         let mut ctx: Self = Self {
297             table: [0; 0x100],
298             eval: a_crc64l,
299         };
300         unsafe { a_crc64l_init(ctx.table.as_mut_ptr(), poly) };
301         ctx
302     }
303     /// generate for MSB CRC-64
304     #[inline(always)]
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;
308         self
309     }
310     /// generate for LSB CRC-64
311     #[inline(always)]
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;
315         self
316     }
317     /// calculate for CRC-64
318     #[inline(always)]
319     pub fn eval(self, block: &[u8], value: u64) -> u64 {
320         unsafe { (self.eval)(self.table.as_ptr(), block.as_ptr(), block.len(), value) }
321     }
324 #[allow(clippy::excessive_precision)]
325 const TAU: float = 6.28318530717958647692528676655900577;
327 /// High Pass Filter
328 #[repr(C)]
329 pub struct hpf {
330     /// filter coefficient
331     pub alpha: float,
332     /// filter output
333     pub output: float,
334     /// filter input
335     pub input: float,
338 impl hpf {
339     /// initialize for High Pass Filter
340     #[inline(always)]
341     pub fn new(fc: float, ts: float) -> Self {
342         Self {
343             alpha: 1.0 / (TAU * fc * ts + 1.0),
344             output: 0.0,
345             input: 0.0,
346         }
347     }
348     /// generate for High Pass Filter
349     #[inline(always)]
350     pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
351         self.alpha = 1.0 / (TAU * fc * ts + 1.0);
352         self
353     }
354     /// calculate for High Pass Filter
355     #[inline(always)]
356     pub fn iter(&mut self, x: float) -> float {
357         self.output = self.alpha * (self.output + x - self.input);
358         self.input = x;
359         self.output
360     }
361     /// zeroing for High Pass Filter
362     #[inline(always)]
363     pub fn zero(&mut self) -> &mut Self {
364         self.output = 0.0;
365         self.input = 0.0;
366         self
367     }
370 #[allow(clippy::excessive_precision)]
371 const _1_TAU: float = 0.159154943091895335768883763372514362;
373 /// Low Pass Filter
374 #[repr(C)]
375 pub struct lpf {
376     /// filter coefficient
377     pub alpha: float,
378     /// filter output
379     pub output: float,
382 impl lpf {
383     /// initialize for Low Pass Filter
384     #[inline(always)]
385     pub fn new(fc: float, ts: float) -> Self {
386         Self {
387             alpha: ts / (_1_TAU / fc + ts),
388             output: 0.0,
389         }
390     }
391     /// generate for Low Pass Filter
392     #[inline(always)]
393     pub fn gen(&mut self, fc: float, ts: float) -> &mut Self {
394         self.alpha = ts / (_1_TAU / fc + ts);
395         self
396     }
397     /// calculate for Low Pass Filter
398     #[inline(always)]
399     pub fn iter(&mut self, x: float) -> float {
400         self.output *= 1.0 - self.alpha;
401         self.output += x * self.alpha;
402         self.output
403     }
404     /// zeroing for Low Pass Filter
405     #[inline(always)]
406     pub fn zero(&mut self) -> &mut Self {
407         self.output = 0.0;
408         self
409     }
412 /// membership function
413 pub mod mf {
414     use crate::c_int;
415     /// none
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;
444     use crate::float;
445     extern "C" {
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;
459     }
461     /// gaussian membership function
462     #[inline(always)]
463     pub fn gauss(x: float, sigma: float, c: float) -> float {
464         unsafe { a_mf_gauss(x, sigma, c) }
465     }
466     /// gaussian combination membership function
467     #[inline(always)]
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) }
470     }
471     /// generalized bell-shaped membership function
472     #[inline(always)]
473     pub fn gbell(x: float, a: float, b: float, c: float) -> float {
474         unsafe { a_mf_gbell(x, a, b, c) }
475     }
476     /// sigmoidal membership function
477     #[inline(always)]
478     pub fn sig(x: float, a: float, c: float) -> float {
479         unsafe { a_mf_sig(x, a, c) }
480     }
481     /// difference between two sigmoidal membership functions
482     #[inline(always)]
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) }
485     }
486     /// product of two sigmoidal membership functions
487     #[inline(always)]
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) }
490     }
491     /// trapezoidal membership function
492     #[inline(always)]
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) }
495     }
496     /// triangular membership function
497     #[inline(always)]
498     pub fn tri(x: float, a: float, b: float, c: float) -> float {
499         unsafe { a_mf_tri(x, a, b, c) }
500     }
501     /// linear s-shaped saturation membership function
502     #[inline(always)]
503     pub fn lins(x: float, a: float, b: float) -> float {
504         unsafe { a_mf_lins(x, a, b) }
505     }
506     /// linear z-shaped saturation membership function
507     #[inline(always)]
508     pub fn linz(x: float, a: float, b: float) -> float {
509         unsafe { a_mf_linz(x, a, b) }
510     }
511     /// s-shaped membership function
512     #[inline(always)]
513     pub fn s(x: float, a: float, b: float) -> float {
514         unsafe { a_mf_s(x, a, b) }
515     }
516     /// z-shaped membership function
517     #[inline(always)]
518     pub fn z(x: float, a: float, b: float) -> float {
519         unsafe { a_mf_z(x, a, b) }
520     }
521     /// pi-shaped membership function
522     #[inline(always)]
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) }
525     }
528 /// proportional integral derivative controller
529 #[repr(C)]
530 pub struct pid {
531     /// proportional constant
532     pub kp: float,
533     /// integral constant
534     pub ki: float,
535     /// derivative constant
536     pub kd: float,
537     /// maximum integral output
538     pub summax: float,
539     /// minimum integral output
540     pub summin: float,
541     /// controller integral output
542     pub sum: float,
543     /// maximum final output
544     pub outmax: float,
545     /// minimum final output
546     pub outmin: float,
547     /// controller final output
548     pub out: float,
549     /// cache variable
550     var: float,
551     /// cache feedback
552     pub fdb: float,
553     /// cache error
554     pub err: float,
557 impl Default for pid {
558     #[inline(always)]
559     fn default() -> Self {
560         Self {
561             kp: 0.0,
562             ki: 0.0,
563             kd: 0.0,
564             summax: float::INFINITY,
565             summin: -float::INFINITY,
566             sum: 0.0,
567             outmax: float::INFINITY,
568             outmin: -float::INFINITY,
569             out: 0.0,
570             var: 0.0,
571             fdb: 0.0,
572             err: 0.0,
573         }
574     }
577 extern "C" {
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);
585 impl pid {
586     /// initialize for PID controller
587     #[inline(always)]
588     pub fn new() -> Self {
589         Self::default()
590     }
591     /// set proportional integral derivative constant for PID controller
592     #[inline(always)]
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) };
595         self
596     }
597     /// calculate for PID controller
598     #[inline(always)]
599     pub fn run(&mut self, set: float, fdb: float) -> float {
600         unsafe { a_pid_run(self, set, fdb) }
601     }
602     /// calculate for positional PID controller
603     #[inline(always)]
604     pub fn pos(&mut self, set: float, fdb: float) -> float {
605         unsafe { a_pid_pos(self, set, fdb) }
606     }
607     /// calculate for incremental PID controller
608     #[inline(always)]
609     pub fn inc(&mut self, set: float, fdb: float) -> float {
610         unsafe { a_pid_inc(self, set, fdb) }
611     }
612     /// zeroing for PID controller
613     #[inline(always)]
614     pub fn zero(&mut self) -> &mut Self {
615         unsafe { a_pid_zero(self) };
616         self
617     }
620 /// fuzzy PID controller operator
621 pub mod fuzzy {
622     use crate::c_uint;
623     /// min(a,b)
624     pub const CAP: c_uint = 1;
625     /// a*b
626     pub const CAP_ALGEBRA: c_uint = 2;
627     /// max(a+b-1,0)
628     pub const CAP_BOUNDED: c_uint = 3;
629     /// max(a,b)
630     pub const CUP: c_uint = 4;
631     /// a+b-a*b
632     pub const CUP_ALGEBRA: c_uint = 5;
633     /// min(a+b,1)
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
640 #[repr(C)]
641 pub struct pid_fuzzy {
642     /// proportional integral derivative controller
643     pub pid: pid,
644     me: *const float,
645     mec: *const float,
646     mkp: *const float,
647     mki: *const float,
648     mkd: *const float,
649     idx: *mut c_uint,
650     val: *mut float,
651     /// fuzzy relational operator
652     opr: extern "C" fn(float, float) -> float,
653     /// base proportional constant
654     pub kp: float,
655     /// base integral constant
656     pub ki: float,
657     /// base derivative constant
658     pub kd: float,
659     /// number of order in the square matrix
660     nrule: c_uint,
661     /// maximum number triggered by the rule
662     nfuzz: c_uint,
665 impl Default for pid_fuzzy {
666     #[inline(always)]
667     fn default() -> Self {
668         Self {
669             pid: pid::default(),
670             me: null(),
671             mec: null(),
672             mkp: null(),
673             mki: null(),
674             mkd: null(),
675             idx: null_mut(),
676             val: null_mut(),
677             opr: unsafe { a_pid_fuzzy_opr(fuzzy::EQU) },
678             kp: 0.0,
679             ki: 0.0,
680             kd: 0.0,
681             nrule: 0,
682             nfuzz: 0,
683         }
684     }
687 extern "C" {
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(
693         ctx: *mut pid_fuzzy,
694         num: c_uint,
695         me: *const float,
696         mec: *const float,
697         mkp: *const float,
698         mki: *const float,
699         mkd: *const float,
700     );
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);
708 impl pid_fuzzy {
709     /// initialize for fuzzy PID controller
710     #[inline(always)]
711     pub fn new() -> Self {
712         Self::default()
713     }
714     /// set fuzzy relational operator for fuzzy PID controller
715     #[inline(always)]
716     pub fn set_opr(&mut self, opr: c_uint) -> &mut Self {
717         unsafe { a_pid_fuzzy_set_opr(self, opr) };
718         self
719     }
720     /// compute size of memory block for fuzzy PID controller
721     #[inline(always)]
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)
725     }
726     /// get memory block for fuzzy PID controller
727     #[inline(always)]
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)) }
730     }
731     /// set memory block for fuzzy PID controller
732     #[inline(always)]
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) };
735         self
736     }
737     /// set rule base for fuzzy PID controller
738     #[inline(always)]
739     pub fn set_rule(
740         &mut self,
741         col: usize,
742         me: &[float],
743         mec: &[float],
744         mkp: &[float],
745         mki: &[float],
746         mkd: &[float],
747     ) -> &mut Self {
748         unsafe {
749             a_pid_fuzzy_set_rule(
750                 self,
751                 col as c_uint,
752                 me.as_ptr(),
753                 mec.as_ptr(),
754                 mkp.as_ptr(),
755                 mki.as_ptr(),
756                 mkd.as_ptr(),
757             )
758         };
759         self
760     }
761     /// set proportional integral derivative constant for fuzzy PID controller
762     #[inline(always)]
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) };
765         self
766     }
767     /// calculate for fuzzy PID controller
768     #[inline(always)]
769     pub fn run(&mut self, set: float, fdb: float) -> float {
770         unsafe { a_pid_fuzzy_run(self, set, fdb) }
771     }
772     /// calculate for positional fuzzy PID controller
773     #[inline(always)]
774     pub fn pos(&mut self, set: float, fdb: float) -> float {
775         unsafe { a_pid_fuzzy_pos(self, set, fdb) }
776     }
777     /// calculate for incremental fuzzy PID controller
778     #[inline(always)]
779     pub fn inc(&mut self, set: float, fdb: float) -> float {
780         unsafe { a_pid_fuzzy_inc(self, set, fdb) }
781     }
782     /// zeroing for fuzzy PID controller
783     #[inline(always)]
784     pub fn zero(&mut self) -> &mut Self {
785         unsafe { a_pid_fuzzy_zero(self) };
786         self
787     }
790 /// single neuron proportional integral derivative controller
791 #[repr(C)]
792 pub struct pid_neuro {
793     /// proportional integral derivative controller
794     pub pid: pid,
795     /// proportional coefficient
796     pub k: float,
797     /// proportional weight
798     pub wp: float,
799     /// integral weight
800     pub wi: float,
801     /// derivative weight
802     pub wd: float,
803     /// error change
804     pub ec: float,
807 impl Default for pid_neuro {
808     #[inline(always)]
809     fn default() -> Self {
810         Self {
811             pid: pid::default(),
812             k: 0.0,
813             wp: 0.0,
814             wi: 0.0,
815             wd: 0.0,
816             ec: 0.0,
817         }
818     }
821 extern "C" {
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);
829 impl pid_neuro {
830     /// initialize for single neuron PID controller
831     #[inline(always)]
832     pub fn new() -> Self {
833         Self::default()
834     }
835     /// set proportional integral derivative constant for single neuron PID controller
836     #[inline(always)]
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) };
839         self
840     }
841     /// set proportional integral derivative weight for single neuron PID controller
842     #[inline(always)]
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) };
845         self
846     }
847     /// calculate for single neuron PID controller
848     #[inline(always)]
849     pub fn run(&mut self, set: float, fdb: float) -> float {
850         unsafe { a_pid_neuro_run(self, set, fdb) }
851     }
852     /// calculate for incremental single neuron PID controller
853     #[inline(always)]
854     pub fn inc(&mut self, set: float, fdb: float) -> float {
855         unsafe { a_pid_neuro_inc(self, set, fdb) }
856     }
857     /// zeroing for single neuron PID controller
858     #[inline(always)]
859     pub fn zero(&mut self) -> &mut Self {
860         unsafe { a_pid_neuro_zero(self) };
861         self
862     }
865 /// simple linear regression
866 #[repr(C)]
867 pub struct regress_simple {
868     /// regression coefficient
869     pub coef: float,
870     /// intercept
871     pub bias: float,
874 extern "C" {
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,
879         n: usize,
880         x: *const float,
881         y: *const float,
882         x_mean: float,
883         y_mean: float,
884     );
885     fn a_regress_simple_olsx(
886         ctx: *mut regress_simple,
887         n: usize,
888         x: *const float,
889         y: *const float,
890         x_mean: float,
891     );
892     fn a_regress_simple_olsy(
893         ctx: *mut regress_simple,
894         n: usize,
895         x: *const float,
896         y: *const float,
897         y_mean: float,
898     );
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
905     #[inline(always)]
906     pub fn new(coef: float, bias: float) -> Self {
907         Self { coef, bias }
908     }
909     /// calculate predicted value for simple linear regression
910     #[inline(always)]
911     pub fn eval(&self, val: float) -> float {
912         unsafe { a_regress_simple_eval(self, val) }
913     }
914     /// calculate predicted value for simple linear regression
915     #[inline(always)]
916     pub fn evar(&self, val: float) -> float {
917         unsafe { a_regress_simple_evar(self, val) }
918     }
919     /// ordinary least squares for simple linear regression
920     #[inline(always)]
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) };
923         self
924     }
925     /// ordinary least squares for simple linear regression
926     #[inline(always)]
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) };
929         self
930     }
931     /// ordinary least squares for simple linear regression
932     #[inline(always)]
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) };
935         self
936     }
937     /// ordinary least squares for simple linear regression
938     #[inline(always)]
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()) };
941         self
942     }
943     /// zeroing for simple linear regression
944     #[inline(always)]
945     pub fn zero(&mut self) -> &mut Self {
946         unsafe { a_regress_simple_zero(self) };
947         self
948     }
951 /// transfer function
952 #[repr(C)]
953 pub struct tf {
954     /// input
955     input: *mut float,
956     /// output
957     output: *mut float,
958     /// numerator
959     num_p: *const float,
960     /// denominator
961     den_p: *const float,
962     /// numerator number
963     num_n: c_uint,
964     /// denominator number
965     den_n: c_uint,
968 extern "C" {
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);
971     fn a_tf_init(
972         ctx: *mut tf,
973         num_n: c_uint,
974         num_p: *const float,
975         input: *mut float,
976         den_n: c_uint,
977         den_p: *const float,
978         output: *mut float,
979     );
980     fn a_tf_iter(ctx: *const tf, x: float) -> float;
981     fn a_tf_zero(ctx: *const tf);
984 impl tf {
985     /// initialize for transfer function
986     #[inline(always)]
987     pub fn new(num: &[float], input: &mut [float], den: &[float], output: &mut [float]) -> Self {
988         let mut ctx: Self = Self {
989             input: null_mut(),
990             output: null_mut(),
991             num_p: null(),
992             den_p: null(),
993             num_n: 0,
994             den_n: 0,
995         };
996         unsafe {
997             a_tf_init(
998                 &mut ctx,
999                 num.len() as c_uint,
1000                 num.as_ptr(),
1001                 input.as_mut_ptr(),
1002                 den.len() as c_uint,
1003                 den.as_ptr(),
1004                 output.as_mut_ptr(),
1005             )
1006         };
1007         ctx
1008     }
1009     /// calculate for transfer function
1010     #[inline(always)]
1011     pub fn iter(&mut self, x: float) -> float {
1012         unsafe { a_tf_iter(self, x) }
1013     }
1014     /// zeroing for transfer function
1015     #[inline(always)]
1016     pub fn zero(&mut self) -> &mut Self {
1017         unsafe { a_tf_zero(self) };
1018         self
1019     }
1020     /// get input for transfer function
1021     #[inline(always)]
1022     pub fn input(&self) -> &[float] {
1023         unsafe { from_raw_parts(self.input, self.num_n as usize) }
1024     }
1025     /// get numerator for transfer function
1026     #[inline(always)]
1027     pub fn num(&self) -> &[float] {
1028         unsafe { from_raw_parts(self.num_p, self.num_n as usize) }
1029     }
1030     /// set numerator for transfer function
1031     #[inline(always)]
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()) };
1034         self
1035     }
1036     /// get output for transfer function
1037     #[inline(always)]
1038     pub fn output(&self) -> &[float] {
1039         unsafe { from_raw_parts(self.output, self.den_n as usize) }
1040     }
1041     /// get denominator for transfer function
1042     #[inline(always)]
1043     pub fn den(&self) -> &[float] {
1044         unsafe { from_raw_parts(self.den_p, self.den_n as usize) }
1045     }
1046     /// set denominator for transfer function
1047     #[inline(always)]
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()) };
1050         self
1051     }
1054 /// bell-shaped velocity trajectory
1055 #[repr(C)]
1056 pub struct trajbell {
1057     /// total duration
1058     pub t: float,
1059     /// constant velocity phase
1060     pub tv: float,
1061     /// acceleration phase
1062     pub ta: float,
1063     /// deceleration phase
1064     pub td: float,
1065     /// time-interval in which the jerk is constant (j max or j min ) during the acceleration phase
1066     pub taj: float,
1067     /// time-interval in which the jerk is constant (j max or j min ) during the deceleration phase
1068     pub tdj: float,
1069     /// initial position
1070     pub p0: float,
1071     /// final position
1072     pub p1: float,
1073     /// initial velocity
1074     pub v0: float,
1075     /// final velocity
1076     pub v1: float,
1077     /// maximum velocity
1078     pub vm: float,
1079     /// maximum jerk
1080     pub jm: float,
1081     /// maximum acceleration
1082     pub am: float,
1083     /// maximum deceleration
1084     pub dm: float,
1087 impl Default for trajbell {
1088     #[inline(always)]
1089     fn default() -> Self {
1090         Self {
1091             t: 0.0,
1092             tv: 0.0,
1093             ta: 0.0,
1094             td: 0.0,
1095             taj: 0.0,
1096             tdj: 0.0,
1097             p0: 0.0,
1098             p1: 0.0,
1099             v0: 0.0,
1100             v1: 0.0,
1101             vm: 0.0,
1102             jm: 0.0,
1103             am: 0.0,
1104             dm: 0.0,
1105         }
1106     }
1109 extern "C" {
1110     fn a_trajbell_gen(
1111         ctx: *mut trajbell,
1112         jm: float,
1113         am: float,
1114         vm: float,
1115         p0: float,
1116         p1: float,
1117         v0: float,
1118         v1: float,
1119     ) -> float;
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;
1126 impl trajbell {
1127     /// initialize for bell-shaped velocity trajectory
1128     #[inline(always)]
1129     pub fn new() -> Self {
1130         Self::default()
1131     }
1132     /// generate for bell-shaped velocity trajectory
1133     #[allow(clippy::too_many_arguments)]
1134     #[inline(always)]
1135     pub fn gen(
1136         &mut self,
1137         jm: float,
1138         am: float,
1139         vm: float,
1140         p0: float,
1141         p1: float,
1142         v0: float,
1143         v1: float,
1144     ) -> float {
1145         unsafe { a_trajbell_gen(self, jm, am, vm, p0, p1, v0, v1) }
1146     }
1147     /// calculate position for bell-shaped velocity trajectory
1148     #[inline(always)]
1149     pub fn pos(&mut self, x: float) -> float {
1150         unsafe { a_trajbell_pos(self, x) }
1151     }
1152     /// calculate velocity for bell-shaped velocity trajectory
1153     #[inline(always)]
1154     pub fn vel(&mut self, x: float) -> float {
1155         unsafe { a_trajbell_vel(self, x) }
1156     }
1157     /// calculate acceleration for bell-shaped velocity trajectory
1158     #[inline(always)]
1159     pub fn acc(&mut self, x: float) -> float {
1160         unsafe { a_trajbell_acc(self, x) }
1161     }
1162     /// calculate jerk for bell-shaped velocity trajectory
1163     #[inline(always)]
1164     pub fn jer(&mut self, x: float) -> float {
1165         unsafe { a_trajbell_jer(self, x) }
1166     }
1169 /// cubic polynomial trajectory
1170 #[repr(C)]
1171 pub struct trajpoly3 {
1172     /// coefficients of position
1173     pub p: [float; 4],
1174     /// coefficients of velocity
1175     pub v: [float; 3],
1176     /// coefficients of acceleration
1177     pub a: [float; 2],
1180 extern "C" {
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;
1187 impl trajpoly3 {
1188     /// initialize for cubic polynomial trajectory
1189     #[inline(always)]
1190     pub fn new(ts: float, p0: float, p1: float, v0: float, v1: float) -> Self {
1191         let mut ctx: Self = Self {
1192             p: [0.0; 4],
1193             v: [0.0; 3],
1194             a: [0.0; 2],
1195         };
1196         unsafe { a_trajpoly3_gen(&mut ctx, ts, p0, p1, v0, v1) };
1197         ctx
1198     }
1199     /// generate for cubic polynomial trajectory
1200     #[inline(always)]
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) };
1203         self
1204     }
1205     /// calculate position for cubic polynomial trajectory
1206     #[inline(always)]
1207     pub fn pos(&mut self, x: float) -> float {
1208         unsafe { a_trajpoly3_pos(self, x) }
1209     }
1210     /// calculate velocity for cubic polynomial trajectory
1211     #[inline(always)]
1212     pub fn vel(&mut self, x: float) -> float {
1213         unsafe { a_trajpoly3_vel(self, x) }
1214     }
1215     /// calculate acceleration for cubic polynomial trajectory
1216     #[inline(always)]
1217     pub fn acc(&mut self, x: float) -> float {
1218         unsafe { a_trajpoly3_acc(self, x) }
1219     }
1222 /// quintic polynomial trajectory
1223 #[repr(C)]
1224 pub struct trajpoly5 {
1225     /// coefficients of position
1226     pub p: [float; 6],
1227     /// coefficients of velocity
1228     pub v: [float; 5],
1229     /// coefficients of acceleration
1230     pub a: [float; 4],
1233 extern "C" {
1234     fn a_trajpoly5_gen(
1235         ctx: *mut trajpoly5,
1236         ts: float,
1237         p0: float,
1238         p1: float,
1239         v0: float,
1240         v1: float,
1241         a0: float,
1242         a1: float,
1243     );
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;
1249 impl trajpoly5 {
1250     /// initialize for quintic polynomial trajectory
1251     #[allow(clippy::too_many_arguments)]
1252     #[inline(always)]
1253     pub fn new(
1254         ts: float,
1255         p0: float,
1256         p1: float,
1257         v0: float,
1258         v1: float,
1259         a0: float,
1260         a1: float,
1261     ) -> Self {
1262         let mut ctx: Self = Self {
1263             p: [0.0; 6],
1264             v: [0.0; 5],
1265             a: [0.0; 4],
1266         };
1267         unsafe { a_trajpoly5_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1) };
1268         ctx
1269     }
1270     /// generate for quintic polynomial trajectory
1271     #[allow(clippy::too_many_arguments)]
1272     #[inline(always)]
1273     pub fn gen(
1274         &mut self,
1275         ts: float,
1276         p0: float,
1277         p1: float,
1278         v0: float,
1279         v1: float,
1280         a0: float,
1281         a1: float,
1282     ) -> &mut Self {
1283         unsafe { a_trajpoly5_gen(self, ts, p0, p1, v0, v1, a0, a1) };
1284         self
1285     }
1286     /// calculate position for quintic polynomial trajectory
1287     #[inline(always)]
1288     pub fn pos(&mut self, x: float) -> float {
1289         unsafe { a_trajpoly5_pos(self, x) }
1290     }
1291     /// calculate velocity for quintic polynomial trajectory
1292     #[inline(always)]
1293     pub fn vel(&mut self, x: float) -> float {
1294         unsafe { a_trajpoly5_vel(self, x) }
1295     }
1296     /// calculate acceleration for quintic polynomial trajectory
1297     #[inline(always)]
1298     pub fn acc(&mut self, x: float) -> float {
1299         unsafe { a_trajpoly5_acc(self, x) }
1300     }
1303 /// hepta polynomial trajectory
1304 #[repr(C)]
1305 pub struct trajpoly7 {
1306     /// coefficients of position
1307     pub p: [float; 8],
1308     /// coefficients of velocity
1309     pub v: [float; 7],
1310     /// coefficients of acceleration
1311     pub a: [float; 6],
1312     /// coefficients of jerk
1313     pub j: [float; 5],
1316 extern "C" {
1317     fn a_trajpoly7_gen(
1318         ctx: *mut trajpoly7,
1319         ts: float,
1320         p0: float,
1321         p1: float,
1322         v0: float,
1323         v1: float,
1324         a0: float,
1325         a1: float,
1326         j0: float,
1327         j1: float,
1328     );
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;
1335 impl trajpoly7 {
1336     /// initialize for hepta polynomial trajectory
1337     #[allow(clippy::too_many_arguments)]
1338     #[inline(always)]
1339     pub fn new(
1340         ts: float,
1341         p0: float,
1342         p1: float,
1343         v0: float,
1344         v1: float,
1345         a0: float,
1346         a1: float,
1347         j0: float,
1348         j1: float,
1349     ) -> Self {
1350         let mut ctx: Self = Self {
1351             p: [0.0; 8],
1352             v: [0.0; 7],
1353             a: [0.0; 6],
1354             j: [0.0; 5],
1355         };
1356         unsafe { a_trajpoly7_gen(&mut ctx, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1357         ctx
1358     }
1359     /// generate for hepta polynomial trajectory
1360     #[allow(clippy::too_many_arguments)]
1361     #[inline(always)]
1362     pub fn gen(
1363         &mut self,
1364         ts: float,
1365         p0: float,
1366         p1: float,
1367         v0: float,
1368         v1: float,
1369         a0: float,
1370         a1: float,
1371         j0: float,
1372         j1: float,
1373     ) -> &mut Self {
1374         unsafe { a_trajpoly7_gen(self, ts, p0, p1, v0, v1, a0, a1, j0, j1) };
1375         self
1376     }
1377     /// calculate position for hepta polynomial trajectory
1378     #[inline(always)]
1379     pub fn pos(&mut self, x: float) -> float {
1380         unsafe { a_trajpoly7_pos(self, x) }
1381     }
1382     /// calculate velocity for hepta polynomial trajectory
1383     #[inline(always)]
1384     pub fn vel(&mut self, x: float) -> float {
1385         unsafe { a_trajpoly7_vel(self, x) }
1386     }
1387     /// calculate acceleration for hepta polynomial trajectory
1388     #[inline(always)]
1389     pub fn acc(&mut self, x: float) -> float {
1390         unsafe { a_trajpoly7_acc(self, x) }
1391     }
1392     /// calculate jerk for hepta polynomial trajectory
1393     #[inline(always)]
1394     pub fn jer(&mut self, x: float) -> float {
1395         unsafe { a_trajpoly7_jer(self, x) }
1396     }
1399 /// trapezoidal velocity trajectory
1400 #[repr(C)]
1401 pub struct trajtrap {
1402     /// total duration
1403     pub t: float,
1404     /// initial position
1405     pub p0: float,
1406     /// final position
1407     pub p1: float,
1408     /// initial velocity
1409     pub v0: float,
1410     /// final velocity
1411     pub v1: float,
1412     /// constant velocity
1413     pub vc: float,
1414     /// time before constant velocity
1415     pub ta: float,
1416     /// time after constant velocity
1417     pub td: float,
1418     /// position before constant velocity
1419     pub pa: float,
1420     /// position after constant velocity
1421     pub pd: float,
1422     /// acceleration before constant velocity
1423     pub ac: float,
1424     /// acceleration after constant velocity
1425     pub de: float,
1428 impl Default for trajtrap {
1429     #[inline(always)]
1430     fn default() -> Self {
1431         Self {
1432             t: 0.0,
1433             p0: 0.0,
1434             p1: 0.0,
1435             v0: 0.0,
1436             v1: 0.0,
1437             vc: 0.0,
1438             ta: 0.0,
1439             td: 0.0,
1440             pa: 0.0,
1441             pd: 0.0,
1442             ac: 0.0,
1443             de: 0.0,
1444         }
1445     }
1448 extern "C" {
1449     fn a_trajtrap_gen(
1450         ctx: *mut trajtrap,
1451         vm: float,
1452         ac: float,
1453         de: float,
1454         p0: float,
1455         p1: float,
1456         v0: float,
1457         v1: float,
1458     ) -> float;
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;
1464 impl trajtrap {
1465     /// initialize for trapezoidal velocity trajectory
1466     #[inline(always)]
1467     pub fn new() -> Self {
1468         Self::default()
1469     }
1470     /// generate for trapezoidal velocity trajectory
1471     #[allow(clippy::too_many_arguments)]
1472     #[inline(always)]
1473     pub fn gen(
1474         &mut self,
1475         vm: float,
1476         ac: float,
1477         de: float,
1478         p0: float,
1479         p1: float,
1480         v0: float,
1481         v1: float,
1482     ) -> float {
1483         unsafe { a_trajtrap_gen(self, vm, ac, de, p0, p1, v0, v1) }
1484     }
1485     /// calculate position for trapezoidal velocity trajectory
1486     #[inline(always)]
1487     pub fn pos(&mut self, x: float) -> float {
1488         unsafe { a_trajtrap_pos(self, x) }
1489     }
1490     /// calculate velocity for trapezoidal velocity trajectory
1491     #[inline(always)]
1492     pub fn vel(&mut self, x: float) -> float {
1493         unsafe { a_trajtrap_vel(self, x) }
1494     }
1495     /// calculate acceleration for trapezoidal velocity trajectory
1496     #[inline(always)]
1497     pub fn acc(&mut self, x: float) -> float {
1498         unsafe { a_trajtrap_acc(self, x) }
1499     }
1502 /// version
1503 #[repr(C)]
1504 pub struct version {
1505     /// major number
1506     pub major: c_uint,
1507     /// minor number
1508     pub minor: c_uint,
1509     /// third number
1510     pub third: c_uint,
1511     /// extra number
1512     pub extra: c_uint,
1513     /// alphabet
1514     pub alpha: [u8; 4],
1517 impl Default for version {
1518     #[inline(always)]
1519     fn default() -> Self {
1520         Self {
1521             major: 0,
1522             minor: 0,
1523             third: 0,
1524             extra: 0,
1525             alpha: [b'.', 0, 0, 0],
1526         }
1527     }
1530 extern "C" {
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;
1548 impl version {
1549     /// initialize for version
1550     #[inline(always)]
1551     pub fn new(major: c_uint, minor: c_uint, third: c_uint) -> Self {
1552         Self {
1553             major,
1554             minor,
1555             third,
1556             ..Default::default()
1557         }
1558     }
1559     /// set alphabet for version
1560     #[inline(always)]
1561     pub fn set_alpha(&mut self, alpha: &[u8]) {
1562         unsafe { a_version_set_alpha(self, alpha.as_ptr()) }
1563     }
1564     /// get alphabet for version
1565     #[inline(always)]
1566     pub fn alpha(&self, alpha: &mut [u8; 5]) {
1567         unsafe { a_version_alpha(self, alpha) }
1568     }
1569     /// parse version string to version
1570     #[inline(always)]
1571     pub fn parse(&mut self, ver: &str) -> c_uint {
1572         unsafe { a_version_parse(self, ver.as_ptr()) }
1573     }
1574     /// convert version to string
1575     #[inline(always)]
1576     pub fn tostr(&mut self, ver: &mut [u8]) -> c_int {
1577         unsafe { a_version_tostr(self, ver.as_mut_ptr(), ver.len()) }
1578     }
1579     /// algorithm library version check
1580     #[inline(always)]
1581     pub fn check(major: c_uint, minor: c_uint, patch: c_uint) -> c_int {
1582         unsafe { a_version_check(major, minor, patch) }
1583     }
1584     /// algorithm library version major
1585     #[inline(always)]
1586     pub fn major() -> c_uint {
1587         unsafe { a_version_major }
1588     }
1589     /// algorithm library version minor
1590     #[inline(always)]
1591     pub fn minor() -> c_uint {
1592         unsafe { a_version_minor }
1593     }
1594     /// algorithm library version patch
1595     #[inline(always)]
1596     pub fn patch() -> c_uint {
1597         unsafe { a_version_patch }
1598     }
1599     /// algorithm library version tweak
1600     #[inline(always)]
1601     pub fn tweak() -> u32 {
1602         unsafe { a_version_tweak }
1603     }
1606 impl PartialOrd for version {
1607     #[inline(always)]
1608     fn partial_cmp(&self, other: &version) -> Option<Ordering> {
1609         let ok: c_int = unsafe { a_version_cmp(self, other) };
1610         if ok > 0 {
1611             return Some(Ordering::Greater);
1612         }
1613         if ok < 0 {
1614             return Some(Ordering::Less);
1615         }
1616         Some(Ordering::Equal)
1617     }
1618     #[inline(always)]
1619     fn lt(&self, other: &version) -> bool {
1620         unsafe { a_version_lt(self, other) }
1621     }
1622     #[inline(always)]
1623     fn gt(&self, other: &version) -> bool {
1624         unsafe { a_version_gt(self, other) }
1625     }
1626     #[inline(always)]
1627     fn le(&self, other: &version) -> bool {
1628         unsafe { a_version_le(self, other) }
1629     }
1630     #[inline(always)]
1631     fn ge(&self, other: &version) -> bool {
1632         unsafe { a_version_ge(self, other) }
1633     }
1636 impl PartialEq for version {
1637     #[inline(always)]
1638     fn eq(&self, other: &version) -> bool {
1639         unsafe { a_version_eq(self, other) }
1640     }