Is there a way to extend JavaScript call stack size? - javascript

I have tried setting Error.stackTraceLimit = Infinity in chrome and firefox, but no effect.
I'm just trying to multiply two matrixes in a recursive way.
it breakes at the point of a [32][32] matrix.
Here is the code that i run, a simple devide and conquer matrix multiplication
first i generate 2 random matrices and then multiply them
function divideConquer(a, b) {
var i = 0,
j = 0,
k = 0;
var c = [];
let row = [];
// creating the output
for (let l = 0; l < a.length; l++) {
row = [];
for (let m = 0; m < b[0].length; m++) {
row.push(parseInt(0));
}
c.push(row);
}
multiplyRecursion(a, b);
return c;
function multiplyRecursion(a, b) {
// If all rows traversed
if (i >= a.length)
return;
// If i < row1
if (j < b[0].length) {
if (k < a[0].length) {
c[i][j] += a[i][k] * b[k][j];
k++;
multiplyRecursion(a, b);
}
k = 0;
j++;
multiplyRecursion(a, b);
}
j = 0;
i++;
multiplyRecursion(a, b);
}
}
function generateRandomMatrix(n) {
let row = [],
matrix = [];
for (let i = 0; i < n; i++) {
row = [];
for (let j = 0; j < n; j++) {
row.push(Math.floor(Math.random() * 10));
}
matrix.push(row);
}
return matrix;
}
let a = generateRandomMatrix(32);
let b = generateRandomMatrix(32);
console.log(divideConquer(a, b));

Related

I got a "TypeError: Cannot read property 'length' of undefined" error on my Javascript project I got following a tutorial. How do I fix the error?

I am following the Nature of Code tutorial by Code Train and when I tested the code I got the TypeError. It pointed to function FromArray, line 19. I am trying to follow his coding challenge on teaching the neural network xor, where he visualizes the xor problem. The code I have so far should produce a flicking black and white screen. Here is a specific error message I got:
at Function.fromArray (matrix.js:19)
at NeuralNetwork.train (nn.js:61)
at draw (sketch.js:44)
at e.d.redraw (p5.min.js:33)
at e.<anonymous> (p5.min.js:32)
at e.<anonymous> (p5.min.js:32)
at new e (p5.min.js:32)
at e (p5.min.js:32).
I tried rewatching some of the videos to see if I missed something and I even checked with his code on GitHub but I still get that error. I tried searching for what to do with TypeError but most answers I found on forums.
Please help. Also, his tutorial series is really good.
//This is my code for the matrix math (Matrix.js):
// let m = new Matrix(3,2);
class Matrix {
constructor(rows, cols) {
this.rows = rows;
this.cols = cols;
this.data = [];
for (let i = 0; i < this.rows; i++) {
this.data[i] = [];
for (let j = 0; j < this.cols; j++) {
this.data[i][j] = 0;
}
}
}
static fromArray(arr) {
let m = new Matrix(arr.length, 1);
for (let i = 0; i < arr.length; i++) {
m.data[i][0] = arr[i];
}
return m;
}
static subtract(a, b) {
// Return a new Matrix a-b
let result = new Matrix(a.rows, a.cols);
for (let i = 0; i < result.rows; i++) {
for (let j = 0; j < result.cols; j++) {
result.data[i][j] = a.data[i][j] - b.data[i][j];
}
}
return result;
}
toArray() {
let arr = [];
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
arr.push(this.data[i][j]);
}
}
return arr;
}
randomize() {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] = Math.random() * 2 - 1;
}
}
}
add(n) {
if (n instanceof Matrix) {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] += n.data[i][j];
}
}
} else {
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] += n;
}
}
}
}
static transpose(matrix) {
let result = new Matrix(matrix.cols, matrix.rows);
for (let i = 0; i < matrix.rows; i++) {
for (let j = 0; j < matrix.cols; j++) {
result.data[j][i] = matrix.data[i][j];
}
}
return result;
}
static multiply(a, b) {
// Matrix product
if (a.cols !== b.rows) {
console.log('Columns of A must match rows of B.')
return undefined;
}
let result = new Matrix(a.rows, b.cols);
for (let i = 0; i < result.rows; i++) {
for (let j = 0; j < result.cols; j++) {
// Dot product of values in col
let sum = 0;
for (let k = 0; k < a.cols; k++) {
sum += a.data[i][k] * b.data[k][j];
}
result.data[i][j] = sum;
}
}
return result;
}
multiply(n) {
if (n instanceof Matrix) {
// hadamard product
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] *= n.data[i][j];
}
}
} else {
// Scalar product
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
this.data[i][j] *= n;
}
}
}
}
map(func) {
// Apply a function to every element of matrix
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
let val = this.data[i][j];
this.data[i][j] = func(val);
}
}
}
static map(matrix, func) {
let result = new Matrix(matrix.rows, matrix.cols);
// Apply a function to every element of matrix
for (let i = 0; i < matrix.rows; i++) {
for (let j = 0; j < matrix.cols; j++) {
let val = matrix.data[i][j];
result.data[i][j] = func(val);
}
}
return result;
}
print() {
console.table(this.data);
}
}
if (typeof module !== 'undefined') {
module.exports = Matrix;
}
//This the code that trains the neural network:
function sigmoid(x) {
return 1 / (1 + Math.exp(-x));
}
function dsigmoid(y) {
// return sigmoid(x) * (1 - sigmoid(x));
return y * (1 - y);
}
class NeuralNetwork {
constructor(input_nodes, hidden_nodes, output_nodes) {
this.input_nodes = input_nodes;
this.hidden_nodes = hidden_nodes;
this.output_nodes = output_nodes;
this.weights_ih = new Matrix(this.hidden_nodes, this.input_nodes);
this.weights_ho = new Matrix(this.output_nodes, this.hidden_nodes);
this.weights_ih.randomize();
this.weights_ho.randomize();
this.bias_h = new Matrix(this.hidden_nodes, 1);
this.bias_o = new Matrix(this.output_nodes, 1);
this.bias_h.randomize();
this.bias_o.randomize();
this.learning_rate = 0.1;
}
feedforward(input_array) {
// Generating the Hidden Outputs
let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(sigmoid);
// Generating the output's output!
let output = Matrix.multiply(this.weights_ho, hidden);
output.add(this.bias_o);
output.map(sigmoid);
// Sending back to the caller!
return output.toArray();
}
train(input_array, target_array) {
// Generating the Hidden Outputs
let inputs = Matrix.fromArray(input_array);
let hidden = Matrix.multiply(this.weights_ih, inputs);
hidden.add(this.bias_h);
// activation function!
hidden.map(sigmoid);
// Generating the output's output!
let outputs = Matrix.multiply(this.weights_ho, hidden);
outputs.add(this.bias_o);
outputs.map(sigmoid);
// Convert array to matrix object
let targets = Matrix.fromArray(target_array);
// Calculate the error
// ERROR = TARGETS - OUTPUTS
let output_errors = Matrix.subtract(targets, outputs);
// let gradient = outputs * (1 - outputs);
// Calculate gradient
let gradients = Matrix.map(outputs, dsigmoid);
gradients.multiply(output_errors);
gradients.multiply(this.learning_rate);
// Calculate deltas
let hidden_T = Matrix.transpose(hidden);
let weight_ho_deltas = Matrix.multiply(gradients, hidden_T);
// Adjust the weights by deltas
this.weights_ho.add(weight_ho_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_o.add(gradients);
// Calculate the hidden layer errors
let who_t = Matrix.transpose(this.weights_ho);
let hidden_errors = Matrix.multiply(who_t, output_errors);
// Calculate hidden gradient
let hidden_gradient = Matrix.map(hidden, dsigmoid);
hidden_gradient.multiply(hidden_errors);
hidden_gradient.multiply(this.learning_rate);
// Calcuate input->hidden deltas
let inputs_T = Matrix.transpose(inputs);
let weight_ih_deltas = Matrix.multiply(hidden_gradient, inputs_T);
this.weights_ih.add(weight_ih_deltas);
// Adjust the bias by its deltas (which is just the gradients)
this.bias_h.add(hidden_gradient);
// outputs.print();
// targets.print();
// error.print();
}
}
//And this does the sketch and outputs the results:
let nn;
//Test Data
let training_data = [
{
inputs: [0,1],
targets: [1]
},
{
inputs: [1,0],
targets: [1]
},
{
inputs: [0,0],
targets: [0]
},
{
inputs: [1,1],
targets: [0]
},
];
function setup() {
//Test Data
// for (let i = 0; i < 50000; i++) {
// let data = random(training_data);
// nn.train(data.inputs, data.targets);
// }
// console.log(nn.feedforward([1,0]));
// console.log(nn.feedforward([0,1]));
// console.log(nn.feedforward([1,1]));
// console.log(nn.feedforward([0,0]));
createCanvas(400, 400);
nn = new NeuralNetwork(2, 2, 1);
}
function draw() {
background(0)
for (let i = 0; i < 1000; i++) {
let data = random(training_data);
nn.train(data.inputs, data.outputs);
}
let resolution = 10;
let cols = width / resolution;
let rows = height / resolution;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
fill(random(255));
rect(i*resolution,j*resolution,resolution, resolution)
}
}
}

JavaScript Refactor From Two to Many Function Arguments

These two JavaScript functions each accept TWO array arguments and return ONE array result. Conforming to ES3, how can I rewrite these to accept an indefinite number of array inputs?
function sum(v, w) {
for (var a = jsArray(v), b = jsArray(w), t = 0; t < a.length; t++) a[t] += b[t];
return vbArray(a);
}
function mul(v, w) {
for (var a = jsArray(v), b = jsArray(w), t = 0; t < a.length; t++) a[t] *= b[t];
return vbArray(a);
}
The odd jsArray() function is required because the arrays to be processed are coming from VBA and jsArray() converts them to JavaScript arrays:
function jsArray(v) {
return new VBArray(v).toArray()
}
You can try to use array-like object arguments in order to get all passed arguments:
function someFunc() {
for (var i=0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
someFunc('a', 'b', 'c');
Example of transformed sum function. Beware that this works if all the passed arrays have the same length.
function sum() {
var arrays = [];
for (var i = 0; i < arguments.length; i++) {
arrays[i] = jsArray(arguments[i]);
}
for (var j = 1; j < arrays.length; j++) {
for (var t = 0; t < arrays[0].length; t++) {
arrays[0][t] += arrays[j][t];
}
}
return vbArray(arrays[0]);
}
Generalized solution:
function process(concreteFunc) {
var arrays = [];
for (var i = 1; i < arguments.length; i++) {
arrays.push(jsArray(arguments[i]));
}
for (var j = 1; j < arrays.length; j++) {
for (var t = 0; t < arrays[0].length; t++) {
arrays[0][t] = concreteFunc(arrays[0][t], arrays[j][t]);
}
}
return vbArray(arrays[0]);
}
var sum = process.bind(null, function (a, b) {return a + b});
var mul = process.bind(null, function (a, b) {return a * b});
Solution without .bind:
function process(concreteFunc, args) {
var arrays = [];
for (var i = 0; i < args.length; i++) {
arrays.push(jsArray(args[i]));
}
for (var j = 1; j < arrays.length; j++) {
for (var t = 0; t < arrays[0].length; t++) {
arrays[0][t] = concreteFunc(arrays[0][t], arrays[j][t]);
}
}
return vbArray(arrays[0]);
}
function createFunc(handler) {
return function() {
return process(handler, Array.prototype.slice.call(arguments));
}
}
var sum = createFunc(function (a, b) {return a + b});
var mul = createFunc(function (a, b) {return a * b});
Improved version to support ability to implement avg:
function process(concreteFunc, args) {
var arrays = [];
for (var i = 0; i < args.length; i++) {
arrays.push(jsArray(args[i]));
}
var result = [];
for (var j = 0; j < arrays[0].length; j++) {
var items = [];
for (var t = 0; t < arrays.length; t++) {
items.push(arrays[t][j]);
}
result.push(concreteFunc(items));
}
return vbArray(result);
}
function createFunc(handler) {
return function() {
return process(handler, Array.prototype.slice.call(arguments));
}
}
function reduce(items, handler) {
var result = items[0];
for (var i = 1; i < items.length; i++) {
result = handler(result, items[i]);
}
return result;
}
var sum = createFunc(function(items) {
return reduce(items, function (a, b) {return a + b});
});
var mul = createFunc(function(items) {
return reduce(items, function (a, b) {return a * b});
});
var avg = createFunc(function(items) {
return reduce(items, function (a, b) {return a + b}) / items.length;
});

What realization is faster and why

I wrote a function that calculate this value/formula:
and I have 2 realizations, and I don't understand, why realization with 3 loops is working faster than realization with if's?
Please, explain to me why is that?
If's realization:
function res(p, square) {
let res = 0
let i = 1;
let j = 1;
let k = 1;
label: for (;;) {
res += (i ** 3 * j ** 2 * k)
if (k < p) {
k++
continue label
}
if (j < p) {
k = 1
j++
continue label
}
if (i < p) {
k = 1
j = 1;
i++
continue label
}
if (k == p && j == p && i == p) {
return res
}
}
}
Loop realization:
function res1(p) {
let res = 0
for (let i = 0; i <= p; i++) {
for (let j = 0; j <= p; j++) {
for (let k = 0; k <= p; k++) {
res += (i ** 3 * j ** 2 * k)
}
}
}
return res
}

Arrays with elements less or equal to the elements in given array

What is the most JS-style way to solve the following problem?
Given an array A, find all arrays B, such that for i <= A.length: B[i] <= A[i]. Example of what I expect:
#Input
A = [1,2,0]
#Output
B = [[0,0,0],
[1,0,0],
[1,1,0],
[1,2,0],
[0,1,0],
[0,2,0]]
In Python I used:
B = [[]];
for t in [range(e+1) for e in A]:
B = [x+[y] for x in B for y in t]
Thanks in advance!
Use the following code (any loop for one item of the array a):
var a = [1, 2, 0], b = [];
for (var i = 0; i < a[0]; i++) {
for (var j = 0; j < a[1]; j++) {
for (var k = 0; k <= a[2]; k++) {
b.push([i, j, k]);
}
}
}
If you know the numebr of items in the array a only on runtime, use the following recursive function:
function fillArray(source, dest, recursionLevel, tempArr) {
if (recursionLevel >= source.length) {
dest.push(tempArr);
return;
}
for (var i = 0; i <= source[recursionLevel]; i++) {
var tempArr2 = tempArr.slice(); // Copy tempArr
tempArr2.push(i);
fillArray(source, dest, recursionLevel + 1, tempArr2);
}
}
fillArray(a, b, 0, []);
I found this solution. I'm sure it can be coded in a much nicer way. However, it works and I hope you find it useful
all_combinations(A){
var B = [];
for (var i = 0; i < A[0] + 1; i++) {
B.push([i]);
}
for (var i = 1; i < A.length; i++) {
var _tmp_array = [];
for (var j = 0; j < A[i] + 1; j++) {
for (var k = 0; k < B.length; k++) {
var _new_element = B[k].concat([j]);
_tmp_array.push(_new_element);
}
}
B = _tmp_array;
}
return B;
}

Combinations of n words from array of m words - Javascript

Given arr = ['mat','cat','fat']
A function getComb(arr, n = 2) where n is the number of words each combination must have.
Expected results:
mat cat
mat fat
cat fat
I could not modify the code below any further to get the desired results. Any idea? thx
Thanks to Knskan3:
'getCombinations': (arr, n) => {
let i, j, k, elem, l = arr.length, childperm, ret = [];
if (n === 1) {
for (let i = 0; i < arr.length; i++) {
ret.push([arr[i]]);
}
return ret;
}
else {
for (i = 0; i < l; i++) {
elem = arr.shift();
for (j = 0; j < elem.length; j++) {
childperm = lib.getCombinations(arr.slice(), n - 1);
for (k = 0; k < childperm.length; k++) {
ret.push([elem[j]].concat(childperm[k]));
}
}
}
return ret;
}
},
I suggest a space-efficient generator function:
// Generate all k-combinations of first n array elements:
function* combinations(array, k, n = array.length) {
if (k < 1) {
yield [];
} else {
for (let i = --k; i < n; i++) {
for (let combination of combinations(array, k, i)) {
combination.push(array[i]);
yield combination;
}
}
}
}
// Example:
console.log(...combinations(['mat', 'cat', 'fat'], 2));

Categories