How to fix "matrix dimensions must agree" error
4 views (last 30 days)
Walter Roberson on 6 Sep 2022
That is a row vector
That is a row vector pasted on top if itself. The result is two identical rows the same length as t, which is acceptable to MATLAB.
s is a symbolic scalar, t is a row vector, Q is a row vector the same length as t, which is fine.
row vector pasted on top of a row vector the same length, giving two rows and length(t) columns, which is acceptable to MATLAB.
psi1=[1 2*t; 3*t 1]
The way this  operator works is that MATLAB first picks out the corresponding columns, and proceeds to use the vertcat() operation for each column. Then it proceeds to horzcat() together the resulting columns.
So we have to isolate the corresponding columns. It starts with [1; 3*t] and then does [2*t; 1] and then  those two together, as if you had written [[1;3*t], [2*t, 1]]
But... t is a row vector and 1 is a scalar, so 1 has a different number of columns as 3*t has, which is going to give you an error.
If you were to write
psi1=[[1 2*t]; [3*t 1]]
then that would create a row vector of length 1 + length(t) fo the top, and a row vector of the same length for the bottom, and then would horizontally paste the two together, which would be acceptable since the two would have the same length.
eta would be two rows both length(t), so a 2 x length(t) array. Y0 would then be the same size.
[t, Y]=ode45(@(t,Y) psi1*Y + B*u1 + Y,Tspan,Y0);
As explored above, Y0 is eta is 2 x length(t) . But
Initial conditions, specified as a vector. y0 must be the same length as the vector output of odefun, so that y0 contains an initial condition for each equation defined in odefun.
So passing in a 2D array of y0 would not be permitted.
If you were to
[t, Y]=ode45(@(t,Y) psi1*Y + B*u1 + Y,Tspan,Y0(:));
then the Y received and used in the computation would be a vector with 2 * length(t) elements. You want to do matrix multiplication with psi1 which, as explored above, might be 2 rows and 1 + length(t) columns. You could consider reshaping the Y, but unless you are trying to match up the dimension of length 2 and produce length(t) by (length(t)+1) as the output array, you have a problem.
Reminder that the function you calculate must return a column vector.
psi1 has 2 rows. If psi1*Y were somehow successful, returning 2 rows and some number of columns, then the result would have to be added to Y or some reshaped version of it, and the result would have to be a column vector...
Your problems are most easily explained if instead of processing a vector of t values, that you are instead mentally having it calculate with a scalar t at any time, with it somehow repeating for additional t values.
Would it be possible to vectorize the calculation over all t? Yes, it would. I suspect the solution would require creating psi1 as a block-diagonal matrix though.
More Answers (1)
Bjorn Gustavsson on 6 Sep 2022
Whe you run into problems like this you will have to learn to use the debug-capabilities of matla. Do this at the command-line:
>> dbstop in try1
This will give you the possibility to run the script line by line and inspect each variable after you've run each line at the debug-prompt. You will also be able to plot the variables, and try different combinations of transposes to see/learn which matrix dimensions should match in each operation.
We could tell you exactly what correction to make - but you learning this (tedious) procedure of investigating why how and WHY! you get different errors and unexpected behaviour will be more valuable to you even in the medium-term perspective.