Solving for the coefficent of linear equations with one known coefficent - matlab

clc;
clear all;
syms y a2 a3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% [ 0.5 0.25 0.125 ] [ a2 ] [ y ]
% [ 1 1 1 ] [ a3 ] = [ 3 ]
% [ 2 4 8 ] [ 6 ] [ 2 ]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
M = [0.5 0.25 0.125; 1 1 1; 2 4 8];
t = [a2 a3 6];
r = [y 3 2];
sol = M * t'
s1 = solve(sol(1), a2) % solve for a2
s2 = solve(sol(2), a3) % solve for a3
This is what I have so far.
These are my output
sol =
conj(a2)/2 + conj(a3)/4 + 3/4
conj(a2) + conj(a3) + 6
2*conj(a2) + 4*conj(a3) + 48
s1 =
- conj(a3)/2 - 3/2 - Im(a3)*i
s2 =
- conj(a2) - 6 - 2*Im(a2)*i
sol looks like what we would have if we put them back into equation form:
0.5 * a2 + 0.25 * a3 + 0.125 * a4
a2 + a3 + a4 = 3
2*a2 + 4*a3 + 8*a4 = 2
where a4 is known == 6.
My problem is, I am stuck with how to use solve to actually solve these equations to get the values of a2 and a3.
s2 solve for a3 but it doesn't match what we have on paper (not quite).
a2 + a3 + 6 = 3 should yield a3 = -3 - a2.
because of the imaginary. Somehow I need to equate the vector solution sol to the values [y 3 2] for each row.

You need to provide solve function with an equation. Just as simple as that:
sol = solve(M * t' == r');
As a result you have
sol.a2 = 17
sol.a3 = -20
sol.y = 17/4
This works for MATLAB R2012b. In general this can be solved just in one line:
solve('a2 / 2 + a3 / 4 - y + 3 / 4 = 0', 'a2 + a3 + 3 = 0', '2 * a2 + 4 * a3 + 46 = 0')
P.S. I have checked, this works for MATLAB R2011b.

Related

matlab system of equations with one unchanging solution ('q')

I am trying to solve a model of 4 equations, where everything is real. It is essentially a pipe branch problem with "1" being upstream of the pump (with some head on it), and "2" and "3" are downstream w/o head. The units are English.
Anyway, I'm just solving the system of 4 equations and 4 unknowns and looking at a plot of head (ha) vs. total flow rate (Q1). Across this space though I only am collecting points in a vertical line, i.e. the head changes but the flowrate doesn't.
I was thinking the problem may be some variables are being held onto, but I treat "ha" the same as "Q1" so that doesn't seem likely... Realistically, this is matching a system curve to a pump curve, and of course that point moves when the system changes (both flowrate and head), so it seems I am doing something wrong....
Here is the script:
clear sol1 sol2 sol3 sol4 S q h
clc; clearvars; close all;
syms Q1 Q2 Q3 ha
D1 = 1.25/12; Z1 = 0; P1 = 62.4*10; A1 = pi*(1/4)*D1*D1; f1 = 0.011; L1 = 50;
D2 = 0.5/12; Z2 = 25; P2 = 0; A2 = pi*(1/4)*D2*D2; f2 = 0.011; L2 = 100; %V2 = Q2 / A2;
D3 = 0.5/12; Z3 = 10; P3 = 0; A3 = pi*(1/4)*D3*D3; f3 = 0.011; L3 = 100; %V3 = Q3 / A3;
gamma = 62.468;
origPumpData = [0 150; 0.4 148; 0.8 145; 1.2 143; 1.6 141; 2 139; 2.4 138; 2.8 136; 3.2 134; 3.6 132; 4 130; 4.4 128; 4.8 127; 5.2 125; 5.6 124; 6 121; 6.4 118; 6.8 117; 7.2 115; 7.6 113; 8 111; 8.4 110; 8.8 108; 9.2 106; 9.6 104; 10 102; 10.4 100; 10.8 98; 11.2 97;
11.6 94; 12.0 93; 12.4 91; 12.8 89; 13.2 87; 13.6 86; 14 84; 14.4 82; 14.8 80; 15.2 78; 15.6 76; 16 74; 16.4 72; 16.6 70];
pumpData(:,1) = origPumpData(:,1)/448.8312;
pumpData(:,2) = origPumpData(:,2);
polyFit = fit(pumpData(:,1),pumpData(:,2),'poly2');
assume(in(Q1,'real') & Q1 > 0.0001 & Q1 < 1 );
assume(in(Q2,'real') & Q2 > 0.0001 & Q2 < 1 );
assume(in(Q3,'real') & Q3 > 0.0001 & Q3 < 1 ) ;
assume(in(ha,'real') & ha > 0.0001 & ha < 1000.0);
eq1 = #(Q1) polyFit.p1*Q1*Q1 + polyFit.p2*Q1 + polyFit.p3;
eq2 = #(P1,Z1,F1,Q1,A1,L1,D1,P2,Z2,F2,Q2,A2,L2,D2) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F2,L2,D2,Q2,A2) + ha == P2/gamma + ((Q2/A2)^2)/64.4 + Z2;
eq3 = #(P1,Z1,F1,Q1,A1,L1,D1,P3,Z3,F3,Q3,A3,L3,D3) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F3,L3,D3,Q3,A3) + ha == P3/gamma + ((Q3/A3)^2)/64.4 + Z3;
eq4 = Q1 == Q2 + Q3;
guesses = [0.07116936917086152675558661517184;
0.035125850031368916048762418970837;
0.036043519139492610706824196201003;
303.02361035523126099594683749354];
for i = 1:1:2
disp(i)
disp(Z1)
Z1 = Z1-5
f1 = f1+0.01
f3 = f3 + 0.01
S(i) = vpasolve([eq1(Q1) eq2(P1,Z1,f1,Q1,A1,L1,D1,P2,Z2,f2,Q2,A2,L2,D2) eq3(P1,Z1,f1,Q1,A1,L1,D1,P3,Z3,f3,Q3,A3,L3,D3) eq4], [Q1 Q2 Q3 ha], guesses )
S(i).Q1
S(i).Q2
S(i).Q3
S(i).ha
q(i) = S(i).Q1
h(i) = S(i).ha
guesses = [S(i).Q1 S(i).Q2 S(i).Q3 S(i).ha]'
clear S
end
plot( q, h, '*b');
function hf = hf(f,L,D,Q,A)
hf = f*(L/D)*(1/64.4)*(Q/A)^2;
end
you're solving eq1 == 0(default) and computing Q1, independent of other equations and parameters. that's why you get constant Q1 in every iteration.

how to get number of rows in matlab?

I want to select 2 minimum elements from every column of matrix. How to can display number of row?
input:
a1 a2 a3
--------
b1 2 4 8
b2 8 5 3
b3 1 5 9
output:
a1 a2 a3 a1 a2 a3
-------- ----------
1 4 3 => b3 b1 b2
2 5 8 b1 b2 b1
my code:
for i = 1:3
MINN(:,i)=getNElements(distance(i,:), 1);
end
function [smallestNElements smallestNIdx] = getNElements(A, n)
[ASorted AIdx] = sort(A);
smallestNElements = ASorted(1:n);
smallestNIdx = AIdx(1:n);
end
Let me guess, is this what you want to do?
x = [2 4 8; 8 5 3; 1 5 9]; % data
n = 2; % desired number of smallest values per column
[y, ind] = sort(x,1); % sort each column and get indices of that sorting
y = y(1:n,:); % keep n smallest
ind = ind(1:n,:); % keep their indices
Results:
y =
1 4 3
2 5 8
ind =
3 1 2
1 2 1

Best way to solve an equation in form f(x)=K*u(x)

I am solving an equation of motion, which is described e.g. as
syms u1 u2 f3 f4;
K=magic(4);
f=[2 3 f3 f4];
u=[u1 u2 9 7];
where both f and K include variables.
Which is the easiest or/and most efficient way to do this? I want something like
solution=solve(f==K*u);
and don't know if it's the efficient way.
Your equations are not yet in standard form, yet are reducible to it.
Compute
>> syms u1 u2 f3 f4;
>> K = magic(4);
>> f = [2 3 f3 f4].';
>> u = [u1 u2 9 7].';
>> K*u - f
ans =
16*u1 + 2*u2 + 116
5*u1 + 11*u2 + 143
9*u1 + 7*u2 - f3 + 138
4*u1 + 14*u2 - f4 + 142
In which I altered the formatting for clarity. From this we can see that if we define
b = [-116 -143 -138 -142].';
A = [16 2 0 0
5 11 0 0
9 7 -1 0
4 14 0 -1];
Then we have an equation in standard form
A*X = b
where
X = [u1 u2 f3 f4].'
Then, it is a simple matter of
>> X = A\b
ans =
-5.963855421686747e+000 % u1
-1.028915662650603e+001 % u2
+1.230120481927711e+001 % f3
-2.590361445783132e+001 % f4

Difference between skewness function and skewness formula result

Consider the matrix
c =
1 2
3 4
m = 2;
n = 2;
% mean
% sum1 = uint32(0);
b4 = sum(c);
b5 = sum(b4');
c5 = b5 / ( m * n )
% standard deviation
sum2 = uint32(0);
for i = 1 : m
for j = 1 : n
b = ( double(c(i,j)) - c5 ) ^ 2 ;
sum2 = sum2 + b ;
end
end
sum3 = sum2 / ( m * n );
std_dev = sqrt(double(sum3))
% skewness
sum9 = 0;
for i = 1 : m
for j = 1 : n
skewness_old = ( ( double(c(i,j)) - c5 ) / ( std_dev) )^ 3 ;
sum9 = sum9 + skewness_old ;
end
end
skewness_new = sum9 / ( m * n )
The skewness result is 0
If I use the matlab function skewness,
skewness(c)
c =
1 2
3 4
skewness(c)
ans =
0 0
Why is the function skewness returning two 0's, While the formula returns only one 0
MATLAB function SKEWNESS by default calculates skewness for each column separately. For the whole matrix do skewness(c(:)).

Matlab Vectorization : How to avoid this "for" loop?

I have following matrices :
X=1 2 3
Y=4 5 6
A=1 2 3
4 5 6
7 8 9
I Want to do
for each (i,j) in A
v = A(i,j)*X - Y
B(i,j) = v * v'
i.e. each element of A is multiplied by vector X, then resultant vector subtracts Y from itself and finally we take inner product of that vector to bring a single number.
Can it be done without for loop ?
One thing often forgotten in Matlab: The operator ' takes the conjugate transposed (.' is the ordinary transposed). In other words, A' == conj(trans(A)), whereas A.' == trans(A), which makes a difference if A is a complex matrix.
Ok, let's apply some mathematics to your equations. We have
v = A(i,j)*X - Y
B(i,j) = v * v'
= (A(i,j)*X - Y) * (A(i,j)*X - Y)'
= A(i,j)*X * conj(A(i,j))*X' - Y * conj(A(i,j))*X'
- A(i,j)*X * Y' + Y * Y'
= A(i,j)*conj(A(i,j)) * X*X' - conj(A(i,j)) * Y*X' - A(i,j) * X*Y' + Y*Y'
So a first result would be
B = A.*conj(A) * (X*X') - conj(A) * (Y*X') - A * (X*Y') + Y*Y'
In the case of real matrices/vectors, one has the identities
X*Y' == Y*X'
A == conj(A)
which means, you can reduce the expression to
B = A.*A * (X*X') - 2*A * (X*Y') + Y*Y'
= A.^2 * (X*X') - 2*A * (X*Y') + Y*Y'
An alternative method:
X = [1 2 3]
Y = [4 5 6]
A = [1 2 3; 4 5 6; 7 8 9]
V = bsxfun(#minus, A(:)*X, [4 5 6])
b = sum((V.^2)')
B = reshape(b , 3, 3)
I get the result:
B = 27 5 11
45 107 197
315 461 635