I am trying to write a matrix library in processing using javascript but keep getting the error above on line 5. I can't seem to spot what is causing the error so any help would be appreciated.
The goal is to implement the matrix product function.
function Matrix(rows,cols){
this.rows = rows;
this.cols = cols;
this.data = [];
for(var i = 0; i < this.rows; i++){
//assign every row an array
this.data[i] = [];
for (var j = 0; j < this.cols; j++){
//assign every column an array
this.data[i][j] = 0;
}
}
}
Matrix.prototype.multiply = function(n){
if(n instanceof Matrix){
// Matrix product
if (this.cols !== n.rows) {
console.log('Columns of A must match rows of B.');
return undefined;
}
let result = new Matrix(this.rows, n.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 < this.cols; k++) {
sum += this.data[i][k] * n.data[k][j];
}
result.data[i][j] = sum;
}
}
return result;
}
else{
for(var i = 0; i < this.rows; i++){
for (var j = 0; j < this.cols; j++){
//multiply scalar
this.data[i][j] *= n;
}
}
}
}
I found the error it was just a curly bracket in the wrong place!
Related
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)
}
}
}
I am learning to use Javascript. I tried to fill an empty matrix, through a For cycle. I think that the sentence I declare has logic, and it should work, I have something intrigued. Anyone know the reason why Javascript does not work with this code?
I am learning to use Javascript. I tried to fill an empty matrix, through a For cycle. I think that the sentence I declare has logic, and it should work, I have something intrigued. Anyone know the reason why Javascript does not work with this code?
var i = 0 , j = 0;
var arr = [[],[]];
for( i = 0; i < 8; i++){
for( j = 0; j < 8; j++){
arr[i][j] = 7;
alert(arr[i][j]);
}
alert(arr[i][j]);
}
This should do what you are looking for.
var ar = new Array(10)
for(i = 0; i < 10; i++) {
ar[i] = new Array(10)
}
for(i = 0; i < 10; i++){
for(j = 0; j< 10; j++) {
ar[i][j] = 1
}
}
console.log(ar)
Check if the element that you want to use exists, if not, create it
var i = 0;
var j = 0;
var arr = [];
for( i = 0; i < 8; i++) {
for( j = 0; j < 8; j++) {
arr[i] = arr[i] || []; // Create array if needed
arr[i][j] = 'value';
}
}
Trying to count possible combinations to get a targetTotal. Using powerSet returns the sum without adding itself. E.g [1,2,3,5] returns [3+1] for a targetSum of 4, whereas I expect to get [1+1+1+1], [2+2], [3+1].
Do you have any ideas how I could make it count itself first as a case?
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSums(numbers, targetSum) {
var sumSets = [];
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
sumSets.push(numberSet);
}
return sumSets;
}
Example invocation:
findSums([1,2,3,4,5],6); [[2,3], [1,4], [5], [1,1,1,1,1,1], [2,2,2], [3,3]]
I come from a Ruby background, which features an enumerable class. In Ruby, I can easily find combinations of array elements.
array.combination(2).count
I know that JavaScript doesn't feature such built in functions, so I was wondering how I could implement this in JS. I was thinking something like
I have an array as follows
var numbers = [9,7,12]
var combos = []
for (var i = 0; i < numbers.length; i++) {
combos.push([numbers[i], numbers[i+1])
}
By the way, the possible combos are
[9,7], [9,12] and [7,12]
so by calling the length function on this array, 3 would be returned.
Any ideas?
How about:
for (var i = 0; i < numbers.length; i++)
for (var j = i + 1; j < numbers.length; j++)
combos.push([numbers[i], numbers[j]]);
Are you strictly talking about 2-combinations of the array or are you interested in a k-combinations solution?
Found this in this gist
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
// Assert {1 < k < set.length}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
Here's a recursive function, which should work for any number:
function combination(arr, num) {
var r= [];
for(var i = 0 ; i < arr.length ; i++) {
if(num===1) r.push([arr[i]]);
else {
combination(arr.slice(i+1), num-1).forEach(function(val) {
r.push([].concat(arr[i], val));
});
}
}
return r;
} //combination
Working Fiddle
I have the following code
for(i = 0; i < num; i++) {
var yPos = 10*i;
var numCells = wid/30;
for(j = 0; j < numCells; j++) {
blocks[i][j] = 1;
}
}
With
blocks = new Array();
However, when I execute the code I receive an error stating that:
can't convert undefined to object
Any ideas? :/
var blocks = [];
for(i = 0; i < num; i++) {
var yPos = 10*i;
var numCells = wid/30;
blocks[i] = []; // here is a fix
for(j = 0; j < numCells; j++) {
blocks[i][j] = 1;
}
}
In your particular case, since all the rows are initialised to be the same (a series of 1s), you can also do
var blocks = new Array(),
blockRow = new Array();
for (var i = 0; i < numCells; i++) {
blockRow.push(1);
}
for (var i = 0; i < num; i++) {
blocks.push(blockRow.slice()); // slice() makes a copy of blockRow
}