Populating a 2D array in Javascript with random numbers - javascript

I'm trying to populate a 2D array in javascript with random numbers. Although each column in the array is random, each row is identical which is not what I want (see image below). I want both rows and columns to be random.
http://eeldesigns.com/image.jpg
cols = 5;
rows = 10;
front = new Array(cols).fill(new Array(rows));
// Loop through Initial array to randomly place cells
for(var x = 0; x < cols; x++){
for(var y = 0; y < rows; y++){
front[x][y] = Math.floor(Math.random()*5);
}
}
console.table(front) ;

One way of doing this using map
let op = new Array(10)
.fill(0)
.map(e=>(new Array(5)
.fill(0)
.map(e=> Math.floor(Math.random() * 5))))
console.log(op)

The trouble is that you're not initializing the row. It's easily fixed:
cols = 5;
rows = 10;
front = new Array(cols)// .fill(new Array(rows));
// Loop through Initial array to randomly place cells
for(var x = 0; x < cols; x++){
front[x] = []; // ***** Added this line *****
for(var y = 0; y < rows; y++){
front[x][y] = Math.floor(Math.random()*5);
}
}
console.table(front) ; // browser console only, not StackOverflow's
Update
This is a cleaner version, somewhat similar to the one from Code Maniac, but simplified a bit:
const randomTable = (rows, cols) => Array.from(
{length: rows},
() => Array.from({length: cols}, () => Math.floor(Math.random() * 5))
)
console.table(randomTable(10, 5)) // browser console only, not StackOverflow's

This can be accomplished using a combination of Array.prototype.fill() and Array.prototype.map():
new Array(rows).fill([]).map(x => Array(columns).fill(0).map(x => x + Math.floor(Math.random() * (max - min)) + min));
For example, we can create a 100 by 964 column array full of random numbers between 900 and 1000 using the following:
new Array(100).fill([]).map(x => Array(964).fill(0).map(x => x + Math.floor(Math.random() * (1000 - 900)) + 900));

Related

Min value on main diagonal of the 2D Array

I managed to create a 2d array and populate it automatically with my code. I'd like to find the min value on the main diagonal, but I'm stuck and have no idea how to approach that idea from my code. Can anyone explain me how can I manage to achieve this pretty please? Everything that I've tried or come up with gave no results whatsoever..
var matrix = Array.from(Array(10), () => new Array(10));
for(i=0; i<10; i++){
for(j=0; j<10; j++)
matrix[i][j] = Math.floor(Math.random() * 100);
}
console.log(matrix);
Construct a 1-d array of the diagonal. Use Math.min with .apply to find the min value in that array.
var matrix = Array.from(Array(10), () => new Array(10));
for(i=0; i<10; i++){
for(j=0; j<10; j++)
matrix[i][j] = Math.floor(Math.random() * 100);
}
const diag = matrix.map((m, i) => m[i]);
const min = Math.min.apply(null, diag);
console.log(diag, "min = " + min);
The main diagonal of 2D Square Array (Matrix) is always at col_index == row_index, so you can iterate through the array to find the minimum value through it.
I made the array to 3x3 in my snippet to show the simpler case, but you may get it to 10x10 to try as well.
function getMinimumOfDiag(arr) {
var min = Infinity;
for (var i = 0; i < arr.length; i++)
if(arr[i].length > i)
if(arr[i][i] < min)
min = arr[i][i]
return min;
};
var matrix = Array.from(Array(3), () => new Array(3));
for(i=0; i<3; i++){
for(j=0; j<3; j++)
matrix[i][j] = Math.floor(Math.random() * 100);
}
console.log(matrix);
console.log(getMinimumOfDiag(matrix));
Assuming the matrix has rows and columns of same length, This should work,
var matrix = Array.from(Array(10), () => new Array(10));
const matrixLength = 10;
for(let i=0; i<matrixLength; i++){
for(j=0; j<matrixLength; j++)
matrix[i][j] = Math.floor(Math.random() * 100);
}
let minValueInDiagonal = Number.MAX_SAFE_INTEGER;
for(let i = 0; i < matrixLength; i++) {
minValueInDiagonal = Math.min(matrix[i][i], minValueInDiagonal);
}
console.log("Matrix is", matrix);
console.log("Min value in diagonal is: ", minValueInDiagonal);

Create an array of arrays, in which every array has 10 random numbers

Here I try to understand how to create array of arrays: I created one array but how to create an array of arrays, in which every array has 10 random numbers?
var arrRand = [];
while(arrRand.length < 10){
var random = Math.floor(Math.random() * 10) + 1;
if(arrRand.indexOf(random) === -1) arrRand.push(random);
}
console.log(arrRand);
A functional approach with every number being random.
let x = Array(4).fill().map(
() => Array(10).fill().map(
() => Math.floor(Math.random() * 10)
)
);
console.log(x);
You can use Math.random and a nested for loop. Here is an example:
let arr = [];
for(let i = 0; i < 4; i++){
let current = [];
for(let j = 0; j < 10; j++)
current.push(Math.floor(Math.random() * 10));
arr.push(current);
}
console.log(arr)
In order to keep clean and dry code, you can use map function in ES6 syntax.
const x = [...Array(6)].map(
() => [...Array(10)].map(
() => Math.floor(Math.random() * 10) + 1
)
)
console.log(x)
let a = Array(4).fill(Array(10).fill(null))
Then fill it with Math.random() in loop

Random array between given range of integers, containing at least one instance of each integer in the range

I'm trying to generate an array that contains a random set of integers between a range that will contain at least one instance of each possible integer. I can generate an array with random integers between a range, but cannot figure out how to generate one that contains at least one instance of each integer in said range. I'm trying to generate an array that contains 84 keys with a range between 0 and 40 (including 0 and 40). The array should contain at least one instance of each possible integer in said range. This is the code that I have right now:
<script>
ints = [];
function sortInt(a, b) {
return a - b;
}
for (i=0; i<84; i++) {
ints.push(Math.round(Math.random() * 40));
}
ints.sort(sortInt);
for (s=0; s<ints.length; s++) {
document.write(ints[s] + '<br />');
}
</script>
Please try the below snippet
function generateNumbers(number, startRange, endRange) {
if (startRange > endRange) return generateNumbers(number, endRange, startRange);
const arr = [];
for (let i = startRange; i <= endRange; ++i) arr.push(i);
while(number > arr.length) {
const newNumber = Math.round(Math.random() * (endRange - startRange));
arr.push(newNumber);
}
arr.sort((a, b) => a - b);
return arr;
}
console.log(generateNumbers(84, 0, 40));
I think if it needs all the integers between a range then you can start with generating between the range. Then all the other numbers can be random. Finally just need to use sort() on the array.
Like this:
const generate = (till, count) => {
const array = Array.from(new Array(till + 1).keys());
for (let i = till; i < count; i++) {
array.push(Math.round(Math.random() * till));
}
return array.sort((a,b) => a - b);
}
const result = generate(40, 84);
console.log(result);
I hope that helps!
You can create random index to insert a number from the desired range:
if (i == randomIndex)
ints.push(startRange);
else
ints.push(Math.floor(Math.random() * endRange) + startRange);
An example:
ints = [];
let startRange = 1, endRange = 84;
let randomIndex = Math.floor(Math.random() * endRange) + startRange;
for (i=0; i < 84; i++) {
if (i == randomIndex)
ints.push(startRange);
else
ints.push(Math.floor(Math.random() * endRange) + startRange);
}
ints.sort((a,b) => a - b);
console.log(ints)
I'd use randojs.com for this. Grab a shuffled array from 0 to 40, then add 43 more random numbers between 0 and 40 to the array and sort:
var ints = randoSequence(40);
for(var i = 0; i < 43; i++) ints.push(rando(40));
console.log( ints.sort((a, b) => {return a - b;}) );
<script src="https://randojs.com/1.0.0.js"></script>

Tensorflow, conv2d and filters

I'm beginner in deep learning, and trying to understand how algorithms works, writing them using JavaScript. Now I'm working on JavaScript implementation of conv2d like Tensorflow does, and misunderstand how to handle different count of filters, I have succeeded for one output filter and multiple output, but I'm confused how to produce operations with multiple filters input e.g. 32 -> 64
Here is example of code using ndarray
:
const outCount = 32 // count of inputs filters
const inCount = 1 // count of output features
const filterSize = 3
const stride = 1
const inShape = [1, 10, 10, outCount]
const outShape = [
1,
Math.ceil((inShape[1] - filterSize + 1) / stride),
Math.ceil((inShape[2] - filterSize + 1) / stride),
outCount
];
const filters = ndarray([], [filterSize, filterSize, inCount, outCount])
const conv2d = (input) => {
const result = ndarray(outShape)
// for each output feature
for (let fo = 0; fo < outCount; fo += 1) {
for (let x = 0; x < outShape[1]; x += 1) {
for (let y = 0; y < outShape[2]; y += 1) {
const fragment = ndarray([], [filterSize, filterSize]);
const filter = ndarray([], [filterSize, filterSize]);
// agregate fragment of image and filter
for (let fx = 0; fx < filterSize; fx += 1) {
for (let fy = 0; fy < filterSize; fy += 1) {
const dx = (x * stride) + fx;
const dy = (y * stride) + fy;
fragment.data.push(input.get(0, dx, dy, 0));
filter.data.push(filters.get(fx, fy, 0, fo));
}
}
// calc dot product of filter and image fragment
result.set(0, x, y, fo, dot(filter, fragment));
}
}
}
return result
}
For test I'm using a Tenforflow as a source of true and it algorithm works correct but with 1 -> N. But my question how to add a support of multiple filters in input value like N -> M.
Could someone explain how to modify this algorithm to make it more compatible with Tensorflow tf.nn.conv2d
A lot of thanks.
You would need to add another for loop. You didn't specify all of your input shapes and dimensions so it's actually kind of hard to write it exactly but it would look like this.
// agregate fragment of image and filter
for (let fx = 0; fx < filterSize; fx += 1) {
for (let fy = 0; fy < filterSize; fy += 1) {
//addition
for (let ch = 0; ch < input.get_channels) {
const dx = (x * stride) + fx;
const dy = (y * stride) + fy;
fragment.data.push(input.get(0, dx, dy, ch));
filter.data.push(filters.get(fx, fy, ch, fo));
}
}
}

Better way to assign unique numbers to 2D Array

My goal is to create a 2D Array, and assign a unique number from 0 to n for each in Javascript.
For example, if there is 5 rows and 5 cols, I first make an array of values containing the numbers from 0 to 24. I then want to shuffle those numbers and then if the number is less than 10, place a 'Y' for that spot in the Array or a 'N' if it's greater than or equal to 10. The end result should be 15 N's and 10 Y's randomly located.
I have the following code that does that, but I find it really inefficient and was wondering if there was a better way of doing it.
//Define Empty Array
test = new Array(rows);
for (var k = 0; k < rows; k++)
{
test[k] = Array(cols);
}
var values = [];
var index = 0;
var maxVals = (rows * cols);
//If maxVals is equal to 25, then the values array will hold "1,2,3,4, ... 24,25"
while(values.push(index++)<maxVals);
//Shuffle all those values so they're no longer in order
var shuffledValues = _.shuffle(values);
var i = 0;
var smallerThan = 10;
for (var x = 0; x < rows; x++)
{
for (var y = 0; y < cols; y++)
{
//Make all the numbers smaller than 10 a Y
if (shuffledValues[i] < smallerThan)
{
test[x][y] = "Y";
}
else
{
test[x][y] = "N";
}
i++;
}
}
Since you need to iterate over all n = rows×columns elements in your array to set a value your algorithm already has a minimum time complexity of O(n). The loop that creates the indexes array is another n and the shuffle method (if implemented correctly) should shuffle in n as well, so you algorithm is already O(3n) = O(n). While you may be able to reduce the constant factor of 3 it's not going to make any huge difference as your number of rows and columns grows large.
If you don't need exactly a certain number to be "Y" or "N" and just a ratio of them on average then you could do this instead:
var ratio = 0.5; //use your required ratio here
for (var x = 0; x < rows; x++)
{
for (var y = 0; y < cols; y++)
{
test[x][y] = Math.random() < ratio ? "Y" : "N";
}
}

Categories