Create 2-D array of strings with nested fill - arrays

I am initializing a vector of strings like this
mask = fill(fill(' ', maxx), maxy)
in order to then populate it by setting individual elements:
mask[y][x] = 'ยท'
This doesn't work: I get maxy times the same string. I guess the outer fill just creates a list of pointers to the Vector created by the inner fill (the documentation of fill! confirms this explicitly). What should I do instead?

One solution is to use a list comprehension like this:
mask = [fill(' ', maxx) for y in 1:maxy]
(But I'd still be interested to learn whether there is a solution with fill.)

Related

Array intersection issue (Matlab)

I am trying to carry out the intersection of two arrays in Matlab but I cannot find the way.
The arrays that I want to intersect are:
and
I have tried:[dur, itimes, inewtimes ] = intersect(array2,char(array1));
but no luck.
However, if I try to intersect array1 with array3 (see array3 below), [dur, itimes, inewtimes ] = intersect(array3,char(array1));the intersection is performed without any error.
Why I cannot intersect array1 with array2?, how could I do it?. Thank you.
Just for ease of reading, your formats for Arrays are different, and you want to make them the same. There are many options for you, like #Visser suggested, you could convert the date/time into a long int which allows faster computation, or you can keep them as strings, or even convert them into characters (like what you have done with char(Array2)).
This is my example:
A = {'00:00:00';'00:01:01'} %//Type is Cell String
Z = ['00:00:00';'00:01:01'] %//Type is Cell Char
Q = {{'00:00:00'};{'00:01:01'}} %//Type is a Cell of Cells
A = cellstr(A) %//Convert CellStr to CellStr is essentially doing nothing
Z = cellstr(Z) %//Convert CellChar to CellStr
Q = vertcat(Q{:,:}) %// Convert Cell of Cells to Cell of Strings
I = intersect (A,Z)
>>'00:00:00'
'00:01:01'
II = intersect (A,Q)
>>'00:00:00'
'00:01:01'
This keeps your dates in the format of Strings in case you want to export them back into a txt/csv file.
Your first array would look something like this:
array1 = linspace(0,1,86400); % creates 86400 seconds in 1 day
Your second array should be converted using datenum, then use cell2mat to make it a matrix. Lastly, use ismember to find the intersection:
InterSect = ismember(array2,array1);

Concise way to create an array filled within a range in Matlab

I need to create an array filled within a range in Matlab
e.g.
from=2
to=6
increment=1
result
[2,3,4,5,6]
e.g.
from=15
to=25
increment=2
result
[15,17,19,21,23,25]
Obviously I can create a loop to perform this action from scratch but I wondering if there is a coincise and efficent way to do this with built-in matlab commands since seems a very common operation
EDIT
If I use linspace the operation is weird since the spacing between the points is (x2-x1)/(n-1).
This can be handled simply by the : operator in the following notation
array = from:increment:to
Note that the increment defaults to 1 if written with only one colon seperator
array = from:to
Example
array1 = 2:6 %Produces [2,3,4,5,6]
array2 = 15:2:25 %Produces [15,17,19,21,23,25]

R populate multidimensional array

Hi I am stuck with one of these simple but time-consuming errors:
How can I populate an array with loops? I know I am on a C approach here
and R isn't C.
Data <-[SOMETHING HERE]
One <-200
Two <-100
array222 <- array(0,length(SomeLength))
for (i in 1:One)
{
for (j in 1:Two)
{
array222[i][j] = sample(Data,1)
}
I want to populate the array with random samples from another dataset but all
I get is this:
Warning in array222[i][j] = sample(Data, 1) :
number of items to replace is not a multiple of replacement length
First of all, you wouldn't use loops to do this in R. You'd just do
array222 <- matrix(sample(Data, One*Two, replace=T), nrow=One, ncol=Two)
But going back to your code, you fail to properly initialize your array222 variable. The matrix() syntax is probably easier for a 2-D array, but you could also use array(0, dim=c(One,Two)). You need to create it with the proper dimensions.
And additionally, the proper way to index a dimensional array is
array222[i,j] #NOT array222[i][j]

How to set the fields simultaneously in a large structure array in Matlab?

I have a large structure array.
I would like to perform a sensitivity analysis on a function that processes this array.
So, say my structure array has name 's', 10,000 elements, and field names 'x' and 'y'.
I'd like to do the following:
xs = [s(:).x];
xs = xs + 5*randn(size(xs));
s(:).x = xs;
Sadly, the last step is not valid matlab. Any thoughts? Was hoping to avoid a loop.
From this answer and after playing around with deal. I think I have what you are looking for but it requires converting xs into a cell array using num2cell:
xs_cell = num2cell(xs); % convert matrix to cell array.
[S(:).X]=xs_cell{:}; % update the values in the field X

Distributing a function over a single dimension of an array in MATLAB?

I often find myself wanting to collapse an n-dimensional matrix across one dimension using a custom function, and can't figure out if there is a concise incantation I can use to do this.
For example, when parsing an image, I often want to do something like this. (Note! Illustrative example only. I know about rgb2gray for this specific case.)
img = imread('whatever.jpg');
s = size(img);
for i=1:s(1)
for j=1:s(2)
bw_img(i,j) = mean(img(i,j,:));
end
end
I would love to express this as something like:
bw = on(color, 3, #mean);
or
bw(:,:,1) = mean(color);
Is there a short way to do this?
EDIT: Apparently mean already does this; I want to be able to do this for any function I've written. E.g.,
...
filtered_img(i,j) = reddish_tint(img(i,j,:));
...
where
function out = reddish_tint(in)
out = in(1) * 0.5 + in(2) * 0.25 + in(3) * 0.25;
end
Many basic MATLAB functions, like MEAN, MAX, MIN, SUM, etc., are designed to operate across a specific dimension:
bw = mean(img,3); %# Mean across dimension 3
You can also take advantage of the fact that MATLAB arithmetic operators are designed to operate in an element-wise fashion on matrices. For example, the operation in your function reddish_tint can be applied to all pixels of your image with this single line:
filtered_img = 0.5.*img(:,:,1)+0.25.*img(:,:,2)+0.25.*img(:,:,3);
To handle a more general case where you want to apply a function to an arbitrary dimension of an N-dimensional matrix, you will probably want to write your function such that it accepts an additional input argument for which dimension to operate over (like the above-mentioned MATLAB functions do) and then uses some simple logic (i.e. if-else statements) and element-wise matrix operations to apply its computations to the proper dimension of the matrix.
Although I would not suggest using it, there is a quick-and-dirty solution, but it's rather ugly and computationally more expensive. You can use the function NUM2CELL to collect values along a dimension of your array into cells of a cell array, then apply your function to each cell using the function CELLFUN:
cellArray = num2cell(img,3); %# Collect values in dimension 3 into cells
filtered_img = cellfun(#reddish_tint,cellArray); %# Apply function to each cell
I wrote a helper function called 'vecfun' that might be useful for this, if it's what you're trying to achieve?
link
You could use BSXFUN for at least some of your tasks. It performs an element-wise operation among two arrays by expanding the size 1 - dimensions to match the size in the other array. The 'reddish tint' function would become
reddish_image = bsxfun(#times,img,cat(3,0.5,0.25,0.25));
filtered_img = sum(reddish_image,3);
All the above statement requires in order to work is that the third dimension of img has size 1 or 3. Number and size of the other dimensions can be chosen freely.
If you are consistently trying to apply a function to a vector comprised by the 3 dimension in a block of images, I recommend using a pair reshapes, for instance:
Img = rand(480,640,3);
sz = size(Img);
output = reshape(myFavoriteFunction(reshape(Img,[prod(sz(1:2)),sz(3)])'),sz);
This way you can swap in any function that operates on matrices along their first dimension.
edit.
The above code will crash if you input an image which has only one layer: The function below can fix it.
function o = nLayerImage2MatrixOfPixels(i)
%function o = nLayerImage2MatrixOfPixels(i)
s = size(i);
if(length(s) == 2)
s3 = 1;
else
s3 = s(3);
end
o = reshape(i,[s(1)*s(2),s(3)])';
Well, if you are only concerned with multiplying vectors together you could just use the dot product, like this:
bw(:,:,1)*[0.3;0.2;0.5]
taking care that the shapes of your vectors conform.

Resources