Storing iterative function outputs into matrices [duplicate] - matlab

This question already has an answer here:
Saving return values of function returning multiple variables in Matlab
(1 answer)
Closed 7 years ago.
I have an iterative function which gives me two vector outputs. How can I store these outputs into two separate matrices in matlab?
[A, B]=iterative_function(x,y)
the size of A and B varies in every loop.

If the sizes of the outputs vary, it's best to store them in a cell array:
A_cell = cell(1, num_iter);
B_cell = cell(1, num_iter);
for ii = 1:num_iter
...
[A_cell{ii}, B_cell{ii}] = iterative_function(x, y);
...
end
where num_iter is the number of iterations and ii is the loop variable.

Related

Matlab: Create vector of arrays [duplicate]

This question already has an answer here:
Creating a list of matrices [duplicate]
(1 answer)
Closed 3 years ago.
I am a python (and numpy) regular who just started using Matlab. I am solving boundary value problems using bv4pc, and I want to store the result arrays, solved for different parameters, in a larger array.
For example, consider the following code that returns a result vector y for each value of the parameter t -
for j = 1:loops
t = 1/(sqrt(2).^j)
% solve ODE that depends on parameter t
sol = bvp4c(#(x,y)elasticaODE(x,y,t),#(ya,yb)elasticaBC(ya,yb,t),solinit,options);
% The solution at the mesh points
x = sol.x;
y = sol.y;
In python, I would just do:
yVector = []
for (t in tArray):
... solve ODE, get y ...
yVector.append(y)
yVector = np.array(yVector)
What is the equivalent in Matlab?
In Matlab, most variables are matrices by default. There are two exceptions that might be what you are looking for:
1- Cells
Cells are similar to Python arrays, in the sense that each element can be anything
my_cell = {'a', 1, "wut", [1,2,3]};
And you can access the elements using the curly braces notation:
my_cell{1} % yields 'a'
my_cell{4}(2) % yields 2
2-Struct Arrays
You can define a struct by declaring it's fields, and they are mutable, a bit like in a Python dictionary:
my_struct.a = 1
my_struct.b = 2
If you have structs with the same fields, you can create a vector of structs:
my_second_struct.a = 3
my_second_struct.b = 4
my_vector_of_structs = [my_struct; my_second_struct]
Again, each field in a struct can be anything, even another struct.

How to vectorize the evaluation of outer product matrix for every row of the 2D matrix? [duplicate]

This question already has answers here:
Efficiently compute a 3D matrix of outer products - MATLAB
(3 answers)
Closed 3 years ago.
I am trying to speed the process in evaluation the outer product matrix. I have a 4*n matrix named a. I want to evaluate the outer product matrix for every row of a, by the formula:
K = a*a';
If I code this process using a for loop, it is as below:
K=zeros(4,4,size(a,2));
for i=1:size(a,2)
K(:,:,i) = a(:,i)*a(:,i)';
end
I have found another method, using cellfun, which is even slower than before.
acell = num2cell(a, 1);
b = cellfun(#(x)(x*x'),acell,'UniformOutput',false);
K = reshape(cell2mat(b),4,4,[]);
Is there any good way to implement these process, such as vectorization?
You can use kron to repeat the matrix n time, so no need to preallocation, then perform an element wise multiplication with a(:).', finally reshape to add a 3rd dimension.
%Dummy 2D matrix 4x3
a = [1 4 7
2 5 8
3 6 9
4 7 10]
%Size of the first dimension
n = size(a,1);
%Repeat the matrix n time
p = kron(a,ones(1,n)).*a(:).'
%Reshape to A = 4x4x3
A = reshape(p,n,n,[])
You loose the readability of the for loop method but you should increase the performance.

matlab: specify which dimension to index [duplicate]

This question already has answers here:
On shape-agnostic slicing of ndarrays
(2 answers)
Dynamic slicing of Matlab array
(1 answer)
Closed 4 years ago.
Imagine a function where you want to output a snippet in a user-specified dimension of a n-dimensional matrix
function result=a(x,dim)
window=1:10;
dim=3;
result=x(:,:,window);
end
How can I put window to the desired dimension? E.g. if dim=2; then result=x(:,window,:).
The way I can think of right now is to evaluate a string command that puts window in the correct position - or use a lot of if then else blocks. What's a better way of doing this?
You can do this using a cell array to define your indexes, following the examples here.
Specifically, if you have a matrix
x = ones(7,5,9);
You can define the indexes you want like:
% get all the indexes in all dimensions
all_indexes = {':', ':', ':'};
% get all indexes in dimensions 1 and 3, and just indices 1:4 in dimension 2
indexes_2 = {':', 1:4, ':'};
And then get those indexes from your matrix x like
a = x(all_indexes{:});
b = x(indexes_2{:});
So, you could write a function like
function result=extract_cells(x, dim, window)
% Create blank cell array {':', ':', ...} with entries ':' for each dimension
% Edit (c/o Cris Luengo): need to use ndims(x) to get the number of dimensions
num_dims = ndims(x)
dims = cell(1, num_dims);
dims(:) = {':'};
% Set the specified window of cells in the specified dimension
dims{dim} = window;
% Pick out the required cells
result=x(dims{:});
end
Which could return all the cells in the dimensions other than one specified, and in that direction would return the cells in the range given by window. So in the following code, a and b would be equivalent.
a = extract_cells(x, 2, 1:5);
b = x(:, 1:5, :)

How to store a series of vectors from a for loop matlab [duplicate]

This question already has an answer here:
Subscript indices must either be real positive integers or logicals?
(1 answer)
Closed 8 years ago.
I have a for loop which generates a vector. i want to store these vectors in a matrix.
normally i would do:
for r=1:100
vec=[x:y]+r;
mat(:,r)=vec
end
But this doesnt work, because i have something like:
dr=10/20
for r=1:dr:20
vec=[x;y]+r;
...
How would I store the vectors in a matrix now? Because i cant use r for the column indices, because the values of r arent integers most of the time.
Many options eg:
r=1:dr:20
for rr=1:length(r)
vec=[x;y]+r(rr);
mat(:,rr)=vec;
...
or
col = 1;
for r=1:dr:20
vec=[x;y]+r;
mat(:,col)=vec;
col = col + 1;
....
But whatever you choose you must preallocate mat before your for loop like this:
mat = zeros(length(x) + length(y), length(1:dr:20))
Pre-allocation is essential when using loops in Matlab or they will run very inefficiently.

Create 'n' matrices in a loop [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to concatenate a number to a variable name in MATLAB?
Hi everyone, as the title, i'd like to learn if anyone knows how, in Matlab, create 'n' matrices in a loop.
Like this:
for (i=1:n)
p_i = P(i, :);
q_i = Q(i, :);
A_i = [p_i, p_i', q_i];
end
Matlab, of course, rewrites n times on the matrix A_i, but i would like to have n matrices of 'i' index.
Thank you in advance, have a good day!!
You could concatenate everything into a 3D array:
A_i = zeros(D1,D2,n); % D1 and D2 are the dimensions of the 2D arrays
for i = 1:n
p_i = P(i,:);
q_i = Q(i,:);
A_i(:,:,i) = [p_i, p_i', q_i];
end
If you genuinely want n distinct matrices, then you will need a cell array. Your code would become something like:
A_i = cell(1,n);
for i = 1:n
p_i = P(i,:);
q_i = Q(i,:);
A_i{i} = [p_i, p_i', q_i];
end
Note that you should carefully consider which would suit your needs the best. The only real advantage of a cell array is that it allows each element to be a different data-type, or a different-sized array. A 3D array has several advantages over a cell array of 2D arrays (you can sum over it, reshape it, slice 3D sub-chunks out of it, etc. etc.).