# embedded-complex-f32
Nombres complexes `f32` pour systèmes embarqués `no_std`.
**Zéro dépendance C · Sans `unsafe` · Racine carrée via [`embedded-f32-sqrt`](https://crates.io/crates/embedded-f32-sqrt)**
[](https://crates.io/crates/embedded-complex-f32)
[](https://docs.rs/embedded-complex-f32)
[](LICENSE)
---
## Fonctionnalités
- Arithmétique complète : `+`, `-`, `*`, `/` (opérateurs Rust natifs)
- Opérations scalaires `f32` : `z + 1.0`, `z * 2.0`, etc.
- Module (norme), carré de la norme, conjugué
- Puissance entière (`powi`) par exponentiation rapide
- Racine carrée complexe (`csqrt`)
- Inverse (`inv`), division vérifiée (`checked_div`)
- Gestion robuste de NaN / Infinity (IEEE 754)
- `Display` et `Debug` via `core::fmt`
- Conversions `From<f32>`, `From<(f32, f32)>`, `Into<(f32, f32)>`
## Hors périmètre
`arg()`, `to_polar()`, `from_polar()`, `exp()`, `ln()` requièrent des fonctions
trigonométriques précises. Utilisez `libm` ou `micromath` selon votre target et
construisez par-dessus ce type.
---
## Installation
```toml
[dependencies]
embedded-complex-f32 = "0.1.0"
```
---
## Démarrage rapide
```rust
use embedded_complex_f32::Complex;
let a = Complex::new(3.0, 4.0); // 3 + 4i
let b = Complex::new(1.0, -1.0); // 1 - i
// Arithmétique de base
let sum = a + b; // 4 + 3i
let diff = a - b; // 2 + 5i
let prod = a * b; // 7 + i
// Module et conjugué
assert!((a.norm() - 5.0).abs() < 1e-4); // |3 + 4i| = 5
assert_eq!(a.conj(), Complex::new(3.0, -4.0));
// Division sûre
match a.checked_div(b) {
Ok(r) => { /* utiliser r */ }
Err(e) => { /* ComplexError::DivisionByZero */ }
}
```
---
## Référence API
### Constantes
```rust
Complex::ZERO // 0 + 0i
Complex::ONE // 1 + 0i
Complex::I // 0 + 1i
```
### Constructeurs et accesseurs
```rust
Complex::new(re: f32, im: f32) -> Complex
z.re() -> f32 // partie réelle
z.im() -> f32 // partie imaginaire
z.is_nan() -> bool
z.is_infinite() -> bool
z.is_finite() -> bool
```
### Arithmétique
```rust
// Complex op Complex
z1 + z2 z1 - z2 z1 * z2 z1 / z2
z1 += z2 z1 -= z2 z1 *= z2 z1 /= z2
// Complex op f32
z + 1.0 z - 1.0 z * 2.0 z / 2.0
// Négation
-z
```
### Opérations algébriques
```rust
// Conjugué : re - im·i
z.conj() -> Complex
// Norme : √(re² + im²)
z.norm() -> f32
// Carré de la norme : re² + im² (évite la racine carrée)
z.norm_sq() -> f32
// Division vérifiée
z.checked_div(rhs: Complex) -> Result<Complex, ComplexError>
// Inverse : 1 / self
z.inv() -> Result<Complex, ComplexError>
// Racine carrée complexe
z.csqrt() -> Result<Complex, ComplexError>
// Complex::new( 9.0, 0.0).csqrt() -> Ok(3.0 + 0.0i)
// Complex::new(-1.0, 0.0).csqrt() -> Ok(0.0 + 1.0i)
// Puissance entière (n négatif autorisé)
z.powi(n: i32) -> Result<Complex, ComplexError>
// Complex::I.powi(4) -> Ok(1.0 + 0.0i)
// Complex::new(2.0, 0.0).powi(-1) -> Ok(0.5 + 0.0i)
```
### Conversions
```rust
Complex::from(3.0f32) // 3.0 + 0.0i
Complex::from((1.0f32, -2.0f32)) // 1.0 - 2.0i
let (re, im): (f32, f32) = z.into();
```
### Gestion d'erreurs
```rust
use embedded_complex_f32::ComplexError;
match z.checked_div(w) {
Ok(result) => { /* ... */ }
Err(ComplexError::DivisionByZero) => { /* |w| == 0 */ }
Err(ComplexError::NegativeInput) => { /* entrée invalide pour √ */ }
Err(ComplexError::Undefined) => { /* NaN propagé */ }
}
```
---
## Exemples
### Filtre IIR (pôle complexe)
```rust
use embedded_complex_f32::Complex;
// Pôle fourni sous forme cartésienne par l'appelant
let pole = Complex::new(0.8, 0.3);
// Un pas : y[n] = x[n] + pole * y[n-1]
fn iir_step(x: f32, y_prev: Complex, pole: Complex) -> Complex {
Complex::from(x) + pole * y_prev
}
```
### Puissance entière
```rust
use embedded_complex_f32::Complex;
// (1 + i)^8 = 16
let z = Complex::new(1.0, 1.0);
let r = z.powi(8).unwrap();
assert!((r.re() - 16.0).abs() < 1e-3);
assert!(r.im().abs() < 1e-3);
```
### Racine carrée
```rust
use embedded_complex_f32::Complex;
// Vérification : s² == z
let z = Complex::new(3.0, 4.0);
let s = z.csqrt().unwrap();
let back = s * s;
assert!((back.re() - 3.0).abs() < 1e-4);
assert!((back.im() - 4.0).abs() < 1e-4);
```
---
## Précision numérique
Toutes les opérations reposent sur l'arithmétique IEEE 754 `f32` native
aucune approximation trigonométrique n'est introduite par cette crate.
| `+`, `-`, `*`, `/` | arrondi IEEE 754 f32 |
| `norm`, `norm_sq` | arrondi IEEE 754 f32 |
| `csqrt` | < 1e-4 (via `embedded-f32-sqrt`) |
| `powi` | accumulation d'arrondi f32 |
---
## `no_std`
`#![no_std]` :utilise uniquement `core`. Compatible avec tout target Rust
embarqué : ARM Cortex-M, RISC-V, AVR, etc. Aucun feature flag requis.
---
## Testée sur la Waveshare 2350B
````rust
let z = Complex::new(-1.0, 0.0);
````
Donne bien z=−1+0i , ∣z∣=(−1)^2+0^2=1 , z^2=(−1)^2=1 et sqrt = 0 + 1i
**⚠️ Petit détail subtil (mais important)**
Il existe 2 solutions :i et −i , La fonction csqrt choisit une convention (basée sur le signe de im) → c’est très bien
## Licence
Copyright (C) 2026 Jorge Andre Castro
Ce programme est un logiciel libre : vous pouvez le redistribuer et/ou le
modifier selon les termes de la **GNU General Public License** telle que
publiée par la Free Software Foundation, soit la version 2 de la licence,
soit (à votre gré) n'importe quelle version ultérieure.
Ce programme est distribué dans l'espoir qu'il sera utile, mais **sans aucune
garantie** ; sans même la garantie implicite de **commercialisation** ou
d'**adéquation à un usage particulier**.
`SPDX-License-Identifier: GPL-2.0-or-later` <https://www.gnu.org/licenses/>