Compare commits
5 Commits
f4201536de
...
826cfe8569
| Author | SHA1 | Date | |
|---|---|---|---|
| 826cfe8569 | |||
| 04b0d79058 | |||
| 36402570ee | |||
| 369a83bcfd | |||
| 6a23a35f40 |
52
Code/ldpc/Cargo.lock
generated
52
Code/ldpc/Cargo.lock
generated
@ -40,6 +40,37 @@ dependencies = [
|
|||||||
"libc",
|
"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]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -116,6 +147,7 @@ name = "ldpc"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -193,6 +225,26 @@ version = "0.10.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
|
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]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
|
|||||||
@ -5,3 +5,4 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.10.0"
|
rand = "0.10.0"
|
||||||
|
rayon = "1.11.0"
|
||||||
|
|||||||
BIN
Code/ldpc/src/analyse/1_Clean_Waterfall.png
Normal file
BIN
Code/ldpc/src/analyse/1_Clean_Waterfall.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
Code/ldpc/src/analyse/2_Clean_Bars.png
Normal file
BIN
Code/ldpc/src/analyse/2_Clean_Bars.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
BIN
Code/ldpc/src/analyse/3_Clean_Heatmap.png
Normal file
BIN
Code/ldpc/src/analyse/3_Clean_Heatmap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
91
Code/ldpc/src/analyse/ldpc_analysis_results.csv
Normal file
91
Code/ldpc/src/analyse/ldpc_analysis_results.csv
Normal 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
|
||||||
|
138
Code/ldpc/src/analyse/trace.py
Normal file
138
Code/ldpc/src/analyse/trace.py
Normal 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)")
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -8,6 +8,24 @@ mod matrix;
|
|||||||
mod simulation;
|
mod simulation;
|
||||||
mod tanner;
|
mod tanner;
|
||||||
|
|
||||||
|
use analysis::{AnalysisConfig, Analyzer, DecoderAlgorithm};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
simulation::run_simulation(8, 2, 4, 0.1);
|
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");
|
||||||
|
// simulation::run_simulation(1000, 3, 6, 0.005);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,8 +40,8 @@ pub fn run_simulation(k: usize, wc: usize, wr: usize, error_prob: f64) {
|
|||||||
|
|
||||||
let codeword = encoder.encode(&message);
|
let codeword = encoder.encode(&message);
|
||||||
|
|
||||||
println!(" -> Message u ({:02} bits) : {:?}", k, message);
|
// println!(" -> Message u ({:02} bits) : {:?}", k, message);
|
||||||
println!(" -> Codeword s ({:02} bits) : {:?}", encoder.n, codeword);
|
// println!(" -> Codeword s ({:02} bits) : {:?}", encoder.n, codeword);
|
||||||
|
|
||||||
println!("\nCanal bruité (p = {})", error_prob);
|
println!("\nCanal bruité (p = {})", error_prob);
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ pub fn run_simulation(k: usize, wc: usize, wr: usize, error_prob: f64) {
|
|||||||
println!(" -> Aucune erreur.")
|
println!(" -> Aucune erreur.")
|
||||||
} else {
|
} else {
|
||||||
println!(" -> {} erreurs !", nb_errors);
|
println!(" -> {} erreurs !", nb_errors);
|
||||||
println!(" -> Recu r ({:02} bits) : {:?}", received.len(), received);
|
// println!(" -> Recu r ({:02} bits) : {:?}", received.len(), received);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("\n Décodage (bit-flipping)");
|
println!("\n Décodage (bit-flipping)");
|
||||||
|
|||||||
Reference in New Issue
Block a user