How to declare an array without size in MATLAB? - arrays

I wan to declare an array in MATLAB without specifying the size, rather like std::vector in C++, and then I want to "push" elements to the array. How can I declare this array and push to it?

Altough the answer of Paul R is correct, it is a very bad practice to let an array grow in Matlab without pre-allocation. Note that even std::vector has the option to reserve() memory to avoid repeated re-allocations of memory.
You might want to consider pre-allocating a certain amount of memeory and then resize to fit the actual needed size.
You can read more on pre-allocation here.

You can just define an empty array like this:
A = [];
To "push" a column element:
A = [ A 42 ];
To "push" a row element:
A = [ A ; 42 ];

As Shai pointed out, pushing elements onto a vector is not a good approach in MATLAB. I'm assuming you're doing this in a loop. In that case, this would be better approach:
A = NaN(max_row, 1);
it = 0;
while condition
it = it + 1;
A(it) = value;
end
A = A(1:it);
If you don't know the maximum dimension, you may try something like this:
stack_size = 100;
A = NaN(stack_size,1);
it = 0;
while some_condition
it = it + 1;
if mod(it, stack_size) == 0
A = [A; NaN(stack_size,1)];
end
A(it) = value;
end
A = A(1:it);

Related

Scala: filtering an array with filter vs. for each

I have this problem: I want to iterate on the elements of an array that satisfy a certain condition.
The first thing I though is to use the filter method on the original array and then iterates over the resulting elements. But I had some memory usage problem with that, i.e. java heap space.
When a filter is applied on an array, it will instantiate a new array? So it will copy each element?
Is it better to use this approach:
array.filter(<condition>).foreach{ element =>
do something
}
Or the following one?
for(i <- array.indices if <condition>){
do something
}
Moreover, I wrote these two tests:
With for
val size = 10000000
val elements = Array.ofDim[Double](size)
for (i <- elements.indices) {
elements.update(i, math.random)
}
var cont = 0
val n = 0.5
while(true){
cont = 0
for (j <- elements.indices if elements(j) < n) {
cont += 1
}
println(cont)
}
with filter
val size = 10000000
val elements = Array.ofDim[Double](size)
for (i <- elements.indices) {
elements.update(i, math.random)
}
val n = 0.5
while(true){
val valid = elements.filter(x => x < n)
println(valid.size)
}
and I checked the memory usage with VisualVM, it seem that the first solution uses less memory than the second one.
This is the memory used by the first solution
This is the memory used by the second solution
The for expression use the withFilter method rather than filter, which avoids creating the intermediate Array. So either use the for version or use withFilter rather than filter.

How can you initialize an entire array at once in GML?

I want to initialize an entire array at once but I can't find any examles of this being done anywhere.
I want to do something like this:
int a [][] = {{0,1,0},
{0,1,1},
{2,1,0}};
Unfortunately GML is not like many other languages in the sense that GML does not have single line array initialization. You can easily write a script to accomplish this, but the GML docs use this method to initialize arrays. The example they gave initializes a 10 record array (0-9) with zeros.
var i;
i = 9;
repeat(10)
{
array[i] = 0;
i -= 1;
}
If you want different values for every record then you have to manually type every position. This is the example the docs gave.
count = 3;
array[count] = "you?"
count -= 1;
array[count] = "are "
count -= 1;
array[count] = "How "
count -= 1;
array[count] = "Hello!"
count -= 1;
In regards to a script: Here is a simple one for 1D arrays. Used as var myArray = array(record 1, record 2, 3, 4, ...)
///array(*args);
var arr;
for (var i=0;i<argument_count;i+=1)
{
arr[i] = argument[i];
}
return arr;
If you are using a current version of GameMaker, there's array literal syntax in form of [...items] (documentation). So you can do
a = [[0,1,0],
[0,1,1],
[2,1,1]];
and that'll work fine.
The only thing to note that this'll produce an array of arrays (which is how arrays work in most languages) rather than GML-specific legacy 2d array, so you'd need to use a pair of [index] accessors rather than [index1, index2].

Matlab variable size arrays

I am very new to Matlab, and I feel completely overwhelmed by the use of arrays. What is the most efficient implementation of the following C++ code in Matlab?
A = std::vector<double>();
for (int i = 0; i < 100; i++) {
if (complicatedBoolFunction(i)) {
A.push_back(i);
}
}
Edit: By efficiency I mean to use as little resources as possible to grow the array A - that is, to avoid copy-pasting it into temporary memory
You can do this 2 ways
Pre-allocating for the maximum size, and removing unused elements. This has the advantage of pre-allocating memory in case the condition is often met...
A = NaN(100,1)
for ii = 0:99
if rand > 0.5 % some condition
A(ii+1) = ii; % some value
end
end
A(isnan(A)) = []; % remove unused elements
Appending to the array. This avoids making A way too large if appending is unlikely...
A = []; % empty array
for ii = 0:99
if rand > 0.5 % some condition
A(end+1, 1) = ii; % some value. Equivalent to 'A = [A; ii];'
end
end
A better, and more Matlab-esque way of doing this would be to vectorise your conditional function. This way you avoid looping and allocation issues...
ii = 0:99;
A = ii(rand(100, 1) > 0.5);
You can use any Boolean function you like as an indexing array, as long as it returns a logical array with the same number of elements as the array you're indexing (ii here) or integer indices of the elements to choose.
The most efficient implementation of such C++ code would be
i = 0:99;
A = i(complicatedBoolFunction(i));
Anyway you can grow an array with concatenation, which is (or was) usually not recommended, like the following
A = [];
for i = 0:99
if (complicatedBoolFunction(i))
A = [A i];
end
end
or much more efficiently like this:
A = [];
for i = 0:99
if (complicatedBoolFunction(i))
A(end + 1) = i;
end
end

Grow 3D array in Matlab

Is there a way to grow a 3D array in the third dimension using the end index in a loop in Matlab?
In 2D it can be done like
a = [];
for x = y
a(end + 1, :) = f(x);
end
But in 3D the same thing will not work as a(1,1,end) will try to index a(1,1,1) the first iteration (not a(1,1,0) as one might expect). So I can't do
im = [];
for x = y
im(:, :, end + 1) = g(x);
end
It seems the end of a in third dimension is handled a bit differently than in the first two:
>> a = [];
>> a(end,end,end) = 1
Attempted to access a(0,0,1); index must be a positive integer or logical.
Am I missing something about how end indexing works here?
What you're asking...
If you know the size of g(x), initialize im to an empty 3d-array:
im = zeros(n, m, 0); %instead of im = [];
I think your code should work now.
A better way...
Another note, resizing arrays each iteration is expensive! This doesn't really matter if the array is small, but for huge matrices, there can be a big performance hit.
I'd initialize to:
im = zeros(n, m, length(y));
And then index appropriately. For example:
i = 1;
for x = y
im(:, :, i) = g(x);
i = i + 1;
end
This way you're not assigning new memory and copying over the whole matrix im each time it gets resized!

Matlab - Slicing an Array without using additional memory

I want to slice an 4D-array into n parts along the 5th Dimension in order to use it in parfor:
X(:,:,:,particles)-->X(:,:,:,particles/n,n)
The Problem is that X is so big that I run out of memory if I start writing it into a new variable, so i want to basically do:
X = cat(5,X(:,:,:,1:particles/n),X(:,:,:,particles/n+1:2*particles/n),...)
I am doing this with
sliced = 'cat(5'
for i=1:n
sliced = strcat(2,sliced,sprintf(',X(:,:,:,(1+(%i-1)*%i):%i*%i)',i,particles/n,i,particles/n))
end
sliced = strcat(2,sliced,')');
X = eval(sliced);
I get:
Error: The input character is not valid in MATLAB statements or expressions.
If i print out the contents of sliced and comment everything and paste the printout of sliced manually into eval('...') it works.
Anyone got a solution for my problem or another way of slicing a 4D array without using additional memory?
Thanks
You can use reshape, which must not use any additional memory -
sz_X = size(X) %// get size
X = reshape(X,sz_X(1),sz_X(2),sz_X(3),sz_X(4)/n,[]); %// reshape and save
%// into same variable and as such must be memory efficient
Ok. I just got things mixed up cat and strcat are not the same... oops :o
n = 4;
particles = 200;
X = rand(6,6,6,particles);
sliced = sprintf('X = cat(5');
for i = 1:n
sliced = cat(2,sliced,sprintf(',X(:,:,:,(1+(%i-1)*%i):%i*%i)',i,particles/n,i,particles/n));
end
sliced = cat(2,sliced,sprintf(');'));
eval(sliced);
works just fine. If somebody has got a better way to slice without memory usage - please feel free to post...

Resources