MATLAB: Setting many variables based on the contents of a row array - arrays

I'm trying to tidy up my code. I have an array with 5 columns, each of which is assigned to a variable. At present, I use:
x = inputData(i,1);
y = inputData(i,2);
currentSampleTime = inputData(i,3);
velocityX = inputData(i,4);
velocityY = inputData(i,5);
I thought I could tidy things up a bit by just doing the following:
[x y currentSampleTime velocityX velocityY] = inputData(i,:);
Apparently this does not work. I presume there must be an elegant solution?

If inputData was a cell array then you could do this:
[x y currentSampleTime velocityX velocityY] = deal(inputData{i,:});
However, since you are indexing the row with the variable i can I assume that this is inside a for loop?
If so I would just do the following before the loop?
x = inputData(:,1);
y = inputData(:,2);
currentSampleTime = inputData(:,3);
velocityX = inputData(:,4);
velocityY = inputData(:,5);
Then just use x(i) y(i) etc inside of your loop.
... or depending on how inputData is generated try to create the necessary arrays when reading in or creating inputData.
Also, on a personal note I don't like using i as a variable in m-code because it can easily get confused with the imaginary number if not properly initialized.

Try this:
wh = size(inputData);
temp = mat2cell(inputData,wh(1),ones(1,wh(2)));
[x,y,currentSampleTime,velocityX,velocityY] = deal(temp{:});

Related

I want to append 1st element of numpy array with 1st element in another numpy array and do this for all other elements

I have Three numpy arrays
X = [1,2,3,4,4,5,56,..,n]
Y = [1,2,344,4,4,4,..,n]
Z = [1,2,244,24,445,64,..,n]
I want to make output like this
final_list = [(X1,Y1,Z1),(X2,Y2,Z2),(X3,Y3,Z3), ... (Xn,Yn,Zn)]
And then to check if Z in any of them is > some threshold
Pop it up all with its correspondence X and Y
Is there some suggestions please?
I tried
np.conctatenate
but no any good results.
Thanks a lot:)
A simple way with if else could be:
X = [1,2,3,4,4,5,56]
Y = [1,2,344,4,4,4,89]
Z = [1,2,244,24,445,64,89]
d=[]
for i in range(len(X)):
if Z[i]>thresh:
print("print something")
else:
d.append([X[i],Y[i],Z[i]])
print(d)
if you check if z>thresh at the time of creating the list there is no need of poping those items later.
One way with just list comprehension:
out = [(x,y,z) for x,y,z in zip(X,Y,Z) if z<threshold]
With numpy you can do something like this:
xyz = np.array([X,Y,Z])
under_thresh = xyz[xyz[-1]<threshold]

How to store the character for each looping in Matlab?

I have a string :
A="ILOVEYOUMATLAB"
and I create 2 empty array:
B1=[]
B2=[]
when i used the while loop, for the first time looping, if i want the first character from the A to store in B1 array, what command i need to write?
if in Python, i just need to used append command, but if in Matlab, what is the commend need to apply?
If you have MATLAB R2016b or newer you can use the new string class' overloaded + operator to append text in a more pythonic manner:
A = 'hi';
B = "";
B = B + A(1)
Which gives you:
B =
"h"
Here I've created A as a traditional character array ('') and B as a string array (""), mainly to avoid having to index into the string array (A{1}(1) instead of A(1)).
You can also just use traditional matrix concatenation to accomplish the task:
B = [B, A(1)];
% or
B = strcat(B, A(1));
% or
B(end+1) = A(1);
Note that 4 of these approaches will continually grow B in memory, which can be a significant performance bottleneck. If you know how many elements B is going to contain you can save a lot of IO time by preallocating the array and using matrix indexing to assign values inside your loop:
A = {'apple', 'banana', 'cucumber'};
B = char(zeros(1, numel(A)));
for ii = 1:numel(A)
B(ii) = A{ii}(1);
end
you can try strcat for concatenating strings in matlab
https://www.mathworks.com/help/matlab/ref/strcat.html
Try using arrays instead of matrices. You can assign the first letter to the first position of the B1 array like this:
>> A = 'ILOVEMATLAB';
>> B1 = {};
>> B1{1} = A(1);
>> B1{1}
ans =
I
To Loop through:
for i = 1:length(A)
B1{i} = A{i};
end

Create a 2D list with variable length [torch]

I want to create a 2D list that can have elements of variable lengths inside, for example, if I have a 10x10 list in MATLAB, I can
define it with:
z = cell(10,10)
and start assigning some elements by doing this:
z{2}{3} = ones(3,1)
z{1}{1} = zeros(100,1)
z{1}{2} = []
z{1}{3} = randn(20,1)
...
What is the optimal way to define such empty 2D list in torch? Moreover, is there a way to exploit the tensor structure to do this?
In python, I can do something along this to define an empty 10x10 2D list:
z = [[None for j in range(10)] for i in range(10)]
My best guess for torch is doing something like
z = torch.Tensor(10,10)
for i=1,10 do
for j=1,10 do
z[{{i},{j}}] = torch.Tensor()
end
end
but, this does not work, and defining a tensor inside a tensor seems like a bad idea ...
This is a follow up to the question asked here (however in the link it is asked in python): Create 2D lists in python with variable length indexed vectors
From the documentation I've read, tensors only support primitive numeric data types. You won't be able to use tensor for your intended usage. Leverage tables.
local function makeMatrix(initialVal, ...)
local isfunc = type(initialVal) == "function"
local dimtable = {...}
local function helper(depth)
if depth == 0 then
return isfunc and initialVal() or initialVal
else
local plane = {}
for i = 1, dimtable[depth] do
plane[i] = helper(depth-1)
end
return plane
end
end
return helper(#dimtable)
end
p = makeMatrix(0, 2, 3, 5) -- makes 3D matrix of size 2x3x5 with all elements initialized to 0
makeMatrix(torch.Tensor, m ,n)
Answer from Torch's Google Group forums. Agreeing that tables is the solution:
z = {}
for i=1,10 do
z[i] = {}
for j=1,10 do
z[i][j] = torch.Tensor()
end
end

How to concatenate arrays from cell arrays in Matlab

I am new to Matlab and was trying to concatenate array from cell arrays. I have done it as shown below.
S = load('input_file.mat');
c = struct2cell(S);
v = cell2mat(c(1,1));
temp = v(1:500,1:600);
v = cell2mat(c(3,1));
temp1 = v(1:500,1:600);
v = cell2mat(c(2,1));
temp2 = v(1:500,1:600);
v = cell2mat(c(4,1));
temp3 = v(1:500,1:600);
array1 = vertcat(temp,temp1);
array2 = vertcat(temp2,temp3);
But i guess there should be a better way or a direct function call which can get me the same result as i am getting from the code shown?
This is a very specific task, not very general, unless I'm missing the pattern. Starting after struct2cell:
C3 = cellfun(#(x)x(1:500,1:600),c,'uni',0);
array1 = vertcat(C3{[1 3]});
array2 = vertcat(C3{[2 4]});
Although, you could probably get rid of your initial structfun if you replace cellfun above with structfun, taking s as an input. It simply operates on each field.

Three dimensional table in Lua

I need the best way to store a three dimensional table for pixels. What I need to do is have multiple x,y tables (basically three dimensional) it is to raster multiple two dimensional pixel maps with transparency. You see I can create two dimensions easily like so:
pixels = {{},{}}
pixels[1][5] = "green" --just an example
print(pixels[1][5])
However, I cannot do this like I can in Java...
pixels = {{}, {}, {}}
pixels[1][4][3] = "red" -- [x][y][z]
print(pixels[1][4][3])
This is the functionality I want, but I have disgustingly got around this by doing this...
pixels = {}
pixels["x23,y02,z05"] = "green"
print(pixels["x23,y02,z05"]")
I just use string.sub, and string.concat to read and set the tables... I really would like the functionality of example 2 to work, however I know it might need to be implemented differently.
There are basically two ways to go about this
Auto-tables
Auto-tables generate sub-tables transparently using metatables and essentially after creating it you should be able to forget about them.
function newAutotable(dim)
local MT = {};
for i=1, dim do
MT[i] = {__index = function(t, k)
if i < dim then
t[k] = setmetatable({}, MT[i+1])
return t[k];
end
end}
end
return setmetatable({}, MT[1]);
end
-- Usage
local at = newAutotable(3);
print(at[0]) -- returns table
print(at[0][1]) -- returns table
print(at[0][1][2]) -- returns nil
at[0][1][2] = 2;
print(at[0][1][2]) -- returns value
print(at[0][1][3][3]) -- error, because only 3 dimensions set
What is not so nice about them is that they generate lots of tables -- obviously. That's some memory overhead and each level of depth increases the execution time.
What's nice about them is that they can be completely dynamic in size. You could even make them infinitely deep. Though in your use-case this is very likely not necessary and probably even a bad idea.
This structure is very suitable for non-integer indexes though, you could for example make the depth even depend on a "template structure" and so implement a transparent dynamic configuration table, but I'm getting side-tracked...
Flattened arrays
The other variant are flattened arrays. user3125367 already wrote about them, but I want to expand on this as this can be done a lot more convenient and explain a few things.
Often flattening your multi-dimensional arrays is a good idea in CG anyway, since then you can do many matrix operations very easily. Calculating a modified index is also relatively cheap in terms of processing time required. But it should be noted, although kind of obvious, that this approach only works with numeric keys and a predefined size of your matrix.
function newMdArray(X, Y, Z)
local MT = { __call = function(t, x, y, z, v)
if x>X or y>Y or z>Z or x<1 or y<1 or z<1 then return; end
local k = x + X*(y-1) + X*Y*(z-1);
if v ~= nil then t[k] = v; end
return t[k];
end };
return setmetatable({}, MT);
end
-- Usage
local mdt = newMdArray(100, 100, 100);
local v = mdt(1, 2, 3);
mdt(1, 2, 3, v*.1);
This code is taken from another answer from me: dynamic tables or arrays
It can probably be optimised a little (for example calculate X*Y in the closure) but I wanted to paste the original code here. Anyway, with this you can both easily work on the flattened structure by just using normal array indexing:
for i=1, #mdt
mdt[i] = (mdt[i] or 0)*.5
end
As well as access 3d indexes directly:
mdt(12, 13, 14, 0)
You can also easily modify the function to return a default value for missing keys by adding an __index field to the metatable or so that the table saves the matrix dimensions etc.
In addition to classic 'array in array in array' scheme, you can use benefits of Lua table internals. How? Lua table is just a mapping from key to value, and when you use it as an array, you may skip some keys and this will cost virtually nothing.
t = { }
t[1] = "Hello"
t[500000] = "World" -- does NOT allocate additional 499999 elements
So, if your data is sparse (over 50% of your 3d-points having no value), you may benefit from this:
local n_x, n_y, n_z = 1920, 1080, 1000
local n_xy = n_x * n_y
function setValue(t, x, y, z, value)
assert(x > 0 and x < n_x)
assert(y > 0 and y < n_y)
assert(z > 0 and z < n_z)
t[((z-1) * n_xy) + ((y-1) * n_z) + x] = value
end
function getValue(t, x, y, z)
assert(x > 0 and x < n_x)
assert(y > 0 and y < n_y)
assert(z > 0 and z < n_z)
return t[((z-1) * n_xy) + ((y-1) * n_z) + x]
end
t = { }
setValue(t, 1, 1, 1, "red")
setValue(t, 1, 1, 2, "green")
In your first code:
pixels = {{},{}}
is equivalent to:
pixels = {}
pixels[1] = {}
pixels[2] = {}
Here, pixels[1] is already a table, that's why you can assign a value to pixels[1][5].
But in you second code:
pixels = {{}, {}, {}}
Here, pixels is still a two-dimensional array (with 3 elements). It's equivalent to :
pixels = {}
pixels[1] = {}
pixels[2] = {}
pixels[3] = {}
pixels[1] is a table, but pixels[1][4] is not. What you need to do is to give pixels[1][4] a table constructor like this:
pixels = {{}, {}, {}}
pixels[1][4] = {} --initialize it to an empty table
pixels[1][4][3] = "red"
print(pixels[1][4][3])

Resources