This might seem a dumb question but its been a few hours I search about it without really finding exactly what I'm seeking for.
In Maple, if you have a polynomial like this:
How do I convert this expression to an expression that has floating point coefficients (s^3 + 19s^2 + 89.13s + 71.13) within Maple?
This should just be embedded in the collect() function in my opinion (like a parameter 'float'). Right now I have to calculate myself each polynomial myself (only using Maple to simplify some lengthy calculations in a physics class), which is downright retarded.
Thanks!
There is no need to use (or introduce) any explicitly written float coefficient just to get your desired effect. And indeed you may have good reason to want to have all coefficients be exact, perhaps for some earlier computations.
restart;
S := (s+9-Pi) * (s+9+Pi) * (s+1):
sort( evalf( expand(S) ), s, ascending );
2 3
71.13039560 + 89.13039560 s + 19. s + s
sort( evalf( expand(S) ), s, descending );
3 2
s + 19. s + 89.13039560 s + 71.13039560
The above may be useful to you, if this is not adequate:
evalf( expand(S) );
3 2
s + 19. s + 89.13039560 s + 71.13039560
The easiest way to evaluate your results using floating point approximation is to use the evalf command:
evalf(collect((s+9+Pi)*(s+9+Pi)*(s+1),s));
returns
147.4182721+s^3+25.28318530*s^2+171.7014573*s
If you are really just interested in floating point results, it is worth noting that if one or more of the terms in your original expression is floating point, Maple will evaluate the results in floating point. For example:
collect((s+9.+Pi)*(s+9+Pi)*(s+1),s);
Also note that I changed your use of lower-case pi (the Greek letter) to Pi (the mathematical constant) in the code above.
Related
I have a few simple equations that I want to pipe through matlab. But I would like to get exact answers, because these values are expected to be used and simplified later on.
Right now Matlab shows sqrt(2.0) as 1.1414 instead of something like 2^(1/2) as I would like.
I tried turning on format rat but this is dangerous becasue it shows sqrt(2) as 1393/985 without any sort of warning.
There is "symbolic math" but it seems like overkill.
All I want is that 2 + sqrt(50) would return something like 2 + 5 * (2)^(1/2) and even my 5 years old CASIO calculator can do this!
So what can I do to get 2 + sqrt(50) evaluate to 2 + 5 * (2)^(1/2) in matlab?
As per #Oleg's comment use symbolic math.
x=sym('2')+sqrt(sym('50'))
x =
5*2^(1/2) + 2
The average time on ten thousand iterations through this expression is 1.2 milliseconds, whilst the time for the numeric expression (x=2+sqrt(50)) is only 0.4 micro seconds, i.e. a factor of ten thousand faster.
I did pre-run the symbolic expression 50 times, because, as Oleg points out in his second comment the symbolic engine needs some warming up. The first run through your expression took my pc almost 2 seconds.
I would therefore recommend using numeric equations due to the huge difference in calculation time. Only use symbolic expressions when you are forced to (e.g. simplifying expressions for a paper) and then use a symbolic computation engine like Maple or Wolfram Alpha.
Matlab main engine is not symbolic but numeric.
Symbolic toolbox. Create expression in x and subs x = 50
syms x
f = 2+sqrt(x)
subs(f,50)
ans =
50^(1/2) + 2
I am trying to calculate some integrals that use very high power exponents. An example equation is:
(-exp(-(x+sqrt(p)).^2)+exp(-(x-sqrt(p)).^2)).^2 ...
./( exp(-(x+sqrt(p)).^2)+exp(-(x-sqrt(p)).^2)) ...
/ (2*sqrt(pi))
where p is constant (1000 being a typical value), and I need the integral for x=[-inf,inf]. If I use the integral function for numeric integration I get NaN as a result. I can avoid that if I set the limits of the integration to something like [-20,20] and a low p (<100), but ideally I need the full range.
I have also tried setting syms x and using int and vpa, but in this case vpa returns:
1.0 - 1.0*numeric::int((1125899906842624*(exp(-(x - 10*10^(1/2))^2) - exp(-(x + 10*10^(1/2))^2))^2)/(3991211251234741*(exp(-(x - 10*10^(1/2))^2) + exp(-(x + 10*10^(1/2))^2)))
without calculating a value. Again, if I set the limits of the integration to lower values I do get a result (also for low p), but I know that the result that I get is wrong – e.g., if x=[-100,100] and p=1000, the result is >1, which should be wrong as the equation should be asymptotic to 1 (or alternatively the codomain should be [0,1) ).
Am I doing something wrong with vpa or is there another way to calculate high precision values for my integrals?
First, you're doing something that makes solving symbolic problems more difficult and less accurate. The variable pi is a floating-point value, not an exact symbolic representation of the fundamental constant. In Matlab symbolic math code, you should always use sym('pi'). You should do the same for any other special numeric values, e.g., sqrt(sym('2')) and exp(sym('1')), you use or they will get converted to an approximate rational fraction by default (the source of strange large number you see in the code in your question). For further details, I recommend that you read through the documentation for the sym function.
Applying the above, here's a runnable example:
syms x;
p = 1000;
f = (-exp(-(x+sqrt(p)).^2)+exp(-(x-sqrt(p)).^2)).^2./(exp(-(x+sqrt(p)).^2)...
+exp(-(x-sqrt(p)).^2))/(2*sqrt(sym('pi')));
Now vpa(int(f,x,-100,100)) and vpa(int(f,x,-1e3,1e3)) return exactly 1.0 (to 32 digits of precision, see below).
Unfortunately, vpa(int(f,x,-Inf,Inf)), does not return an answer, but a call to the underlying MuPAD function numeric::int. As I explain in this answer, this is what can happen when int cannot obtain a result. Normally, it should try to evaluate the the integral numerically, but your function appears to be ill-defined at ±∞, resulting in divide by zero issues that the variable precision quadrature methods can't handle well. You can evaluate the integral at wider bounds by increasing the variable precision using the digits function (just remember to set digits back to the default of 32 when done). Setting digits(128) allowed me to evaluate vpa(int(f,x,-1e4,1e4)). You can also more efficiently evaluate your integral over a wider range via 2*vpa(int(f,x,0,1e4)) at lower effective digits settings.
If your goal is to see exactly how much less than one p = 1000 corresponds to, you can use something like vpa(1-2*int(f,x,0,1e4)). At digits(128), this returns
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086457415971094118490438229708839420392402555445545519907545198837816908450303280444030703989603548138797600750757834260181259102
Applying double to this shows that it is approximately 8.6e-89.
As I've written in the title, I'm trying to find the exact distance (dimensionless distance in this case) when two functions start to differ from each other a 5% of the Y-axis. The two functions intersect at the value of 1 in the X-axis and I need to find the described distance before the intersection, not after (i.e., it must be less than 1). I've written a Matlab code for you to see the shape of the functions and the following calculations which I'm trying to make them work but they don't, I don't know why. "Explicit solution could not be found".
I don't know if I explained it clearly. Please let me know if you need a more detailed explanation.
I hope you can throw some light in this issue.
Thank you so much in advanced.
r=0:0.001:1.2;
ro=0.335;
rt=r./ro;
De=0.3534;
k=2.8552;
B=(2*k/De)^0.5;
Fm=2.*De.*B.*ro.*[1-exp(B.*ro.*(1-rt))].*exp(B.*ro.*(1-rt));
A=5;
b=2.2347;
C=167.4692;
Ftt=(C.*(exp(-b.*rt).*((b.^6.*rt.^5)./120 + (b.^5.*rt.^4)./24 + (b.^4.*rt.^3)./6 + (b.^3.*rt.^2)./2 + b.^2.*rt + b) - b.*exp(-b.*rt).*((b.^6.*rt.^6)./720 + (b.^5.*rt.^5)./120 + (b.^4.*rt.^4)./24 + (b.^3.*rt.^3)./6 + (b.^2.*rt.^2)./2 + b.*rt + 1)))./rt.^6 - (6.*C.*(exp(-b.*rt).*((b.^6.*rt.^6)./720 + (b.^5.*rt.^5)./120 + (b.^4.*rt.^4)./24 + (b.^3.*rt.^3)./6 + (b.^2.*rt.^2)./2 + b.*rt + 1) - 1))./rt.^7 - A.*b.*exp(-b.*rt);
plot(rt,-Fm,'red')
axis([0 2 -1 3])
xlabel('Dimensionless distance')
ylabel('Force, -dU/dr')
hold on
plot(rt,-Ftt,'green')
clear rt
syms rt
%assume(0<rt<1)
r1=solve((Fm-Ftt)/Ftt==0.05,rt)
r2=solve((Ftt-Fm)/Fm==0.05,rt)
Welcome to the crux of floating point data. The reason why is because for the values of r that you are providing, the exact solution of 0.05 may be in between two of the values in your r array and so you won't be able to get an exact solution. Also, FWIW, your equation may never generate a solution of 0.05, which is why you're getting that error too. Either way, doing that explicit solve on floating point data is never recommended, unless you know very well how your data are shaped and what values you expect for the output of the function you're applying the data to.
As such, it's always recommended that you find the nearest value that satisfies your condition. As such, you should do something like this:
[~,ind] = min(abs((Fm-Ftt)./Ftt - 0.05));
r1 = r(ind);
The first line will find the nearest location in your r array that satisfies the 5% criterion. The next line of code will then give you the value that is in your r array that satisfies this. You can do the same with r2 by:
[~,ind2] = min(abs((Ftt-Fm)./Fm - 0.05));
r2 = r(ind2);
What the above code is basically doing is that it is trying to find at what point in your array would the difference between your data and 5% be 0. In other words, which point in your r array would be close enough to make the above relation equal to 0, or essentially when it is as close to 5% as possible.
If you want to improve this, you can always change the step size of r... perhaps make it 0.00001 or something. However, the smaller the step size, the larger your array and you'll eventually run out of memory!
I would like to know how can I get both the positive and the negative solution from a sqrt in Matlab.
For example if I have:
sin(a) = sqrt(1-cos(a)^2);
The docs don't say anything specific about always only providing the positive square root but it does seem like a fair assumption in which case you can get the negative square pretty easily like this:
p = sqrt(1-cos(a)^2);
n = -sqrt(1-cos(a)^2);
btw assigning to sin(a) like that is going to create a variable called sin which will hide the sin function leading to many possible errors, so I would highly recommend choosing a different variable name.
MATLAB (and every other programming language that I know of) only returns the principal square root of x when calling sqrt(x) or equivalent.
How you'd write the square root of x mathematically, is
s = ±√x
which is just a shorthand for writing the whole solution set
s = {+√x -√x}
In MATLAB, you'd write it the same as this last case, but with slightly different syntax,
s = [+sqrt(x) -sqrt(x)]
which can be computed more efficiently if you "factor out" the sqrt:
s = sqrt(x) * [1 -1]
So, for your case,
s = sqrt(1-cos(a)^2) * [1 -1]
or, if you so desire,
s = sin(acos(a)) * [1 -1]
which is a tad slower, but perhaps more readable (and actually a bit more accurate as well).
Now of course, if you can somehow find the components whose quotient results in the value of your cosine, then you wouldn't have to deal with all this messy business of course....
sqrt does not solve equations, only gives numerical output. You will need to formulate your equation as you need it, and then you can use sqrt(...) -1*sqrt(...) to give your positive and negative outputs.
So I'm completely new to MATLAB and I'm trying to understand colon notation within mathematical operations. So, in this book I found this statement:
w(1:5)=j(1:5) + k(1:5);
I do not understand what it really does. I know that w(1:5) is pretty much iterating through the w array from index 1 through 5, but in the statement above, shouldn't all indexes of w be equal to j(5) + k(5) in the end? Or am I completely wrong on how this works? It'd be awesome if someone posted the equivalent in Java to that up there. Thanks in advance :-)
I am pretty sure this means
"The first 5 elements of w shall be the first 5 elements of j + the first 5 elements of k" (I am not sure if matlab arrays start with 0 or 1 though)
So:
w1 = j1+k1
w2 = j2+k2
w3 = j3+k3
w4 = j4+k4
w5 = j5+k5
Think "Vector addition" here.
w(1:5)=j(1:5) + k(1:5);
is the same that:
for i=1:5
w(i)=j(i)+k(i);
end
MATLAB uses vectors and matrices, and is heavily optimized to handle operations on them efficiently.
The expression w(1:5) means a vector consisting of the first 5 elements of w; the expression you posted adds two 5 element vectors (the first 5 elements of j and k) and assigns the result to the first five elements of w.
I think your problem comes from the way how do you call this statement. It is not an iteration, but rather simple assignment. Now we only need to understand what was assigned to what.
I will assume j,k, w are all vectors 1 by N.
j(1:5) - means elements from 1 to 5 of the vector j
j(1:5) + k(1:5) - will result in elementwise sum of both operands
w(1:5) = ... - will assign the result again elementwise to w
Writing your code using colon notation makes it less verbose and more efficient. So it is highly recommended to do so. Also, colon notation is the basic and very powerful feature of MATLAB. Make sure you understand it well, before you move on. MATLAB is very well documented so you can read on this topic here.