Comparing indices for symbolic expression in matlab - matlab

I have a (2x2) symbolic matrix in matlab, and substituted one element.
a = sym('a', [2 2])
a = subs(a, a(1,2), a(2,1))
Then the symbolic matrix looks like
a = [ a1_1, a2_1]
[ a2_1, a2_2]
Now I want to compare the two elements in each row whether their second indices are same or not. For example, if their second indices are same, we substitute them to 10, otherwise no change. After this operation, a should be changed like
a = [ 10, 10]
[ a2_1, a2_2]
How should I write script?

Related

Extracting a matrix from a cell vector in MATLAB

A sparse matrix is a large matrix with almost all elements of the same
value (typically zero). The normal representation of a sparse matrix
takes up lots of memory when the useful information can be captured
with much less. A possible way to represent a sparse matrix is with a
cell vector whose first element is a 2-element vector representing the
size of the sparse matrix. The second element is a scalar specifying
the default value of the sparse matrix. Each successive element of the
cell vector is a 3-element vector representing one element of the
sparse matrix that has a value other than the default. The three
elements are the row index, the column index and the actual value.
Write a function called "sparse2matrix" that takes a single input of a
cell vector as defined above and returns the output argument called
"matrix", the matrix in its traditional form. Consider the following
run:
cellvec = {[2 3], 0, [1 2 3], [2 2 -3]};
matrix = sparse2matrix(cellvec)
matrix =
0 3 0
0 -3 0
Good morning/afternoon/night, everyone
I was wondering if you could help me with this.
I am trying to complete this, but I am not sure how to deal with this. I understand that I am interested in the first part of the cell vector, but I am not sure about how to tell Matlab I need that. This is my code:
function matrix = sparse2matrix(x)
A = [2 3];
B = 0;
C = [1, 2, 3];
x = {A, 0, C};
matrix = cell2mat(x);
end
The result of this code is different from the result I showed above.
I am not getting the right answer and honestly I do not know what to do, so I would appreciate if you guide me a little bit.
Not the most elegant way of doing it but it gets the job done. Uses the cell2mat() function and indexing to grab the necessary values for each step. A for-loop is then used to obtain the 3-element vectors that is used to change the array values from the default values in the respective indices.
cellvec = {[2 3], 0, [1 2 3], [2 2 -3]};
[matrix] = sparse2matrix(cellvec)
function [matrix] = sparse2matrix(x)
Matrix_Size = cell2mat(x(1,1));
Matrix_Height = Matrix_Size(1);
Matrix_Width = Matrix_Size(2);
Default_Value = cell2mat(x(1,2));
matrix = Default_Value*ones(Matrix_Height,Matrix_Width);
Triplets = x(3:end);
Number_Of_Triplets = length(Triplets);
for Triplet_Index = 1: Number_Of_Triplets
Current_Triplet = cell2mat(Triplets(1,Triplet_Index));
Row = Current_Triplet(1,1);
Column = Current_Triplet(1,2);
Value = Current_Triplet(1,3);
matrix(Row,Column) = Value;
end
end
Explanation:
The first line in the local function sparse2matrix() indicates to retrieve row 1, column 1 of the cell array x and then convert it to a matrix. The conversion is done using the cell2mat() function.
Matrix_Size = cell2mat(x(1,1));
Results in:
Matrix_Size = [2 3]
The following line indicates to grab index 1 of the previous array Matrix_Size. This will be used to determine the height of the output array matrix. This is done in a similar fashion to evaluate the Matrix_Width using index 2.
Matrix_Height = Matrix_Size(1);
Results in:
Matrix_Height = 2
Ran using MATLAB R2019b

Matlab - Access elements form each column using a vector containing the rows [duplicate]

I'm writing a MATLAB function to read out data into an n-dimensional array (variable dimension size). I need to be able to access a specific point in the Matrix (to write to it or read it, for example), but I don't know ahead of time how many indexes to specify.
Currently I have a current_point vector which I iterate through to specify each index, and a max_points vector which specifies the size of the array. So, if for example I wanted a 3-dimensional array of size 1000-by-15-by-3, max_points = [1000 15 3], and current_point iterates from [1, 1, 1] to [1000, 15, 3] ([1, 1, 1] -> [1000, 1, 1] -> [1, 2, 1] -> [1000, 2, 1] ->...). What I'd like to be able to do is feed current_point as an index to the matrix like so:
output_matrix(current_point) = val
But apparently something like output_matrix([1 2 3]) = val will just set outputmatrix(1:3) = 30. I can't just use dummy variables because sometimes the matrix will need 3 indexes, other times 4, other times 2, etc, so a vector of variable length is really what I need here. Is there a simple way to use a vector as the points in an index?
Using the function sub2ind to create a linear index is the typical solution to this problem, as shown in this closely-related question. You could also compute a linear index yourself instead of calling sub2ind.
However, your case may be simpler than those in the other questions I linked to. If you're only ever indexing a single point with your current_point vector (i.e. it's just an n-element vector of subscripts into your n-dimensional matrix), then you can use a simple solution where you convert current_point to a cell array of subscripts using the function num2cell and use it to create a comma-separated list of indices. For example:
current_point = [1 2 3 ...]; % A 1-by-n array of subscripts
subCell = num2cell(current_point); % A 1-by-n cell array of subscripts
output_matrix(subCell{:}) = val; % Update the matrix point
The operation subCell{:} creates the equivalent of typing subCell{1}, subCell{2}, ..., which is the equivalent of typing current_point(1), current_point(2), ....
I know it is too late but for anybody who will find this topic. the easiest way that work for me is to use: diag(A (x(:),y(:)) );
unfortunately this works only if you need to get values from the matrix, not for changing values
You can use the sub2ind function to get the linear index from the subscript.
Example:
A=magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
selectElement={2,3}; %# get the element at position 2,3 in A.
indx=sub2ind(size(A),selectElement{:});
A(indx)
ans =
10
In the above example, I've stored the subscripts (can be any number of dimensions) as a cell. If you have it stored as a vector, simply use num2cell() to convert it to a cell.
You can now easily assign a value to this as A(indx)=value;. I've used different variables than yours to keep the answer general, but the idea is the same and you just need to replace the variable names.
You also mentioned in your post that you're looping from (1,1,1) till some value, (1000,15,3) and assigning a value to each of these points. If you're looping along the columns, you can replace this entire operation with a vectorized solution.
Let finalElement={1000,15,3} be the final step of the loop. As before, find the linear index as
index=sub2ind(size(A),finalElement{:});
Now if you have the values you assign in the loop stored as a single vector, values, you can simply assign it in a single step as
A(1:index)=values;

MATLAB: scan the row of a matrix and use values to search another matrix

I have matrix X and A where
X = [x1, y1, 1, 1; x2, y2, 1, 3; x3, y, 2, 4]
A = [1, 1, 0; 1, 3, 1; 1, 4, 2]
I want to:
1. scan the last two columns for every row in X (FYI, these two number combinations are unique)
2. find those values in the first two columns of A
3. get the value of the last column in that row of A.
For example, for the first row of X, I get 1 and 1, so I find 1 and 1 for the first two columns in A (which appears to be the first row), so the number I want to get is 0.
I think I can do it using a loop and a "find" function if it were just one number I'm working with, but I'm new to matlab and have trouble with a combination of two numbers. I would appreciate your help!
The ismember function may be what you're looking for, along with the () and : operators to extract columns from an array.
% Map rows in X to rows in A
[tf,loc] = ismember(X(:,[3 4]), A(:,[1 2]), 'rows');
% Grab the corresponding value from A
rslt = A(loc, 3);
Now you have a logical vector tf that indicates for each row in X whether it was found in A, and loc, which holds the corresponding indexes in to the rows of A for the ones that matched. Then you use those indexes to index in to A to pull out the "value" or dependent variable columns. These are vectorized operations, so it'll be faster than doing it with loops and find().
Read through the documentation for ismember, unique, paren, and the functions they reference to get more background on Matlab's functions for doing recordwise searching like this.

How to fill a matrix using an equation in MATLAB?

I have a matrix A of arbitrary dimensions m x n and wish to fill it using an equation, for example, for every element a_ij of A, i = 1,...,m and j=1,...,n, I would like,
a_ij = i^2 + j^2.
In Matlab filled out manually it would appear similar to this,
A = [1^2+1^2, 1^2+2^2, ..., 1^2+j^2, ..., 1^2+n^2;
2^2+1^2, 2^2+2^2, ..., 2^2+j^2, ..., 2^2+n^2;
.
.
.
i^2+1^2, i^2+2^2, ..., i^2+j^2, ..., i^2+n^2;
.
.
.
m^2+1^2, m^2+2^2, ..., m^2+j^2, ..., m^2+n^2]
and so the first few terms would be:
[2, 5, 10,17,...
5, 8, 13,20,...
10,13,18,25,...
17,20,25,32,...
]
bsxfun based solution -
A = bsxfun(#plus,[1:m]'.^2,[1:n].^2)
bsxfun performs array expansion on the singleton dimensions (i.e. dimensions with number of elements equal to 1) and performs an elementwise operation specified by the function handle
which would be the first input argument to a bsxfun call.
So for our case, if we use a column vector (mx1) and a row vector (1xn), then with the listed bsxfun code, both of these vectors would expand as 2D matrices and would perform elementwise summation of elements (because of the function handle - #plus), giving us the desired 2D output. All of these steps are executed internally by MATLAB.
Note: This has to be pretty efficient with runtime performance, as bsxfun is well-suited for these expansion related problems by its very definition as described earlier.
An alternative using ndgrid:
[I, J] = ndgrid(1:m, 1:n);
A = I.^2 + J.^2;

Use a vector as an index to a matrix

I'm writing a MATLAB function to read out data into an n-dimensional array (variable dimension size). I need to be able to access a specific point in the Matrix (to write to it or read it, for example), but I don't know ahead of time how many indexes to specify.
Currently I have a current_point vector which I iterate through to specify each index, and a max_points vector which specifies the size of the array. So, if for example I wanted a 3-dimensional array of size 1000-by-15-by-3, max_points = [1000 15 3], and current_point iterates from [1, 1, 1] to [1000, 15, 3] ([1, 1, 1] -> [1000, 1, 1] -> [1, 2, 1] -> [1000, 2, 1] ->...). What I'd like to be able to do is feed current_point as an index to the matrix like so:
output_matrix(current_point) = val
But apparently something like output_matrix([1 2 3]) = val will just set outputmatrix(1:3) = 30. I can't just use dummy variables because sometimes the matrix will need 3 indexes, other times 4, other times 2, etc, so a vector of variable length is really what I need here. Is there a simple way to use a vector as the points in an index?
Using the function sub2ind to create a linear index is the typical solution to this problem, as shown in this closely-related question. You could also compute a linear index yourself instead of calling sub2ind.
However, your case may be simpler than those in the other questions I linked to. If you're only ever indexing a single point with your current_point vector (i.e. it's just an n-element vector of subscripts into your n-dimensional matrix), then you can use a simple solution where you convert current_point to a cell array of subscripts using the function num2cell and use it to create a comma-separated list of indices. For example:
current_point = [1 2 3 ...]; % A 1-by-n array of subscripts
subCell = num2cell(current_point); % A 1-by-n cell array of subscripts
output_matrix(subCell{:}) = val; % Update the matrix point
The operation subCell{:} creates the equivalent of typing subCell{1}, subCell{2}, ..., which is the equivalent of typing current_point(1), current_point(2), ....
I know it is too late but for anybody who will find this topic. the easiest way that work for me is to use: diag(A (x(:),y(:)) );
unfortunately this works only if you need to get values from the matrix, not for changing values
You can use the sub2ind function to get the linear index from the subscript.
Example:
A=magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
selectElement={2,3}; %# get the element at position 2,3 in A.
indx=sub2ind(size(A),selectElement{:});
A(indx)
ans =
10
In the above example, I've stored the subscripts (can be any number of dimensions) as a cell. If you have it stored as a vector, simply use num2cell() to convert it to a cell.
You can now easily assign a value to this as A(indx)=value;. I've used different variables than yours to keep the answer general, but the idea is the same and you just need to replace the variable names.
You also mentioned in your post that you're looping from (1,1,1) till some value, (1000,15,3) and assigning a value to each of these points. If you're looping along the columns, you can replace this entire operation with a vectorized solution.
Let finalElement={1000,15,3} be the final step of the loop. As before, find the linear index as
index=sub2ind(size(A),finalElement{:});
Now if you have the values you assign in the loop stored as a single vector, values, you can simply assign it in a single step as
A(1:index)=values;