I have a 2 column vector with different lengths y1 and y2. I want to mixed them together in one matrix.
This matrix should have y1 and y2 as a rows, but they have different lengths. Is it possible to add 0 to shorter vector that it has the same length as longer one?
Many ways to do this, here is one:
>> y1 = [1;2;3;4;5];
>> y2 = [7;8;9];
>> z = zeros(2, max(length(y1), length(y2)));
>> z(1, 1:length(y1)) = y1;
>> z(2, 1:length(y2)) = y2
z =
1 2 3 4 5
7 8 9 0 0
vec2mat does that easily:
vec2mat([y1; y2], max(numel(y1), numel(y2)))
Related
I want to use solve() to solve a large system of linear equations. The solve() function needs equations and variables. I use a loop to generate the equations and my variables are contained in a large array. This is a simple code of what I am trying to do:
x = sym('x',[1 3])
eqn = sym('eqn', [1,3])
eqn1 = 2*x1 + x2 + x3 - 2 == 0
eqn2 = 2*x2 -x2 -x1- x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
Y = solve(eqn, x)
MATLAB does not recognize my variable x1. I have solved the same system using the following code:
syms x1 x2 x3
eqn1 = 2*x1 + x2 + x3 == 2
eqn2 = 2*x2 -x2 -x1 - x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
X = solve([eqn1, eqn2, eqn3, eqn4], [x1 x2 x3])
structfun(#subs,X)
But this is useless for a very large number of equations. What am I doing wrong?
You don't need symbolic (syms) for that. This is a standard linear system of equations that can be represented as:
Ax = b where A = [2 1 1; -1 1 -1; 1 2 3], x = [x1; x2; x3] and b = [0; 3; -10]
To solve for x, you would first define
A = [2 1 1; -1 1 -1; 1 2 3]
and
b = [0; 3; -10]
and then solve using
x = A\b
PS. There are some odd things in your question, eg. in eq.2 eqn2 = 2*x2 -x2 -x1- x3 == 3 I assume you omitted simplying this to -x1 +x2 -x3 ==3.
PS2. This is pretty standard Matlab, you can find a lot of info under the standard mldivide page in the documentation along with a lot similar questions here on SO.
I have an array of matrix m such that
m1 = [1 2;3 4];
m2 = [2 7; 8 9];
m3 = [9 7; 8 91];
m = [m1 m2 m3]
m =
1 2 2 7 9 7
3 4 8 9 8 91
I also have a vector
v = [1 2 3];
such that i want the operations between v and m result in h such that
h = [1*m1 2*m2 3*m3] = [h1 h2 h3];
I imagine I have to do this in 3-dimensional array for h, which is a 3d array. Or maybe there are better ways.
Let A be a simple 2 by 2 matrix, rand(2,2).
From h i want to extract h1 h2 and h3 out(or better not doing any extraction) and perform operations to A such that
1.
h1*A*h1'
h2*A*h2'
h3*A*h3'
and
2.
h1*h1', h2*h2', h3*h3'.
Why i want to do this in array is because i have a lot of matrix mi so I want to avoid for loop by vectorization.
From what i could understand from the question, i suppose element-wise multiplication would be better choice. You would just have to use proper concatenation and repeatation of matrices.
m1 = [1 2; 3 4];
m2 = [2 7; 8 9];
m3 = [9 7; 8 91];
% Concatenate to create 3D matrix
m = cat(3,m1,m2,m3);
v = [1 2 3];
% Create similar 3D matrix
v1 = cat(3,ones(size(m1))*v(1),ones(size(m2))*v(2),ones(size(m3))*v(3));
% Simple element wise multiplication
h = m.*v1;
% Creating a repeated 3D matrix A, repetation is along third dimension
A = repmat(rand(2,2),[1 1 3]);
% Outputs
op_1 = h.*A.*permute(h,[2 1 3]);
op_2 = h.*permute(h,[2 1 3]);
I am a bit new in using Matlab, and I have a question about defining a multivariable function for vector input.
If the function is a single function, say f(t), I know how to make it for vector input. The general way is to use arrayfun after defining a f(t). How about for multivariable function, say f(x,y)? What I want to do is to get two inputs, say [1 2 3] for x and [4 5 6 7] for y (dimension may be different, but both of them are either column vector or row vector) so that I can calculate to give
[f(1,4),f(1,5),f(1,6),f(1,7);
f(2,4),f(2,5),f(2,6),f(2,7);
f(3,4),f(3,5),f(3,6),f(3,7)]
The difficulty is that the vector input for x and y may not be in the same dimension.
I understand it may be difficult to illustrate if I do not have an example of f(x,y). For my use of f(x,y), it may be very complicated to display f(x,y). For simplicity, treat f(x,y) to be x^2+y, and once defined, you cannot change it to x.^2+y for vector inputs.
Here is a set of suggestions using ndgrid:
testfun = #(x,y) x^2+y; % non-vectorized form
x = 1:3;
y = 4:7;
[X,Y] = ndgrid(x,y);
% if the function can be vectorized (fastest!):
testfun_vec = #(x,y) x.^2+y; % vectorized form
A = testfun_vec(X,Y);
% or without ndgrid (also super fast):
B = bsxfun(testfun_vec,x.',y); % use the transpose to take all combinations
% if not, or if it's not bivariate operation (slowest):
C = arrayfun(testfun,X(:),Y(:));
C = reshape(C,length(x),length(y));
% and if you want a loop:
D = zeros(length(x),length(y));
for k = 1:length(X(:))
D(k) = testfun(X(k),Y(k));
end
Which will output for all cases (A,B,C and D):
5 6 7 8
8 9 10 11
13 14 15 16
As mentioned already, if you can vectorize your function - this is the best solution, and if it has only two inputs bsxfun is also a good solution. Otherwise if you have small data and want to keep your code compact use arrayfun, if you are dealing with large arrays use an un-nested for loop.
Here is the code using for loops and inline functions:
x = [1 2 3];
y = [4 5 6 7];
f = #(x,y) x^2 +y;
A = zeros(length(x), length(y));
for m = 1:length(x)
for n = 1:length(y)
A(m, n) = f(x(m), y(n));
end
end
disp(A);
Result:
A =
5 6 7 8
8 9 10 11
13 14 15 16
>> x = [1 2 3];
>> y = [4 5 6 7];
>> outValue = foo(x, y);
>> outValue
outValue =
5 6 7 8
8 9 10 11
13 14 15 16
Make this function:
function out = foo(x, y)
for i = 1 : length(x)
for j = 1 : length(y)
out(i, j) = x(i)^2 + y(j);
end
end
I have 4 known (corner) values of an matrix:
grid = [2 5
5 8];
This values are my corners and I want to interpolate between them, that I get a non-squared matrix, e.g. a 350x250 matrix.
I searched some familiar questions but I couldnt find a solution or wasnt able to transfer it to my problem. I found the interp2 function but not how to tell that I only have the 4 corner values?
I made an easy example to show what I need and what doesnt work (or what I am doing wrong):
test = [2 0 0 0 8
0 0 0 0 0
6 0 0 0 12 ];
[X, Y] = meshgrid(1:5,1:3);
M = interp2(X,Y,test,X,Y);
The resulting matrix is exactly the same as the input matrix test. How can I interpolate the zeros? In general my Input is only this:
grid = [2 8; 6 12];
After long thinking I found a solution:
x = 350;
y = 250;
V = [2 8
6 12];
[X, Y] = meshgrid(1:2,1:2);
a = linspace(1,2,x);
Xq = a(ones(1,y),:); % oder repmat([1 n], y);
b = linspace(1,2,y)';
Yq = b(:,ones(1,x));
M = interp2(X,Y,V,Xq,Yq);
I hope it helps anybody who has the same problem, I didnt understood that the final size is only in the last two parameters present.
I want to define a symbolic vector in Matlab, but every element of the vector should be created through a symbolic function.
Let's say f(x)=x^2 is my function and I have a vector A=[1 2 3 4 5]. I want to create a symbolic vector so that it is going to be like this;
Symbolic_vector=[x^2 2*x^2 3*x^2 4*x^2 5*x^2]
How can I realize this ?
So far I have
A=[1 2 3 4 5];
syms x;
m = sym('m', [1 100]);
f = sym('x^2*m');
f = subs(f, m, A);
One way to do this and keep things symbolic is
A = sym('[1 2 3 a 5]');
f = #(x) x.^2;
B = f(A);
% results in B = [1 4 9 a^2 25]
You can also do directly
B = A.^2;
syms a;
A = [1 2 3 a 5];
B = A.^2;
I hope this helps.