Skip to content

Instantly share code, notes, and snippets.

@kalesan
Created August 12, 2021 11:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kalesan/1a2f99c792825c547f89d92e6dacbd6e to your computer and use it in GitHub Desktop.
Save kalesan/1a2f99c792825c547f89d92e6dacbd6e to your computer and use it in GitHub Desktop.
<html>
<head>
<title>Water-filling illustration in Chart.js</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"> </script>
</head>
<body>
<center>
<div>Bisection step</div>
<div style="width:50%">
<input style="width:100%" type="range" min="1" max="35" value="21" id="myRange" onchange="updateStep(this.value)" oninput="updateStep(this.value)">
</div>
<div>Convergence error</div>
<div style="width:50%">
<canvas width=100 id="alphaId"></canvas>
</div>
<div>Sum power level</div>
<div style="width:50%">
<canvas width=100 id="powerId"></canvas>
</div>
<div>Power allocation</div>
<div style="width:50%">
<canvas width=100 id="powerAllocationId"></canvas>
</div>
<div>Channel gains</div>
<div style="width:50%">
<canvas width=100 id="channelId"></canvas>
</div>
</center>
<script>
// Current step to illustrate (initial 21)
var step = 21;
// Convergence error parameters
const alpha_data=[305175.781,152587.891,76293.9453,38146.9727,19073.4863,9536.74316,4768.37158,2384.18579,1192.0929,596.046448,298.023224,149.011612,74.505806,37.252903,18.6264515,9.31322575,4.65661287,2.32830644,1.16415322,.582076609,.291038305,.145519152,.0727595761,.0363797881,.018189894,.00909494702,.00454747351,.00227373675,.00113686838,.000568434189,.000284217094,.000142108547,710542736e-13,355271368e-13,177635684e-13];
// Sum power data
const sum_power_data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,.695780064754675,3.945661168612298,14.713412237435255,6.939782885484734,9.903048865915252,12.040988142146364,10.915756944129992,10.396419468122431,10.146611568270696,10.024064296645317,9.963366901921775,9.993667956116573,10.00885418751978,10.001258090618451,9.997462278506424,9.999359998292336,10.000308997881012,9.999834486443936];
// Fixed power budged line (fixed to value 10)
const P_data = Array(alpha_data.length).fill(10);
// Step data for power allocation bar graphs. Indexed by step - 1.
const step_data=[[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,.38391202,0,0,0,.21447334,0,0,0,.0973947],[0,1.24290548,0,.67290073,0,1.0734668,0,0,0,.95638816],[0,2.9608924,1.46914203,2.39088764,.90168168,2.79145372,1.52497969,0,0,2.67437508],[0,1.81556779,.32381742,1.24556303,0,1.64612911,.37965507,0,0,1.52905047],[0,2.27369763,.78194726,1.70369288,.21448691,2.10425895,.83778492,0,0,1.98718031],[0,2.57911753,1.08736716,2.00911277,.51990681,2.40967885,1.14320482,0,0,2.29260021],[0,2.41837021,.92661985,1.84836546,.35915949,2.24893154,.9824575,0,0,2.13185289],[0,2.34417915,.85242878,1.77417439,.28496843,2.17474047,.90826643,0,0,2.05766183],[0,2.3084923,.81674193,1.73848755,.24928158,2.13905362,.87257959,0,0,2.02197498],[0,2.29098555,.79923518,1.7209808,.23177483,2.12154687,.85507284,0,0,2.00446823],[0,2.28231449,.79056413,1.71230974,.22310377,2.11287582,.84640178,0,0,1.99579717],[0,2.28664322,.79489285,1.71663846,.2274325,2.11720454,.8507305,0,0,2.0001259],[0,2.28881268,.79706231,1.71880792,.22960196,2.119374,.85289997,0,0,2.00229536],[0,2.28772752,.79597715,1.71772277,.2285168,2.11828884,.85181481,0,0,2.0012102],[0,2.28718526,.79543489,1.71718051,.22797454,2.11774658,.85127255,0,0,2.00066794],[0,2.28745636,.795706,1.71745161,.22824564,2.11801769,.85154365,0,0,2.00093904],[0,2.28759194,.79584157,1.71758718,.22838122,2.11815326,.85167922,0,0,2.00107462],[0,2.28752415,.79577378,1.71751939,.22831343,2.11808547,.85161144,0,0,2.00100683]];
// Fixed channel gains, used in the simulation
const gains = [0.11415057, 2.10490228, 0.50843188, 0.95685888, 0.3945875, 1.55154195, 0.52328784, 0.05926548, 0.19887587, 1.31302735];
// Update the range slider min/max attributes to reflect the dataset sizes
var range = document.getElementById("myRange");
range.setAttribute('min', 1);
range.setAttribute('max', alpha_data.length);
// Define the convergence error chart
var ctx = document.getElementById("alphaId");
var alphaChart = new Chart(ctx, {
type: 'line',
data: {
labels: [...Array(step).keys()].map(x => x + 1),
datasets: [{
label: 'Alpha error',
data: alpha_data.slice(0, step),
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgb(75, 192, 192)',
borderWidth: 1
}]
},
options: {
aspectRatio: 4,
scales: {
y: {
beginAtZero: true,
type: 'logarithmic'
}
}
}
});
// Sum power allocatio chart
var ctx = document.getElementById("powerId");
var powerChart = new Chart(ctx, {
type: 'line',
data: {
labels: [...Array(step).keys()].map(x => x + 1),
datasets: [
{
label: 'Sum power level',
data: sum_power_data.slice(0, step),
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgb(54, 162, 235)',
borderWidth: 1
},
{
label: 'Power budget',
data: P_data.slice(0, step),
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgb(255, 99, 132)',
borderWidth: 1
},
]
},
options: {
aspectRatio: 3,
scales: {
y: {
beginAtZero: true,
}
}
}
});
// Channel specific power allocation bar chart
var ctx = document.getElementById("powerAllocationId");
var powerAllocationChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [...Array(10).keys()].map(x => x + 1),
datasets: [{
label: 'Power allocation',
data: step_data[step],
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgb(54, 162, 235)',
borderWidth: 1
}]
},
options: {
aspectRatio: 2,
scales: {
y: {
beginAtZero: true
}
}
}
});
// Channel gains bar chart
var ctx = document.getElementById("channelId");
var channelChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [...Array(10).keys()].map(x => x + 1),
datasets: [{
label: 'Channel gains',
data: gains,
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgb(255, 99, 132)',
borderWidth: 1
}]
},
options: {
aspectRatio: 2,
scales: {
y: {
beginAtZero: true
}
}
}
});
// Chart updates callbackg
function updateStep(val) {
step = parseInt(val); // Parse new integer value from the slider update
// Step labels from [1, step]
steps = [...Array(step).keys()].map(x => x + 1)
// Update the datasets to match the value of index step
alphaChart.data.labels = steps;
alphaChart.data.datasets[0].data = alpha_data.slice(0, step);
alphaChart.update()
powerChart.data.labels = steps;
powerChart.data.datasets[0].data = sum_power_data.slice(0, step);
powerChart.data.datasets[1].data = P_data.slice(0, step);
powerChart.update()
powerAllocationChart.data.datasets[0].data = step_data[step-1];
powerAllocationChart.update();
}
</script>
</body>
</html>
@kalesan
Copy link
Author

kalesan commented Aug 12, 2021

This is the source for illustrating the state changes in the water-filling algorithm. For more details see

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment