I have a system that looks something like this:
z1 = 5*x1 + x2*cos(x3)
z2 = x1*sin(x3) + 3*x2
z3 = 3*x1 - 2*x2
which is the transformation of a system of differential equations (just to give some context, I don't think you really need to know this). Now I would like to find the inverse of this transformation which would look something like:
x1 = ...(stuff with z1, z2, z3)...
x2 = ...
x3 = ...
now I guess with this system it is relatively easy to find it manually but I have to do the same thing with a 7 variable 7 equation system and it would get pretty tedious to do.
I cannot find a way to get Matlab to do this, can anybody help?
Maybe this could work:
You could get an approximate solution by taylor expanding the trigonometric functions and then doing Gaussian elimination.
Gaussian elimination can be done using rref in Matlab if the problem can be put on the form (using random numbers):
x+3y+4z = 5
2x+y+6z= 4
8x+2y+7z=3
Then Ax=b, A=[1 3 4;2 1 6;8 2 7], b=[5;4;3]
To find x do: E=[A b]
x=rref(E)
EDIT: Sorry, I see now that you don't have numbers for z1, z2.. so this is not really a solution for your case.
Related
For the linear regression, I want to generate the matrix for polynomials of n degree.
if n is 1
X=[x(:), ones(length(x),1)]
if n is 2
X=[x(:).^2 x(:) ones(length(x),1)]
...
if n is 5
X=[x(:).^5 x(:).^4 x(:).^3 x(:).^2 x(:) ones(length(x),1)]
I do not know how to code with matlab if I set n=6 and it will automatically generate the wanted X matrix. Hope you can help me.
This can be easily done with bsxfun:
X = bsxfun(#power, x(:), n:-1:0);
Or, in Matlab versions from R1016b onwards, you can use implicit expansion:
X = x(:).^(n:-1:0);
Check out the polyval function. I believe that will do what you’re looking for.
To get increasing the polynomial to increase in degree, you can increase the length of your p argument using a loop.
If you write edit polyfit you can see how MATLAB have implemented the polyfit command, which is similar to what you are trying to do. In there you will find the code
% Construct the Vandermonde matrix V = [x.^n ... x.^2 x ones(size(x))]
V(:,n+1) = ones(length(x),1,class(x));
for j = n:-1:1
V(:,j) = x.*V(:,j+1);
end
Which constructs the matrix you are interested in. The benefit of this method over the bsxfun is that you only calculate x(:).^n and then saves the intermediary results. Instead of treating all powers as seperate problems, e.g. x(:)^(n-1) as a seperate problem to x(:).^n.
This is my code to solve equation systems.
Something is wrong with my code but I can't fix it.
D=1
E=2
F=3
syms a b c;
S= solve('a+b-c=D','2*+b-3*c=E','a-2*b=F')
S = [S.a S.b S.c]
Fixing your problem with symbolic solving
Looking at the documentation for solve, you can see an example for how to input equations to the solve function. They should not be strings (like you have done), but instead they should be equations using == in place of =.
Docs example:
syms x
solx = solve(sin(x) == 1,x)
Applying this to your system:
D=1; E=2; F=3;
syms a b c;
S = solve(a+b-c==D, 2*b-3*c==E, a-2*b==F);
S = [S.a S.b S.c];
% Ouput:
% S = [5/7, -8/7, -10/7]
Note, in the above example I have replaced *+ in your second equation with *. Use either * or +, but not both! I'm assuming this was a typo, it is not the root of your problems.
Another option without using symbolic maths
You can solve this without the symbolic math toolbox too. Your equations can be written as
1a + 1b - 1c = D
0a + 2b - 3c = E
1a - 2b + 0c = F
Which, in matrix form, is the same as
1 1 -1 a D
0 2 -3 * b = E
1 -2 0 c F
Using matrix operations, this can be solved by pre-multiplying both sides by the inverse of the 3x3 matrix. In MATLAB, getting this result is easy:
% Set up 3x3 matrix of coefficients
coeffs = [1 1 -1; 0 2 -3; 1 -2 0];
% Set up left hand side vector
DEF = [1; 2; 3];
% Solve
S = coeffs\DEF;
% Ouput
% S = [0.7143, -1.1429, -1.4286]
This output is the same as before, although clearly not in exact fractional form, since that is inherited from a,b and c being symbolic.
Edit:
Some things to consider about solving matrix equations in MATLAB, as prompted by Dev-iL's comment...
The backslash \ operator I've used above is shorthand for MATLAB's mldivide function
As noted in the above linked docs, they are interchangeable:
x = mldivide(A,B) is an alternative way to execute x = A\B
Also in the docs are notes on how \ works:
If A is a square matrix, A\B is roughly equal to inv(A)*B, but MATLAB processes A\B differently and more robustly.
In particular, MATLAB automatically chooses the most efficient algorithm for solving the system. Example decision flows can be seen in the docs, I will not replicate here as it is beyond the scope of the question.
The versatility of mldivide in solving linear systems stems from its ability to take advantage of symmetries in the problem by dispatching to an appropriate solver.
In summary:
Whilst mathematically "pre-multiplying by the inverse of the coeffs matrix" gives the solution to the system, using the backslash operator (a.k.a mldivide) is the MATLAB-esque way to solve this problem.
How does this extension relate to your original question? Hopefully you are better informed about which methods can be used for this problem. In particular, know that (unless needed for your particular situation) you can do this task easily (in less lines, quicker) without relying on MATLAB's symbolic math toolbox.
I have really big problem solving equations like this one (simplified one):
a*cos(x) + b*sin(x) = cos(x) + sin(x), with respect to a,b.
In the equation can stand expressions of: sin(x), cos(x), exp(C*x) and polynomials.
I need to get solution in this form: [a b] = [1 1].
Only solution I can reach now is: b = 0, a = (cos(x) + sin(x))/cos(x).
I was trying hard to find something, but I did not find anything. I really appreciate any help! Thank you!
I guess I get it. If I specify the variables with assume:
assume(a, 'real')
assume(b, 'real')
I get the result I am looking for.
As the title suggests, I am wondering how I can find the derivative of a 'function'. I am unsure what to do because I really do not have a function defined, just an array of values. So lets try a simple example:
x = 1:5;
y = x.^2
y =
1 4 9 16 25
As expected. Now I want to take the derivative. I know that this is 2x. Possibly use the diff function, as if in symbolic toolkit?
diff(y)
ans =
3 5 7 9
This looks like either 2x +// 1, with length length(y)-1. Is there any way I can compute the derivative of this and get a vector of length(y)?
I do not have the symbolic toolkit.
There is little you can do. This topic has already been discussed ad nauseum at the MathWorks web forums.
#noah has provided an example of numerical differentiation (ie: differencing) on a finite data set, whereas you are looking for a means of doing symbolic differentiation of continuous-domain-continuous-range function applied to a discrete-domain data set.
In short, not happening. You're asking how to install a shelf without a hammer, screw driver, or nails. You could always just download and install GNU Octave, a free alternative to MATLAB.
References.
"Symbolic Math In MATLAB" http://faraday.elec.uow.edu.au/subjects/annual/ECTE313/Symbolic_Maths.pdf
"Symbolic differentiation without symbolic math toolbox" http://www.mathworks.com/matlabcentral/newsreader/view_thread/83397
"GNU Octave - Download" http://www.gnu.org/software/octave/
"Symbolic differentiation with GNU Octave" http://octave.1599824.n4.nabble.com/Examples-for-use-of-symbolic-toolbox-td1601724.html
Numerical differentiation is kind of tricky with small data sets. The best way I can think of offhand to do this is to explicitly create the function and then apply it to the data.
>> syms x y
>> y = x^2;
>> dy = diff(y);
>> dy
ans =
2*x
>> v = 1:5;
>> f = matlabFunction(dy);
>> f(v)
ans =
2 4 6 8 10
You have no symbolic toolbox and you want the symbolic derivative. Here is a suggestion: If you already know the derivative of the function you are trying to apply to your vector (with knowledge of basic calculus), just apply it directly to your vector. For example:
vector = [1 2 3 4 5] % intended function = x^2
result = 2*vector
vector = [1 2 3 4 5] % intended function = sin(x)
result = cos(vector)
Is there any function you are trying to apply which you don't already know the derivative?
I have a system of 2 equations in 2 unknowns that I want to solve using MATLAB but don't know exactly how to program. I've been given some information about a gamma distribution (mean of 1.86, 90% interval between 1.61 and 2.11) and ultimately want to get the mean and variance. I know that I could use the normal approximation but I'd rather solve for A and B, the shape and scale parameters of the gamma distribution, and find the mean and variance that way. In pseudo-MATLAB code I would want to solve this:
gamcdf(2.11, A, B) - gamcdf(1.61, A, B) = 0.90;
A*B = 1.86;
How would you go about solving this? I have the symbolic math toolbox if that helps.
The mean is A*B. So can you solve for perhaps A in terms of the mean(mu) and B?
A = mu/B
Of course, this does no good unless you knew B. Or does it?
Look at your first expression. Can you substitute?
gamcdf(2.11, mu/B, B) - gamcdf(1.61, mu/B, B) = 0.90
Does this get you any closer? Perhaps. There will be no useful symbolic solution available, except in terms of the incomplete gamma function itself. How do you solve a single equation numerically in one unknown in matlab? Use fzero.
Of course, fzero looks for a zero value. But by subtracting 0.90, that is resolved.
Can we define a function that fzero can use? Use a function handle.
>> mu = 1.86;
>> gamfun = #(B) gamcdf(2.11, mu/B, B) - gamcdf(1.61, mu/B, B) - 0.90;
So try it. Before we do that, I always recommend plotting things.
>> ezplot(gamfun)
Hmm. That plot suggests that it might be difficult to find a zero of your function. If you do try it, you will find that good starting values for fzero are necessary here.
Sorry about my first try. Better starting values for fzero, plus some more plotting does give a gamma distribution that yields the desired shape.
>> B = fzero(gamfun,[.0000001,.1])
B =
0.0124760672290871
>> A = mu/B
A =
149.085442218805
>> ezplot(#(x) gampdf(x,A,B))
In fact this is a very "normal", i.e, Gaussian, looking curve.