Creating Matrix With 'Array.New(N, Array.New)'

Creating matrix with `Array.new(n, Array.new)`

Follow the code:

@gameboard = Array.new(3, Array.new(3, " "))
@gameboard.map { |a| a.object_id }
# => [76584030, 76584030, 76584030]

means new(size=0, obj=nil) method creates an array of size, having the same ob.

But new(size) {|index| block } method works in a different way; it creates an array of size, having different obs.

See the code below:

@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard.map { |a| a.object_id }
# => [75510080, 75509920, 75509540]

The above is the same as your second code example:

@gameboard = [[" ", " ", " "], [" ", " ", " "], [" ", " ", " "]]
@gameboard.map { |a| a.object_id }
# => [80194090, 80193400, 80193080]

If you change or update the the value at index 1 of the first element array of @gameboard, it wouldn't affect all other inner array elements.

@gameboard = Array.new(3) { Array.new(3, " ") }
@gameboard[0][1] = 2
@gameboard
# => [[" ", 2, " "], [" ", " ", " "], [" ", " ", " "]]

How do I declare a 2d array in C++ using new?

If your row length is a compile time constant, C++11 allows

auto arr2d = new int [nrows][CONSTANT];

See this answer. Compilers like gcc that allow variable-length arrays as an extension to C++ can use new as shown here to get fully runtime-variable array dimension functionality like C99 allows, but portable ISO C++ is limited to only the first dimension being variable.

Another efficient option is to do the 2d indexing manually into a big 1d array, as another answer shows, allowing the same compiler optimizations as a real 2D array (e.g. proving or checking that arrays don't alias each other / overlap).


Otherwise, you can use an array of pointers to arrays to allow 2D syntax like contiguous 2D arrays, even though it's not an efficient single large allocation. You can initialize it using a loop, like this:

int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
a[i] = new int[colCount];

The above, for colCount= 5 and rowCount = 4, would produce the following:

Sample Image

Don't forget to delete each row separately with a loop, before deleting the array of pointers. Example in another answer.

Making a matrix with numpy.array

Make it a list on the 4th line of your code. Also, correct your function as mentioned in the code below. Function call and function creation are two different things, so does the arguments you pass into it.

import numpy as np

def matrix_input(N): # Argument to function while creation is wrong, use N instead of 3.
matrix = []
for i in range(N):
a = list(np.array(input().split(),int)) # Make it a list here
matrix.append(a)
print(matrix)

output:

matrix_input(3)
1 1 1
1 1
1 1 1

[[1, 1, 1], [1, 1], [1, 1, 1]]

Alternative method for creating a Proper matrix :

import numpy as np

matrix_1 = np.matrix([[1,1,1],[1,1,0],[1,1,1]])
print(matrix_1)

Output:

[[1 1 1]
[1 1 0]
[1 1 1]]

Creating Matrix(array) where each element itself is a matrix

A sample creating function:

In [510]: def foo(astr,m,n):
...: alist = [astr+'%d%d'%(i,j) for i in range(m) for j in range(n)]
...: return np.array(alist).reshape(m,n)
In [511]: foo('A',2,2)
Out[511]:
array([['A00', 'A01'],
['A10', 'A11']], dtype='<U3')

A list of 4 such arrays:

In [512]: alist = [foo('A',2,2),foo('B',2,2),foo('C',2,2),foo('D',2,2)]

Various ways of stacking:

In [513]: np.stack(alist)
Out[513]:
array([[['A00', 'A01'],
['A10', 'A11']],

[['B00', 'B01'],
['B10', 'B11']],

[['C00', 'C01'],
['C10', 'C11']],

[['D00', 'D01'],
['D10', 'D11']]], dtype='<U3')

In [514]: np.stack(alist,2)
Out[514]:
array([[['A00', 'B00', 'C00', 'D00'],
['A01', 'B01', 'C01', 'D01']],

[['A10', 'B10', 'C10', 'D10'],
['A11', 'B11', 'C11', 'D11']]], dtype='<U3')
In [515]: _.shape
Out[515]: (2, 2, 4)

This can be reshaped in various ways:

In [516]: __.reshape(2,2,2,2)
Out[516]:
array([[[['A00', 'B00'],
['C00', 'D00']],

[['A01', 'B01'],
['C01', 'D01']]],


[[['A10', 'B10'],
['C10', 'D10']],

[['A11', 'B11'],
['C11', 'D11']]]], dtype='<U3')
In [517]: _.reshape(4,2,2)
Out[517]:
array([[['A00', 'B00'],
['C00', 'D00']],

[['A01', 'B01'],
['C01', 'D01']],

[['A10', 'B10'],
['C10', 'D10']],

[['A11', 'B11'],
['C11', 'D11']]], dtype='<U3')

Instead different axis, you can create one and transpose the axes to your heart's content.

How to build a matrix of strings in C

Keep the string object implementation and the matrix separated. The most simplistic string object would be something like:

typedef struct {
size_t length;
char* str;
} str_t;

Then we can create a 2D array of such strings:

str_t strings [rows][cols];

Or in case you need dynamic memory allocation, this is equivalent but allocated on the heap:

str_t (*strings)[cols] = malloc( sizeof(str_t[rows][cols]) );
...
free(strings);

Then populate the 2D array as you would have done with one made of int. Except strings have to be assigned with strcpy rather than the assignment operator =. And in this case we also which to store the length.

Also, the sole benefit of using char* str for the string rather than a fixed length array char str[30] is that we can adjust the size to match the data being stored:

  size_t length = strlen(some_items[i][j]);
strings[i][j].str = malloc(length + 1);
strcpy(strings[i][j].str, some_items[i][j]);

Full example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
typedef struct {
size_t length;
char* str;
} str_t;

size_t rows = 5;
size_t cols = 2;

str_t (*strings)[cols] = malloc( sizeof(str_t[rows][cols]) );

const char* some_items[5][2] =
{
{"here", "are"},
{"some", "random"},
{"strings", "and"},
{"here", "are"},
{"some", "more"},
};

for(size_t i=0; i<rows; i++)
{
for(size_t j=0; j<cols; j++)
{
size_t length = strlen(some_items[i][j]);
strings[i][j].str = malloc(length + 1);
strcpy(strings[i][j].str, some_items[i][j]);
strings[i][j].length = length;

printf("%s ", strings[i][j].str);
}
printf("\n");
}

free(strings);
return 0;
}

fill 2d array with 1d array java

Based on your example, you want to use the values in the array to insert in line in the matrix.

First, let's build our matrix and array values :

int m = 3;
int n = 5;
float[][] mat = new float[m][n];
float[] array = {1,2,3,4};

Then, iterate the matrix to prepare the update :

for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
// update here
}
}

So, what you want is to use the array to set the value, when you reach the end, you start over. There is two solution I see :

Using an index

We increment it but use the modulo to get back to "0" when we reach the length of the array.

int currentIndex = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mat[i][j] = array[currentIndex];
currentIndex = (currentIndex + 1 ) % array.length;
}
}

Using the matrix coordinate

Or you can get the index by doing the sum of both index of the matrix then using the modulo again, this allow to update any value without a loop, (if needed)

for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mat[i][j] = array[(i+j)%array.length];
}
}

One problem with this solution, you will not get the correct output for a matrix where m + n > Integer.MAX_VALUE simply because the sum will give a negative value, give an incorrect index.

Output

You can see the result using :

System.out.println(java.util.Arrays.deepToString(mat));

Both solution give :

[
[1.0, 2.0, 3.0, 4.0, 1.0],
[2.0, 3.0, 4.0, 1.0, 2.0],
[3.0, 4.0, 1.0, 2.0, 3.0]
]

Issue with creating a matrix in R

This was a change in R 4.0.0 -- see the second entry for that version in https://cran.r-project.org/doc/manuals/r-release/NEWS.html:

  • matrix objects now also inherit from class "array", so e.g., class(diag(1)) is c("matrix", "array"). This invalidates code incorrectly assuming that class(matrix_obj)) has length one.

    S3 methods for class "array" are now dispatched for matrix objects.

Previously it was bad form to check that the class was equal to a particular value, now it doesn't work. You (or their authors) will need to fix the downstream tests. The test that works in both old and new versions is

if (inherits(matrix_obj, "matrix")) ...

Dimensions for two-dimensional array creation in Java seem backwards

An expression like new int[2][5] will create an outer array of length 2, with each element referencing an array of length 5, so a total of 3 arrays are created. This is well-documented in the Java Language Specification, Example 15.10.2-2. Multi-Dimensional Array Creation:

The declaration:

float[][] matrix = new float[3][3];

is equivalent in behavior to:

float[][] matrix = new float[3][];
for (int d = 0; d < matrix.length; d++)
matrix[d] = new float[3];

It does not mean (int[2])[5], i.e. an array of 5 referencing arrays of 2.

Because of that, the expression to lookup values is evaluated left-to-right, e.g. x[2][5] means (x[2])[5], i.e. in int[][] x variable, lookup x[2], which is an int[], and in that array lookup value at index 5.

int[][] x = new int[9][9];
// z = x[2][5]
int[] y = x[2];
int z = y[5];


Related Topics



Leave a reply



Submit