embedded-complex-f32 0.1.0

Nombres complexes f32 no_std pour systèmes embarqués sans dépendance C, sans unsafe
Documentation
# 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)**

[![Crates.io](https://img.shields.io/crates/v/embedded-complex-f32)](https://crates.io/crates/embedded-complex-f32)
[![Docs.rs](https://docs.rs/embedded-complex-f32/badge.svg)](https://docs.rs/embedded-complex-f32)
[![License: GPL-2.0-or-later](https://img.shields.io/badge/license-GPL--2.0--or--later-blue)](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
let quot = a / b;   // NaN + NaN·i si |b| == 0 préférer checked_div

// 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.

| Opération | Précision |
|-----------|-----------|
| `+`, `-`, `*`, `/` | 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/>