Is there a way to calculate pi in Javascript? I know there you can use Math.PI to find pie like this:
var pie = Math.PI;
alert(pie); // output "3.141592653589793"
but this is not accurate. What I want is to be able to calculate it, to have as many digits as you want, not anything like pie = 3.141592.... But still, what I want is not have just have some more digits, but as much as you can (like having one thousand digits, but I need more).
Here is an implementation of a streaming algorithm described by Jeremy Gibbons in Unbounded Spigot Algorithms for the Digits of Pi (2004), Chaper 6:
function * generateDigitsOfPi() {
let q = 1n;
let r = 180n;
let t = 60n;
let i = 2n;
while (true) {
let digit = ((i * 27n - 12n) * q + r * 5n) / (t * 5n);
yield Number(digit);
let u = i * 3n;
u = (u + 1n) * 3n * (u + 2n);
r = u * 10n * (q * (i * 5n - 2n) + r - t * digit);
q *= 10n * i * (i++ * 2n - 1n);
t *= u;
}
}
// Demo
let iter = generateDigitsOfPi();
let output = document.querySelector("div");
(function displayTenNextDigits() {
let digits = "";
for (let i = 0; i < 10; i++) digits += iter.next().value;
output.insertAdjacentHTML("beforeend", digits);
scrollTo(0, document.body.scrollHeight);
requestAnimationFrame(displayTenNextDigits);
})();
div { word-wrap:break-word; font-family: monospace }
<div></div>
I found this code on this website:
mess = "";
Base = Math.pow(10, 11);
cellSize = Math.floor(Math.log(Base) / Math.LN10);
a = Number.MAX_VALUE;
MaxDiv = Math.floor(Math.sqrt(a));
function makeArray(n, aX, Integer) {
var i = 0;
for (i = 1; i < n; i++) aX[i] = null;
aX[0] = Integer
}
function isEmpty(aX) {
var empty = true
for (i = 0; i < aX.length; i++)
if (aX[i]) {
empty = false;
break
}
return empty
}
function Add(n, aX, aY) {
carry = 0
for (i = n - 1; i >= 0; i--) {
aX[i] += Number(aY[i]) + Number(carry);
if (aX[i] < Base) carry = 0;
else {
carry = 1;
aX[i] = Number(aX[i]) - Number(Base)
}
}
}
function Sub(n, aX, aY) {
for (i = n - 1; i >= 0; i--) {
aX[i] -= aY[i];
if (aX[i] < 0) {
if (i > 0) {
aX[i] += Base;
aX[i - 1]--
}
}
}
}
function Mul(n, aX, iMult) {
carry = 0;
for (i = n - 1; i >= 0; i--) {
prod = (aX[i]) * iMult;
prod += carry;
if (prod >= Base) {
carry = Math.floor(prod / Base);
prod -= (carry * Base)
} else carry = 0;
aX[i] = prod
}
}
function Div(n, aX, iDiv, aY) {
carry = 0;
for (i = 0; i < n; i++) {
currVal = Number(aX[i]) + Number(carry * Base);
theDiv = Math.floor(currVal / iDiv);
carry = currVal - theDiv * iDiv;
aY[i] = theDiv
}
}
function arctan(iAng, n, aX) {
iAng_squared = iAng * iAng;
k = 3;
sign = 0;
makeArray(n, aX, 0);
makeArray(n, aAngle, 1);
Div(n, aAngle, iAng, aAngle);
Add(n, aX, aAngle);
while (!isEmpty(aAngle)) {
Div(n, aAngle, iAng_squared, aAngle);
Div(n, aAngle, k, aDivK);
if (sign) Add(n, aX, aDivK);
else Sub(n, aX, aDivK);
k += 2;
sign = 1 - sign
}
mess += "aArctan=" + aArctan + "<br>"
}
function calcPI(numDec) {
var ans = "";
t1 = new Date();
numDec = Number(numDec) + 5;
iAng = new Array(10);
coeff = new Array(10);
arrayLength = Math.ceil(1 + numDec / cellSize);
aPI = new Array(arrayLength);
aArctan = new Array(arrayLength);
aAngle = new Array(arrayLength);
aDivK = new Array(arrayLength);
coeff[0] = 4;
coeff[1] = -1;
coeff[2] = 0;
iAng[0] = 5;
iAng[1] = 239;
iAng[2] = 0;
makeArray(arrayLength, aPI, 0);
makeArray(arrayLength, aAngle, 0);
makeArray(arrayLength, aDivK, 0);
for (var i = 0; coeff[i] != 0; i++) {
arctan(iAng[i], arrayLength, aArctan);
Mul(arrayLength, aArctan, Math.abs(coeff[i]));
if (coeff[i] > 0) Add(arrayLength, aPI, aArctan);
else Sub(arrayLength, aPI, aArctan)
}
Mul(arrayLength, aPI, 4);
sPI = "";
tempPI = "";
for (i = 0; i < aPI.length; i++) {
aPI[i] = String(aPI[i]);
if (aPI[i].length < cellSize && i != 0) {
while (aPI[i].length < cellSize) aPI[i] = "0" + aPI[i]
}
tempPI += aPI[i]
}
for (i = 0; i <= numDec; i++) {
if (i == 0) sPI += tempPI.charAt(i) + ".<br>";
else {
if (document.getElementById("cbCount").checked) addcount = " (" + (i) + ")";
else addcount = "";
if (document.getElementById("cbSpace").checked) thespace = " ";
else thespace = "";
if ((i) % 50 == 0 && i != 0) sPI += tempPI.charAt(i) + addcount + "<br>";
else if (i % 5 == 0) sPI += tempPI.charAt(i) + thespace;
else sPI += tempPI.charAt(i)
}
}
ans += ("PI (" + numDec + ")=" + sPI + "<br>");
ans += ("Win PI=<br>3.1415926535897932384626433832795<br>");
t2 = new Date();
timeTaken = (t2.getTime() - t1.getTime()) / 1000;
ans += "It took: " + timeTaken + " seconds";
var myDiv = document.getElementById("d1");
myDiv.innerHTML = ans
}
<form name="" onsubmit="calcPI(this.t1.value);return false;">
Number of Digits:<br>
<input type="text" name="t1" id="t1" value="100" size="25" maxlength="25">
<br>Add Count:
<input type="checkbox" name="cbCount" id="cbCount" value="" checked="checked">
<br>Add Spaces:
<input type="checkbox" name="cbSpace" id="cbSpace" value="" checked="checked">
<br>
<input type="button" value="Calculate Pi" onclick="calcPI(this.form.t1.value)">
</form>
<div id="d1"></div>
You can approximate the value of π through the use of Monte Carlo simulation. Generate a random X and Y each in the range [-1,1] Then the likelihood (X, Y) is in the unit circle centered at the origin is π/4. More samples yields a better estimate of its value. You can then estimate π by comparing the ratio of samples in the unit circle with the total number of samples and multiply by 4.
this.pi = function(count) {
var inside = 0;
for (var i = 0; i < count; i++) {
var x = random()*2-1;
var y = random()*2-1;
if ((x*x + y*y) < 1) {
inside++
}
}
return 4.0 * inside / count;
}
Here is my implementation using Infinite Series
function calculatePI(iterations = 10000){
let pi = 0;
let iterator = sequence();
for(let i = 0; i < iterations; i++){
pi += 4 / iterator.next().value;
pi -= 4 / iterator.next().value;
}
function* sequence() {
let i = 1;
while(true){
yield i;
i += 2;
}
}
return pi;
}
You can use this for your purpose
Math.PI.toFixed(n)
where n is the number of decimals you wish to display.
It displays the rounded value of pi. It can be considered fairly correct upto 15 decimal places.
Related
This is my code
function convertToCurr(value) {
var x = value.toString().length;
var z = x % 3;
var a = 0;
if (z == 0) {
a = (x / 3) - 1;
}
else {
a = (x / 3);
}
var last = 0;
var vals = [];
var i;
for (i = 1; i <= a; i++) {
steps = 3;
start = x - steps * i;
end = start + steps;
last = end - steps;
vals.unshift(value.toString().slice(start, end));
}
vals.unshift("R " + value.toString().slice(0, last));
return vals.join();
}
basicIO.write(convertToCurr(input));
context.log.INFO("log data");
}
These are my outputs
{"output":"R 1,000,000,.00","log":["log data"]}
{"output":"R 1,000,.00","log":["log data"]}
I need to exctract the last "," so that the amounts make sense
The most straightforward solution is to perform a String.prototype.replace() on the final join().
function convertToCurr(value) {
var x = value.toString().length;
var z = x % 3;
var a = 0;
if (z == 0) {
a = (x / 3) - 1;
}
else {
a = (x / 3);
}
var last = 0;
var vals = [];
var i;
for (i = 1; i <= a; i++) {
steps = 3;
start = x - steps * i;
end = start + steps;
last = end - steps;
vals.unshift(value.toString().slice(start, end));
}
vals.unshift("R " + value.toString().slice(0, last));
return vals.join().replace(',.', '.');
}
console.log(convertToCurr(10000.75));
console.log(convertToCurr(10.01));
console.log(convertToCurr(1000));
console.log(convertToCurr(7002344));
It should be noted that replace() only replaces a single instance of the substring you provide it in the input string, but this doesn't matter here since ,. only appears in your output string one time.
function convertToCurr(value) {
var x = value.toString().length;
var z = x % 3;
var a = 0;
var combinedString; // holds string value after join
if (z == 0) {
a = x / 3 - 1;
} else {
a = x / 3;
}
var last = 0;
var vals = [];
var i;
for (i = 1; i <= a; i++) {
steps = 3;
start = x - steps * i;
end = start + steps;
last = end - steps;
vals.unshift(value.toString().slice(start, end));
}
vals.unshift("R " + value.toString().slice(0, last));
combinedString = vals.join(); // join array into string
return combinedString.replace(",.", "."); // replace ,. with .
}
console.log(convertToCurr(50000000.15));
So This makes it so every level from 1-30 will be 17 exp + 3 more after each level but i wanted to do the same thing but in Times (x) rather than adding 3 every level.
if (level > 30) {
var exp = 17;
level -= 30;
for (var i = 1; i <= level; i++) {
exp += 17 + (i * 3);```
var exp;
function Times(x) {
if (x > 30) {
exp = 17;
x-=30
for (var i = 1; i <= x; i++) {
exp += 17 + (i * 3);
}
}
return exp;
}
console.log(Times(45))
I have two text boxes. Each will take input up to thousand digits.
Now i want to add these two numbers. My question is what data type should i use to store the result?
I have tried this:
<script>
var x = 'Thousand digit of number'
var y = 'Thousand digit of number'
var z = x + y
</script>
but i am getting result in exponential form. How to store the result and display it?
Yet another solution, because it's faster and cleaner.
function add(A, B) {
const AL = A.length
const BL = B.length
const ML = Math.max(AL, BL)
let carry = 0, sum = ''
for (let i = 1; i <= ML; i++) {
let a = +A.charAt(AL - i)
let b = +B.charAt(BL - i)
let t = carry + a + b
carry = t/10 |0
t %= 10
sum = (i === ML && carry)
? carry*10 + t + sum
: t + sum
}
return sum
}
> add(
'9999999999999999999999999999999999999999999999999999999999999999999999999999',
'999999999999999999999999999999999999999'
)
> "10000000000000000000000000000000000000999999999999999999999999999999999999998"
Use BigInt as described here: https://stackoverflow.com/a/56370672/641913
const z = BigInt(x) + BigInt(y);
console.log(z.toString());
Here is another solution not so different from others you can find in the internet (consider that it doesn't work with negative numbers!):
function sums(arg1, arg2) {
var sum = "";
var r = 0;
var a1, a2, i;
// Pick the shortest string as first parameter and the longest as second parameter in my algorithm
if (arg1.length < arg2.length) {
a1 = arg1;
a2 = arg2;
}
else {
a1 = arg2;
a2 = arg1;
}
a1 = a1.split("").reverse();
a2 = a2.split("").reverse();
// Sum a1 and a2 digits
for (i = 0; i < a2.length; i++) {
var t = ((i < a1.length) ? parseInt(a1[i]) : 0) + parseInt(a2[i]) + r;
sum += t % 10;
r = t < 10 ? 0 : Math.floor(t / 10);
}
// Append the last remain
if (r > 0)
sum += r;
sum = sum.split("").reverse();
// Trim the leading "0"
while (sum[0] == "0")
sum.shift();
return sum.length > 0 ? sum.join("") : "0";
}
// Test
function testEquals(expected, actual) {
if (expected == actual)
console.log("OK: " + expected);
else
console.error("ERROR: " + expected + " != " + actual);
}
testEquals("100", sums("99", "1"));
testEquals("100", sums("00099", "0001"));
testEquals("10000000000", sums("9999999999", "1"));
testEquals("10000010101", sums("9999999999", "10102"));
testEquals("0", sums("0", "0"));
testEquals("1", sums("0", "1"));
testEquals("9", sums("8", "1"));
testEquals("9", sums("1", "8"));
testEquals("10000000000000000000000000000000000000000", sums("9999999999999999999999999999999999999999", "1"));
Input the numbers as string and add each characters each other as array something like this:
function add() {
document.getElementById("demo").innerHTML = "";
var x = document.getElementById("txt1").value;
var y = document.getElementById("txt2").value;
var len;
var lenx = x.length;
var leny = y.length;
var x1,y1,rem,div=0;
if(lenx>leny) len = lenx; else len = leny;
for(var i=0;i<len;i++){
if(i>=lenx) x1 = 0;
else x1 = parseInt(x[lenx-i-1]);
if(i>=leny) y1 = 0;
else y1 = parseInt(y[leny-i-1]);
rem = (x1+y1+div)%10;
div = Math.floor((x1 + y1+div)/10);
document.getElementById("demo").innerHTML = rem + document.getElementById("demo").innerHTML;
}
if(div>0){
document.getElementById("demo").innerHTML = div + document.getElementById("demo").innerHTML;
}
}
Here the code: https://jsfiddle.net/mtsL1k2x/5/
Note: this is only for natural numbers. You can modify depending on your inputs
Either use a big number library like https://mathjs.org/docs/datatypes/bignumbers.html , or you can use something lighter weight (but easy to understand) like http://www.discoversdk.com/knowledge-base/arbitrary-length-integer-addition-in-javascript
Well, if you want to do this without using BigInt or any third-party Library, then I don't think you need to convert to an array, you can use the charAt() function to add the individual characters at each point in the string. You would have to use the for loop starting from its maximum value and reducing till its lowest. The code snippet is below;
function add(a, b) {
let sum='';
let z,x;
let r=0;
if (a.length>=b.length){
z=a;
x=b;
}
else{
z=b;
x=a;
};
let p=x.length;
for (let i=z.length;i>0;i--){
let t=((p>0)?parseInt(x.charAt(p-1)):0)+parseInt(z.charAt(i-1))+r;
sum=(t%10)+sum;
r=t<10?0:Math.floor(t/10);
p=p-1;
};
if (r>0){sum=r+sum};
return sum;
};
function add(a, b) {
a = a.split("").reverse();
b = b.split("").reverse();
let maxLen=Math.max(a.length, b.length);
let sum = [];
let remainder = 0;
for (let i = 0; i < maxLen; i++) {
let x = parseInt(a[i]) ? parseInt(a[i]) : 0;
let y = parseInt(b[i]) ? parseInt(b[i]) : 0;
let digit = (x + y + remainder) % 10;
remainder = Math.floor((x + y + remainder) / 10);
sum.unshift(digit);
}
if (remainder) {sum.unshift(remainder)}
return sum.join("");
}
function add(x, y) {
//this function adds two extremely large numbers, negative and/or positive
var temp, borrow=false, bothNeg=false, oneNeg=false, neg=false;
if (x < 0 && y < 0) { bothNeg = true; x = -x; y = -y; }
else if (x < 0 || y < 0) {
oneNeg = true;
if (Math.abs(x) == Math.abs(y)) { x = 0; y = 0; }
else if (x < 0 && Math.abs(x) > Math.abs(y)) { neg = true; x = -x; y = -y; }
else if (x < 0 && Math.abs(x) < Math.abs(y)) { temp = y; y = x; x = temp; }
else if (y < 0 && Math.abs(x) < Math.abs(y)) { neg = true; temp = y; y = -x; x = -temp; }
}
x = parseInt(x*1000000000/10).toString();
y = parseInt(y*1000000000/10).toString();
var lenx=x.length, leny=y.length, len=(lenx>leny)?lenx:leny, sum="", div=0, x1, y1, rem;
for (var i = 0; i < len; i++) {
x1 = (i >= lenx) ? 0 : parseInt(x[lenx-i-1]);
y1 = (i >= leny) ? 0 : parseInt(y[leny-i-1]);
y1 = (isNaN(y1)) ? 0 : y1;
if (oneNeg) y1 = -y1;
if (borrow) x1 = x1 - 1;
if (y < 0 && x1 > 0 && Math.abs(x1) >= Math.abs(y1)) { borrow=false; div=0; }
if (y < 0 && y1 <= 0 && (x1 < 0 || Math.abs(x1) < Math.abs(y1))) { borrow=true; rem=(x1+y1+div+10)%10; div=10; }
else { rem=(x1+y1+div)%10; div=Math.floor((x1+y1+div)/10); }
sum = Math.abs(rem).toString() + sum;
}
if (div > 0) sum = div.toString() + sum;
sum = parseFloat(sum*10/1000000000);
if (bothNeg || neg) sum = -sum;
return sum;
}
<body>
<p>Click the button to calculate x.</p>
<button onclick="myFunction()">Try it</button>
<br/>
<br/>Enter first number:
<input type="text" id="txt1" name="text1">Enter second number:
<input type="text" id="txt2" name="text2">
<p id="demo"></p>
<script>
function myFunction() {
var y = document.getElementById("txt1").value;
var z = document.getElementById("txt2").value;
var x = +y + +z;
document.getElementById("demo").innerHTML = x;
}
</script>
https://jsfiddle.net/Sanjeevgaut/mtsL1k2x/
My results for numbers between 1 and 28321 (limit)
sum of all numbers: 395465626
sum of all abundant numbers: 392188885
sum of all non abundant numbers: 3276741 (correct answer is 4179871)
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++)
{
if (divisors(i))
{abundent[k] = i; k++};
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++){
for (var j = i; j < abundentCount; j++){
if (abundent[i] + abundent[j] <= upperLimit){canBeWrittenAsAbundant[abundent[i]+abundent[j]] = true;}
else {
break;
}
}
}
for (i=1; i <= upperLimit; i++){
if (canBeWrittenAsAbundant[i] == true){continue;}
else {canBeWrittenAsAbundant[i] = false;}
}
var sum = 0;
for (i=1; i <= upperLimit; i++)
{
if (!canBeWrittenAsAbundant[i]){
sum += i;
}
}
console.log(sum);
I'm using http://www.mathblog.dk/project-euler-23-find-positive-integers-not-sum-of-abundant-numbers/ as guidance, but my results are different. I'm a pretty big newb in the programming community so please keep that in mind.
You do not need to calculate the sum of all numbers using a cycle, since there is a formula, like this:
1 + 2 + ... + number = (number * (number + 1)) / 2
Next, let's take a look at divisors:
var divisors = function(number){
sqrtNumber = Math.sqrt(number);
var sum = 1;
for(var i = 2; i<= sqrtNumber; i++)
{
if (number == sqrtNumber * sqrtNumber)
{
sum += sqrtNumber;
sqrtNumber--;
}
if( number % i == 0 )
{
sum += i + (number/i);
}
}
if (sum > number) {return true;}
else {return false;}
};
You initialize sum with 1, since it is a divisor. However, I do not quite understand why do you iterate until the square root instead of the half of the number. For example, if you call the function for 100, then you are iterating until i reaches 10. However, 100 is divisible with 20 for example. Aside of that, your function is not optimal. You should return true as soon as you found out that the number is abundant. Also, the name of divisors is misleading, you should name your function with a more significant name, like isAbundant. Finally, I do not understand why do you decrease square root if number happens to be its exact square and if you do so, why do you have this check in the cycle. Implementation:
var isAbundant = function(number) {
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) {
sum += i;
if (sum > number) {
return true;
}
}
}
return false;
}
Note, that perfect numbers are not considered to be abundant by the function.
You do not need to store all numbers, since you are calculating aggregate data. Instead, do it like this:
//we assume that number has been initialized
console.log("Sum of all numbers: " + ((number * (number + 1)) / 2));
var abundantSum = 0;
var nonAbundantSum = 0;
for (var i = 0; i <= number) {
if (isAbundant(i)) {
abundantSum += i;
} else {
nonAbundantSum += i;
}
}
console.log("Sum of non abundant numbers: " + nonAbundantSum);
console.log("Sum of abundant numbers: " + abundantSum);
Code is not tested. Also, beware overflow problems and structure your code.
Below is the Corrected Code for NodeJS..
var divisors = function (number) {
sqrtNumber = Math.sqrt(number);
var sum = 1;
var half = number / 2;
for (var i = 2; i <= half; i++) {
if (number % i === 0) { sum += i; }
}
if (sum > number) { return true; }
else { return false; }
};
var abundent = [], k = 0;
var upperLimit = 28123;
for (var i = 1; i <= upperLimit; i++) {
if (divisors(i)) { abundent[k] = i; k++ };
}
var abundentCount = abundent.length;
var canBeWrittenAsAbundant = [];
for (var i = 0; i < abundentCount; i++) {
for (var j = i; j < abundentCount; j++) {
if (abundent[i] + abundent[j] <= upperLimit) { canBeWrittenAsAbundant[abundent[i] + abundent[j]] = true; }
else {
break;
}
}
}
for (i = 1; i <= upperLimit; i++) {
if (canBeWrittenAsAbundant[i] == true) { continue; }
else { canBeWrittenAsAbundant[i] = false; }
}
var sum = 0;
for (i = 1; i <= upperLimit; i++) {
if (!canBeWrittenAsAbundant[i]) {
sum += i;
}
}
console.log(sum);
So I am trying to model Gram-Schmidt for any size N×N matrix, and I have officially hit a roadblock I can't get past. I know it's a matter of looping this correctly, but I can't figure out what the problem is. Remember I do not want to just pass in a 3×3 matrix, but any size N×N.
The course notes QR Decomposition with Gram-Schmidt explains exactly what I want to do. Very simple calculation by the way. In the course notes ||u|| means that it is the sum of the square of the elements, so sqrt(x12 + x22 + x32 + .... + xn2).
The multiplication symbol is actually the dot product.
The code I wrote so far is listed below. What is wrong with it?
function qrProjection(arr) {
var qProjected = [];
var tempArray = [];
var aTemp = arr;
var uTemp = new Array(arr.length);
var uSquareSqrt = new Array(arr.length);
var eTemp = [];
var sum = 0;
var sumOfSquares = 0;
var breakCondition = 0;
var secondBreakCondition = 0;
var iterationCounter = 0;
//Build uTemp Array
for (i = 0; i < arr.length; i++) {
uTemp[i] = new Array(arr[i].length);
}
for (i = 0; i < arr.length; i++) {
eTemp[i] = new Array(arr[i].length);
}
uTemp[0] = aTemp[0];
for (j = 0; j <= arr.length; j++) {
for (l = 0; l < arr[j].length; l++) {
if (breakCondition == 1) break;
sumOfSquares = Math.pow(uTemp[j][l], 2) + sumOfSquares;
}
if (breakCondition == 0) {
uSquareSqrt[j] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
}
for (i = 0; i < arr[j].length; i++) {
if (breakCondition == 1) break;
eTemp[j][i] = (1 / (uSquareSqrt[j])) * (uTemp[j][i]);
}
breakCondition = 1;
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
matrixDotProduct = aTemp[j + 1][m] * eTemp[j][m] + matrixDotProduct;
}
}
else {
for (m = 0; m < arr[j].length; m++) {
for (s = 0; s <= iterationCounter; s++) {
matrixDotProduct = aTemp[j + 1][s] * eTemp[m][s] + matrixDotProduct;
}
for (t = 0; t < arr[j].length; t++) {
uTemp[j + 1][t] = aTemp[j + 1][t] - eTemp[j][t] * matrixDotProduct;
}
}
}
if (iterationCounter == 0) {
for (m = 0; m < arr[j].length; m++) {
uTemp[j + 1][m] = aTemp[j + 1][m] - eTemp[j][m] * matrixDotProduct;
}
}
matrixDotProduct = 0;
for (l = 0; l < arr[j].length; l++) {
sumOfSquares = Math.pow(uTemp[j + 1][l], 2) + sumOfSquares;
}
uSquareSqrt[j + 1] = Math.sqrt(sumOfSquares);
sumOfSquares = 0;
for (i = 0; i < arr[j].length; i++) {
eTemp[j + 1][i] = (1 / (uSquareSqrt[j + 1])) * (uTemp[j + 1][i]);
}
iterationCounter++;
}
qProjected = eTemp;
return qProjected;
}
I must apologize that instead of tweaking your code, I wrote my own from scratch:
/* Main function of interest */
// Each entry of a matrix object represents a column
function gramSchmidt(matrixA, n) {
var totalVectors = matrixA.length;
for (var i = 0; i < totalVectors; i++) {
var tempVector = matrixA[i];
for (var j = 0; j < i; j++) {
var dotProd = dot(matrixA[i], matrixA[j], n);
var toSubtract = multiply(dotProd, matrixA[j], n);
tempVector = subtract(tempVector, toSubtract, n);
}
var nrm = norm(tempVector, n);
matrixA[i] = multiply(1 / nrm, tempVector, n);
}
}
/*
* Example usage:
* var myMatrix = [[1,0,0],[2,3,0],[5,4,7]];
* gramSchmidt(myMatrix, 3);
* ==> myMatrix now equals [[1,0,0],[0,1,0],[0,0,1]]
* 3 here equals the number of dimensions per vector
*/
/* Simple vector arithmetic */
function subtract(vectorX, vectorY, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = vectorX[i] - vectorY[i];
return result;
}
function multiply(scalarC, vectorX, n) {
var result = new Array(n);
for (var i = 0; i < n; i++)
result[i] = scalarC * vectorX[i];
return result;
}
function dot(vectorX, vectorY, n) {
var sum = 0;
for (var i = 0; i < n; i++)
sum += vectorX[i] * vectorY[i];
return sum;
}
function norm(vectorX, n) {
return Math.sqrt(dot(vectorX, vectorX, n));
}
Note that the algorithm above computes the Gram-Schmidt orthogonalization, which is the matrix [e1 | e2 | ... | en], not the QR factorization!