MATLAB matrix replacement assignment gives error - matlab

I tried to update some part of a matrix, I got the following error message:
??? Assignment has fewer non-singleton rhs dimensions than non-singleton subscripts
My code tries to update some values of a matrix that represent a binary image. My code is as follows:
outImage(3:5,2:4,1) = max(imBinary(3:5,2:4,1));
When I delete last parameter (1), this time I get the same error. I guess there is a mismatch between dimensions but I could not get it. outImage is a new object that is created at that time (I tried to create it before, but nothing changed). What may be wrong?

You mention in one of your comments on another answer that you are trying to create your own dilation algorithm, and therefore want to take the maximum value in a 3-by-3-by-1 submatrix and replace the values in that submatrix with the maximum value. The function MAX will by default operate along the columns of your submatrix, which will give you a 1-by-3 matrix (i.e. the maximum values of the columns of your 3-by-3-by-1 matrix). The error results because MATLAB can't assign a 1-by-3 matrix to a 3-by-3-by-1 matrix.
One solution is to call MAX again on your 1-by-3 matrix to get a scalar value, which you can then assign to each element of your 3-by-3-by-1 submatrix without error:
outImage(3:5,2:4,1) = max(max(imBinary(3:5,2:4,1)));

On the rhs of your equation you take the max of a 3x3x1 sub-matrix, which returns a 1x3 vector. You then try to assign this to a 3x3x1 sub-matrix. A singleton subscript is one with the value 1. So the rhs has 1 non-singleton subscript, and the lhs has 2. Matlab can't figure out how to expand a 1x3 matrix to fill a 3x3x1 space.
I'm not entirely sure what you want to do, so I won't guess a solution. Do you want to make 3 copies of the rhs and put one into each row of the sub-matrix on the lhs ? Or are you trying to construct a 3x3x1 matrix on the rhs ?

Do you want to fill all indexed elements in outImage by maximum value for each column of rhs expression? You can expand the row you get on rhs with REPMAT:
outImage(3:5,2:4,1) = repmat(max(imBinary(3:5,2:4,1)),3,1)
outImage(3:5,2:4) works as well.

I got the same error before, and what I have done was defining the left hand matrix before. I don't know if you have the same case but you can try the following:
outImage=Zeros(M,N,K);
M, N, and K are the dimensions that you have. Then just type:
outImage(3:5,2:4,1) = max(max(imBinary(3:5,2:4,1)));

Related

How to plot a function with an exponential multiplied by a sine function?

Hello I need help plotting the below equation in matlab.
v=10.0004+10.229*e^(-3*t)*sin(5.196*t-257.856)
here is what I have but I keep getting an error:
t=[0:0.1:2];
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
plot(t,v)
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the
number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
Error in example (line 2)
v=10.0004+10.229*exp(t)*sin(5.196*t+257.856);
Because t is a matrix, you cannot simply input it as you would a single variable. You have to access each value individually and calculate a corresponding v, then you store that value and move on. Rinse and repeat for each value.
This can be visualized with a for loop. Get the length of your time variable, which will determine how many values you need to calculate, then let the loop run for the corresponding number of elements. Make sure the loop counter is also used to index each element in v.
t = 0:0.1:2 ;
%For each element (n) in t, create a corresponding one of v.
for n = 1:length(t)
v(n) = 10.0004+10.229*exp(t(n))*sin(5.196*t(n)+257.856);
end
plot(t,v)
As we can interpret from the loop, there is a need to do element-wise (good keyword to remember) multiplication. In other languages, you might HAVE to use the loop method. Luckily in Matlab there is a dedicated operator for this '.*'. Therefore in Matlab you could simply modify your code as follows:
t=[0:0.1:2];
v=10.0004+10.229.*exp(t).*sin(5.196.*t+257.856);
plot(t,v)
Either method gives you the desired plot. The first I included to illustrate the underlying logic of what you're looking to do, and the second to simply it with Matlab's syntax. Hope this helps guide you in the future.
Best of luck out there.

matlab looping through rows of matrix non-singleton rhs dimensions

I made an empty array and want to loop through each row:
theta = zeros(500,20);
for i=1:100
...
y = x*theta(i,:)';
...
end
So for each i I want to use the ith row vector, but I'm getting errors saying that "Assignment has more non-singleton rhs dimensions than non-singleton subscripts"
We can't answer this question without knowing what x is in this scenario. Please update this with the definition of your x variable.
If you're multiplying two vectors together the matrix dimensions must agree, unless x is just a singular value. I can't replicate your error when I run the code, arbitrarily defining x.

How can I use NxM matrix to be my initial condition in `pdepe`

I solved a PDE using Matlab solver, pdepe. The initial condition is the solution of an ODE, which I solved in a different m.file. Now, I have the ODE solution in a matrix form of size NxM. How I can use that to be my IC in pdepe? Is that even possible? When I use for loop, pdepe takes only the last iteration to be the initial condition. Any help is appreciated.
Per the pdepe documentation, the initial condition function for the solver has the syntax:
u = icFun(x);
where the initial value of the PDE at a specified value of x is returned in the column vector u.
So the only time an initial condition will be a N x M matrix is when the PDE is a system of N unknowns with M spatial mesh points.
Therefore, an N x M matrix could be used to populate the initial condition, but there would need to be some mapping that associates a given column with a specific value of x. For instance, in the main function that calls pdepe, there could be
% icData is the NxM matrix of data
% xMesh is an 1xM row vector that has the spatial value for each column of icData
icFun = #(x) icData(:,x==xMesh);
The only shortcoming of this approach is that the mesh of the initial condition, and therefore the pdepe solution, is constrained by the initial data. This can be overcome by using an interpolation scheme like:
% icData is the NxM matrix of data
% xMesh is an 1xM row vector that has the spatial value for each column of icData
icFun = #(x) interp1(xMesh,icData',x,'pchip')';
where the transposes are present to conform to the interpretation of the data by interp1.
it is easier for u to use 'method of line' style to define different conditions on each mesh rather than using pdepe
MOL is also more flexible to use in different situation like 3D problem
just saying :))
My experience is that the function defining the initial conditions must return a column vector, i.e. Nx1 matrix if you have N equations. Even if your xmesh is an array of M numbers, the matrix corresponding to the initial condition is still Nx1. You can still return a spatially varying initial condition, and my solution was the following.
I defined an anonymous function, pdeic, which was passed as an argument to pdepe:
pdeic=#(x) pdeic2(x,p1,p2,p3);
And I also defined pdeic2, which always returns a 3x1 column vector, but depending on x, the value is different:
function u0=pdeic2(x,extrap1,extrap2,extrap3)
if x==extrap3
u0=[extrap1;0;extrap2];
else
u0=[extrap1;0;0];
end
So going back to your original question, my guess would be that you have to pass the solution of your ODE to what is named 'pdeic2' in my example, and depending on X, return a column vector.

Assign value to column in matlab

In matlab if
a = zeros(1,2); b= ones(2,1) then it is wrong a+b;
but X=zeros(2,2), X(:,1)=a works well, why?
Good question. The exact answer can be found on the Matlab site, right near the bottom of the page:
Indexing on Assignment When assigning values from one matrix to
another matrix, you can use any of the styles of indexing covered in
this section. Matrix assignment statements also have the following
requirement.
In the assignment A(J,K,...) = B(M,N,…), subscripts J, K, M, N, etc.
may be scalar, vector, or array, provided that all of the following
are true:
The number of subscripts specified for B, not including trailing
subscripts equal to 1, does not exceed ndims(B).
The number of
nonscalar subscripts specified for A equals the number of nonscalar
subscripts specified for B. For example, A(5, 1:4, 1, 2) = B(5:8) is
valid because both sides of the equation use one nonscalar subscript.
The order and length of all nonscalar subscripts specified for A
matches the order and length of nonscalar subscripts specified for B.
For example, A(1:4, 3, 3:9) = B(5:8, 1:7) is valid because both sides
of the equation (ignoring the one scalar subscript 3) use a 4-element
subscript followed by a 7-element subscript.
When you look at your example, it follows the last point in the above: although you are assigning to X(:,2) which is a 2x1 column vector, and the right hand side is a 1x2 row vector, the rule "order and length of all non scalar subscripts specified for A matches the order and length of non scalar subscripts specified for B".
Note that the same is not true when you want to add two matrices - in that case, they actually need to be of exactly the same shape (so you can't add a 2x1 and a 1x2 matrix, even though both have two elements).
With "X(:,1)=b", you are asking MATLAB to copy the values of the column vector b to the first column of X. b has two rows, and so does X. So the value assignment works.
As for "a+b", matrix-matrix addition requires exact match of dimensions.

Multiplying complex matrices

I'm trying to multiply two complex matrices (b+c*i), but I'm getting no results.
??? Error using ==> mtimes
Inner matrix dimensions must agree.
Error in ==> impedancaZ at 14
l=mtimes(R1,h)
I don't understand this error, as matrix dimension are the same (2 coluoms and 9 rows)
Can you help me?
Inner matrix dimensions must agree means that the inner dimensions of the matrices must match. If the first matrix has dimensions 2x9, then the second would need to be 9x(something). that's just basic liner algebra/matrix multiplication. In that case, you'll need to figure out what the second array should be. Maybe it's the transpose of what you expect it to be; instead of x*y, you might want x*y' (see the "prime" marker after the y?
Alternatively, maybe you want a "scalar multiply" rather than a "matrix multiply" for this. That is, you don't want to multiply the matrices x and y in the "linear algebra" sense, but you just want to multiply the elements of the arrays, element by element. In that case, you'd do x.*y (see the dot before the *?).
Unfortunately, I can't tell which is really correct for your situation without more context. You'll either have to supply some more information or figure it out yourself from the hints I've given.