1![zscilib](doc/img/zscilib_logo_200px.png)
2
3# Zephyr Scientific Library (zscilib)
4
5[![API Documentation](doc/img/badge_api.svg)][1]
6
7[1]: https://zephyrproject-rtos.github.io/zscilib/
8
9The **Zephyr Scientific Library (zscilib)** is an attempt to provide a set of
10functions useful for scientific computing, data analysis and data manipulation
11in the context of resource constrained embedded hardware devices.
12
13It is written entirely in C, and while the main development target for the
14library is the [Zephyr Project](https://github.com/zephyrproject-rtos/zephyr),
15it tries to be as portable as possible, and a standalone reference project
16is included to use this library in non-Zephyr-based projects.
17
18This version of zscilib has been developed and tested against **Zephyr 3.3.0**.
19
20## Motivation
21
22As the processing power of small, embedded MCUs increases and costs fall, more
23computation can be done on the endnode itself. This allows for more of the
24'complex' data analysis that used to take place at the PC or server level
25(data aggregation, statistical analysis, etc.) to be done in less time,
26using less data storage, and at a lower overall processing cost on small,
27embedded devices.
28
29> A key goal of zscilib is to allow more data processing to happen on the
30  endnode.
31
32By generating scientifically-relevant data points (standard SI units,
33pre-filtered data, etc.) directly on the endnode, zscilib aims to be a bridge
34between raw data and more numerically complex toolkits like `gsl`, `numpy`
35or `R`.
36
37#### What makes zscilib distinct?
38
39Numerous high quality, mature, open source scientific libraries already exist:
40
41- [GNU scientific library (gsl)](https://www.gnu.org/software/gsl/)
42- [Lis (Library of Iterative Solvers for linear systems)](https://github.com/anishida/lis)
43- [CMSIS-DSP](http://www.keil.com/pack/doc/CMSIS/DSP/html/index.html)
44
45Despite the wealth of mature functions in these existing libraries, though,
46they tend to have the following two problems in an embedded context:
47
48- They are overly broad and resource intensive (GSL, etc.), and thus aren't
49  appropriate for small, resource constrained devices like the ARM Cortex M
50  family.
51- They are missing many of the domain-specific features required to convert
52  raw sensor data into actionable information (CMSIS-DSP, Lis).
53
54The second item is of particular importance, since the goal of embedded systems
55is often 'sensing' via raw data, correlating that data, and acting on the final
56data points or passing them on for further analysis.
57
58CMSIS-DSP contains a number of highly efficient algorithms for filtering
59raw sensor data, but it doesn't offer any domain-specific assistance converting
60filtered accelerometer vectors into orientation data, for example, or reading
61a set of photodiodes and converting that data into a useful photometric value
62like lux. It is excellent at 'conditioning' data, but not at 'understanding' it.
63
64zscilib aims to find a middle ground between these two, allowing for richer
65processing of raw data, but within the confines and limitations of the class
66of microcontrollers commonly used on low-cost sensor endnodes.
67
68## Quick Start: Standalone
69
70A few makefile-based projects are included in `samples/standalone` showing
71how zscilib can be used independent of Zephyr.
72
73If you already have an appropriate GNU toolchain and build tools (`make`, etc.)
74installed, you can simply execute the following commands:
75
76```bash
77$ cd samples/standalone/svd_pinv
78$ make
79$ bin/zscilib
80  Hello, zscilib!
81  ...
82```
83
84## Quick Start: Zephyr RTOS
85
86### Running a sample application
87
88To run one of the sample applications using qemu, run the following commands:
89
90> Be sure to run `source zephyr/zephyr-env.sh` (OS X or Linux) or
91  `.\zephyr\zephyr-env.cmd` (Windows) before the commands below! This also
92  assumes `qemu-system-arm` is available on your local system.
93
94```
95$ west build -p -b mps2_an521 \
96  modules/lib/zscilib/samples/matrix/mult -t run
97...
98*** Booting Zephyr OS build zephyr-v2.6.0-536-g89212a7fbf5f  ***
99zscilib matrix mult demo
100
101mtx multiply output (4x3 * 3x4 = 4x4):
102
10314.000000 17.000000 20.000000 23.000000
10435.000000 44.000000 53.000000 62.000000
10556.000000 71.000000 86.000000 101.000000
1067.000000 9.000000 11.000000 13.000000
107```
108
109Press **`CTRL+A`** then **`x`** to quit qemu.
110
111### Running Unit Tests
112
113To run the unit tests for this library, run the following command:
114
115```bash
116$ twister --inline-logs -p mps2_an521 -T modules/lib/zscilib/tests
117```
118
119See the `tests` folder for further details.
120
121To run compliance tests to make sure submitted code matches Zephyr PR
122requirements, run this (updating `HEAD~2` for the number of commits to check,
123or setting it to `origin/master..` to check everything):
124
125```bash
126$ ../../../zephyr/scripts/ci/check_compliance.py \
127  -m Gitlint -m Identity -m Nits -m pylint -m checkpatch \
128  -c HEAD~2..
129```
130
131### Debugging with QEMU
132
133If you wish to debug using QEMU (and with minor variation actual hardware),
134you can run the following commands to start a new GDB debug session.
135
136> For an overview of debugging in GDB, you may find the following presentation
137  useful: [LVC21-308: Essential ARM Cortex-M Debugging with GDB][LV21-308]
138
139[LV21-308]: https://connect.linaro.org/resources/lvc21/lvc21-308/
140
141In one terminal window, run:
142
143```bash
144$ west build -p auto -b mps2_an521 modules/lib/zscilib/samples/matrix/pinv
145```
146
147Once the ELF file has been built, we can start a GDB server on the default
148`1234` socket, and wait for a new connection via:
149
150```bash
151$ cd build
152$ ninja debugserver
153```
154
155In a new terminal window, connect to the GDB server via:
156
157```bash
158$ cd <zephyr_path>
159$ arm-none-eabi-gdb-py \
160  --eval-command="target remote localhost:1234" \
161  --se=build/zephyr/zephyr.elf
162```
163
164> The `-py` extension is optional, and makes use of a version of GDB from the
165  ARM GNU toolchain releases that enables Python scripts to be used with your
166  debug sessions. See the [LVC21-308][LV21-308] presentation at the top of this
167  section for details.
168
169From here, you can start debugging with the `(gdb)` prompt.
170
171For example:
172
173```
174(gdb) b main
175(gdb) c
176Continuing.
177
178Breakpoint 1, main () at modules/lib/zscilib/samples/matrix/pinv/src/main.c:70
17970              printf("\n\nzscilib pseudo-inverse demo\n\n");
180(gdb) n
18172              pinv_demo();
182(gdb) step
183pinv_demo () at modules/lib/zscilib/samples/matrix/pinv/src/main.c:25
18425              zsl_real_t vi[18 * 3] = {
185(gdb) n
186...
187(gdb) quit
188```
189
190## Floating-Point Usage
191
192zscilib can be configured to make use of single-precision (32-bit) or
193double-precision (64-bit) floating point values via the
194`CONFIG_ZSL_SINGLE_PRECISION` flag, which will determine the size of
195`zsl_real_t` used throughout the library. The default setting for this
196flag is `n`, meaning **64-bit values are used by default**.
197
198There is a tradeoff between the added range and precision that 64-bit
199(double-precision) floating point values offer, and the memory and performance
200gains of the smaller, less-precise but faster 32-bit (single-precision)
201operations.
202
203> Due to the reduced precision of single-precision values, certain complex
204  functions in zscilib are **only available when double-precision is enabled**
205  (PINV, SVD, etc.).
206
207### Comparison
208
209#### Single-Precision (32-bit) Floats
210
211- Require 4 bytes of memory to store
212- Have about **7 significant digits of precision**
213- Have a range of about 1.E-36 to 1.E+36
214- HW acceleration available on Cortex-M4F, Cortex-M7 and most Cortex-M33 MCUs.
215- Generates smaller, more efficient code than double
216
217#### Double-Precision (64-bit) Floats
218
219- Requires 8 bytes of memory to store
220- Have about **13 significant digits of precision**
221- Have a range of about 1.E-303 to 1.E+303
222- HW acceleration generally only available on large, Cortex-M7 MCUs
223- Generates larger code, with more processing overhead per operation
224
225### Float Stack Usage in Zephyr
226
227The sample code in this library typically has the `CONFIG_FPU` option set,
228meaning that floating-point support is configured for
229[Unshared FP registers mode][2]. This mode is used when the application
230has a **single thread** that uses floating point registers.
231
232If your application makes use of **multiple threads**, and more than one of
233these threads uses floating-point operations, you should also enable the
234`CONFIG_FPU_SHARING` config flag, which configures the kernel for
235[Shared FP registers mode][3]. In this mode, the floating point registers are
236saved and restored during each context switch, even when the associated threads
237are not using them. This feature comes at the expense of an extra 72 bytes of
238stack memory per stack frame (`s0..s15` + `FPCSR`, plus an alignment word
239to ensure that the stack pointer is double-word aligned).
240
241[2]: https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/reference/kernel/other/float.rst#unshared-fp-registers-mode
242[3]: https://github.com/zephyrproject-rtos/zephyr/blob/master/doc/reference/kernel/other/float.rst#shared-fp-registers-mode
243
244## Current Features
245
246> Features marked with the
247  [v0.2.0](https://github.com/zephyrproject-rtos/zscilib/projects/2) flag are in progress
248  or planned as part of the current release cycle, and may be partially
249  implemented or stubbed at present.
250  [v0.3.0](https://github.com/zephyrproject-rtos/zscilib/projects/3) indicates features planned for that later release.
251
252### Linear Algebra
253
254#### Vector Operations
255
256- **f32**: Single-precision floating-point operations
257- **f64**: Double-precision floating-point operations
258- **ARM**: Optimised Arm Thumb-2 ASM implementation
259
260| Feature         | Func                  | f32 | f64 | Arm | Notes           |
261|-----------------|-----------------------|-----|-----|-----|-----------------|
262| Array to vector | `zsl_vec_from_arr`    | x   | x   |     |                 |
263| Copy            | `zsl_vec_copy`        | x   | x   |     |                 |
264| Get subset      | `zsl_vec_get_subset`  | x   | x   |     |                 |
265| Add             | `zsl_vec_add`         | x   | x   |     |                 |
266| Subtract        | `zsl_vec_sub`         | x   | x   |     |                 |
267| Negate          | `zsl_vec_neg`         | x   | x   |     |                 |
268| Sum             | `zsl_vec_sum`         | x   | x   |     | 2 or more vects |
269| Scalar add      | `zsl_vec_scalar_add`  | x   | x   |     |                 |
270| Scalar multiply | `zsl_vec_scalar_mult` | x   | x   |     |                 |
271| Scalar divide   | `zsl_vec_scalar_div`  | x   | x   |     |                 |
272| Distance        | `zsl_vec_dist`        | x   | x   |     | Between 2 vects |
273| Dot product     | `zsl_vec_dot`         | x   | x   |     |                 |
274| Norm/abs value  | `zsl_vec_norm`        | x   | x   |     |                 |
275| Project         | `zsl_vec_project`     | x   | x   |     |                 |
276| To unit vector  | `zsl_vec_to_unit`     | x   | x   |     |                 |
277| Cross product   | `zsl_vec_cross`       | x   | x   |     |                 |
278| Sum of squares  | `zsl_vec_sum_of_sqrs` | x   | x   |     |                 |
279| Comp-wise mean  | `zsl_vec_mean`        | x   | x   |     |                 |
280| Arithmetic mean | `zsl_vec_ar_mean`     | x   | x   |     |                 |
281| Reverse         | `zsl_vec_rev`         | x   | x   |     |                 |
282| Zero to end     | `zsl_vec_zte`         | x   | x   |     | 0 vals to end   |
283| Equality check  | `zsl_vec_is_equal`    | x   | x   |     |                 |
284| Non-neg check   | `zsl_vec_is_nonneg`   | x   | x   |     | All values >= 0 |
285| Contains        | `zsl_vec_contains`    | x   | x   |     |                 |
286| Quicksort       | `zsl_vec_sort`        | x   | x   |     |                 |
287| Print           | `zsl_vec_print`       | x   | x   |     |                 |
288
289#### Matrix Operations
290
291- **f32**: Single-precision floating-point operations
292- **f64**: Double-precision floating-point operations
293- **ARM**: Optimised Arm Thumb-2 ASM implementation
294
295| Feature         | Func                  | f32 | f64 | Arm | Notes           |
296|-----------------|-----------------------|-----|-----|-----|-----------------|
297| Array to matrix | `zsl_mtx_from_arr`    | x   | x   |     |                 |
298| Copy            | `zsl_mtx_copy`        | x   | x   |     |                 |
299| Get value       | `zsl_mtx_get`         | x   | x   |     |                 |
300| Set value       | `zsl_mtx_set`         | x   | x   |     |                 |
301| Get row         | `zsl_mtx_get_row`     | x   | x   |     |                 |
302| Set row         | `zsl_mtx_set_row`     | x   | x   |     |                 |
303| Get col         | `zsl_mtx_get_col`     | x   | x   |     |                 |
304| Set col         | `zsl_mtx_set_col`     | x   | x   |     |                 |
305| Add             | `zsl_mtx_add`         | x   | x   |     |                 |
306| Add (d)         | `zsl_mtx_add_d`       | x   | x   |     | Destructive     |
307| Sum rows        | `zsl_mtx_sum_rows_d`  | x   | x   |     | Destructive     |
308| Sum rows scaled | `zsl_mtx_sum_rows_scaled_d` | x | x |   | Destructive     |
309| Subtract        | `zsl_mtx_sub`         | x   | x   |     |                 |
310| Subtract (d)    | `zsl_mtx_sub_d`       | x   | x   |     | Destructive     |
311| Multiply        | `zsl_mtx_mult`        | x   | x   |     |                 |
312| Multiply (d)    | `zsl_mtx_mult_d`      | x   | x   |     | Destructive     |
313| Multiply sc (d) | `zsl_mtx_scalar_mult_d`|x   | x   |     | Destructive     |
314| Multiple row sc (d)| `zsl_mtx_scalar_mult_row_d`|x|x|     | Destructive     |
315| Transpose       | `zsl_mtx_trans`       | x   | x   |     |                 |
316| Adjoint 3x3     | `zsl_mtx_adjoint_3x3` | x   | x   |     |                 |
317| Adjoint         | `zsl_mtx_adjoint`     | x   | x   |     |                 |
318| Wedge product   | `zsl_mtx_vec_wedge`   |     | x   |     |                 |
319| Reduce          | `zsl_mtx_reduce`      | x   | x   |     | Row+col removal |
320| Reduce (iter)   | `zsl_mtx_reduce_iter` | x   | x   |     | Iterative ver.  |
321| Augment         | `zsl_mtx_augm_diag`   | x   | x   |     | Adds row+col(s) |
322| Determinant 3x3 | `zsl_mtx_deter_3x3`   | x   | x   |     |                 |
323| Determinant     | `zsl_mtx_deter`       | x   | x   |     |                 |
324| Gaussian El.    | `zsl_mtx_gauss_elim`  | x   | x   |     |                 |
325| Gaussian El. (d)| `zsl_mtx_gauss_elim_d`| x   | x   |     | Destructive     |
326| Gaussian Rd.    | `zsl_mtx_gauss_reduc` | x   | x   |     |                 |
327| Column norm.    | `zsl_mtx_cols_norm`   | x   | x   |     | Unitary col vals|
328| Gram-Schimdt    | `zsl_mtx_gram_schmidt`| x   | x   |     |                 |
329| Elem. norm.     | `zsl_mtx_norm_elem`   | x   | x   |     | Norm vals to i,j|
330| Elem. norm. (d) | `zsl_mtx_norm_elem_d` | x   | x   |     | Destructive     |
331| Invert 3x3      | `zsl_mtx_inv_3x3`     | x   | x   |     |                 |
332| Invert          | `zsl_mtx_inv`         | x   | x   |     |                 |
333| Balance         | `zsl_mtx_balance`     | x   | x   |     |                 |
334| Householder Ref.| `zsl_mtx_householder` | x   | x   |     |                 |
335| QR decomposition| `zsl_mtx_qrd`         | x   | x   |     |                 |
336| QR decomp. iter.| `zsl_mtx_qrd_iter`    |     | x   |     |                 |
337| Eigenvalues     | `zsl_mtx_eigenvalues` |     | x   |     |                 |
338| Eigenvectors    | `zsl_mtx_eigenvectors`|     | x   |     |                 |
339| SVD             | `zsl_mtx_svd`         |     | x   |     |                 |
340| Pseudoinverse   | `zsl_mtx_pinv`        |     | x   |     |                 |
341| Min value       | `zsl_mtx_min`         | x   | x   |     |                 |
342| Max value       | `zsl_mtx_max`         | x   | x   |     |                 |
343| Min index       | `zsl_mtx_min_idx`     | x   | x   |     |                 |
344| Max index       | `zsl_mtx_max_idx`     | x   | x   |     |                 |
345| Equality check  | `zsl_mtx_is_equal`    | x   | x   |     |                 |
346| Non-neg check   | `zsl_mtx_is_notneg`   | x   | x   |     | All values >= 0 |
347| Symmetr. check  | `zsl_mtx_is_sym`      | x   | x   |     |                 |
348| Print           | `zsl_mtx_print`       | x   | x   |     |                 |
349
350##### Unary matrix operations
351
352The following component-wise unary operations can be executed on a matrix
353using the `zsl_mtx_unary_op` function:
354
355- [x] Increment (`++`)
356- [x] Decrement (`--`)
357- [x] Negative (`-`)
358- [x] Logical negation (`!`)
359- [x] Round
360- [x] Abs
361- [x] Floor
362- [x] Ceiling
363- [x] Exponent
364- [x] Natural log
365- [x] Log10
366- [x] Square root
367- [x] Sin, cos, tan
368- [x] Asin, acos, atan
369- [x] Sinh, cosh, tanh
370
371##### Binary matrix operations
372
373The following component-wise binary operations can be executed on a pair
374of symmetric matrices using the `zsl_mtx_binary_op` function:
375
376- [x] Add (`a + b`)
377- [x] Subtract (`a - b`)
378- [x] Multiply (`a * b`)
379- [x] Divide (`a / b`)
380- [x] Mean (`mean(a, b`)
381- [x] Exponent (`a^b`)
382- [x] Min (`min(a, b)`)
383- [x] Max (`max(a, b)`)
384- [x] Equal (`a == b`)
385- [x] Not equal (`a != b`)
386- [x] Less than (`a < b`)
387- [x] Greater than (`a > b`)
388- [x] Less than or equal to (`a <= b`)
389- [x] Greater than or equal to (`a >= b`)
390
391> **NOTE**: Component-wise **unary** and **binary** matrix operations can also
392  make use of user-defined functions at the application level if the existing
393  operand list is not sufficient. See `zsl_mtx_unary_func` and
394  `zsl_mtx_binary_func` for details.
395
396### Numerical Analysis
397
398#### Statistics
399
400- [x] Mean
401- [x] Trimmed mean
402- [x] Weighted mean
403- [x] Time-weighted mean
404- [x] De-mean
405- [x] Percentile (AKA quantile)
406- [x] Median
407- [x] Weighted median
408- [x] Quartile
409- [x] Interquartile range
410- [x] Mode
411- [x] Data range
412- [x] Mean absolute deviation
413- [x] Median absolute deviation from median
414- [x] Variance
415- [x] Standard deviation
416- [x] Covariance
417- [x] Covariance matrix
418- [x] Linear regression
419- [x] Multiple linear regression \[1\]
420- [x] Weighted multiple minear regression \[1\]
421- [x] Quadrid fitting (Least-squars fitting of a quadric surface) \[1\]
422- [x] Absolute error
423- [x] Relative error
424- [x] Standard error
425
426\[1\] Only available in double-precision
427
428#### Probability Operations
429
430- [X] Uniform probability density function (PDF)
431- [X] Uniform distribution mean
432- [X] Uniform distribution variance
433- [X] Uniform cumulative distribution function (CDF)
434- [X] Normal probability density function (PDF)
435- [X] Normal cumulative distribution function (CDF)
436- [X] Inverse Error function
437- [X] Inverse normal cumulative distribution function (CDF)
438- [x] Factorial
439- [X] Binomial coefficient
440- [X] Binomial probability density function (PDF)
441- [X] Binomial distribution mean
442- [X] Binomial distribution variance
443- [X] Binomial cumulative distribution function (CDF)
444- [X] Information entropy
445- [x] Bayes' Theorem
446
447### Interpolation
448
449- [x] Nearest neighbour (AKA 'piecewise constant')
450- [x] Linear (AKA 'piecewise linear')
451- [x] Natural cubic spline
452
453### Physics
454
455#### Atomic
456
457- [x] Nuclear radius
458- [x] Atomic Radioactive decay
459- [x] Bohr orbital radius
460- [x] Bohr orbital velocity
461- [x] Bohr orbital energy
462- [x] Bragg's law
463
464#### Dynamics
465
466- [x] Newton's second law
467- [x] Mass-acceleration relationship
468- [x] Friction (Fn, uK/s)
469- [x] Normal force on an incline (in newtons based on mass, gravity, angle)
470- [x] Tension
471- [x] Dynamic lever
472- [x] Pendulums
473  - [x] Period
474  - [x] Max Speed
475
476#### Electrical Components
477
478- [x] Capacitance
479  - [x] Charge, voltage
480  - [x] Area, distance
481- [x] Energy stored in capacitor
482- [x] Energy stored in inductor
483- [x] Transformer turns to voltage
484- [x] Resistor/inductor/capacitor voltage relationship
485- [x] Resistor/capacitor charge/discharge
486  - [x] Current during charge
487  - [x] Current during discharge
488  - [x] Charge (in coulombs) during charge
489  - [x] Charge (in coulombs) during discharge
490- [x] Current of RL circuit in time
491
492#### Electric
493
494- [x] Coulomb's law
495- [x] Charge density
496- [x] Potential energy
497- [x] Electric field
498- [x] Coulombs potential
499- [x] Electric flux
500- [x] Force from a charge
501
502#### Electricity
503
504- [x] Current (charge per second)
505- [x] Resistors in series/parallel
506- [x] Capacitors in series/parallel
507- [x] Resistivity of wire
508- [x] Ohm's law
509- [x] Power
510  - [x] Current, voltage
511  - [x] Voltage, resistance
512  - [x] Current, resistance
513
514#### Energy
515
516- [x] Kinetic energy
517- [x] Elastic potential energy
518- [x] Gravitational potential energy
519- [x] Power (work/energy over time)
520- [x] Energy lost to friction
521- [x] Energy of a photon
522- [x] Mechanical energy of a system
523- [x] Total energy of a system
524
525#### Fluids
526
527- [x] Density (of substance in Kg/m^2)
528- [x] Simple pressure (force, area)
529- [x] Pressure in a fluid (at a certain height/depth, gravity, density, surf. pres.)
530- [x] Bouyant Force
531- [x] Fluid flow rate proportion
532- [x] Fluid force rate proportion
533- [x] Bernoulli's equation
534- [x] Volume flow rate
535
536#### Gases
537
538- [x] Average velocity of a gas molecule (mass, temp, moles)
539- [x] Ideal gas law (pressure based on moles, temp, volume)
540- [x] Boyle's law (relationship of pressure, volume)
541- [x] Charles/Gay-Lussac law (relationship of pressure, volume)
542
543#### Gravitation
544
545- [x] Orbital period
546- [x] Escape velocity
547- [x] Gravitational acceleration
548- [x] Orbital velocity
549- [x] Gravitational force
550- [x] Gravitational potential energy
551
552#### Kinematics
553
554- [x] Change in distance (initial velocity, time, acceleration)
555- [x] Initial position (final pos, init velocity, accel, time)
556- [x] Initial position (final pos, init velocity, final velocity, accel)
557- [x] Change in time (initial and final velocity, acceleration)
558- [x] Instantaneous velocity (initial velocity, time, acceleration)
559- [x] Velocity (initial velocity, distance, acceleration)
560- [x] Average velocity (distance, time)
561- [x] Acceleration (initial and final velocity, time)
562- [x] Centripetal acceleration (radius, period, via radius/speed or radius/period)
563
564#### Magnetics
565
566- [x] Magnetic force
567- [x] Force on current carrying wire
568- [x] Torque on current loop
569- [x] Potential energy from a dipole
570- [x] Orbital radius in magnetic field
571- [x] Magnetic flux
572- [x] Magnetic moment
573
574#### Mass
575
576- [x] Calculate the CoM of a group of objects based on their mass and
577      distance from an arbitrary point
578
579#### Momentum
580
581- [x] Calculate momentum (mass, velocity)
582- [x] Impulse (force, time)
583- [x] Change in momentum/force (mass, initial and final velocity)
584- [x] Elastic collision (when two objects collide and bounce)
585- [x] Inelastic collision (when two objects collide and stick)
586
587#### Optics
588
589- [x] Refraction index
590- [x] Snell's law
591- [x] Focus distance
592- [x] Critical angle of incision
593- [x] Power (based on focal length)
594- [x] Magnification (real and apparent length)
595- [x] Diffraction
596
597#### Photons
598
599- [x] Energy
600- [x] Linear momentum
601- [x] Wavelength
602- [x] Frequency
603- [x] Kinetic energy of photoelectric effect
604
605#### Projectiles
606
607- [x] Horizontal and vertical velocity components (initial velocity, theta)
608- [x] Total time of flight
609  - Formula 1: gravity, y2, y1, Vy
610  - Formula 2: initial and final vertical velocity and gravity
611- [x] Vertical motion: position at time (Vy, gravity, time, initial height)
612- [x] Horizontal motion: horizontal change of distance at time
613- [x] Velocity (overall velocity from vertical and horizontal components)
614- [x] Trajectory
615- [x] Theta (angle between vertical and horizontal velocity)
616- [x] Range (distance travelled from ground using initial velocity, gravity, angle)
617
618#### Relativity (v0.3.0)
619
620- [ ] Time dilatation
621- [ ] Lorentz contraction
622- [ ] Relativistic momentum
623- [ ] Kinetic energy
624- [ ] Mass to energy
625- [ ] Lorenz velocity transformation
626- [ ] Relativistic doppler affect
627
628#### Rotation
629
630- [x] Change in theta (analog to distance in kinematics)
631- [x] Distance travelled in circular motion
632- [x] Number of rotations around circle
633- [x] Change in time (analog to time in kinematics)
634- [x] Instantaneous angular velocity
635- [x] Angular velocity
636- [x] Average angular velocity
637- [x] Angular acceleration
638- [x] Rotational kinetic energy
639- [x] Rotational period
640- [x] Rotational frequency
641- [x] Centripetal acceleration
642- [x] Total acceleration
643- [x] Mechanical power (torque multiplied by angular velocity)
644
645#### Sound
646
647- [x] Pressure amplitude
648- [x] Decibels (sound level between two intensities of the same frequency)
649- [x] Intensity (pressure amplitude, bulk modulus, density)
650- [x] Shock wave angle (speed of sound and velocity through medium)
651- [x] Doppler effect
652- [x] Beats (frequency resulting from overlap of two similar frequencies)
653
654#### Thermodynamics
655
656- [x] Temperature conversion (fahrenheit, celsius, kelvin)
657- [x] Latent heat of fusion/vaporisation
658- [x] Heat (in joules of a material based on mass, specific heat and delta temp)
659- [x] Linear expansion of metal (length, alpha constant, change in temperature)
660- [x] Mean free path
661- [x] Efficiency of a heat engine (based on energy of hot and cold chambers)
662- [x] Carnot engine proportion
663
664#### Waves
665
666- TBD
667
668#### Work
669
670- [x] Work done over an interval of distance and constant applied force
671- [x] Work done cosine (as above but with x-component or on an incline)
672- [x] Work done sine (as above but with y-component or on an incline)
673- [x] Work-KE theorem
674
675### Motion and Orientation
676
677#### AHRS/Attitude (Degrees)
678
679- [x] Basic struct definitions
680- [x] Conversion
681  - [x] To vector (access vector API)
682  - [x] To Euler (degrees to radian)
683  - [x] From Euler (radians to degrees)
684  - [x] From Accel + Mag (roll, pitch, yaw)
685  - [x] From Accel (roll, pitch)
686- [x] Angle between two accelerometers
687
688#### Compass
689
690- [x] Degrees, Minutes, Seconds to Decimal Degrees (dms to dd)
691- [x] Magnetic north
692- [x] Geographic (AKA true) north
693
694#### Euler Angles (Radians)
695
696- [x] Basic struct definitions
697- [x] Conversion
698  - [x] To vector (access vector API)
699
700#### Gravity
701
702- [x] Gravitational field from latitude and altitude
703
704#### Quaternions
705
706- [x] Basic struct definitions
707- [x] Magnitude
708- [x] Unit check
709- [x] Scaling
710- [x] Multiplication
711- [x] Exp
712- [x] Log
713- [x] Exponentiation
714- [x] Conjugate
715- [x] Inverse
716- [x] Difference
717- [x] Rotate
718- [x] Interpolation
719  - [x] Lerp
720  - [x] Slerp
721- [x] Integration
722  - [x] Angular velocity (rad/s + time + current value)
723  - [x] Angular momentum (Same as above, plus rotational mass)
724- [x] Conversion
725  - [x] To unit (Normalise)
726  - [x] To Euler (radians)
727  - [x] From Euler (radians)
728  - [x] To rotation matrix
729  - [x] From rotation matrix
730  - [x] To axis-angle
731  - [x] From axis-angle
732- [x] Special Forms
733  - [x] Identity
734
735#### Sensor Fusion
736
737- [x] Define generic fusion interface/struct (accel+mag+gyro -> quaternion)
738- [x] Matrix rotation (adjust device orientation)
739- [x] Axis-angle rotation (adjust device orientation)
740- [x] Calibration
741  - [x] Magnetometer (hard-iron and soft-iron errors)
742  - [x] Correct magnetometer (apply correction coefficients)
743  - [x] Madgwick calibration
744  - [x] Mahoney calibration
745- [x] Implementations
746  - [x] AQUA
747  - [x] Complementary
748  - [x] Extended Kalman
749  - [x] Madgwick
750  - [x] Mahoney
751  - [x] SAAM
752
753### Colorimetry
754
755#### Types/Structs
756
757- [x] Spectral power distribution (SPD)
758- [x] CIE 1931 XYZ tristimulus
759- [x] CIE 1931 xyY chromaticity
760- [x] CIE 1960 UCS chromaticity
761- [x] CIE 1976 UCS chromaticity
762- [x] RGBA color using floating-space notation (0.0 .. 1.0)
763- [x] RGBA color using 8-bit values
764- [x] RGBA color using 16-bit values
765- [x] CIE 1960 CCT, Duv value pair
766- [x] CIE 1931 XYZ tristimulus values for a standard illuminant
767- [x] CIE 1931 XYZ tristimulus values for a standard observer model
768
769#### Functions
770
771- [x] SPD normalisation
772- [x] SPD to XYZ tristimulus
773- [x] CIE 1931 xyY chromaticity to XYZ tristimulus
774- [x] CIE 1931 XYZ tristimulus values to xyY chromaticity
775- [x] CIE 1931 xyY chromaticity to CIE 1960 uv
776- [x] CIE 1931 XYZ tristimulus to CIE 1960 uv
777- [x] CIE 1960 uv to CIE 1931 XYZ tristimulus
778- [x] CIE 1960 uv to CIE 1931 xyY chromaticity
779- [x] CIE 1960 uv to CIE 1976 u'v'
780- [x] CIE 1976 u'v' value to CIE 1960 uv
781- [x] Color temperature to (u,v) chromaticity
782- [x] CIE 1960 CCT (Duv = 0.0) to CIE 1931 XYZ tristimulus
783- [x] CIE 1960 CCT (Duv = 0.0) to 8-bit RGBA (supplied XYZ to RGB color space correlation matrix)
784- [x] CIE 1960 CCT (Duv = 0.0) to float RGBA (supplied XYZ to RGB color space correlation matrix)
785- [x] CIE 1960 CCT and Duv pair to CIE 1931 xyY chromaticity
786- [x] CIE 1960 CCT and Duv pair to CIE 1931 XYZ tristimulus
787- [x] CIE 1960 (u, v) pair to CIE 1960 CCT and Duv pair using:
788  - [x] McCamy
789  - [x] Ohno 2014
790- [x] CIE 1931 XYZ tristimulus to 8-bit RGBA (supplied XYZ to RGB color space correlation matrix)
791- [x] CIE 1931 XYZ tristimulus to float RGBA (supplied XYZ to RGB color space correlation matrix)
792- [ ] Gamma encode
793- [ ] Gamma decode
794
795#### Color Data
796
797##### Illuminants
798
799- [x] A
800- [x] B
801- [x] C
802- [x] D50
803- [x] D55
804- [x] D65
805- [x] E
806- [x] ICC
807
808##### CIE Standard Observer Models
809
810- [x] CIE 1931 2 degree standard observer color matching functions
811- [x] CIE 1964 10 degree standard observer color matching functions
812
813##### CIE Luminous Efficiency Functions
814
815- [x] CIE 1988 Photopic
816- [x] CIE 1951 Scotopic
817- [x] CIE LERP interpolation helper function
818
819##### XYZ to RGB Color Space Correlation Matrices
820
821- [x] XYZ to linear sRGB (D65)
822- [x] XYZ to linear sRGB (D50)
823- [x] XYZ to Adobe RGB 98
824- [x] XYZ to Sony S-Gamut3.cine D65
825- [x] XYZ to NTSC
826- [x] XYZ to PAL/SECAM
827- [x] XYZ to ITU-R BT.709
828- [x] XYZ to ITU-R BT.2020
829- [x] XYZ to ACES Primaries #0 (AP0)
830- [x] XYZ to ACES Primaries #1 (AP1)
831- [x] XYZ to DCI-P3
832- [x] XYZ to DCI-P3+
833- [x] XYZ to CIE RGB
834
835### Chemistry
836
837- [ ] Periodic table data including:
838  - [ ] Full name
839  - [ ] Abbreviation
840  - [x] Atomic number
841  - [x] Standard atomic weight
842
843### Measurement API (v0.2.0)
844
845The `zsl_measurement` struct is a proof of concept attempt at representing
846measurements in a concise but unambiguous manner.
847
848It consists of:
849
850- A **measurement type** (Base Type + Extended Type)
851- The **SI unit** it uses (SI Unit Type)
852- The specific **C type** used to represent it in memory (C Type)
853- Additional meta-data to help interpret the measurement payload
854
855There is an option to adjust the measurement's **scale** in +/- 10^n steps
856(Scale Factor) from the default SI unit and scale indicated by the SI Unit
857Type. For example, if 'Ampere' is indicated as the SI unit, the measurement
858could indicate that the value is in uA by setting the scale factor to -6.
859
860- [x] Measurement struct(s) (see: `zsl_measurement`)
861- [x] Base Measurement Types
862- [ ] Extended Measurement Types
863  - [x] Color
864  - [x] Light
865  - [x] Temperature
866  - [ ] Other groups TBD
867- [x] SI Units
868- [x] SI Scales
869- [x] C Types
870
871## Longer Term Planned Features
872
873Help is welcome on the following planned or desirable features.
874
875### Scalar Operations
876
877- Fast trigonometry approximations
878
879### Digital Signal Processing (v0.3.0)
880
881- Simple moving average filter
882- Windowed moving average filter
883- Weighted moving average filter
884- Other basic IIR and FIR-type filters and helper functions.
885
886### Spectrometry
887
888- Conversion between radiometric and photometric units
889- Radiometric data to lux
890- Radiometric data to CCT/Duv
891- Spectral analysis
892
893### Calibration
894
895- Offset management
896- Correlation matrix generation
897- Non-linear compensation
898
899## Architecture-Specific Optimisations
900
901Basic tooling has been added to allow for optimised architecture-specific
902implementations of key functions in assembly.
903
904At present, this feature isn't being actively used or developed, but an aim
905of zscilib is to add optimised versions of key functions to try to get the
906best possible performance out of limited resources.
907
908Initial optimisation will target the **Arm Cortex-M** family of devices and the
909**Thumb** and **Thumb-2** instruction sets, though other architectures can be
910accommodated if necessary or useful.
911
912## Code Style
913
914Since the primary target of this codebase is running as a module in
915[Zephyr OS][CS0], it follows the same [coding style][CS1], which is itself
916based on the [Linux kernel coding style][CS2].
917
918You can format the source code to match this style automatically using the
919[uncrustify][CS3] command line tool, which has plugins available for many
920common text editors (Atom Beautify, for example).
921
922- [Crustify rules file][CS4]
923
924[CS0]: https://www.zephyrproject.org/
925[CS1]: https://docs.zephyrproject.org/latest/contribute/index.html#coding-style
926[CS2]: https://kernel.org/doc/html/latest/process/coding-style.html
927[CS3]: http://uncrustify.sourceforge.net/
928[CS4]: https://github.com/zephyrproject-rtos/zephyr/blob/master/.uncrustify.cfg
929
930## Contributing
931
932If you wish to contribute to this library, you can raise a PR as follows:
933
9341. Fork the repository: https://github.com/zephyrproject-rtos/zscilib/fork
9352. `git clone` your forked repository.
9363. Update your local repo and commit any changes.
9374. Push the changes out to your fork on Github.
9385. Navigate to https://github.com/zephyrproject-rtos/zscilib and to the
939   right of the **Branch** menu click **New pull request**.
9406. Fill out the form that is presented.
9417. Click the **Create Pull Request** button to submit the PR.
942
943Also have a look at the [Issues][4] page to see if there is any outstanding
944work or issues that you might be able to help with!
945
946[4]: https://github.com/zephyrproject-rtos/zscilib/issues
947
948## License
949
950Apache 2.0.
951