-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAN_Labo6_RiebenAxel.js
More file actions
125 lines (101 loc) · 4.3 KB
/
AN_Labo6_RiebenAxel.js
File metadata and controls
125 lines (101 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/****************************************************************************/
/* Authors : Axel Rieben */
/* Date : 10 juin 2017 */
/* Numerical algorithm : CORDIC */
/****************************************************************************/
/*******************************************************/
/* Tools */
/*******************************************************/
function $(id) {
return document.getElementById(id);
}
function $name(name) {
return document.getElementsByName(name);
}
//Convert degrees into radians
function toRadians(value) {
return (value * Math.PI) / 180;
}
/*******************************************************/
/* User/html interactions */
/*******************************************************/
//Function called when the run button is pressed
function run() {
let input = $('alpha').value;
let iteration = $('iteration').value;
//Check if the value is beetween 0 and 90 degrees (the CORDIC algorithm don't work with other values)
if (input > 90 || input < 0 || isNaN(input)) {
$('errorAlpha').value = "The value must be a number beetween 0 and 90";
} else {
$('errorAlpha').value = "";
//Check if the number of iteration is beetween 1 and 1000 (above that the arctan value start becoming to small to make any difference)
if (iteration > 1000 || iteration < 1 || isNaN(iteration)) {
$('errorIteration').value = "The value must be a number beetween 1 and 1000";
} else {
$('errorIteration').value = "";
input = toRadians(input);
iterations = $('iteration').value;
init();
//Use CORDIC and calculate time
let time = performance.now();
let resultArray = cordic(input);
time = performance.now() - time;
//Show results in HTML
$('cordicCos').value = resultArray[0];
$('cordicSin').value = resultArray[1];
$('cordicTan').value = resultArray[1] / resultArray[0];
$('jsCos').value = Math.cos(input);
$('jsSin').value = Math.sin(input);
$('jsTan').value = Math.sin(input) / Math.cos(input);
$('diffCos').value = Math.abs(Math.cos(input) - resultArray[0]);
$('diffSin').value = Math.abs(Math.sin(input) - resultArray[1]);
$('diffTan').value = Math.abs((Math.sin(input) / Math.cos(input)) - (resultArray[1] / resultArray[0]));
$('cordicTime').value = "Computation time for " + iterations + " iteration(s) : " + time + " ms";
}
}
}
/*******************************************************/
/* CORDIC Algorithm */
/*******************************************************/
//Constants
var omegaTable;
var arctanTable;
var iterations;
//Create a table containing every values of 2^-i
//And create a second table with arctan value of 2^-i
//With i from 0 to the number of iterations
function init() {
omegaTable = new Array();
arctanTable = new Array();
for (let i = 0; i < iterations; i++) {
omegaTable.push(Math.pow(2, -i));
arctanTable.push(Math.atan(omegaTable[i]));
}
//console.log(arctanTable);
}
//Approximate cosine and sine of a given angle using the CORDIC method
//Return [cos(alpha), sin(alpha)]
function cordic(alpha) {
//Initialisation of the system
let x = 1;
let y = 0;
let r = 1;
//Loop the algorithm for the number of iterations
for (let i = 0; i < iterations; i++) {
while (alpha > arctanTable[i]) {
//Calculate the next values
let dx = x - y * omegaTable[i];
let dy = y + x * omegaTable[i];
let rx = r * Math.sqrt(1 + Math.pow(omegaTable[i], 2));
//Affect the new values
alpha = alpha - arctanTable[i];
x = dx;
y = dy;
r = rx;
//console.log("Cordic iteration : " + i + ", x = " + x + ", y = " + y + ", r = " + r + ", alpha = " + alpha);
}
}
let cos = x / r; //Adjacent / hypotenus
let sin = y / r; //Opposed / hypotenus
return [cos, sin];
}