I have A, b, f matrices as follows :
A = [ 2 1
1 2 ]
B = [ 4; 3 ]
F = [ 1; 1 ]
LB = [ 0; 0 ]
[X, fval, exitflag, output, lambda] = linprog(F, A, B, [], [], LB)
After that, the solution provided by the MATLAB is surprising. It says the value of fval is 1.2169e-013. This is not the solution. Can you help me by identifying the fault?
Related
I'm trying to use LU method to solve Ax=B, and when I do start doing so, using:
(P, L, U := LUDecomposition(A))
to create my three different matrices (P, L, U) I get the error
Error, cannot split rhs for multiple assignment
which doesn't make sense since LUDecomposition creates 3 matrices, which correspond to my P, L, U.
If you do either of the following then the call will return an expression sequence of containing three Matrices, and it will work for input A a Matrix.
with(LinearAlgebra):
P, L, U := LUDecomposition(A);
Or,
P, L, U := LinearAlgebra:-LUDecomposition(A);
But if you don't load the LinearAlgebra package and you also don't use the long-form name of that package's export then you're simply making a function call to an undefined name.
And, if you are in fact accidentally simply calling the undefined name LUDecomposition (because you have not used one of the mentioned methods for calling the package export of that name), then the result will be an unevaluated function call. And you cannot assign that single thing to three names on the left-hand-side of an assignment statement.
restart;
A := Matrix([[1,2],[3,5]]):
# Look, this next one does no computation.
# The return value is a single thing, an unevaluated
# function call.
LUDecomposition(A);
/[1 2]\
LUDecomposition|[ ]|
\[3 5]/
P, L, U := LUDecomposition(A);
Error, cannot split rhs for multiple assignment
But this would return the actual result,
LinearAlgebra:-LUDecomposition(A);
[1 0] [1 0] [1 2]
[ ], [ ], [ ]
[0 1] [3 1] [0 -1]
And so those three Matrices could be assigned to three names.
P, L, U := LinearAlgebra:-LUDecomposition(A);
[1 0] [1 0] [1 2]
P, L, U := [ ], [ ], [ ]
[0 1] [3 1] [0 -1]
Another way to do it is to first load the whole package, so that you can utilize the short-form command name,
with(LinearAlgebra):
LUDecomposition(A);
[1 0] [1 0] [1 2]
[ ], [ ], [ ]
[0 1] [3 1] [0 -1]
P, L, U := LUDecomposition(A);
[1 0] [1 0] [1 2]
P, L, U := [ ], [ ], [ ]
[0 1] [3 1] [0 -1]
I want to programatically generate state-space [A B C D] system from a generated MNA (modified nodal analysis) system of equations. I don't know which MATLAB functions to call.
I use the SCAM link script from Erik Cheever to generate the system of equations.
I made file example3.cir link which is a spice RLC circuit with input source Vs.
I also tried netlist2linss link github but it is not in laplace domain and it does not work correctly.
example3.cir:
R1 2 1 R
C1 3 0 C
L1 2 3 L
Vs 1 0 V
>> fname = 'example3.cir'; scam; system_of_eqns = [Z == A*X]
Solved variables:
v_1
v_2
v_3
I_Vs
system_of_eqns =
0 == I_Vs + v_1/R1 - v_2/R1
0 == v_2*(1/R1 + 1/(L1*s)) - v_1/R1 - v_3/(L1*s)
0 == v_3*(C1*s + 1/(L1*s)) - v_2/(L1*s)
Vs == v_1
>> [A_,b_] = equationsToMatrix(system_of_eqns, X)
A_ =
[ -1/R1, 1/R1, 0, -1]
[ 1/R1, - 1/R1 - 1/(L1*s), 1/(L1*s), 0]
[ 0, 1/(L1*s), - C1*s - 1/(L1*s), 0]
[ -1, 0, 0, 0]
b_ =
0
0
0
-Vs
expected (capacitor voltage as output):
A =
[ 0, 1/C1 ]
[ -1/L1, -R/L1 ]
B =
[ 0, 1/L1 ]
C =
[ 1, 0 ]
D =
[ 0 ]
states = [sVC1 sIL1]
input = [ Vs ]
I found a solution in python called lcapy:
https://github.com/mph-/lcapy
If for example I have three expressions: A, B and C as follows:
A(i+1) = A(i) + C(i).k
B(i+1) = B(i) + A(i).h
C(i+1) = A(i) + B(i)
where k and h are some constants and m and n is the desired size of C. i is the previous obtained value, i+1 is the next value. Now, if I use for loop, then I can code it as:
A(1)= 2;
B(1)= 5;
C(1)= 3;
for i=1:10
A(i+1) = A(i) + C(i)*2;
B(i+1) = B(i) + A(i)*3;
C(i+1) = A(i) + B(i);
end
And it works just fine. But I want to code it in a vector form, as in without having to use a loop. But the problem is I do not know how to get around the dependency of:
A on its previous value and previous C value
B on it previous values and previous C value of A
C on the previous values of A and B
Here's a matrix-based way to obtain the n-th value of the [A;B;C] vector. I wouldn't exactly call it vectorization, but this could speed things up considerably for you:
[A,B,C] = deal(zeros(11,1));
A(1)= 2;
B(1)= 5;
C(1)= 3;
%% // Original method
for k=1:10
A(k+1) = A(k) + C(k)*2;
B(k+1) = B(k) + A(k)*3;
C(k+1) = A(k) + B(k);
end
%% // Matrix method:
%// [ A ] [1 0 2][ A ]
%// | B | = |3 1 0|| B |
%// [ C ] [1 1 0][ C ]
%// i+1 i
%//
%// [ A ] [1 0 2][ A ] [1 0 2] ( [1 0 2][ A ] )
%// | B | = |3 1 0|| B | = |3 1 0| * ( |3 1 0|| B | )
%// [ C ] [1 1 0][ C ] [1 1 0] ( [1 1 0][ C ] )
%// i+2 i+1 i
%// Thus, this coefficient matrix taken to the n-th power, multiplied by the input
%// vector will yield the values of A(n+1), B(n+1), and C(n+1):
M = [1 0 2
3 1 0
1 1 0];
isequal(M^10*[A(1);B(1);C(1)],[A(11);B(11);C(11)])
In reality you can use M to the appropriate power (positive or negative) to obtain any [A,B,C]n from any [A,B,C]k ...
First, forgive me for abusing Matlab syntax for expressing mathematical stuff.
Consider following code, where we do exactly the same as in your example. Note that A,B,C are the rows of X.
X = zeros(3,N+1);
X(:,1) = [2,5,3];
M= [1,0,2;3,1,0;1,1,0];
for i=1:N
X(:,i+1) = M*X(:,i);
end
This is just a matrix vector notation of the above code. I think it is even slower. Note that we could also compute: X(:,i+1) = M^i * X(:,1) which is even slower.
Notice that we can use the eigenvalue decomposition:
[V,D] = eigs(M);
X(:,i+1) = [V*D*inv(V)]^i * X;
Therefore
X(:,i+1) = V*D^i*inv(V) * X;
So V*D^i*inv(V) is an explicit formula for the i+1th term of X. I suggest computing those analytically, and plug the formula you get into your code again.
EDIT: I wrote some code that should be close to analyitcally solving the system, you can compare the runtimes. It seems in the end preallocation with your first method is still the fastest IF you need ALL the terms. If you only need one of them, my suggested method is certainly quicker.
clear;clc
N = 10000000;
tic
A(1)= 2;
B(1)= 5;
C(1)= 3;
A = zeros(1,N+1);
B=A;C=A;
for i=1:N
A(i+1) = A(i) + C(i)*2;
B(i+1) = B(i) + A(i)*3;
C(i+1) = A(i) + B(i);
end
toc
tic
X = zeros(3,N+1);
X(:,1) = [2,5,3];
M= [1,0,2;3,1,0;1,1,0];
for i=1:N
X(:,i+1) = M*X(:,i);
end
toc
tic
M= [1,0,2;3,1,0;1,1,0];
[V,D]=eig(M);
v=0:N;
d=diag(D);
B=bsxfun(#power,repmat(d,1,N+1),v);
Y=bsxfun(#times,V * B, V \[2;5;3]);
toc
tic
M= [1,0,2;3,1,0;1,1,0];
[V,D]=eig(M);
v=0:N;
d=diag(D);
Y = ones(3,N+1);
for i=1:N
Y(:,i+1) = d.*Y(:,i);
end
Y=bsxfun(#times,V * B, V \[2;5;3]);
toc
When using equationsToMatrix you solve a set of linear equations as in the example (the solution is included)
syms x y z;
[A, b] = equationsToMatrix([x + y - 2*z == 0, x + y + z == 1, 2*y - z + 5 == 0], [x, y, z])
%solution of the equation set
A =
[ 1, 1, -2]
[ 1, 1, 1]
[ 0, 2, -1]
b =
0
1
-5
The vector b returns the values of the variables at issue: x,y, and z. However if I type x then MATLAB returns x and not 0, which is the solution of the equation in this case. This also occurs without adding the syms option.
The other problem is that if I type b(1) or b(2), I don't get any value: I would expect b to contain the values of x,y and z.
What I would need is to get something like this in the end
b(1) = 0
or
x = 0
What should I do to get the values of x,y,z by just typing x,y,z?
What you have is a way of converting symbolic linear equations into a numeric system by extracting the coefficient matrices. To solve the system you need to do
sol = A\b;
and now you can use the values in another expression with
subst(expr, {x,y,z}, {sol(1),sol(2),sol(3));
for example
A =
1 1 -2
1 1 1
0 2 -1
b =
0
1
-5
>> A\b
ans =
3.0000
-2.3333
0.3333
This is probably very simple but I'm having trouble setting up matrices to solve two linear equations using symbolic objects.
The equations are on the form:
(1) a11*x1 + a12*x2 + b1 = 0
(2) a21*x1 + a22*x2 + b2 = 0
So I have a vector {E}:
[ a11*x1 + a12*x2 + b1 ]
{E} = [ a21*x1 + a22*x2 + b2 ]
I want to get a matrix [A] and a vector {B} so I can solve the equations, i.e.
[A]*{X} + {B} = 0 => {X} = -[A]{B}.
Where
[ x1 ]
{X} = [ x2 ]
[ a11 a12 ]
[A] = [ a21 a22 ]
[ b1 ]
{B} = [ b2 ]
Matrix [A] is just the Jacobian matrix of {E} but what operation do I have to perform on {E} to get {B}, i.e. the terms that don't include an x?
This is what I have done:
x = sym('x', [2 1]);
a = sym('a', [2 2]);
b = sym('b', [2 1]);
E = a*x + b;
A = jacobian(E,x);
n = length(E);
B = -E;
for i = 1:n
for j = 1:n
B(i) = subs(B(i), x(j), 0);
end
end
X = A\B
I'm thinking there must be some function that does this in one line.
So basically my question is: what can I do instead of those for loops?
(I realize this is something very simple and easily found by searching. The problem is I don't know what this is called so I don't know what to look for.)
It is just B = subs(B,x,[0 0])