I wanted to know if there is a efficient way using MATLAB vectorization to generate a specific matrix from two vectors.
Suppose the vectors are
x = [u v]
y = [a1 a2 a3 b1 b2 b3]
where u, v, a1, a2, a3, b1, b2, b3 are some real numbers.
The 2-column matrix that I wish to generate using these vectors is
M = [u a1;
u a2;
u a3;
v a1;
v a2;
v a3;
u b1;
u b2;
u b3;
v b1;
v b2;
v b3]
In general, the length of x can be anything and the length of y is multiple of 3. Here is the code that I have now, but I think there should some better way (that possibly avoids the use of for-loop):
M = [];
Y = reshape(y, 3, []);
for j = 1:size(Y, 2)
[a, b] = meshgrid(x, Y(:, j));
L = [a(:) b(:)];
M = [M; L];
end
A solution using repmat and repelem :
M = [repmat(repelem(x(:),3),numel(y)/3,1) , ...
reshape(repmat(reshape(y,3,[]),numel(x),1),[],1)];
you have a pretty strange order in M. Is that order important? if not, or if you are happy to fix the order later yourself I have two solutions:
1) code
[a,b] = meshgrid(x,y);
M = [a(:) b(:)]
will give you:
M = [
u a1
u a2
u a3
u b1
u b2
u b3
v a1
v a2
v a3
v b1
v b2
v b3]
and
2) code M = combvec(x, y)' gives you:
M = [
u a1
v a1
u a2
v a2
u a3
v a3
u b1
v b1
u b2
v b2
u b3
v b3]
I would like to seek y particular of ODE y'' - y' - 2y = 4x^2
I made the following script:
syms x A0 A1 A2
ypa = A2*x^2+A1*x+A0; % y_p assume
cyp = diff(ypa,2) - diff(ypa) - 2*ypa % according to ODE
P1 = 4*x^2; P2 = cyp ; % Equating P1 and P2
C = coeffs(P1 - P2,x);
A0 = solve(C(1),A0)
A1 = solve(C(2),A1)
A2 = solve(C(3),A2)
I got the correct answer for A2 = -2. But I did not get for A0 (should be -3) and A1 (should be 2). How to get them automatically?
P.S I'm using MATLAB R2013a.
Instead of calling solve 3 times, once on each equation of C, you should call it once on the entire system of equations so that the proper substitutions are done to give you a numeric result for each variable:
>> [A0, A1, A2] = solve(C)
A0 =
-3
A1 =
2
A2 =
-2
I'm trying to calculate Euler-Lagrange equations for a robotic structure.
I'll use q to indicate the vector of the joint variables.
In my code, I use
syms t;
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
to declare that q1 and q2 depend on time t.
After I calculate the Lagrangian L (in this case it is a simple link with a rotoidal joint)
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
The problem is that when I try to differentiate L respect to q using diff(L, q), I get this error
Error using sym/diff (line 69)
The second argument must be a variable or a nonnegative integer specifying the number of differentiations.
How can I differentiate L respect to q to have the first term of the Euler-Lagrange equation?
I also tried to write q simply as
syms q1 q2
q = [q1 q2]
without the time dependency but differentiation will not work, i.e. will obviously give me [0, 0]
That's what I've got in the workspace (I1z is the inertia of the link respect to z-axis, M1 is the mass of the link, L1 is the length of the link)
q = [q1(t), q2(t)]
diff(q, t) = [diff(q1(t), t), diff(q2(t), t)]
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
If you want to run the full code, you have to download all the .m files from here and then use
[t, q, L, M, I] = initiate();
L = lagrangian(odof(q, L), q, M, I, t, 1)
otherwise the following code should be the same.
syms t I1z L1 M1
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
qp = diff(q, t);
L = (I1z*qp(1)^2)/2 + (L1^2*M1*qp(1)^2)/8;
EDIT
Thanks to AVK's answer I realized the problem.
Example 1 (AVK's code)
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt = [diff(L,q1t), diff(L,q2t)]
This will work and its result will be
dLdqt = [(M1*q1t*L1^2)/4 + I1z*q1t, 0]
Example 2 (wrong)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = diff(L, qt)
This will not work, because diff expects a single variable of differentiation
Example 3 (right)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = jacobian(L, qt)
This will work, because jacobian expects at least a variable of differentiation
EDIT 2
Seems that MATLAB's Symbolit Toolbox can't handle differentiation with respect to q(t), so you have to use the variable q.
So using these as functions
q = [q1(t), q2(t), q3(t), q4(t), q5(t), q6(t)]
qp = [diff(q1(t), t), diff(q2(t), t), diff(q3(t), t), diff(q4(t), t), diff(q5(t), t), diff(q6(t), t)]
and these as variables
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
solved the problem.
The whole code will looks like this
syms q1 q2 q3 q4 q5 q6;
syms q1p q2p q3p q4p q5p q6p;
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
Lagv = subs(Lag, [q, qp], [qv, qvp]);
dLdq = jacobian(Lagv, qv);
dLdqp = jacobian(Lagv, qvp);
dLdq = subs(dLdq, [qv, qvp], [q, qp]);
dLdqp = subs(dLdqp, [qv, qvp], [q, qp]);
m_eq = diff(dLdqp, t) - dLdq;
If you want to differentiate L with respect to q, q must be a variable. You can use subs to replace it with a function and calculate
later:
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt= [diff(L,q1t), diff(L,q2t)]
dLdq = [diff(L,q1), diff(L,q2)]
syms q1_f(t) q2_f(t) % functions
q1t_f(t)= diff(q1_f,t)
q2t_f(t)= diff(q2_f,t)
% replace the variables with the functions
dLdq_f= subs(dLdq,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
dLdqt_f= subs(dLdqt,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
% now we can solve the equation
dsolve(diff(dLdqt_f,t)-dLdq_f==0)
I developed the Euler-Lagrange Library in MATLAB, with a list of illustrative examples. you can download it using the following link:
https://www.mathworks.com/matlabcentral/fileexchange/86563-matlab-euler-lagrange-library
I have groups of scalars and two groups of vectors respertively:
w1, w2... wn
b1, b2... bn
c1, c2... cn
w1, w2... wn are scalars and stored in w,
b1, b2... bn stored in B and
c1, c2... cn stored in C. How efficiently get
w1*(b1*c1') + w2*(b2*c2') + ... + wn*(bn*cn')
Where bi and ci are vectors but bi*ci' is matrix, not a scalar?
Sizes: 1 x N for w, P x N for B and Q x N for C. wi = w(i), bi = B(:, i) and Ci = C(:, i)
Simply:
result = B*diag(W)*C';
If N is much bigger than P and Q, you might prefer to compute the weight matrix diag(W) in its sparse form with spdiags(W', 0, N, N) instead.
I have a module that takes three inputs, each of which is three bits wide.
output = f(inputA, inputB, inputC)
The output depends on the values of the three inputs but does not depend on their order.
i.e. f(inputA, inputB, inputC) = f(inputB, inputC, inputA)
The solution should work well for both FPGAs and ASICs. Currently I am implementing it without taking advantage of the symmetry, but I assume that explicitly forcing the synthesizer to consider the symmetry will result in a better implementation.
I am planning on implementing this using a hash, h, of the three inputs that does not depend on their order. I can then do:
hash <= h(inputA, inputB, inputC);
output <= VALUE0 when hash = 0 else
VALUE1 when hash = 1 else
.....
My question is what should I use for the hash function?
My thoughts so far:
If each input is 3 bits wide there are 512 possibilities, but only 120 when you consider the symmetry, so theoretically I should be able to use a hash that is 7 bits wide. Practically it may need to be longer.
Each bit of the hash is a function of the input bits and must respect the symmetry of the three inputs. The bits of the hash should be independent from one another. But I'm not sure how to generate these functions.
As mentioned in your question, you could sort and concatenate your inputs.
In pseudo code:
if (A < B)
swap(A, B);
if (B < C)
swap(B, C);
if (A < B)
swap(A, B);
As block diagram:
The 6-in/6-out function needed for a "conditional swap" block:
A3x = A3 B3 ;
A2x = A3 B3' B2 + A3' A2 B3 + A2 B2 ;
A1x = A2 B3' B2' B1 + A3' A2' A1 B2 + A3 A2 B2' B1
+ A2' A1 B3 B2 + A3 B3' B1 + A3' A1 B3 + A1 B1;
B3x = B3 + A3 ;
B2x = A3' B2 + A2 B3' + B3 B2 + A3 A2 ;
B1x = A3' A2' B1 + A1 B3' B2' + A2' B3 B1 + A3 A1 B2'
+ A3' B2 B1 + A2 A1 B3' + A3' B3 B1 + A3 A1 B3'
+ B3 B2 B1 + A3 A2 A1 ;
I have to admit that this solution is not exactly "cheap" and results in a 9-bit hash rather than in a 7-bit hash. Therefore, a look-up table might in fact be the best solution.