// Use JS to write whatever HTML and data you want to the page
// One way of using JS to write HTML and data is with a multi-line string
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
document.write ( `
<div id="menu-controls">
<span id="menu-title"><h2>ANN Logic Gate</h2>
</span>
<div id="controls">
<table id="trainAndTest">
<tr>
<td><span class="info">?<div class="infotext">
<p>The <b>ANN</b> model proposed can <b>simulate</b> the behaviour of the most common binary <b>logic gates</b>.
</p>
<p>The choosen gate is displayed alongside in a light blue box.</p>
<p>Use the <u>change</u> link to select a different one.</p> </div></span></td>
<td>
<span id="changeGateControl">
Logic Gate: <span id="gateText"></span>
</span>
</td>
<td>
<span class="jsLink" onclick="showLogicGateSelector()">change</span>
</td>
</tr>
<tr>
<td><span class="info">?<div class="infotext">
<p>Select the inputs desired using the option fields within the <b>input neurons</b>.</p>
<p>Clicking the <b>Train</b> button the system will evaluate the inputs and generate the exact computed output.</p>
<p>These data will be <b>propagate</b> in the ANN and <b>weigths</b> will be <b>updated</b> accordingly.</p>
</div></span></td>
<td>Train with <span>i<sub>0</sub>, i<sub>1</sub></span> inputs</td>
<td><button id="propagate">Train</button></td>
</tr>
<tr>
<td><span class="info">?<div class="infotext">
<p>Use the input field to <b>type a number</b>.</p>
<p>The system will use the number to produce as many <b>random</b> examples which will be used to <b>train the ANN</b>.</p>
</div></span></td>
<td>
<div id="n-examples">Train <input type="number" value="100" placeholder="number" id="times" /> times</div>
</td>
<td>
<button id="train">Train</button>
</td>
</tr>
<tr>
<td><span class="info">?<div class="infotext">
<p>Select the inputs desired using the <b>input neurons</b>.</p>
<p>By clicking the <b>Test</b> button, the ANN will evaluate the inputs.</p>
<p>The exact result will be highlighted with a <b>light green outer border</b> in the correspondent output neuron. </p>
<p>The ANN's computed result will be displayed lighting up in green the correspondent output neuron.</p>
</div></span></td>
<td>Test with <span>i<sub>0</sub>, i<sub>1</sub></span> inputs</td>
<td><button id="test">Test</button></td>
</tr>
<tr>
<td><span class="info">?<div class="infotext">
<p>The ANN will save the <b>number of example</b> used to train it.</p>
<p><b>Changing</b> the simulated <b>logic gate</b> will <b>reset</b> this number to 0.</p>
<p>The <b>accuracy</b> measure the <b>reliability</b> of the ANN,
it is calculated <b>testing a set of inputs</b> and elaborating the <b>total error</b>.</p>
</div></span></td>
<td>
<span class="infoANN">Examples fed: <span id="examplesPropagate">0</span></span>
</td>
<td>
<span class="infoANN">Accuracy: <span id="accuracy">00.00</span>%</span>
</td>
</tr>
<tr>
<td><span class="info">?<div class="infotext">
<p>This option allows users to <b>track the progress</b> of the ANN by <b>displaying the weigths</b>.</p>
<p>Weigths are shown in form of a <b>table</b> between the <b>neuron layers</b> involved</p>
<p>Weigths table will be <b>updated</b> after every <b>traing process</b>.</p>
</div></span></td>
<td>Show weigths</td>
<td>
<label class="switch">
<input onclick="toggleWeigths()" id="weigthsCheckbox" type="checkbox">
<span class="slider round"></span>
</label>
</td>
</tr>
</table>
</div>
<br>
</div>
<div id="opacityDiv"></div>
<div id="logicGateSelector">
<p>Select a logic operator:</p> <div id="logicalOperatorSelector"></div><br>
<button onclick="changeLogicGate()">Confirm</button><span class="jsLink" onclick="cancelChange()">Cancel</span>
<p>Changing the logic operator requests the ANN to be reload <br> <i>All training progress will be lost</i></p>
</div>
<div id="ANN">
<div class="layer" id="input_layer"></div>
<div class="weigth"><table id="w_ih"></table></div>
<div class="layer" id="hidden_layer"></div>
<div class="weigth"><table id="w_ho"></table></div>
<div class="layer" id="output_layer"></div>
</div>
<style>
body{
font-family: 'Nunito', sans-serif;
text-align: center;
background-color: #fff;
color: #000;
}
body > * {
vertical-align: middle;
}
.layer{
position: relative;
display: block;
margin-top: 0px;
}
.neuron{
position: relative;
height: 55px;
width: 55px;
border-radius: 55px;
background-color: #035b96;
line-height: 55px;
margin: 20px 20px;
color: #fff;
display: inline-block;
}
table{
position: relative;
display: block;
text-align: center;
margin: auto;
}
td, th{
padding: 0px 10px 0px 10px;
}
select, option{
border-radius: 5px;
border: 1px solid #035b96;
margin-top: 14px;
}
input, select, option{
font-family: 'Nunito', sans-serif;
}
.weigth{
margin-top: 20px;
display: inline-block;
}
.neuron span{
letter-spacing: -1px;
}
#menu-controls{
text-align: left;
}
#menu-title{
display: inline-block;
}
#n-examples{
display: inline-block;
}
#logicGateSelector{
top:0px;
text-align: center;
border-radius: 10px;
position: fixed;
width: 280px;
padding: 10px;
left: 50%;
margin-left: -150px;
margin-top: -1000%;
transition: all 0.3s ease;
z-index: 100;
background-color: #ffffff;
-webkit-box-shadow: 0px 0px 46px -27px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 0px 46px -27px rgba(0,0,0,0.75);
box-shadow: 0px 0px 46px -27px rgba(0,0,0,0.75);
}
#logicGateSelector i{
color: red;
}
.jsLink{
text-decoration: underline;
cursor: pointer;
margin: 4px;
color: #7d7d7d;
}
.selectedOperator{
background-color: #035b96!important;
color: #fff!important;
}
.activated{
background-color: rgb(65, 178, 65)!important;
}
.target{
border: 4px solid rgb(154, 241, 154);
}
.separator{
margin-top: 25px;
}
.separator hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
.subSection{
position: relative;
background-color: #fff;
max-width: 200px;
margin: auto;
margin-top: -30px;
}
.info{
color: #ccc;
border: 1.5px solid #ccc;
display: inline-block;
border-radius: 30px;
width: 15px;
height: 15px;
text-align: center;
line-height: 15px;
font-size: 13px;
transition: all 0.4s ease;
cursor: pointer;
}
.info .infotext{
display: none;
position: absolute;
top: 0px;
left: 30px;
background-color: #fff;
padding: 5px 15px;
border: 1.5px solid #656565;
border-radius: 5px;
color: #656565;
max-width: 250px;
text-align: justify;
font-family: 'Nunito', sans-serif;
font-size: 15.3px;
line-height: 20px;
font-style: normal;
z-index: 98;
}
.info:hover .infotext{
display: block;
}
.info:hover{
color: #656565;
border: 1.5px solid #656565;
}
.operatorSelector{
display: inline-block;
padding: 10px;
background-color: #ceeaff;
color: #035b96;
margin: 5px;
border-radius: 7px;
cursor: pointer;
transition: all 0.5s ease;
}
.operatorSelector:hover{
color: #fff;
background-color: #035b96!important;
}
#opacityDiv{
top:0px;
opacity: 0.2;
position: fixed;
width: 100%;
height: 100%;
background-color: #fff;
margin-top: -1000%;
z-index: 99;
}
#changeGateControl, #changeGateControl span, #controls .jsLink{
font-family: 'Nunito', sans-serif!important;
font-style: normal!important;
}
#gateText{
font-size: 16px;
background-color: #ceeaff;
color: #035b96;
padding: 3px 7px;
margin: 5px;
border-radius: 30px;
}
button, input{
background-color: transparent;
color: #035b96;
border: 1.5px solid #035b96;
border-radius: 5px;
padding: 5px;
}
input[type=number] {
border: 1px solid #ccc!important;
color: #000!important;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
button{
cursor: pointer;
margin: 4px;
transition: all 0.5s ease;
font-weight: bold;
width: 70px;
}
button:hover{
color: #fff;
background-color: #035b96;
}
.neuron span{
color: #000;
}
#ANNinfo, #menu-controls{
display: inline-block;
}
table{
color: #aaa;
}
#times{
width: 60px;
}
#controls .jsLink{
font-size: 16px;
}
#menu-title h2{
position: relative;
top:2px;
display: inline-block;
}
th, .neuron span, #trainAndTest span{
font-family: 'Noto Serif', serif;
font-style: italic;
}
#trainAndTest{
color: #000;
text-align: left;
}
.infoANN, .infoANN span{
font-family: 'Nunito', sans-serif!important;
font-style: normal!important;
}
.infoANN span{
font-weight: bold;
}
#trainAndTest td {
padding: 4px 4px;
}
#ANN{
display: inline-block;
}
#doc-container, #doc-header{
max-width: 800px;
text-align: justify;
margin: auto;
padding: 5px 20px;
font-size: 18px;
}
#doc-container{
margin-bottom: 150px;
}
figure{
text-align: center;
padding: 10px 0px;
}
figure img{
max-width: 400px;
margin: auto;
}
figcaption{
color: #7d7d7d;
}
table.illustrate{
border: 1px solid #7d7d7d;
display: inline-block;
color: #000;
margin: 15px;
}
table.illustrate td{
border: 1px solid #7d7d7d;
}
table.illustrate th{
font-family: 'Nunito', sans-serif;
color: #035b96;
font-style: normal;
border: 1px solid #7d7d7d;
}
table.illustrate th i{
color:#03961a;
font-style: normal;
}
.quote{
font-style: italic;
font-weight: bold;
}
.in-bl{
display: inline-block;
}
.center-equation{
line-height: 40px;
text-align: center;
margin-bottom: 25px;
}
.center-equation .MathJax{
margin: 0px 30px;
}
.mathSerif{
font-family: 'Times New Roman', Times, serif;
}
a, a:visited{
color: #035b96;
}
/********** Slider CSS ***********/
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 25px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #035b96;
}
input:focus + .slider {
box-shadow: 0 0 1px #035b96;
}
input:checked + .slider:before {
-webkit-transform: translateX(23px);
-ms-transform: translateX(23px);
transform: translateX(23px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
/* ************ END SLIDER ********** */
</style>
` );
/* VARIABLES */
/**
* This script aims to give a representation of an
* ANN using the SGD algorithm.
* The ANN needs two boolean variables in input and
* outputs the result of a logic function.
*/
/**
* Defining Logical operators as Classes
*/
class AND{
constructor(){this.name = 'AND'}
evaluate = function(a,b){
return Number(a&&b);
}
}
class OR{
constructor(){this.name = 'OR'}
evaluate = function(a,b){
return Number(a||b);
}
}
class NOR{
constructor(){this.name = 'NOR'}
evaluate = function(a,b){
return Number(!(a||b));
}
}
class XOR{
constructor(){this.name = 'XOR'}
evaluate = function(a,b){
return Number((a && !b) || (b && !a));
}
}
class NAND{
constructor(){this.name = 'NAND'}
evaluate = function(a,b){
return Number(!(a&&b));
}
}
/**
* Select the operator in position binaryOperator[0]
*/
var selectedOperator = 0;
//var unaryOperators = [{0: "NOT"}];
var binaryOperators = [new AND(), new OR(), new XOR(), new NOR(), new NAND()];
var d = 2; // input layer size (default)
var e = 4; // hidden layer size (default)
var f = 2; // output layer size (default)
const noActivationRange = 0;
const activationRange = 1;
/** Values of dataset used to learn */
var input_data_set = []
function createInput(){
let i1 = Number(Math.random() < 0.5);
let i2 = Number(Math.random() < 0.5);
return createInputGiven(i1,i2);
}
function createInputGiven(i1, i2){
var operator = binaryOperators[selectedOperator];
var strInput = i1.toString() + i2.toString()
var result = operator.evaluate(Number(i1),Number(i2));
var out = obj(result);
return {input: strInput.toString(), objective: out};
}
var numberOfExamplesPropagate = 0;
/* END VARIABLES */
/* ANN */
/**
* This script contains the core feautures of the ANN.
* In the proposed model the ANN will present a single hidden layer
* Author: Stefano Marzo
* website: www.stefanomarzo.it
*/
/**
* Dimension of layers:
*/
const i_length = d;
const o_length = f;
const h_length = e;
/**
* Learning rate
*/
var learning_rate = 0.5;
/**
* Array of weigths between layers in order:
* (input-hidden), (hidden-output)
*/
var w_ih = [];
var w_ho = [];
/**
* Arrays containing the neurons of the ANN
*/
var input_layer = [];
var hidden_layer = [];
var output_layer = [];
/**
* Array containing the Objective values
*/
var objective = [];
/**
* Initialize all the weights randomly.
* Weights are stored in the w_xy array container.
* Access to a weight can be performed by using
* the w_xy array container with (j,k) indixes
* representing the j-th neuron giver and the
* k-th neuron receiver. E.g. w_ih[1][3] is the
* weight between input_layer[1] and hidden_layer[3]
*/
function initRandomWeights(){
w_ih = [];
w_ho = [];
for(let i = 0; i < i_length; i++){
let wi = [];
for(let j = 0; j < h_length; j++){
wi.push(Math.random());
}
w_ih.push(wi);
}
for(let i = 0; i < h_length; i++){
let wh = [];
for(let j = 0; j < o_length; j++){
wh.push(Math.random());
}
w_ho.push(wh);
}
}
/**
* Function used to create the objective vector.
* Initialize an array with the same length of the
* output_layer array.
* Pushes noActivationRange value in every cell of
* the array and sets the activationRange value only
* to the cell representing the expected output from
* a training dataset.
*/
function obj(v){
var l = [];
for(let i = 0; i < o_length; i++){
l.push(noActivationRange);
}
l[v]=activationRange;
return l;
}
/**
* calculate the net function of the j-th hidden neuron
*/
function neth(j){
let sum = 0;
for(let n = 0; n < i_length; n++) {
sum += input_layer[n]*w_ih[n][j];
}
return sum;
}
/**
* calculate the net function of the k-th output neuron
*/
function neto(k){
let sum = 0;
for(let n = 0; n < h_length; n++) {
sum += hidden_layer[n]*w_ho[n][k];
}
return sum;
}
/**
* calculate the activation function of the j-th
* hidden neuron
*/
function acth(j){
return sigmoid(neth(j));
}
/**
* calculate the activation function of the k-th
* output neuron
*/
function acto(k){
return sigmoid(neto(k));
}
/**
* calculate the error function of the k-th output neuron
*/
function eo(k){
return Math.pow(objective[k] - output_layer[k], 2)/2;
}
/**
* calculate the total error function of the ANN
*/
function etot(){
let sum = 0;
for(let n = 0; n < o_length; n++){
sum += eo(n);
}
return sum;
}
/**
* calculate the delta parameter used to update weights
*/
function delta(y, z){
return (output_layer[z]-objective[z]) * output_layer[z] * (1-output_layer[z]) * hidden_layer[y];
}
/**
* calculate the numeric derivative of the total error
* with respect to w_ho[y][z].
* The value is multiplied by learning_rate and is
* used to update the weight w_ho[y][z].
*/
function newWho(y, z){
return delta(y, z)*learning_rate;
}
/**
* calculate the numeric derivative of the total error
* with respect to w_ih[x][y].
* The value is multiplied by learning_rate and is
* used to update the weight w_ih[x][y].
*/
function newWih(x,y){
let sum = 0;
for(let z = 0; z < o_length; z++) {
sum += delta(y,z) * (1 - hidden_layer[y]) * w_ho[y][z] * input_layer[x];
}
return sum * learning_rate;
}
/**
* The activation function chosen for the ANN.
*/
function sigmoid(x){
return activationRange/(1+Math.pow(Math.E,-x));
}
/**
* The derivative of the activation function
* chosen for the ANN.
*/
function sigmoidDeriv(x){
return sigmoid(x)*(1-sigmoid(x));
}
/**
* Assuming data is an object in form of:
* {input: String, objective: Array<Number>}.
* Sets the ANN's input_layer and objective arrays
* by parsing the data.input and data.objective values
* and using the values of activation stored in
* activationRange and noActivationRange.
* Prepares the ANN to propagate the input and calculate
* the error.
*/
function initInputAndObjective(data){
objective = (data.objective);
let inputConstuctor = [];
for(let ch = 0; ch < data.input.length; ch++) {
let cha = Number(data.input.charAt(ch));
(cha==0) ? inputConstuctor.push(noActivationRange) : inputConstuctor.push(activationRange);
}
input_layer = inputConstuctor;
}
/**
* Propagates the input by activating all the neurons
* of hidden and output layers.
*/
function propagate(){
for(let n = 0; n < h_length; n++) {
hidden_layer[n] = acth(n);
}
for(let n = 0; n < o_length; n++) {
output_layer[n] = acto(n);
}
}
/**
* Calculates the contribution of every weight to
* the error produced by the ANN and updates the
* weights accordingly.
*/
function backpropagate(){
for(let x = 0; x < i_length; x++){
for(let y = 0; y < h_length; y++) {
w_ih[x][y] -= newWih(x,y);
}
}
for(let y = 0; y < h_length; y++){
for(let z = 0; z < o_length; z++) {
w_ho[y][z] -= newWho(y,z);
}
}
}
/**
* Incapsulate the process of initialization,
* propagation and backpropagation with respect
* to a given data.
*/
function train(data){
initInputAndObjective(data);
propagate();
backpropagate();
}
/**
* Accuracy is expressed in terms of %
*
* In this project we can feed the ANN
* with all the possible combination of
* inputs due to the manageble size.
* This may not apply in other cases.
*/
function calculateAccuracy(){
var eAvarage = calculateAvarageLoss();
return 100/Math.pow((eAvarage + 1),10);
}
function calculateAvarageLoss(){
var datas = [
createInputGiven(0,0),
createInputGiven(0,1),
createInputGiven(1,0),
createInputGiven(1,1),
];
var sumErr = 0;
for(let input of datas) {
initInputAndObjective(input);
propagate();
sumErr += etot();
}
return sumErr/datas.length;
}
initRandomWeights();
/* ANN ENDS */
/* GRAPHICS */
function drawInputLayer(){
let s = ""
for(let i = 0; i < i_length; i++) {
s += '<div id="i'+i+'" class="neuron input_neuron"><br><span>i<sub>'+(i)+'</sub></span></div>';
}
document.getElementById("input_layer").innerHTML = s;
}
function drawHiddenLayer(){
let s = ""
for(let i = 0; i < h_length; i++) {
s += '<div id="h'+i+'" class="neuron hidden_neuron"><br><span>h<sub>'+(i)+'</sub></span></div>';
}
document.getElementById("hidden_layer").innerHTML = s;
}
function drawOutputLayer(){
let s = ""
for(let i = 0; i < o_length; i++) {
s += '<div id="o'+i+'" class="neuron output_neuron"><br><span>o<sub>'+(i)+'</sub></span></div>';
}
document.getElementById("output_layer").innerHTML = s;
}
function drawLayers(){
drawInputLayer();
drawHiddenLayer();
drawOutputLayer();
}
function truncateNumbTo2Decimals(num) {
return with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0];
}
function drawIHWeigths(){
let s = "<tr><th>Weigth</th>";
for(i in w_ih[0]){
s+='<th>h<sub>'+(i)+'</sub></th>';
}
s+="</tr>";
for(i in w_ih){
s+='<tr><th>i<sub>'+(i)+'</sub></th>';
for(j in w_ih[i]){
s+='<td>' + truncateNumbTo2Decimals(w_ih[i][j]) + '</td>';
}
s+='</tr>';
}
document.getElementById("w_ih").innerHTML = s;
}
function drawHOWeigths(){
let s = "<tr><th>Weigth</th>";
for(i in w_ho[0]){
s+='<th>o<sub>'+(i)+'</sub></th>';
}
s+="</tr>";
for(i in w_ho){
s+='<tr><th>h<sub>'+(i)+'</sub></th>';
for(j in w_ho[i]){
s+='<td>' + truncateNumbTo2Decimals(w_ho[i][j]) + '</td>';
}
s+='</tr>';
}
document.getElementById("w_ho").innerHTML = s;
}
function drawHiddenActivationValues(){
for(i in hidden_layer){
document.getElementById('h'+i).innerHTML = truncateNumbTo2Decimals(hidden_layer[i])
+ '<span><br>h<sub>'+(i)+'</sub></span>';
}
}
function drawOutputActivationValues(){
for(i in output_layer){
document.getElementById('o'+i).innerHTML = truncateNumbTo2Decimals(output_layer[i])
+ '<span><br>o<sub>'+(i)+'</sub> ⇒ '+i+'</span>';
}
}
function provideInputCommands(){
for(let i = 0; i < i_length; i++) {
document.getElementById("i"+i).innerHTML =
'<select id="inputs'+i+'"><option value="0">0</option><option value="1">1</option></select>'
+
document.getElementById("i"+i).innerHTML;
}
}
function drawWeigths(){
drawIHWeigths();
drawHOWeigths();
}
function drawANN(){
drawLayers();
drawWeigths();
}
function showLogicGateSelector(){
document.getElementById('logicGateSelector').style.marginTop = '20px';
document.getElementById('opacityDiv').style.marginTop = '0%';
}
function hideLogicGateSelector(){
document.getElementById('logicGateSelector').style.marginTop = '-1000%';
document.getElementById('opacityDiv').style.marginTop = '-1000%';
}
function drawLogicGates(){
let s = '';
for(let i in binaryOperators) {
s += '<div id="operator'+i+'" onclick="selectOperator('+i+')" class="operatorSelector">'+binaryOperators[i].name+'</div>';
}
document.getElementById("logicalOperatorSelector").innerHTML = s;
}
function drawCurrentLogicGate(){
var text = binaryOperators[selectedOperator].name;
document.getElementById('gateText').innerText = text;
}
function updateNumOfPropagation(n){
numberOfExamplesPropagate+=Number(n);
document.getElementById('examplesPropagate').innerText = numberOfExamplesPropagate;
}
function updateAccuracy(){
var a = calculateAccuracy();
var s = '';
if(a < 10) s += '0';
document.getElementById('accuracy').innerText = s+truncateNumbTo2Decimals(a);
}
function reDraw(){
drawANN();
drawHiddenActivationValues();
drawOutputActivationValues();
provideInputCommands();
}
function toggleWeigths(){
var c = document.getElementById('weigthsCheckbox').checked;
var w = document.getElementsByClassName('weigth');
if(c) {
for(el of w) el.style.display = 'inline-block';
}
else{
for(el of w) el.style.display = 'none';
}
}
function removeHighlightActivation(){
var actives = document.getElementsByClassName('activated');
if(actives.length > 0) {
for(el of actives) {
el.classList.remove('activated');
}
}
}
function highlightActivation(){
var max = -1;
var index = -1;
for(neuron in output_layer){
if(output_layer[neuron] > max){
max = output_layer[neuron];
index = neuron;
}
}
document.getElementById('o'+index).classList.add('activated');
}
function removeHighlightTarget(){
var targets = document.getElementsByClassName('target');
if(targets.length > 0) {
for(el of targets) {
el.classList.remove('target');
}
}
}
function highlightTarget() {
let nTarget = -1;
for(let i in objective) {
if(objective[i] == activationRange) {
nTarget = i;
}
}
if(nTarget != -1) {
document.getElementById('o'+nTarget).classList.add('target');
}
}
drawANN();
toggleWeigths();
provideInputCommands();
/* GRAPHICS END */
/* CONTROLS */
var operatorId = 'operator';
document.getElementById("propagate").onclick = function(){
let currData = getCurrentData();
updateNumOfPropagation(1);
train(currData);
reDraw();
//removeHighlightActivation();
highlightActivation();
//removeHighlightTarget();
highlightTarget();
updateAccuracy();
}
document.getElementById("train").onclick = function(){
let n = document.getElementById("times").value;
for(let i = 0; i < n; i++) {
var data = createInput();
train(data);
}
updateNumOfPropagation(n);
reDraw();
//removeHighlightActivation();
highlightActivation();
//removeHighlightTarget();
highlightTarget();
updateAccuracy();
}
document.getElementById("test").onclick = function(){
let currData = getCurrentData();
initInputAndObjective(currData);
propagate();
//removeHighlightActivation();
reDraw();
highlightActivation();
highlightTarget();
updateAccuracy();
}
function getCurrentData(){
let i1 = document.getElementById("inputs0").value;
let i2 = document.getElementById("inputs1").value;
return createInputGiven(i1,i2);
}
function selectOperator(i) {
/**
* removes the previous selected class if there's one
*/
var selectedEl = document.getElementsByClassName('selectedOperator');
if(selectedEl.length == 1){
selectedEl[0].classList.remove('selectedOperator')
}
/**
* Select the requested class
*/
document.getElementById(operatorId+i).classList.add('selectedOperator');
}
/**
* triggered on confirm to change operator button
*/
function changeLogicGate(){
var selectedEl = document.getElementsByClassName('selectedOperator');
if(selectedEl.length == 1){
var selOperator = selectedEl[0].id.substring(operatorId.length);
}
let hasChanged = selectedOperator != selOperator;
if(hasChanged){
selectedOperator = Number(selOperator);
drawCurrentLogicGate();
hideLogicGateSelector();
initRandomWeights();
reDraw();
numberOfExamplesPropagate = 0;
document.getElementById('accuracy').innerText = '0';
updateNumOfPropagation(0);
}
}
function cancelChange(){
hideLogicGateSelector();
selectOperator(selectedOperator);
}
drawLogicGates();
selectOperator(selectedOperator);
drawCurrentLogicGate();
/* CONTROLS END */