Compare commits

...

27 Commits

Author SHA1 Message Date
5e997b58d9 text recu works 2026-02-13 17:32:46 +01:00
b343675fa7 vraiment la merde 2026-02-13 17:13:11 +01:00
8c2abd902c c'est la merde 2026-02-13 16:48:28 +01:00
826cfe8569 add thread 2026-02-13 15:31:36 +01:00
04b0d79058 modif 2026-02-13 15:31:09 +01:00
36402570ee analyse 2026-02-13 15:30:58 +01:00
369a83bcfd analyse complete 2026-02-13 15:30:36 +01:00
6a23a35f40 analyse py graphique 2026-02-13 15:30:15 +01:00
f4201536de working BAD 2026-02-13 12:28:50 +01:00
2096cff73c clear main 2026-02-13 12:12:30 +01:00
22db186237 simulation séparé du main 2026-02-13 12:12:14 +01:00
a7ce4a1a17 channel add noise 2026-02-13 11:44:44 +01:00
a6b2690721 channel add 2026-02-13 11:21:44 +01:00
33a376967a note edit 2026-02-13 11:07:55 +01:00
a1da2efedf note edit 2026-02-12 19:19:40 +01:00
6433bb5e9d decoder bit flipping (hard decision) 2026-02-12 19:19:17 +01:00
1c7daec957 generer H avec k 2026-02-12 12:32:46 +01:00
d478be5f77 idiomatique change 2026-02-12 12:20:12 +01:00
92d847ba69 rm bin 2026-02-12 12:02:54 +01:00
374243bc1e rm bin 2026-02-12 12:00:25 +01:00
8df29fb7a2 rm bin 2026-02-12 11:59:44 +01:00
17337f3298 rm bin 2026-02-12 11:56:22 +01:00
11ef294a5a rm bin 2026-02-12 11:55:21 +01:00
092b6bc791 rm bin 2026-02-12 11:53:25 +01:00
08a57f903f simplification rustique 2026-02-11 20:38:57 +01:00
69a65a884d blabla 2026-02-11 20:03:26 +01:00
8082d4c29b ldpc rust 2026-02-11 19:58:43 +01:00
25 changed files with 6060 additions and 3864 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.d
Code/ldpc/target
Code/ldpc/src/target

463
Code/ldpc/Cargo.lock generated Normal file
View File

@ -0,0 +1,463 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
[[package]]
name = "bitflags"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chacha20"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
"cfg-if",
"cpufeatures",
"rand_core",
]
[[package]]
name = "cpufeatures"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
dependencies = [
"libc",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"rand_core",
"wasip2",
"wasip3",
]
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]]
name = "indexmap"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
"serde",
"serde_core",
]
[[package]]
name = "itoa"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]]
name = "ldpc"
version = "0.1.0"
dependencies = [
"rand",
"rayon",
]
[[package]]
name = "leb128fmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
version = "0.2.181"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
dependencies = [
"chacha20",
"getrandom",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
[[package]]
name = "rayon"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "syn"
version = "2.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "wasip2"
version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasip3"
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-encoder"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
"leb128fmt",
"wasmparser",
]
[[package]]
name = "wasm-metadata"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags",
"hashbrown 0.15.5",
"indexmap",
"semver",
]
[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
dependencies = [
"anyhow",
"heck",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
dependencies = [
"anyhow",
"heck",
"indexmap",
"prettyplease",
"syn",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
dependencies = [
"anyhow",
"prettyplease",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
]
[[package]]
name = "wit-component"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser",
]
[[package]]
name = "zmij"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7"

8
Code/ldpc/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "ldpc"
version = "0.1.0"
edition = "2024"
[dependencies]
rand = "0.10.0"
rayon = "1.11.0"

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -0,0 +1,91 @@
k,n,wc,wr,rate,p,ber,fer,avg_iter
50,100,3,6,0.5000,0.000000,0.00000000,0.00000000,0.00
50,100,3,6,0.5000,0.008571,0.09586000,0.21200000,0.00
50,100,3,6,0.5000,0.017143,0.20772000,0.44500000,0.00
50,100,3,6,0.5000,0.025714,0.28084000,0.58700000,0.00
50,100,3,6,0.5000,0.034286,0.35496000,0.74100000,0.00
50,100,3,6,0.5000,0.042857,0.39766000,0.82200000,0.00
50,100,3,6,0.5000,0.051429,0.42240000,0.87200000,0.00
50,100,3,6,0.5000,0.060000,0.44045000,0.91000000,0.00
50,100,3,6,0.5000,0.068571,0.45518000,0.93500000,0.00
50,100,3,6,0.5000,0.077143,0.47826000,0.97400000,0.00
50,100,3,6,0.5000,0.085714,0.48009000,0.98200000,0.00
50,100,3,6,0.5000,0.094286,0.48391000,0.98600000,0.00
50,100,3,6,0.5000,0.102857,0.48988000,0.99300000,0.00
50,100,3,6,0.5000,0.111429,0.49456000,0.99500000,0.00
50,100,3,6,0.5000,0.120000,0.49429000,0.99700000,0.00
50,75,3,9,0.6667,0.000000,0.00000000,0.00000000,0.00
50,75,3,9,0.6667,0.008571,0.07490667,0.14800000,0.00
50,75,3,9,0.6667,0.017143,0.17278667,0.34600000,0.00
50,75,3,9,0.6667,0.025714,0.27240000,0.54800000,0.00
50,75,3,9,0.6667,0.034286,0.34341333,0.69300000,0.00
50,75,3,9,0.6667,0.042857,0.39881333,0.81500000,0.00
50,75,3,9,0.6667,0.051429,0.43321333,0.88400000,0.00
50,75,3,9,0.6667,0.060000,0.45101333,0.91400000,0.00
50,75,3,9,0.6667,0.068571,0.47332000,0.95300000,0.00
50,75,3,9,0.6667,0.077143,0.46954667,0.96000000,0.00
50,75,3,9,0.6667,0.085714,0.47985333,0.98400000,0.00
50,75,3,9,0.6667,0.094286,0.48470667,0.98600000,0.00
50,75,3,9,0.6667,0.102857,0.49201333,0.99400000,0.00
50,75,3,9,0.6667,0.111429,0.49064000,0.99400000,0.00
50,75,3,9,0.6667,0.120000,0.49248000,0.99800000,0.00
200,400,3,6,0.5000,0.000000,0.00000000,0.00000000,0.00
200,400,3,6,0.5000,0.008571,0.30167250,0.60100000,0.00
200,400,3,6,0.5000,0.017143,0.36523750,0.73200000,0.00
200,400,3,6,0.5000,0.025714,0.43035000,0.86000000,0.00
200,400,3,6,0.5000,0.034286,0.46297500,0.92400000,0.00
200,400,3,6,0.5000,0.042857,0.49018000,0.98000000,0.00
200,400,3,6,0.5000,0.051429,0.49391000,0.98900000,0.00
200,400,3,6,0.5000,0.060000,0.49773500,0.99700000,0.00
200,400,3,6,0.5000,0.068571,0.49869750,0.99700000,0.00
200,400,3,6,0.5000,0.077143,0.50014500,1.00000000,50.00
200,400,3,6,0.5000,0.085714,0.49800500,1.00000000,50.00
200,400,3,6,0.5000,0.094286,0.50103250,1.00000000,50.00
200,400,3,6,0.5000,0.102857,0.50059000,1.00000000,50.00
200,400,3,6,0.5000,0.111429,0.49997500,1.00000000,50.00
200,400,3,6,0.5000,0.120000,0.49996000,1.00000000,50.00
200,300,3,9,0.6667,0.000000,0.00000000,0.00000000,0.00
200,300,3,9,0.6667,0.008571,0.27226333,0.54500000,0.00
200,300,3,9,0.6667,0.017143,0.38370000,0.77100000,0.00
200,300,3,9,0.6667,0.025714,0.45723000,0.91600000,0.00
200,300,3,9,0.6667,0.034286,0.48475000,0.97000000,0.00
200,300,3,9,0.6667,0.042857,0.49562667,0.99200000,0.00
200,300,3,9,0.6667,0.051429,0.49894000,0.99800000,0.00
200,300,3,9,0.6667,0.060000,0.50088333,1.00000000,50.00
200,300,3,9,0.6667,0.068571,0.49815667,1.00000000,50.00
200,300,3,9,0.6667,0.077143,0.50034000,1.00000000,50.00
200,300,3,9,0.6667,0.085714,0.49923333,1.00000000,50.00
200,300,3,9,0.6667,0.094286,0.50140000,1.00000000,50.00
200,300,3,9,0.6667,0.102857,0.49978333,1.00000000,50.00
200,300,3,9,0.6667,0.111429,0.50114333,1.00000000,50.00
200,300,3,9,0.6667,0.120000,0.50025667,1.00000000,50.00
400,800,3,6,0.5000,0.000000,0.00000000,0.00000000,0.00
400,800,3,6,0.5000,0.008571,0.32761250,0.65400000,0.00
400,800,3,6,0.5000,0.017143,0.41412625,0.82000000,0.00
400,800,3,6,0.5000,0.025714,0.46907375,0.92900000,0.00
400,800,3,6,0.5000,0.034286,0.48519375,0.96900000,0.00
400,800,3,6,0.5000,0.042857,0.49841750,0.99300000,0.00
400,800,3,6,0.5000,0.051429,0.50101500,1.00000000,50.00
400,800,3,6,0.5000,0.060000,0.49914250,1.00000000,50.00
400,800,3,6,0.5000,0.068571,0.49955625,1.00000000,50.00
400,800,3,6,0.5000,0.077143,0.49976500,1.00000000,50.00
400,800,3,6,0.5000,0.085714,0.50057750,1.00000000,50.00
400,800,3,6,0.5000,0.094286,0.50094625,1.00000000,50.00
400,800,3,6,0.5000,0.102857,0.50099250,1.00000000,50.00
400,800,3,6,0.5000,0.111429,0.50017125,1.00000000,50.00
400,800,3,6,0.5000,0.120000,0.49992750,1.00000000,50.00
400,600,3,9,0.6667,0.000000,0.00000000,0.00000000,0.00
400,600,3,9,0.6667,0.008571,0.35087667,0.70300000,0.00
400,600,3,9,0.6667,0.017143,0.43971000,0.88200000,0.00
400,600,3,9,0.6667,0.025714,0.48824167,0.97500000,0.00
400,600,3,9,0.6667,0.034286,0.49763833,0.99600000,0.00
400,600,3,9,0.6667,0.042857,0.49956833,1.00000000,50.00
400,600,3,9,0.6667,0.051429,0.49943667,1.00000000,50.00
400,600,3,9,0.6667,0.060000,0.50025667,1.00000000,50.00
400,600,3,9,0.6667,0.068571,0.49899333,1.00000000,50.00
400,600,3,9,0.6667,0.077143,0.49918333,1.00000000,50.00
400,600,3,9,0.6667,0.085714,0.50041833,1.00000000,50.00
400,600,3,9,0.6667,0.094286,0.49998167,1.00000000,50.00
400,600,3,9,0.6667,0.102857,0.50129000,1.00000000,50.00
400,600,3,9,0.6667,0.111429,0.49973500,1.00000000,50.00
400,600,3,9,0.6667,0.120000,0.50078833,1.00000000,50.00
1 k n wc wr rate p ber fer avg_iter
2 50 100 3 6 0.5000 0.000000 0.00000000 0.00000000 0.00
3 50 100 3 6 0.5000 0.008571 0.09586000 0.21200000 0.00
4 50 100 3 6 0.5000 0.017143 0.20772000 0.44500000 0.00
5 50 100 3 6 0.5000 0.025714 0.28084000 0.58700000 0.00
6 50 100 3 6 0.5000 0.034286 0.35496000 0.74100000 0.00
7 50 100 3 6 0.5000 0.042857 0.39766000 0.82200000 0.00
8 50 100 3 6 0.5000 0.051429 0.42240000 0.87200000 0.00
9 50 100 3 6 0.5000 0.060000 0.44045000 0.91000000 0.00
10 50 100 3 6 0.5000 0.068571 0.45518000 0.93500000 0.00
11 50 100 3 6 0.5000 0.077143 0.47826000 0.97400000 0.00
12 50 100 3 6 0.5000 0.085714 0.48009000 0.98200000 0.00
13 50 100 3 6 0.5000 0.094286 0.48391000 0.98600000 0.00
14 50 100 3 6 0.5000 0.102857 0.48988000 0.99300000 0.00
15 50 100 3 6 0.5000 0.111429 0.49456000 0.99500000 0.00
16 50 100 3 6 0.5000 0.120000 0.49429000 0.99700000 0.00
17 50 75 3 9 0.6667 0.000000 0.00000000 0.00000000 0.00
18 50 75 3 9 0.6667 0.008571 0.07490667 0.14800000 0.00
19 50 75 3 9 0.6667 0.017143 0.17278667 0.34600000 0.00
20 50 75 3 9 0.6667 0.025714 0.27240000 0.54800000 0.00
21 50 75 3 9 0.6667 0.034286 0.34341333 0.69300000 0.00
22 50 75 3 9 0.6667 0.042857 0.39881333 0.81500000 0.00
23 50 75 3 9 0.6667 0.051429 0.43321333 0.88400000 0.00
24 50 75 3 9 0.6667 0.060000 0.45101333 0.91400000 0.00
25 50 75 3 9 0.6667 0.068571 0.47332000 0.95300000 0.00
26 50 75 3 9 0.6667 0.077143 0.46954667 0.96000000 0.00
27 50 75 3 9 0.6667 0.085714 0.47985333 0.98400000 0.00
28 50 75 3 9 0.6667 0.094286 0.48470667 0.98600000 0.00
29 50 75 3 9 0.6667 0.102857 0.49201333 0.99400000 0.00
30 50 75 3 9 0.6667 0.111429 0.49064000 0.99400000 0.00
31 50 75 3 9 0.6667 0.120000 0.49248000 0.99800000 0.00
32 200 400 3 6 0.5000 0.000000 0.00000000 0.00000000 0.00
33 200 400 3 6 0.5000 0.008571 0.30167250 0.60100000 0.00
34 200 400 3 6 0.5000 0.017143 0.36523750 0.73200000 0.00
35 200 400 3 6 0.5000 0.025714 0.43035000 0.86000000 0.00
36 200 400 3 6 0.5000 0.034286 0.46297500 0.92400000 0.00
37 200 400 3 6 0.5000 0.042857 0.49018000 0.98000000 0.00
38 200 400 3 6 0.5000 0.051429 0.49391000 0.98900000 0.00
39 200 400 3 6 0.5000 0.060000 0.49773500 0.99700000 0.00
40 200 400 3 6 0.5000 0.068571 0.49869750 0.99700000 0.00
41 200 400 3 6 0.5000 0.077143 0.50014500 1.00000000 50.00
42 200 400 3 6 0.5000 0.085714 0.49800500 1.00000000 50.00
43 200 400 3 6 0.5000 0.094286 0.50103250 1.00000000 50.00
44 200 400 3 6 0.5000 0.102857 0.50059000 1.00000000 50.00
45 200 400 3 6 0.5000 0.111429 0.49997500 1.00000000 50.00
46 200 400 3 6 0.5000 0.120000 0.49996000 1.00000000 50.00
47 200 300 3 9 0.6667 0.000000 0.00000000 0.00000000 0.00
48 200 300 3 9 0.6667 0.008571 0.27226333 0.54500000 0.00
49 200 300 3 9 0.6667 0.017143 0.38370000 0.77100000 0.00
50 200 300 3 9 0.6667 0.025714 0.45723000 0.91600000 0.00
51 200 300 3 9 0.6667 0.034286 0.48475000 0.97000000 0.00
52 200 300 3 9 0.6667 0.042857 0.49562667 0.99200000 0.00
53 200 300 3 9 0.6667 0.051429 0.49894000 0.99800000 0.00
54 200 300 3 9 0.6667 0.060000 0.50088333 1.00000000 50.00
55 200 300 3 9 0.6667 0.068571 0.49815667 1.00000000 50.00
56 200 300 3 9 0.6667 0.077143 0.50034000 1.00000000 50.00
57 200 300 3 9 0.6667 0.085714 0.49923333 1.00000000 50.00
58 200 300 3 9 0.6667 0.094286 0.50140000 1.00000000 50.00
59 200 300 3 9 0.6667 0.102857 0.49978333 1.00000000 50.00
60 200 300 3 9 0.6667 0.111429 0.50114333 1.00000000 50.00
61 200 300 3 9 0.6667 0.120000 0.50025667 1.00000000 50.00
62 400 800 3 6 0.5000 0.000000 0.00000000 0.00000000 0.00
63 400 800 3 6 0.5000 0.008571 0.32761250 0.65400000 0.00
64 400 800 3 6 0.5000 0.017143 0.41412625 0.82000000 0.00
65 400 800 3 6 0.5000 0.025714 0.46907375 0.92900000 0.00
66 400 800 3 6 0.5000 0.034286 0.48519375 0.96900000 0.00
67 400 800 3 6 0.5000 0.042857 0.49841750 0.99300000 0.00
68 400 800 3 6 0.5000 0.051429 0.50101500 1.00000000 50.00
69 400 800 3 6 0.5000 0.060000 0.49914250 1.00000000 50.00
70 400 800 3 6 0.5000 0.068571 0.49955625 1.00000000 50.00
71 400 800 3 6 0.5000 0.077143 0.49976500 1.00000000 50.00
72 400 800 3 6 0.5000 0.085714 0.50057750 1.00000000 50.00
73 400 800 3 6 0.5000 0.094286 0.50094625 1.00000000 50.00
74 400 800 3 6 0.5000 0.102857 0.50099250 1.00000000 50.00
75 400 800 3 6 0.5000 0.111429 0.50017125 1.00000000 50.00
76 400 800 3 6 0.5000 0.120000 0.49992750 1.00000000 50.00
77 400 600 3 9 0.6667 0.000000 0.00000000 0.00000000 0.00
78 400 600 3 9 0.6667 0.008571 0.35087667 0.70300000 0.00
79 400 600 3 9 0.6667 0.017143 0.43971000 0.88200000 0.00
80 400 600 3 9 0.6667 0.025714 0.48824167 0.97500000 0.00
81 400 600 3 9 0.6667 0.034286 0.49763833 0.99600000 0.00
82 400 600 3 9 0.6667 0.042857 0.49956833 1.00000000 50.00
83 400 600 3 9 0.6667 0.051429 0.49943667 1.00000000 50.00
84 400 600 3 9 0.6667 0.060000 0.50025667 1.00000000 50.00
85 400 600 3 9 0.6667 0.068571 0.49899333 1.00000000 50.00
86 400 600 3 9 0.6667 0.077143 0.49918333 1.00000000 50.00
87 400 600 3 9 0.6667 0.085714 0.50041833 1.00000000 50.00
88 400 600 3 9 0.6667 0.094286 0.49998167 1.00000000 50.00
89 400 600 3 9 0.6667 0.102857 0.50129000 1.00000000 50.00
90 400 600 3 9 0.6667 0.111429 0.49973500 1.00000000 50.00
91 400 600 3 9 0.6667 0.120000 0.50078833 1.00000000 50.00

View File

@ -0,0 +1,138 @@
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import sys
from matplotlib.colors import LogNorm
import matplotlib.ticker as ticker
sns.set_theme(style="whitegrid", context="talk")
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['figure.dpi'] = 300
def load_data(filename):
try:
df = pd.read_csv(filename)
df['Label'] = (
"k=" + df['k'].astype(str) +
" | Wc=" + df['wc'].astype(str) +
" | Wr=" + df['wr'].astype(str)
)
df = df.sort_values(by=['k', 'wc', 'wr'])
return df
except FileNotFoundError:
print(f"Erreur : Le fichier '{filename}' est introuvable.")
sys.exit(1)
def plot_1_waterfall_zoomed(df):
print(" -> Génération du Waterfall...")
plt.figure(figsize=(14, 9))
df_zoom = df[df['ber'] > 0].copy()
if df_zoom.empty:
print(" Pas d'erreurs trouvées, impossible de tracer.")
return
sns.lineplot(
data=df_zoom,
x='p',
y='ber',
hue='Label',
style='Label',
markers=True,
dashes=False,
linewidth=2.5,
palette="turbo",
markersize=9
)
plt.yscale('log')
ax = plt.gca()
ax.yaxis.set_major_locator(ticker.LogLocator(base=10.0, numticks=12))
plt.title("Vue Globale : Performance des configurations", fontweight='bold', pad=20)
plt.ylabel("BER [Log Scale]", labelpad=15)
plt.xlabel("Bruit du Canal (p)", labelpad=15)
plt.grid(True, which="both", ls="-", alpha=0.3)
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0, title="Configuration", fontsize='x-small')
plt.tight_layout()
plt.savefig("Final_1_Waterfall.png")
def plot_2_ranking_bars(df):
print(" -> Génération du Classement...")
means = df.groupby('p')['ber'].mean()
target_p = means[means > 0.0001].first_valid_index()
if target_p is None:
target_p = df['p'].max()
subset = df[df['p'] == target_p].sort_values('ber', ascending=True)
plt.figure(figsize=(12, max(6, len(subset)*0.4)))
barplot = sns.barplot(
data=subset,
y='Label',
x='ber',
palette="viridis",
edgecolor=".2"
)
plt.xscale('log')
plt.title(f"Robustesse p={target_p:.3f} (Gauche = Meilleur)", fontweight='bold', pad=20)
plt.xlabel("BER", labelpad=10)
plt.ylabel("")
for i, container in enumerate(barplot.containers):
barplot.bar_label(container, fmt='%.1e', padding=5, fontsize=11)
plt.grid(True, axis='x', which="both", ls="--", alpha=0.5)
plt.tight_layout()
plt.savefig("Final_2_Classement.png")
def plot_3_heatmap_gradient(df):
print(" -> Génération de la Heatmap...")
pivot = df.pivot(index="Label", columns="p", values="ber")
pivot_log = pivot.replace(0, 1e-9)
plt.figure(figsize=(16, max(6, len(pivot)*0.5)))
ax = sns.heatmap(
pivot_log,
cmap="Spectral_r",
norm=LogNorm(vmin=1e-5, vmax=1),
cbar_kws={'label': 'BER (Log Scale)'},
linewidths=0.5,
linecolor='white'
)
plt.title("Résistance (Bleu=Zone de Confort, Rouge=Zone d'Échec)", fontweight='bold', pad=20)
plt.xlabel("Bruit du Canal (p)", labelpad=10)
plt.ylabel("")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig("Final_3_Heatmap.png")
if __name__ == "__main__":
print("Démarrage de l'analyse graphique finale...")
df = load_data("ldpc_analysis_results.csv")
plot_1_waterfall_zoomed(df)
plot_2_ranking_bars(df)
plot_3_heatmap_gradient(df)
print("\nTerminé ! Trois images générées :")
print(" 1. Final_1_Waterfall.png (Courbes détaillées)")
print(" 2. Final_2_Classement.png (Comparatif barres)")
print(" 3. Final_3_Heatmap.png (Vision globale couleur)")

208
Code/ldpc/src/analysis.rs Normal file
View File

@ -0,0 +1,208 @@
use crate::channel::Channel;
use crate::code::LdpcCode;
use crate::construction::random::generate_random_h_for_k;
use crate::decoder::bit_flip::BitFlipDecoder;
use crate::encoder::dense::DenseEncoder;
use rand::{Rng, RngExt};
use rayon::prelude::*;
use std::fs::File;
use std::io::Write;
#[derive(Debug, Clone, Copy)]
pub enum DecoderAlgorithm {
BitFlipping,
}
#[derive(Clone)]
pub struct AnalysisConfig {
pub k_values: Vec<usize>,
pub wc_values: Vec<usize>,
pub wr_values: Vec<usize>,
pub min_error_prob: f64,
pub max_error_prob: f64,
pub steps: usize,
pub frames_per_step: usize,
pub max_iter: usize,
pub algorithm: DecoderAlgorithm,
}
#[derive(Debug, Clone)]
pub struct SimulationPoint {
pub k_config: usize,
pub n_real: usize,
pub wc: usize,
pub wr: usize,
pub rate: f64,
pub error_rate: f64,
pub ber: f64,
pub fer: f64,
pub avg_iter: f64,
}
pub struct Analyzer;
impl Analyzer {
pub fn run_batch(config: AnalysisConfig) -> Vec<SimulationPoint> {
let mut tasks = Vec::new();
for &k in &config.k_values {
for &wc in &config.wc_values {
for &wr in &config.wr_values {
if wr <= wc {
continue;
}
if (k * wr) % (wr - wc) != 0 {
continue;
}
tasks.push((k, wc, wr));
}
}
}
println!("Configurations valides : {}", tasks.len());
println!("Execution sur {} coeurs...", rayon::current_num_threads());
let results: Vec<SimulationPoint> = tasks
.par_iter()
.flat_map(|&(k_target, wc, wr)| {
let h_matrix = generate_random_h_for_k(k_target, wc, wr);
let ldpc = LdpcCode::new(h_matrix);
let encoder = DenseEncoder::new(&ldpc);
let k_real = encoder.k;
let n_real = encoder.n;
let rate_theoretical = k_real as f64 / n_real as f64;
let step_size = if config.steps > 1 {
(config.max_error_prob - config.min_error_prob) / (config.steps as f64 - 1.0)
} else {
0.0
};
(0..config.steps)
.into_par_iter()
.map(|i| {
let p = config.min_error_prob + (i as f64 * step_size);
let point = Self::simulate_point(
&encoder,
&ldpc,
p,
&config,
k_real,
k_target,
n_real,
wc,
wr,
rate_theoretical,
);
println!(
"Termine : k={} wc={} wr={} p={:.3} -> BER={:.5}",
point.k_config, point.wc, point.wr, point.error_rate, point.ber
);
point
})
.collect::<Vec<SimulationPoint>>()
})
.collect();
println!("Simulation terminee. {} points generes.", results.len());
results
}
fn simulate_point(
encoder: &DenseEncoder,
ldpc: &LdpcCode,
p: f64,
config: &AnalysisConfig,
k_real: usize,
k_orig: usize,
n: usize,
wc: usize,
wr: usize,
rate: f64,
) -> SimulationPoint {
let channel = Channel::new(p);
let mut rng = rand::rng();
let mut total_bit_errors = 0;
let mut total_frame_errors = 0;
let mut total_iterations = 0;
let mut converged_count = 0;
for _ in 0..config.frames_per_step {
let message: Vec<u8> = (0..k_real).map(|_| rng.random_range(0..2)).collect();
let codeword = encoder.encode(&message);
let received = channel.add_noise(&codeword);
let (decoded, iters) = match config.algorithm {
DecoderAlgorithm::BitFlipping => {
let decoder = BitFlipDecoder::new(ldpc);
let res = decoder.decode(&received, config.max_iter);
(res, 0)
}
};
match decoded {
Some(res_code) => {
if res_code != codeword {
total_frame_errors += 1;
total_bit_errors += Channel::count_errors(&codeword, &res_code);
} else {
converged_count += 1;
total_iterations += iters;
}
}
None => {
total_frame_errors += 1;
total_bit_errors += Channel::count_errors(&codeword, &received);
}
}
}
let total_bits = (config.frames_per_step * n) as f64;
let avg_iter = if converged_count > 0 {
total_iterations as f64 / converged_count as f64
} else {
config.max_iter as f64
};
SimulationPoint {
k_config: k_orig,
n_real: n,
wc,
wr,
rate,
error_rate: p,
ber: total_bit_errors as f64 / total_bits,
fer: total_frame_errors as f64 / config.frames_per_step as f64,
avg_iter,
}
}
pub fn save_csv(results: &[SimulationPoint], filename: &str) {
let mut sorted_results = results.to_vec();
sorted_results.sort_by(|a, b| {
a.k_config
.cmp(&b.k_config)
.then(a.wc.cmp(&b.wc))
.then(a.wr.cmp(&b.wr))
.then(a.error_rate.partial_cmp(&b.error_rate).unwrap())
});
let mut file = File::create(filename).expect("Erreur fichier");
writeln!(file, "k,n,wc,wr,rate,p,ber,fer,avg_iter").unwrap();
for r in sorted_results {
writeln!(
file,
"{},{},{},{},{:.4},{:.6},{:.8},{:.8},{:.2}",
r.k_config, r.n_real, r.wc, r.wr, r.rate, r.error_rate, r.ber, r.fer, r.avg_iter
)
.unwrap();
}
println!("Resultats sauvegardes dans '{}'", filename);
}
}

32
Code/ldpc/src/channel.rs Normal file
View File

@ -0,0 +1,32 @@
use std::usize;
use rand::{Rng, RngExt};
pub struct Channel {
pub error_prob: f64,
}
impl Channel {
pub fn new(error_prob: f64) -> Self {
assert!(error_prob >= 0.0 && error_prob <= 1.0, "0 <= p <= 1");
Self { error_prob }
}
pub fn add_noise(&self, input: &[u8]) -> Vec<u8> {
let mut rng = rand::rng();
let mut out = input.to_vec();
for b in out.iter_mut() {
let r_v: f64 = rng.random_range(0.0..1.0);
if r_v < self.error_prob {
*b ^= 1;
}
}
out
}
pub fn count_errors(original: &[u8], other: &[u8]) -> usize {
assert_eq!(original.len(), other.len(), "Slice pas de la même taille");
original.iter().zip(other).filter(|(a, b)| a != b).count()
}
}

23
Code/ldpc/src/code.rs Normal file
View File

@ -0,0 +1,23 @@
use crate::matrix::MatrixGF2;
use crate::tanner::TannerGraph;
pub struct LdpcCode {
pub n: usize, // Nombre de colonnes
pub k: usize, // Longueur du message
pub h_matrix: MatrixGF2,
pub tanner_graph: TannerGraph,
}
impl LdpcCode {
pub fn new(h_matrix: MatrixGF2) -> Self {
let n = h_matrix.cols;
let k = n - h_matrix.rows;
let tanner_graph = TannerGraph::from_matrix(&h_matrix);
Self {
n,
k,
h_matrix,
tanner_graph,
}
}
}

View File

@ -0,0 +1 @@
pub mod random;

View File

@ -0,0 +1,77 @@
use crate::matrix::MatrixGF2;
use rand::RngExt;
// H doit respecter les contraine des poids w_c et w_r
pub fn generate_random_h(rows: usize, cols: usize, wc: usize, wr: usize) -> MatrixGF2 {
assert_eq!(rows * wr, cols * wc, "Erreur");
loop {
let mut data = vec![0; rows * cols];
let mut row_w = vec![0; rows];
let mut rng = rand::rng();
let mut success = true;
for c in 0..cols {
let mut ones_placed = 0;
let mut avail_rows: Vec<usize> = (0..rows)
.filter(|&r| row_w[r] < wr && !creates_cycle_4(rows, cols, &data, r, c))
.collect();
if avail_rows.len() < wc {
// Les problèmes...
success = false;
break;
}
while ones_placed < wc {
let id = rng.random_range(0..avail_rows.len());
let r = avail_rows.remove(id);
data[r * cols + c] = 1;
row_w[r] += 1;
ones_placed += 1;
}
}
if success {
return MatrixGF2::new(rows, cols, data);
}
}
}
pub fn generate_random_h_for_k(k: usize, wc: usize, wr: usize) -> MatrixGF2 {
assert!(wr > wc, "wr < wc ...");
assert!((k * wr) % (wr - wc) == 0, "Colonnes non entieres");
let n = (k * wr) / (wr - wc);
let m = n - k;
let max_attemps = 50;
let mut best_h = generate_random_h(m, n, wc, wr);
let mut max_rank = 0;
// On garde que les matrice de rang max
for _ in 0..max_attemps {
let h_cand = generate_random_h(m, n, wc, wr);
let mut h_test = h_cand.clone();
let (rank, _) = h_test.gauss_jordan_swap_cols();
if rank == m {
return h_cand;
}
if rank > max_rank {
max_rank = rank;
best_h = h_cand;
}
}
best_h
}
fn creates_cycle_4(rows: usize, cols: usize, data: &[u8], row: usize, col: usize) -> bool {
for r2 in 0..rows {
if r2 != row && data[r2 * cols + col] == 1 {
for c2 in 0..col {
if data[row * cols + c2] == 1 && data[r2 * cols + c2] == 1 {
return true;
}
}
}
}
false
}

1
Code/ldpc/src/decoder.rs Normal file
View File

@ -0,0 +1 @@
pub mod bit_flip;

View File

@ -0,0 +1,88 @@
use rand::RngExt;
use crate::code::LdpcCode;
pub struct BitFlipDecoder<'a> {
code: &'a LdpcCode,
}
impl<'a> BitFlipDecoder<'a> {
pub fn new(code: &'a LdpcCode) -> Self {
Self { code }
}
// TODO paraléliser (le calcul de chaque check-node)
pub fn decode(&self, received: &[u8], max_iter: usize) -> Option<Vec<u8>> {
let n = self.code.n;
let m = self.code.h_matrix.rows;
let mut curr_bits = received.to_vec();
for iter in 0..max_iter {
// Syndrome s = v * H^T
let mut s = vec![0; m];
let mut s_w = 0;
for (cnid, cb) in self.code.tanner_graph.check.iter().enumerate() {
let mut sum = 0;
// Calcul des equation de parité
for &bid in cb {
sum ^= curr_bits[bid];
}
s[cnid] = sum;
// Equation non vérifiée
if sum == 1 {
s_w += 1;
}
}
// println!("poid syndome: {s_w}");
// Aucune erreurs
if s_w == 0 {
return Some(curr_bits);
}
// Calcul du nombre d'équations fausses le bit fait partie
let mut cpt = vec![0; n];
let mut max_cpt = 0;
for (cid, &sb) in s.iter().enumerate() {
if sb == 1 {
for &bid in &self.code.tanner_graph.check[cid] {
cpt[bid] += 1;
if cpt[bid] > max_cpt {
max_cpt = cpt[bid];
}
}
}
}
if max_cpt == 0 {
break;
}
// Flip des bit qui causent le plus d'équations fausses
for i in 0..n {
if cpt[i] == max_cpt {
curr_bits[i] ^= 1; // Bit flip
}
}
// Seuil de 3
// if max_cpt >= 3 {
// for i in 0..n {
// if cpt[i] == max_cpt {
// curr_bits[i] ^= 1;
// }
// }
// } else if max_cpt > 0 {
// if let Some(idx) = cpt.iter().position(|&x| x == max_cpt) {
// curr_bits[idx] ^= 1;
// }
// } else {
// break;
// }
}
None
}
}

1
Code/ldpc/src/encoder.rs Normal file
View File

@ -0,0 +1 @@
pub mod dense;

View File

@ -0,0 +1,74 @@
use crate::code::{self, LdpcCode};
use crate::matrix::MatrixGF2;
pub struct DenseEncoder {
pub g_matrix: MatrixGF2,
pub h_reduced: MatrixGF2, // A enlever c'est juste pour l'affichage...
pub k: usize,
pub n: usize,
pub col_swaps: Vec<(usize, usize)>,
pub rank: usize,
}
impl DenseEncoder {
pub fn new(code: &LdpcCode) -> Self {
let mut h_reduced = code.h_matrix.clone();
let (rank, col_swaps) = h_reduced.gauss_jordan_swap_cols();
let n = h_reduced.cols;
let k = n - rank;
let mut g_data = vec![0; k * n];
for r in 0..k {
for c in 0..rank {
g_data[r * n + c] = h_reduced.get(c, rank + r);
}
}
for i in 0..k {
g_data[i * n + (rank + i)] = 1;
}
Self {
g_matrix: MatrixGF2::new(k, n, g_data),
h_reduced,
k,
n,
col_swaps,
rank,
}
}
pub fn encode(&self, message: &[u8]) -> Vec<u8> {
assert_eq!(message.len(), self.k, "Taille du message non valide");
let mut codeword: Vec<u8> = (0..self.n)
.map(|c| {
message.iter().enumerate().fold(0, |acc, (r, &msg_bit)| {
acc ^ (msg_bit & self.g_matrix.get(r, c))
})
})
.collect();
// Reverse les changement de colonnes
// for &(c1, c2) in self.col_swaps.iter().rev() {
// codeword.swap(c1, c2);
// }
self.g_matrix
.apply_inverse_permutation(&mut codeword, &self.col_swaps);
codeword
}
pub fn extract_message(&self, decoded_codeword: &[u8]) -> Vec<u8> {
let mut working_copy = decoded_codeword.to_vec();
self.g_matrix
.apply_permutation(&mut working_copy, &self.col_swaps);
let mut message = Vec::with_capacity(self.k);
for i in 0..self.k {
message.push(working_copy[self.rank + i]);
}
message
}
}

34
Code/ldpc/src/main.rs Normal file
View File

@ -0,0 +1,34 @@
mod analysis;
mod channel;
mod code;
mod construction;
mod decoder;
mod encoder;
mod matrix;
mod simulation;
mod tanner;
mod utils;
use analysis::{AnalysisConfig, Analyzer, DecoderAlgorithm};
fn main() {
// println!("Analyse des performences");
// let config = AnalysisConfig {
// k_values: vec![50, 200, 400, 800, 1000],
// wc_values: vec![3, 4, 5],
// wr_values: vec![6, 8, 9, 12, 15, 16],
// min_error_prob: 0.00,
// max_error_prob: 0.12,
// steps: 15,
// frames_per_step: 1000,
// max_iter: 50,
// algorithm: DecoderAlgorithm::BitFlipping,
// };
//
// let res = Analyzer::run_batch(config);
// Analyzer::save_csv(&res, "ldpc_analysis_results.csv");
let message = "Je suis un test";
simulation::run_simulation(message, 3, 6, 0.01);
}

145
Code/ldpc/src/matrix.rs Normal file
View File

@ -0,0 +1,145 @@
#[derive(Clone, Debug)]
pub struct MatrixGF2 {
pub rows: usize,
pub cols: usize,
pub data: Vec<u8>,
}
impl MatrixGF2 {
pub fn new(rows: usize, cols: usize, data: Vec<u8>) -> Self {
assert_eq!(data.len(), rows * cols, "Taille incorrecte.");
Self { rows, cols, data }
}
pub fn get(&self, i: usize, j: usize) -> u8 {
self.data[i * self.cols + j]
}
pub fn set(&mut self, i: usize, j: usize, val: u8) {
self.data[i * self.cols + j] = val;
}
pub fn print(&self) {
for i in 0..self.rows {
let start = i * self.cols;
let end = start + self.cols;
println!("{:?}", &self.data[start..end]);
}
}
pub fn swap_rows(&mut self, r1: usize, r2: usize) {
if r1 == r2 {
return;
}
for c in 0..self.cols {
let v1 = self.get(r1, c);
let v2 = self.get(r2, c);
self.set(r1, c, v2);
self.set(r2, c, v1);
}
}
pub fn swap_cols(&mut self, c1: usize, c2: usize) {
if c1 == c2 {
return;
}
for r in 0..self.rows {
let v1 = self.get(r, c1);
let v2 = self.get(r, c2);
self.set(r, c1, v2);
self.set(r, c2, v1);
}
}
pub fn xor_rows(&mut self, src: usize, dest: usize) {
for c in 0..self.cols {
let v_src = self.get(src, c);
let v_dest = self.get(dest, c);
self.set(dest, c, v_src ^ v_dest);
}
}
pub fn gauss_jordan(&mut self) {
let mut l = 0;
for r in 0..self.rows {
if l >= self.cols {
return;
}
let mut i = r;
while self.get(i, l) == 0 {
i += 1;
if i == self.rows {
i = r;
l += 1;
if l == self.cols {
return;
}
}
}
self.swap_rows(i, r);
for i in 0..self.rows {
if i != r && self.get(i, l) == 1 {
self.xor_rows(r, i);
}
}
l += 1;
}
}
pub fn gauss_jordan_swap_cols(&mut self) -> (usize, Vec<(usize, usize)>) {
let mut rank = 0;
let mut col_swaps = Vec::new();
let rows = self.rows;
let cols = self.cols;
for c in 0..cols {
if rank >= rows {
break;
}
let mut pivot_r = rank;
while pivot_r < rows && self.get(pivot_r, c) == 0 {
pivot_r += 1;
}
if pivot_r == rows {
let mut found_swap = false;
for c2 in (c + 1)..cols {
let mut pr2 = rank;
while pr2 < rows && self.get(pr2, c2) == 0 {
pr2 += 1;
}
if pr2 < rows {
self.swap_cols(c, c2);
col_swaps.push((c, c2));
pivot_r = pr2;
found_swap = true;
break;
}
}
if !found_swap {
break;
}
}
self.swap_rows(rank, pivot_r);
for i in 0..rows {
if i != rank && self.get(i, c) == 1 {
self.xor_rows(rank, i);
}
}
rank += 1;
}
(rank, col_swaps)
}
pub fn apply_inverse_permutation(&self, data: &mut [u8], swaps: &[(usize, usize)]) {
for &(c1, c2) in swaps.iter().rev() {
data.swap(c1, c2);
}
}
pub fn apply_permutation(&self, data: &mut [u8], swaps: &[(usize, usize)]) {
for &(c1, c2) in swaps.iter() {
data.swap(c1, c2);
}
}
}

View File

@ -0,0 +1,95 @@
use core::panic::PanicMessage;
use std::sync::mpsc::Receiver;
use crate::channel::Channel;
use crate::code::{self, LdpcCode};
use crate::construction::random::{generate_random_h, generate_random_h_for_k};
use crate::decoder::bit_flip::BitFlipDecoder;
use crate::encoder::dense::DenseEncoder;
use crate::utils;
use rand::{Rng, RngExt};
pub fn run_simulation(text: &str, wc: usize, wr: usize, error_prob: f64) {
let mut message_bits = utils::string_to_bits(text);
let k = message_bits.len();
println!(
"\nSimulation LDPC : k = {} bits, wc = {}, wr = {}, p = {:.2}, text : {}",
k, wc, wr, error_prob, text
);
println!("Construction");
let h_matrix = generate_random_h_for_k(k, wc, wr);
let ldpc = LdpcCode::new(h_matrix);
let encoder = DenseEncoder::new(&ldpc);
let k = encoder.k;
// if encoder.k != k {
// println!("Erreur: la matrice donne k = {} != {}", encoder.k, k);
// }
println!(
" -> Code généré : n = {}, k = {}, k/n = {:.2}",
encoder.n,
encoder.k,
(encoder.k as f64 / encoder.n as f64)
);
println!("Encodage");
let mut rng = rand::rng();
// let message: Vec<u8> = (0..k).map(|_| rng.random_range(0..2)).collect();
let mut message = message_bits.clone();
message.resize(encoder.k, 0);
let codeword = encoder.encode(&message);
// println!(" -> Message u ({:02} bits) : {:?}", k, message);
// println!(" -> Codeword s ({:02} bits) : {:?}", encoder.n, codeword);
println!("\nCanal bruité (p = {})", error_prob);
let channel = Channel::new(error_prob);
let received = channel.add_noise(&codeword);
let nb_errors = Channel::count_errors(&codeword, &received);
if nb_errors == 0 {
println!(" -> Aucune erreur.")
} else {
println!(" -> {} erreurs !", nb_errors);
// println!(" -> Recu r ({:02} bits) : {:?}", received.len(), received);
}
println!("\n Décodage (bit-flipping)");
if nb_errors == 0 {
println!(" -> Pas besoin de correction");
return;
}
let decoder = BitFlipDecoder::new(&ldpc);
let max_iter = 100;
match decoder.decode(&received, max_iter) {
Some(decoded) => {
let decoded_message_bits = encoder.extract_message(&decoded);
let res_text = utils::bits_to_string(&decoded_message_bits);
if decoded == codeword {
println!(" -> Réussite");
} else {
println!(" -> Echec : le decoder a convergé vers un mauvais codeword");
}
println!(" -> Texte recu : {}", res_text);
}
None => {
let rec_bits = encoder.extract_message(&received);
let failed_text = utils::bits_to_string(&rec_bits);
println!(
" -> Echec : impossible decorriger après {} itérations",
max_iter
);
println!(" -> Texte recu : {}", failed_text);
}
}
}

25
Code/ldpc/src/tanner.rs Normal file
View File

@ -0,0 +1,25 @@
use crate::matrix::MatrixGF2;
#[derive(Debug, Clone)]
pub struct TannerGraph {
pub check: Vec<Vec<usize>>,
pub bits: Vec<Vec<usize>>,
}
impl TannerGraph {
pub fn from_matrix(matrix: &MatrixGF2) -> Self {
let mut check = vec![vec![]; matrix.rows];
let mut bits = vec![vec![]; matrix.cols];
for (i, row_check) in check.iter_mut().enumerate() {
for (j, col_bits) in bits.iter_mut().enumerate() {
if matrix.get(i, j) == 0 {
row_check.push(j);
col_bits.push(i);
}
}
}
Self { check, bits }
}
}

26
Code/ldpc/src/utils.rs Normal file
View File

@ -0,0 +1,26 @@
pub fn string_to_bits(s: &str) -> Vec<u8> {
let mut bits = Vec::new();
for byte in s.as_bytes() {
for i in (0..8).rev() {
bits.push((byte >> i) & 1);
}
}
bits
}
pub fn bits_to_string(bits: &[u8]) -> String {
let mut bytes = Vec::new();
for chunk in bits.chunks(8) {
if chunk.len() < 8 {
break;
}
let mut byte = 0u8;
for (i, &bit) in chunk.iter().enumerate() {
if bit == 1 {
byte |= 1 << (7 - i);
}
}
bytes.push(byte);
}
String::from_utf8_lossy(&bytes).into_owned()
}

View File

@ -1,2 +0,0 @@
- Implémenter correction d'erreur classique par répétition avec taux d'erreur varible.
- Implémenter le code de Hamming

File diff suppressed because it is too large Load Diff

View File

@ -480,7 +480,7 @@ Pas de retransmissions.
== Encodage
Matrice _parity-check_
$ H = [A, I_(n-k)] $ avec $A in M_((n-k) times k)(ZZ\/2ZZ)$ on trouve alors $G$ par réducation de Gausse-Jordan sur $H$.
$ H = [A, I_(n-k)] $ avec $A in M_((n-k) times k)(ZZ\/2ZZ)$ on trouve alors $G$ par réducation de Gauss-Jordan sur $H$.
$
G = [I_k, A^T]
@ -492,7 +492,26 @@ Pas de retransmissions.
== Décodage
Voir les exemple du papier @johnson p21.
=== Algorithme _Bit-flipping_
#pad(left: 1cm)[
Algorithme itératif à "décision ferme" (_Hard-Decision_). $!=$ méthodes probabilistes, messages échangés binaires.
+ *Check-nodes (Vérification) :* Chaque noeud de contrôle vérifie la parité des bits connectés. Si la somme vaut 1, l'équation est non satisfaite.
+ *Bit-nodes (Décision) :* Chaque bit compte le nombre de ses _check-nodes_ insatisfaits. Si la *majorité* signale une erreur, le bit inverse sa valeur (_flip_).
+ *Terminaison :* Arrêt immédiat si toutes les équations de parité sont satisfaites (syndrome nul) ou si le nombre maximum d'itérations est atteint.
_Intuition :_ La matrice $H$ étant creuse, un bit qui viole plusieurs règles indépendantes est statistiquement le plus susceptible d'être erroné.
Voir les exemples du papier @johnson p21.\
La présence de *cycles* réduite l'efficaité du processus. @johnson Fig. 2.3.
]
=== Sum-product
_Log-likelihood ratios_
$
L(x) = log ( P(x = 0) / P(x = 1))
$
]
#pagebreak()
@ -503,8 +522,12 @@ Pas de retransmissions.
#pad(left: 1cm)[
- Voir la strucutre du projet en amont
- Implémentation des codes ldpc (avec un peu toutes les méthodes possible pour faire des test etc)
- Implémentation avec $H$ aléatoire (donc G assez dense et $O(n^2)$)
- Implémenter le "repeat-accumulate" (RA)
- Encodage Implémentation avec $H$ aléatoire faire Gauss-Jordan pour trouver $G$ et $s = u G$
- Decodage par bit-flipping
- ---
- Decodage sum product
- Hashmap pour ne pas avoir à recalculer $G$ pour toutes les longueurs de message. (à $H$ fixé)
- Implémenter le "repeat-accumulate" (RA) compliqué
- Et faire un export pour visualiser les matrice et le graphe dans un fichier typst par exemple ou autre
- Implementation en rust https://github.com/daniestevez/ldpc-toolbox (lire le code pour voir)
- Voir SIMD (`std::simd`) pour le calcul de LLR sur plusieur bits en même temps.