The argument for Java 2D arrays being neither row major nor column major is that "two-dimensional array in Java is actually an array of references to arrays". C++ also follows the "array of arrays" abstraction. Then why does C++ require row major order?
Quoting the link in the question
What we may sometimes think of as two-dimensional array in Java is actually an array of references to arrays. It's not stored linearly in memory.
The difference is in C++ arrays are stored linearly in memory.
If you represent an m by n 2D array in linear memory, it has to either be layed out as n groups of m items or m groups of n items. In C and C++ an array like ary[M][N] will be stored as M groups of N items. Whether you want to call those groups rows or columns is arbitrary but the point is the language does specify an order whereas Java does not because a 2D array in Java is not stored "flat".
Related
I need to read from a file some ints.
The first int indicates how many ints I will have in that line.
Example:
5 1 4 7 10 2
4 5 6 7 1
3 1 0 8
3 4 5 6
4 1 2 3 4
Is there a way to create a matrix like this?
I saw that there's a way of doing something similar but it isn't with matrix:
Is it possible to make a matrix with rows that have different #rows on Matlab?
You want a jagged edged matrix.
In mathematical modelling this is normally a most undesirable thing indeed, but in your particular case, a
std::vector<std::vector<int>>
will model this perfectly. Be mindful that the properties of an int vary from platform to platform. The minimum range an int can take is -32767 to + 32767. Consider using a long &c. if necessary.
It is not possible to have 2-d arrays with different row sizes in C++ (If this is what you mean by matrix).
You can use some C++ std library container or some workaround to overcome this limitation. Some options are:
Array of pointers where each pointer points to an array (usually dynamically allocated) of required size.
Array of std::vector or other container. Or std::vector, std::array or other container of std::vector. (For ex: std::vector< std::vector< T > >)
2-d array with max row size.
In all of the above approaches data of rows is not contiguous. To make data contiguous (if required), you may create a class of your own which creates a big 1-d array and emulate it as a 2-d array.
It is possible to create a std::vector<std::vector<int> > i.e. a std::vector with elements of type std::vector<int>.
The individual std::vector<int>s can be of different sizes.
Matrices are by definition rectangular. So, what you are describing is not a matrix. It is a jagged array.
You cannot have an array of arrays where the subarrays are different sized. All elements of an array must have the same type. But you can have an array of pointers, which can point to arrays of any size. A simplest solution is to use std::vector:
std::vector<std::vector<int>> vec_of_vecs;
This is actually the simplest way to represent a 2 dimensional array structure (jagged or not), although the memory representation isn't contiguous like you would expect from a non jagged 2D array.
For performance, it is possible to store the arrays in a single memory block as well, but that is going to be much more complicated. What you can do, is to allocate a single block of memory that contains all of the rows, and another array to store pointers to beginnings of each row.
So I'm trying to create an empty Array that is the length of a table row. I know how to get the length of a row, but I haven't got a clue in how to make an array with a pre-defined length. The program i'm making is dynamic so the length of the array will vary depending on the table I'm accessing.
Does anyone know how?
You've said you want an empty array, so take a look at Array.zeroCreate<'T>.
From the documentation:
Creates an array where the entries are initially the default value
Unchecked.defaultof<'T>.
Example:
let arrayOfTenZeroes : int array = Array.zeroCreate 10
This page has a lot of useful information on F# arrays - have look through it, it should point you in the right direction.
As Panagiotis Kanavos has pointed out in comments, F# differs from a language like C# for array creation, so I will quote directly from the F# language reference article I've linked to above for clarity:
Several functions create arrays without requiring an existing array.
Array.empty creates a new array that does not contain any elements.
Array.create creates an array of a specified size and sets all the
elements to provided values. Array.init creates an array, given a
dimension and a function to generate the elements. Array.zeroCreate
creates an array in which all the elements are initialized to the zero
value for the array's type.
I understand what an array and a matrix is. I want to learn how to create 3D graphics and I want to know if a multi-demionsional array is the same as a matrix.
There are several uses of the term "matrix". Normally however we say that a matrix is a 2-dimensional array of scalar (integer or floating point) values, with known dimensions, an entry for every position (no missing values allowed), and arranged such that the columns represent observations about or operations on the rows of another matrix. So if we have a matrix with four columns, it only makes sense if we have another matrix or vector with four rows to which the four columns apply.
So the obvious way to represent a matrix in C++ is as a 2D array. But 2D arrays aren't identical with matrices. You might have a 2D array that is not a matrix (missing values which are uninitialised or nan), or a matrix that is not a 2D array (we could represent as a 1D array and do the index calculations manually, or as a "sparse matrix" where most values are expected to be zero and we just have a list of non-zero values).
Matrix is an abstract mathematical concept that can be modeled in C++ using a number of ways:
A two-dimensional array,
An array of pointers to arrays with arrays of identical size
A std::vector<std::vector<T>>
An std::array<N,std::array<M,T>>
A library-specific opaque implementation
The actual implementation is always specific to the drawing library that you have in mind.
struct Face
{
// Matrixd is 1D representation of 2D matrix
std::array < Matrixd<5,5>, 2 > M;
};
std::vector <Face> face;
I have a distributed for-loop among nodes. After all nodes finish working on their elements I would like to transfer corresponding elements among nodes. But AFAIK to use MPI_Allgatherv the data should be contiguous. First of all, I switched to 1D representation of 2D matrices (I was using [][] notation before). Now I want to make face.M to be contiguous. I am thinking to copy all elements of say, M[0] to an std::array an transfer that among nodes. Is this way efficient? To give an idea of number of data I work with, if I have 20k cells, at maximum I have 20k*3=60k faces. I might have a million of cells, too.
A true 2D array in C/C++, e.g. int foo[5][5] is already contiguous in memory; it's basically just syntactic sugar for int foo[25] where accesses like foo[3][2] implicitly look up foo[3*5 + 2] in the flat equivalent. Switching to a Matrixd defined in a single dimension won't change the actual memory layout.
std::array is (mostly) just a wrapper for C-style arrays as well; with no virtual members, and compile time defined size with no internal pointers (just the raw array), it's also going to be contiguous. I strongly suspect if you checked the assembly produced, you'd find that the array of Matrixds is already contiguous.
In short, I don't think you need to change anything; you're already contiguous, so MPI should be fine.
I am working on a simple lisp-style pre-processor language.
In the API i want users to be able to pass arrays of any dimension and size to the pre-processor which can be manipulated using the language.
Currently i have an enum of types;
typedef enum LISP_TYPE
{
LT_UINT,
LT_FLOAT,
LT_ARRAY
...,
...
} _LISP_TYPE;
I am having trouble finding an efficient and easy to use method of storing arrays and also accessing them.
There is another structure i use specifically for arrays;
typedef struct _lisp_array
{
LISP_TYPE type;
unsigned int length;
void* data;
} lisp_array;
When the pre-processor See's a list atom with type LT_ARRAY, it will convert its void*(cdr in lisp terms) to the above structure. Where i am having problems is figuring out how to access multi-dimensional arrays. I have thought of calculating a step value to traverse the array but can i guarantee that all arrays passed will be contiguously allocated?
Any help is appreciated.
C built-in (singe and multi-dimensional) arrays are guaranteed to be stored in one contiguous region of memory in row-major mode. This may not answer your question, however. What is the expected layout of the data structure pointed to by _lisp_array::data member?
Since you're writing the interpreter, it's up to you to decide on the representation and make the array contiguous - that is, if you need it to be contiguous. If you make it contiguous, you can access elements by, for example (assuming zero-based indices a, b, c... and dimension size sa, sb, sc...):
(a*sb + b) * sc + c ... (row major order)
(c * sb + b) * sa + a ... (column major order)
There are other ways of representing arrays, of course - you could use arrays-of-pointers-to-arrays, etc. Each has its own advantages and disadvantages; without any specifics on the use case, if the bounds of the array are fixed, and the array is not expected to be sparse, then a contiguous buffer is usually a reasonable approach.
It would depend on how lisp-like you wanted to make it, really. Lisp doesn't have the strict definition of multi-dimensional arrays you're thinking of - everything is either an atom or a list. The closest thing it would have is an array of arrays:
((1 2 3) (4) (5 6))
Note, though, that the sub-arrays aren't the same length. But it's inherently lispy that they don't have to be, and I don't think there's a way to force the issue...
If you need strictly "rectangular" arrays this won't work, obviously, but if you've got wiggle-room, this is how I'd implement it - it's a nice, clean structure (check out the Wikipedia page for more details).
Cheers!