Created
August 12, 2021 11:35
-
-
Save kalesan/1a2f99c792825c547f89d92e6dacbd6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is the source for illustrating the state changes in the water-filling algorithm. For more details see