How to write the following equation in Matlab or Mathematica? - matlab

I have the following equation:
Where N^{optim} and K are my variables and M and S are just constants. I want to do some processing to this function like maximizing it, solving it for some values. So I need to write it in terms of the symbolic variables in Matlab. But I don't know how the summation for the symbolic variables. Any help, recommendation, comment is highly appreciated.
If any one knows how to do it in mathematica, or other software that might help as well but I would prefer Matlab and Mathematica.
Thank you.

In[1]:= Binomial[no - m, m]/Binomial[no, m] Sum[Binomial[s, i] Binomial[m, no]^i
(1 - Binomial[m, no])^(s - i), {i, 0, k}]
Out[1]= -(((1 - Binomial[m, no])^(-1 - k + s)*Binomial[-m + no, m]*(-(((1 -
Binomial[m, no])^(-1))^s*(1 - Binomial[m, no])^k) + ((1-Binomial[m, no])^(-1))^s*
(1 - Binomial[m, no])^k*Binomial[m, no] + Binomial[m, no]^(1 + k)*
Binomial[s, 1 + k]*Hypergeometric2F1[1, 1 + k - s, 2 + k, Binomial[m, no]/
(-1 + Binomial[m, no])]))/Binomial[no, m])
Check that result carefully before you depend on it.

Related

Is there a way to prevent MATLAB's simplify()/numden() function from cancelling equal numerator/denominator terms?

I am trying to find the denominator of a given fraction G, but I cannot find a way to use MATLAB's built-in functions without oversimplifying the fraction, and losing important information.
I've tried using MATLAB's built-in commands "numden", "simplify", and "simplifyFraction" but they keep cancelling equal terms from the numerator and denominator. This is normally okay, but for my application, I need to know all values in the denominator which might cause a hole/instability in the function, G.
I've tried looking into the additional constraints within those functions like "IgnoreAnalyticConstraints", but they don't seem to fix the issue. I've simplified my code to isolate my problem below with my current attempts:
syms 's'
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1));
[n,d]=numden(G)
G_simp=simplify(G)
G_simpC=simplify(G,'IgnoreAnalyticConstraints',false)
G_simpF=simplifyFraction(G)
Output:
n = 3
d = s + 1
G_simp = 3/(s + 1)
G_simpC = 3/(s + 1)
G_simpF = 3/(s + 1)
Here is an example fraction input:
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
which simplifies to:
G = 3*(s - 1)/((s - 1)*(s + 1)). <-desired result
I am trying to keep the fraction in this simplified form, but the built-in commands will cancel the (s-1) terms resulting in:
G = 3/(s + 1). <-actual result
You can use the Control System Toolbox:
s= tf([1 0],1);
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
zpk(G)
The code s= tf([1 0],1); creates a variable s. It contains a Transfer Function object that represents the transfer function f(s)=s. The line
G = 2/(s - 1) + 1/(s + 1) - 4/((s - 1)*(s + 1))
creates a Transfer Function object that contains the corresponding transfer function. And zpk(G) converts this function to the zero/pole/gain form.
The result of the code above is
G =
3 s^3 - 3 s^2 - 3 s + 3
-----------------------
s^4 - 2 s^2 + 1
Continuous-time transfer function.
ans =
3 (s+1) (s-1)^2
---------------
(s+1)^2 (s-1)^2
Continuous-time zero/pole/gain model.

Use bsxfun function to find Max entry of matrix

For a given set of q and r, I want to find the maximum of Tp=x * log(1 + (q* r (1 - 1/y)* (2/x - y))/(1 + r* (1 - 1/y) + q* (2/x - y))) for x in (0,1) and y in (1,2).
I can calculate them using two for loops, but when I use really small steps sizes for x and y, e.g., 0.00001, this takes a long time. But I know that if I get Tp as a matrix for all x and y, i.e., Tp is matrix of size length(x) x length(y), it may easier and faster. As I read, bsxfun(#times,..) may be helped, but I don't know how I can apply it in my problem.
Here is what I have tried, but it doesn't give correct output. Here I used larger step size for understanding. Can someone fix this issue in my code?
function maxTp
hvar=0.1:0.2:1;
hl=length(hvar);
q=hvar; r=hvar;
stepx=0.2;stepy=0.1;
y0=1.1; x0=0.1;
x=x0:stepx:1; y=y0:stepy:2;
ox = zeros(hl,1); oy = zeros(hl,1);
MaxTp = zeros(hl,1);
for k=1:hl
Tp = bsxfun(#times,log(1 + (q(k)*r(k)*(1 - 1./y).*(2./x - y))./(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y))).',x);
MaxTp(k,1)=max(max(Tp));
[p, q] = ind2sub(size(Tp),find(Tp==MaxTp(k,1)));
ox(k,1)=x0+(p-1)*stepx;
oy(k,1)=y0+(q-1)*stepy;
end
Try this inside your for loop:
Tp = bsxfun(#(x,y) log(1+(q(k)*r(k)*(1 - 1./y).*(2./x - y))./(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y)))*x,x,y.'); %\\'
MaxTp(k,1)=max(max(Tp));
[p2, q2] = ind2sub(size(Tp),find(Tp==MaxTp(k,1)));
ox(k,1)=x0+(p2-1)*stepx;
oy(k,1)=y0+(q2-1)*stepy;
I changed the bsxfun to do the calculation in the function part rather than the vector inputs, and you were also overwriting p and q as the results of ind2sub.
You can also use fmincon (be aware the maximisation means we need to minimise the negative of the function). The following code goes inside the for loop:
f=#(x,y) log(1+(q(k)*r(k)*(1 - 1./y).*(2./x - y))./...
(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y)))*x;
o(:,k)=fmincon(#(x) -f(x(1),x(2)),[0.5;0.5],[],[],[],[],[0;1],[1;2]);
o(:,k) gives the x and y coordinates of the maximum, I think it's different to your ox and oy variables though.

Matlab, expanding, simultaneous equation solving for a control system

I have this code in matlab
syms L1 L0 P1 P0 s
L = expand(s*(s^2+L1*s+L0)*(s-75)+1400*(P1*s+P0))
R = expand((s+75)*(s+150)^3)
I want to solve for P1, P0, L1 and L0
L = R
1400*P0 - 75*L0*s + 1400*P1*s + L0*s^2 - 75*L1*s^2 + L1*s^3 - 75*s^3 + s^4 = s^4 + 525*s^3 + 101250*s^2 + 8437500*s + 253125000
by observation:
1400*P0 = 253125000
ETC...
How do i pull simultaneous equations from L=R in Matlab and automatically solve for each variable?
Thanks
You could write the equation as L-R=0, then do something like C=coeffs(L-R,s). Then, something like the following code might solve the equations:
for i=1:length(C)
sol(i)=solve(C(i));
end
but it may be difficult to work out which element of sol refers to which variable. But if you are going to look at the output as the code runs it should be pretty obvious I'd imagine.

Avoiding numerical overflow when calculating the value AND gradient of the Logistic loss function

I am currently trying to implement a machine learning algorithm that involves the logistic loss function in MATLAB. Unfortunately, I am having some trouble due to numerical overflow.
In general, for a given an input s, the value of the logistic function is:
log(1 + exp(s))
and the slope of the logistic loss function is:
exp(s)./(1 + exp(s)) = 1./(1 + exp(-s))
In my algorithm, the value of s = X*beta. Here X is a matrix with N data points and P features per data point (i.e. size(X)=[N,P]) and beta is a vector of P coefficients for each feature such that size(beta)=[P 1].
I am specifically interested in calculating the average value and gradient of the Logistic function for given value of beta.
The average value of the Logistic function w.r.t to a value of beta is:
L = 1/N * sum(log(1+exp(X*beta)),1)
The average value of the slope of the Logistic function w.r.t. to a value of b is:
dL = 1/N * sum((exp(X*beta)./(1+exp(X*beta))' X, 1)'
Note that size(dL) = [P 1].
My issue is that these expressions keep producing numerical overflows. The problem effectively comes from the fact that exp(s)=Inf when s>1000 and exp(s)=0 when s<-1000.
I am looking for a solution such that s can take on any value in floating point arithmetic. Ideally, I would also really appreciate a solution that allows me to evaluate the value and gradient in a vectorized / efficient way.
How about the following approximations:
– For computing L, if s is large, then exp(s) will be much larger than 1:
1 + exp(s) ≅ exp(s)
and consequently
log(1 + exp(s)) ≅ log(exp(s)) = s.
If s is small, then using the Taylor series of exp()
exp(s) ≅ 1 + s
and using the Taylor series of log()
log(1 + exp(s)) ≅ log(2 + s) ≅ log(2) + s / 2.
– For computing dL, for large s
exp(s) ./ (1 + exp(s)) ≅ 1
and for small s
exp(s) ./ (1 + exp(s)) ≅ 1/2 + s / 4.
– The code to compute L could look for example like this:
s = X*beta;
l = log(1+exp(s));
ind = isinf(l);
l(ind) = s(ind);
ind = (l == 0);
l(ind) = log(2) + s(ind) / 2;
L = 1/N * sum(l,1)
I found a good article about this problem.
Cutting through a lot of words, we can simplify the argument to stating that the original expression
log(1 + exp(s))
can be rewritten as
log(exp(s)*(exp(-s) + 1))
= log(exp(s)) + log(exp(-s) + 1)
= s + log(exp(-s) + 1)
This stops overflow from occurring - it doesn't prevent underflow, but by the time that occurs, you have your answer (namely, s). You can't just use this instead of the original, since it will still give you problems. However, we now have the basis for a function that can be written that will be accurate and won't produce over/underflow:
function LL = logistic(s)
if s<0
LL = log(1 + exp(s));
else
LL = s + logistic(-s);
I think this maintains reasonably good accuracy.
EDIT now to the meat of your question - making this vectorized, and allowing the calculation of the slope as well. Let's take these one at a time:
function LL = logisticVec(s)
LL = zeros(size(s));
LL(s<0) = log(1 + exp(s(s<0)));
LL(s>=0) = s(s>=0) + log(1 + exp(-s(s>=0)));
To obtain the average you wanted:
L = logisticVec(X*beta) / N;
The slope is a little bit trickier; note I believe you may have a typo in your expression (missing a multiplication sign).
dL/dbeta = sum(X * exp(X*beta) ./ (1 + exp(X*beta))) / N;
If we divide top and bottom by exp(X*beta) we get
dL = sum(X ./ (exp(-X*beta) + 1)) / N;
Once again, the overflow has gone away and we are left with underflow - but since the underflowed value has 1 added to it, the error this creates is insignificant.

Plotting Surfaces With 3 Symbolic Variables

First, I need to state that I'm not exactly a math lover or an avid Matlab user. This is college homework that I have been trying to solve for the last 3 hours with no luck. I have googled like crazy, even asked for help via Facebook (where I got replies, but nothing that solved my questions).
This is my first time using this software and I need to graph some things really quick. But no matter how much I read I keep getting syntax errors and the like.
Basically, I have this equation:
4*x^2 + y^2 + z^2 - 8*x + 2*y + 3 = 0
And I'm trying to plot it/graph it. I thought it would be very straightforward but I'm having problems doing it.
Google searches have shown me the functions ezplot() and ezsurf(), but:
When I do ezplot('4*x^2 + y^2 + z^2 - 8*x + 2*y + 3'), I get the following error:
??? Error using ==> char
Cell elements must be character arrays.
Error in ==> ezplot at 158
fmsg = char(f);
And when I do ezsurf('4*x^2 + y^2 + z^2 - 8*x + 2*y + 3')
The expression 4*x^2 + y^2 + z^2 - 8*x + 2*y + 3 must only have 2 symbolic variables
Error in ==> ezgraph3>surfplot at 526
[F,var] = ezfixfun(F,fargs,flabel);
Error in ==> ezgraph3 at 49
[dummy,h] = surfplot(f,domain,surfstyle,cax,Npts,fixdomain,flabel,fargs);
Error in ==> ezsurf at 65
h = ezgraph3('surf',args{:});
Again, this is really my first time using this software. The teacher didn't give us any explanation so I have no idea of what these errors are supposed to mean, let alone solving them. I have no idea of what I'm doing or what I am supposed to do.
I have tried using solve() to solve for 'z' first and then plot the two results I get.
s = solve('4*x^2 + y^2 + z^2 - 8*x + 2*y + 3', 'z')
s =
-(- 4*x^2 + 8*x - y^2 - 2*y - 3)^(1/2)
(- 4*x^2 + 8*x - y^2 - 2*y - 3)^(1/2)
But that's not working either. When I use ezplot() it tells me to use ezsurf, and when I use ezsurf() it tells me about a variable "h" that I have never even declared:
>> ezsurf('-(- 4*x^2 + 8*x - y^2 - 2*y - 3)^(1/2)', '(- 4*x^2 + 8*x - y^2 - 2*y - 3)^(1/2)')
??? Undefined function or variable "h".
Error in ==> ezgraph3 at 66
hh = h;
Error in ==> ezsurf at 65
h = ezgraph3('surf',args{:});
Any help plotting that will be really appreciated. My head is going to explode because people have been telling me this is supposed to be really straightforward.
Thank you!
The following works for me:
ezsurf('(8*x - 4*x^2 - y^2 - 2*y -3)^(1/2)');
Note that ezsurf accepts a function of 2 dimensions (that maps into a 3rd dimension). So you must express the function in the form f(x, y) = blah, where blah is what you want as your input to ezsurf. All I did was re-arrange your function into the form z = blah, and then input blah to ezsurf.
Oh, and two other things, 1) The resulting graph only tells half the story, since the square root of z^2 can be z or minus z (by default, matlab takes the positive square root). 2) The function as above can only be analyzed without complex numbers (such as I've done here) for a very restricted domain of x and y.