How can I create an Array of Convex.MaxAtoms (or for that matter, other Convex types) with the Convex package? I'm not sure if an Array is the right structure, but what I want to do is initialize something my_array of length n so that I can update each element in a loop like
using Convex
v = Variable(n)
w = Variable(n)
my_array = ...initialized array?...
for i = 1:n
my_array[i] = max(v[i],w[i])
end
I've tried doing
my_array = Convex.MaxAtom[]
for i = 1:n
push!(x, max(v[i], w[i]))
end
but I want to avoid reallocating memory and do it upfront. I feel that I must be missing an important part of Julia in not understanding what types to use to construct this.
In Julia Vector{AnyType}(n) (replace AnyType with a valid type in the application) allocates a vector of uninitialized AnyType elements of length n. More generally, Array{AnyType,3}(2,3,4) would allocate a 3-dimensional tensor of size 2x3x4 and analogously any dimension or shape can be allocated.
For the case in the question, a solution would be:
a = Vector{Convex.MaxAtom}(n)
P.S. the elements are allocated but uninitialized, this is fast, but it may be safer to use fill(some_value, n) or zero(AnyType, n) (which requires zero(AnyType) to be defined).
Related
It is more than one questions. I need to deal with an NxN matrix A of integers in C. How can I allocate the memory in the heap? Is this correct?
int **A=malloc(N*sizeof(int*));
for(int i=0;i<N;i++) *(A+i)= malloc(N*sizeof(int));
I am not absolutely sure if the second line of the above code should be there to initiate the memory.
Next, suppose I want to access the element A[i, j] where i and j are the row and column indices starting from zero. It it possible to do it via dereferencing the pointer **A somehow? For example, something like (A+ni+j)? I know I have some conceptual gap here and some help will be appreciated.
not absolutely sure if the second line of the above code should be there to initiate the memory.
It needs to be there, as it actually allocates the space for the N rows carrying the N ints each you needs.
The 1st allocation only allocates the row-indexing pointers.
to access the element A[i, j] where i and j are the row and column indices starting from zero. It it possible to do it via dereferencing the pointer **
Sure, just do
A[1][1]
to access the element the 2nd element of the 2nd row.
This is identical to
*(*(A + 1) + 1)
Unrelated to you question:
Although the code you show is correct, a more robust way to code this would be:
int ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; i++)
{
A[i] = malloc(N * sizeof *A[i]);
}
size_t is the type of choice for indexing, as it guaranteed to be large enough to hold any index value possible for the system the code is compiled for.
Also you want to add error checking to the two calls of malloc(), as it might return NULL in case of failure to allocate the amount of memory requested.
The declaration is correct, but the matrix won't occupy continuous memory space. It is array of pointers, where each pointer can point to whatever location, that was returned by malloc. For that reason addressing like (A+ni+j) does not make sense.
Assuming that compiler has support for VLA (which became optional in C11), the idiomatic way to define continuous matrix would be:
int (*matrixA)[N] = malloc(N * sizeof *matrixA);
In general, the syntax of matrix with N rows and M columns is as follows:
int (*matrix)[M] = malloc(N * sizeof *matrixA);
Notice that both M and N does not have to be given as constant expressions (thanks to VLA pointers). That is, they can be ordinary (e.g. automatic) variables.
Then, to access elements, you can use ordinary indice syntax like:
matrixA[0][0] = 100;
Finally, to relase memory for such matrices use single free, e.g.:
free(matrixA);
free(matrix);
You need to understand that 2D and higher arrays do not work well in C 89. Beginner books usually introduce 2D arrays in a very early chapter, just after 1D arrays, which leads people to assume that the natural way to represent 2-dimensional data is via a 2D array. In fact they have many tricky characteristics and should be considered an advanced feature.
If you don't know array dimensions at compile time, or if the array is large, it's almost always easier to allocate a 1D array and access via the logic
array[y*width+x];
so in your case, just call
int *A;
A = malloc(N * N * sizeof(int))
A[3*N+2] = 123; // set element A[3][2] to 123, but you can't use this syntax
It's important to note that the suggestion to use a flat array is just a suggestion, not everyone will agree with it, and 2D array handling is better in later versions of C. However I think you'll find that this method works best.
How do you allocate an array in Go with a run-time size?
The following code is illegal:
n := 1
var a [n]int
you get the message prog.go:12: invalid array bound n (or similar), whereas this works fine:
const n = 1
var a [n]int
The trouble is, I might not know the size of the array I want until run-time.
(By the way, I first looked in the question How to implement resizable arrays in Go for an answer, but that is a different question.)
The answer is you don't allocate an array directly, you get Go to allocate one for you when creating a slice.
The built-in function make([]T, length, capacity) creates a slice and the array behind it, and there is no (silly) compile-time-constant-restriction on the values of length and capacity. As it says in the Go language specification:
A slice created with make always allocates a new, hidden array to which the returned slice value refers.
So we can write:
n := 12
s := make([]int, n, 2*n)
and have an array allocated size 2*n, with s a slice initialised to be the first half of it.
I'm not sure why Go doesn't allocate the array [n]int directly, given that you can do it indirectly, but the answer is clear: "In Go, use slices rather than arrays (most of the time)."
I am trying to create a 2d Array at compile time that has an unknown number of rows that i can dynamically allocate throughout the program but a specific number of columns as 8.
Something like ---->Elements[?][8];
If you have to use 2d array instead of list of array you gonna have to make a array
constant i = 1
foo[i][8]
and every time you want to expand that array
make temp_foo[i][8]
copy foo to temp_foo
delete foo
make foo[i++][8]
copy temp_foo to foo
But that's make confusing. and i think its better if use link list
struct node
{
foo[8]
node *next;
}
adding first element
node *element_head
element->foo = {add elements}
element->next = null
adding new element
node *temp
temp->foo = {add element}
temp->next = element_head
element_head= temp
Knowing the number of columns, and making only the number of rows dynamic you can either use a VLA or dynamic allocation. A VLA is straight forward:
int rows;
// get rows somehow
int table[rows][8];
Keeping in mind a VLA has automatic storage lifetime and will be removed from addressable memory once the enclosing scope expires. And they cannot be globals.
If your implementation doesn't support VLA's, automatic storage space is a concern, or you need a global variable for some nefarious purpose, you'll have to manage this dynamically (which it sounds like you want to do anyway). To do that, declare a pointer to an array of 8 elements, as such:
int rows;
// get rows somehow
int (*table)[8] = malloc(rows * sizeof(*table));
The rest is straight forward. You can reference your elements as table[i][j] for i in 0..rows-1 and j in 0..7. Just remember to free your allocation when finished:
free(table);
and don't reference it again.
As far as I know, you can't have foo[][8] in C. You might be able to hack around it by making a struct and casting a pointer to that struct to an array, as discussed here, but that is a somewhat fragile hack.
What you can do is change the definition of rows and columns in your problem space, so that, in order to access row i, column j, you would do foo[j][i] instead of foo[i][j].
In this case you could declare your array like this: <typename> * foo[8].
I'd go with this approach when the dimensions are unknown.
Assuming data type to be int.
int* a; //this will point to your 2D array
allocate it when you know the dimensions (ROW, COL):
a = malloc(sizeof(int)*ROW*COL);
and access it like
a[ROW*i + j] = value // equivalent of a[i][j]
I think it will not be created when you are not passing any value at compile time, my suggestion is to use dynamic memory allocation as you don't know how many rows
I have a giant 3-dimensional array that represents my world. It's too big to initialize statically:
alias Cell[128][128][128] World; // <-- The compiler points to this line
Error: index 128 overflow for static array
I tried using World* world but it still errors out with the overflow above. So what I have right now is this ugly mess:
alias Cell[][][] World;
// ...
private World world;
// ...
world.length = WORLD_XDIM;
for (uint x = 0; x < world.length; ++x)
{
world[x].length = WORLD_YDIM;
for (uint y = 0; y < world[x].length; ++y)
{
world[x][y].length = WORLD_ZDIM;
}
}
That works, but it makes me cry a little on the inside. Is there a way to cast the result of calloc to a 3-dimensional array? I've done it with slicing regular arrays, but the 3-D thing is confounding me.
If you want to declare a jagged array (i.e. where each sub-array may have varying length), then you need to use a loop like you're doing, but that's unnecessary for uniform arrays. This is how you initialize a multi-dimensional array which isn't jagged:
auto arr = new Cell[][][](128, 128, 128);
When you put the numbers between the brackets, you're make it a dynamic array of static arrays. So,
auto arr = new Cell[128][128][128];
declares a dynamic array of a static arrays of length 128 of static arrays of length 128. I guess that it would be useful if you actually needed to do that (which I never have), but it definitely trips up newbies on a regular basis.
Personally, to avoid such issues completely, I just never put the numbers in between the brackets, even when declaring a single dimension array:
auto arr = new Cell[](128);
I find the fact that putting the number between the brackets on the first dimension is treated as a dynamic array while putting numbers in any further levels is treated as a static array to be a poor design choice, and I don't know why that's the way that it is, but that's the way that it is. I can understand wanting to be able to create dynamic arrays of static arrays, but it would have been far more consistent to either disallow new Cell[128] or to make it return a Cell[128]* rather than a Cell[] of length 128, but unfortunately, that's not how it works.
given the following function signature:
void readFileData(FILE* fp, double inputMatrix[][], int parameters[])
this doesn't compile.
and the corrected one:
void readFileData(FILE* fp, double inputMatrix[][NUM], int parameters[])
my question is, why does the compiler demands that number of columns will be defined when handling a 2D array in C? Is there a way to pass a 2D array to a function with an unknown dimensions?
thank you
Built-in multi-deminsional arrays in C (and in C++) are implemented using the "index-translation" approach. That means that 2D (3D, 4D etc.) array is laid out in memory as an ordinary 1D array of sufficient size, and the access to the elements of such array is implemented through recalculating the multi-dimensional indices onto a corresponding 1D index. For example, if you define a 2D array of size M x N
double inputMatrix[M][N]
in reality, under the hood the compiler creates an array of size M * N
double inputMatrix_[M * N];
Every time you access the element of your array
inputMatrix[i][j]
the compiler translates it into
inputMatrix_[i * N + j]
As you can see, in order to perform the translation the compiler has to know N, but doesn't really need to know M. This translation formula can easily be generalized for arrays with any number of dimensions. It will involve all sizes of the multi-dimensional array except the first one. This is why every time you declare an array, you are required to specify all sizes except the first one.
As the array in C is purely memory without any meta information about dimensions, the compiler need to know how to apply the row and column index when addressing an element of your matrix.
inputMatrix[i][j] is internally translated to something equivalent to *(inputMatrix + i * NUM + j)
and here you see that NUM is needed.
C doesn't have any specific support for multidimensional arrays. A two-dimensional array such as double inputMatrix[N][M] is just an array of length N whose elements are arrays of length M of doubles.
There are circumstances where you can leave off the number of elements in an array type. This results in an incomplete type — a type whose storage requirements are not known. So you can declare double vector[], which is an array of unspecified size of doubles. However, you can't put objects of incomplete types in an array, because the compiler needs to know the element size when you access elements.
For example, you can write double inputMatrix[][M], which declares an array of unspecified length whose elements are arrays of length M of doubles. The compiler then knows that the address of inputMatrix[i] is i*sizeof(double[M]) bytes beyond the address of inputMatrix[0] (and therefore the address of inputMatrix[i][j] is i*sizeof(double[M])+j*sizeof(double) bytes). Note that it needs to know the value of M; this is why you can't leave off M in the declaration of inputMatrix.
A theoretical consequence of how arrays are laid out is that inputMatrix[i][j] denotes the same address as inputMatrix + M * i + j.¹
A practical consequence of this layout is that for efficient code, you should arrange your arrays so that the dimension that varies most often comes last. For example, if you have a pair of nested loops, you will make better use of the cache with for (i=0; i<N; i++) for (j=0; j<M; j++) ... than with loops nested the other way round. If you need to switch between row access and column access mid-program, it can be beneficial to transpose the matrix (which is better done block by block rather than in columns or in lines).
C89 references: §3.5.4.2 (array types), §3.3.2.1 (array subscript expressions)
C99 references: §6.7.5.2 (array types), §6.5.2.1-3 (array subscript expressions).
¹ Proving that this expression is well-defined is left as an exercise for the reader. Whether inputMatrix[0][M] is a valid way of accessing inputMatrix[1][0] is not so clear, though it would be extremely hard for an implementation to make a difference.
This is because in memory, this is just a contiguous area, a single-dimension array if you will. And to get the real offset of inputMatrix[x][y] the compiler has to calculate (x * elementsPerColumn) + y. So it needs to know elementsPerColumn and that in turn means you need to tell it.
No, there's not. The situation's pretty simple really: what the function receives is really just a single, linear block of memory. Telling it the number of columns tells it how to translate something like block[x][y] into a linear address in the block (i.e., it needs to do something like address = row * column_count + column).
Other people have explained why, but the way to pass a 2D array with unknown dimensions is to pass a pointer. The compiler demotes array parameters to pointers anyway. Just make sure it's clear what you expect in your API docs.