Matlab - define a function that is a summation - matlab

I am trying to define I function which I will derivate later and the function is
My code is as below:
syms i q j
syms f(i,q)
f=symsum(((1-q)^(i-j))*j*q,j,0,i)
The f I get shows me 4 terms but in fact I do not know this number. Is it correct or how do I enter this correctly?

First of all, please don't use i and j, because they correspond to the imaginary unit; that causes misunderstandings.
syms N q k
syms f(i,q)
f=symsum(((1-q)^(N-k))*k*q,k,0,N)
piecewise(q == 0, 0, q ~= 0, (q + N*q - q*(1 - q)^N + (1 - q)^N - 1)/q)
The result is a piecewise, and it says that the result is 0 if q is 0, and otherwise the formula given on the right.
You can also evaluate Sum[(1 - q)^(M - k) k q, {k, 0, M}] with WolframAlpha, where you get the same result. As you see, your formula can be written without the sum. You get the derivative with D[Sum[(1 - q)^(M - k) k q, {k, 0, M}],q] on WolframAlpha.

Related

Function and its gradient in Matlab

I am working on a Matlab project and I want to make the gradient of the following function in Matlab:
f(x) = c^T * x - sum (log(bi - (ai ^ T) * x)).
Where ai^T are the rows of a random A matrix nxm , where n=2, and m=20
c is random matrix nx1, and x is also random nx1.
b is random matrix mx1.
I've done the following but the results i get don't seem to be right..
function gc0 = gc(x, c, b, A)
for k = 1 : length(A(:,1))
f1(k) = sum(log(b - A(k,:)'*x(k)));
end
gradient(-f1)
gc0 = c - gradient(f1)';
Any ideas? I'd appreciate your help, I'm newbie in Matlab..
It seems that your loop contains a mistake. Looking at the formula above,
I think that the function evaluation should be
f1 = c'*x;
for k = 1 : length(A(1,:))
f1 = f1 - log(b(k) - A(:,k)'*x)
end
A shorter and faster notation for this in Matlab is
f = c'*x - sum(log(b - A' * x)) ;
The function 'gradient' does not calculate the gradient that I think you
want: it returns the differences of matrix entries, and your function f
is a scalar.
Instead, I suggest calculating the derivatives symbolically:
Gradf = c' + sum( A'./(b - A' * x) );

Evaluating a convolution sum with a unit step function

I want to perform some symbolic computation with the discrete-time unit step function, which I cannot seem to find a built-in definition of. I've tried heaviside(n + 0.5) and also sym('piecewise([n < 0 , 0], [n >= 0, 1])'). Here is some sample code:
syms n k
unitStep = #(n) subs(sym('piecewise([k < 0 , 0], [k >= 0, 1])'), n);
x1 = #(n) unitStep(n);
h1 = #(n) 2 .^ (-n) .* unitStep(n);
y1 = #(n) symsum(x1(k) .* h1(n - k), k, -inf, inf);
simplify(y1(n))
Which gives the output
piecewise([in(n, 'real'), symsum(piecewise([n < k, 0], [k <= n, 2^(k - n)]), k, 0, Inf)])
(Not at all helpful) I cannot seem to get satisfactory results whatever I do. Anyone have tips for evaluating symbolic sums with the unit step function in them? I do not want to use heaviside(n) because heaviside(0) evaluates to 0.5.

Series expansion of a function about infinity - how to return coefficients of series as a Matlab array?

This question is connected to this one. Suppose again the following code:
syms x
f = 1/(x^2+4*x+9)
Now taylor allows the function f to be expanded about infinity:
ts = taylor(f,x,inf,'Order',100)
But the following code
c = coeffs(ts)
produces errors, because the series does not contain positive powers of x (it contains negative powers of x).
In such a case, what code should be used?
Since the Taylor Expansion around infinity was likely performed with the substitution y = 1/x and expanded around 0, I would explicitly make that substitution to make the power positive for use on coeffs:
syms x y
f = 1/(x^2+4x+9);
ts = taylor(f,x,inf,'Order',100);
[c,ty] = coeffs(subs(ts,x,1/y),y);
tx = subs(ty,y,1/x);
The output from taylor is not a multivariate polynomial, so coeffs won't work in this case. One thing you can try is using collect (you may get the same or similar result from using simplify):
syms x
f = 1/(x^2 + 4*x + 9);
ts = series(f,x,Inf,'Order',5) % 4-th order Puiseux series of f about 0
c = collect(ts)
which returns
ts =
1/x^2 - 4/x^3 + 7/x^4 + 8/x^5 - 95/x^6
c =
(x^4 - 4*x^3 + 7*x^2 + 8*x - 95)/x^6
Then you can use numden to extract the numerator and denominator from either c or ts:
[n,d] = numden(ts)
which returns the following polynomials:
n =
x^4 - 4*x^3 + 7*x^2 + 8*x - 95
d =
x^6
coeffs can then be used on the numerator. You may find other functions listed here helpful as well.

How can I simplify in Matlab?

I want to simplify the following operation, but it yields me an error that says: too many input arguments. Can anybody tell me what am i doing wrong???
>>
syms a b c d e f g h i j k l x y xy
A=[1 a b a^2 a*b b^2; 1 c d c*2 c*d d^2; 1 e f e^2 e*f f^2; 1 g h g^2 g*h h^2; 1 i j i^2 i*j j^2; 1 k l k^2 k*l l^2]
B=[1; 0; 0; 0; 0; 0]
A =
[ 1, a, b, a^2, a*b, b^2]
[ 1, c, d, 2*c, c*d, d^2]
[ 1, e, f, e^2, e*f, f^2]
[ 1, g, h, g^2, g*h, h^2]
[ 1, i, j, i^2, i*j, j^2]
[ 1, k, l, k^2, k*l, l^2]
B =
1
0
0
0
0
0
>> simplify(inv(A)*B, 'steps', 100)enter code here
I've put the code you pasted in my copy of matlab (R2013a) and it finishes without any errors. The result is not simplified very much though.
If your computer is choking on the computation (it is very long), you could try separating the things a bit and see if it helps.
vec=inv(A)*B
for n=1:6
results(n)=simplify(vec(n), 'steps', 100);
end
results
Your call belongs to this MATLAB function:
But it is in Symbolic Math Toolbox, which means it can only simplify math formulas instead of complex matrix computation.
Simplify Favoring Real Numbers
To force simplify favor real values over complex values, set the value of Criterion to preferReal:
syms x
f = (exp(x + exp(-x*i)/2 - exp(x*i)/2)*i)/2 - (exp(- x - exp(-x*i)/2 + exp(x*i)/2)*i)/2;
simplify(f, 'Criterion','preferReal', 'Steps', 100)
ans =
cos(sin(x))*sinh(x)*i + sin(sin(x))*cosh(x)
If x is a real value, then this form of expression explicitly shows the real and imaginary parts.
Although the result returned by simplify with the default setting for Criterion is shorter, here the complex value is a parameter of the sine function:
simplify(f, 'Steps', 100)
ans =
sin(x*i + sin(x))
Instead, I think you could try use this function:
Simplify(f, Steps = numberOfSteps)
But first of all, you need a 'f' which could be used like a recursion or iteration function.
e.g. Simplify(sin(x)^2 + cos(x)^2, All)
Hope this helps!

how to solve a system of Ordinary Differential Equations (ODE's) in Matlab

I have to solve a system of ordinary differential equations of the form:
dx/ds = 1/x * [y* (g + s/y) - a*x*f(x^2,y^2)]
dy/ds = 1/x * [-y * (b + y) * f()] - y/s - c
where x, and y are the variables I need to find out, and s is the independent variable; the rest are constants. I've tried to solve this with ode45 with no success so far:
y = ode45(#yprime, s, [1 1]);
function dyds = yprime(s,y)
global g a v0 d
dyds_1 = 1./y(1) .*(y(2) .* (g + s ./ y(2)) - a .* y(1) .* sqrt(y(1).^2 + (v0 + y(2)).^2));
dyds_2 = - (y(2) .* (v0 + y(2)) .* sqrt(y(1).^2 + (v0 + y(2)).^2))./y(1) - y(2)./s - d;
dyds = [dyds_1; dyds_2];
return
where #yprime has the system of equations. I get the following error message:
YPRIME returns a vector of length 0, but the length of initial
conditions vector is 2. The vector returned by YPRIME and the initial
conditions vector must have the same number of elements.
Any ideas?
thanks
Certainly, you should have a look at your function yprime. Using some simple model that shares the number of differential state variables with your problem, have a look at this example.
function dyds = yprime(s, y)
dyds = zeros(2, 1);
dyds(1) = y(1) + y(2);
dyds(2) = 0.5 * y(1);
end
yprime must return a column vector that holds the values of the two right hand sides. The input argument s can be ignored because your model is time-independent. The example you show is somewhat difficult in that it is not of the form dy/dt = f(t, y). You will have to rearrange your equations as a first step. It will help to rename x into y(1) and y into y(2).
Also, are you sure that your global g a v0 d are not empty? If any one of those variables remains uninitialized, you will be multiplying state variables with an empty matrix, eventually resulting in an empty vector dyds being returned. This can be tested with
assert(~isempty(v0), 'v0 not initialized');
in yprime, or you could employ a debugging breakpoint.
the syntax for ODE solvers is [s y]=ode45(#yprime, [1 10], [2 2])
and you dont need to do elementwise operation in your case i.e. instead of .* just use *