During my exercise with wxmaxima 11.08.0 (ubuntu 12.04, Maxima version: 5.24.0)
I followed an example from P.Lutus and his second example didn't work for me.
eq: y(t) = -r*c*'diff(y(t),t)+m*sin(%omega*t);
sol:desolve( eq, y(t) );
Is %omega zero or nonzero? nonzero
then Maxima isn't reacting anymore until I restart it.
Is there something changed in maxima that I need to activate or define first to get the result ?
The expected output should be:
There is a second part of my question in case I define the equation by hand:
sol: y(t) = (m * sin(%omega*t)) / (%omega^2*c^2*r^2 + 1) -
(%omega*c*m*r*cos(%omega*t)) / (%omega^2*c^2*r^2 + 1) +
(%omega*c*m*r*%e^-((1*t)/(c*r))) / (%omega^2*c^2*r^2 + 1);
Initial conditions for a continuous process:
init_val:-(c*m*r*(%e^-(t/r*c))*%omega)/(c^2*r^2*%omega^2+1);
atvalue(y(t),t=0, init_val);
try2 : desolve(sol,y(t));
"Is "%omega" zero or nonzero?" nonzero;
Here the last term is still there. Are these problems based on the use of trigonometric functions ?
Best regards,
Marcus
I updated via PPA to wxMaxima 13.04.0 & Maxima 5.29.1. Now desolve fnished, but the last term seems very complicated.
Doing the init_val with the negativ last term and desolve command still leaves the %e^(..)*... in the equation.
You might get more interest in this question on the Maxima mailing list. See: http://maxima.sourceforge.net/maximalist.html
For the first version of Lutus example 2, I get:
y(t) = m*sin(%omega*t)/(%omega^2*c^2*r^2+1)
-%omega*c*m*r*cos(%omega*t)/(%omega^2*c^2*r^2+1)
+(y(0)*%omega^2*c^3*r^3+%omega*c^2*m*r^2+y(0)*c*r)*%e^-(t/(c*r))
/(c*r*(%omega^2*c^2*r^2+1))$
which is the same as the expected result, if y(0) = 0. However, I don't see where that is assumed.
After atvalue(y(t),t=0,init_val), I get the same result as Lutus, namely:
y(t) = m*sin(%omega*t)/(%omega^2*c^2*r^2+1)
-%omega*c*m*r*cos(%omega*t)/(%omega^2*c^2*r^2+1)$
I am working with Maxima 5.31.1, built with Clisp, on Linux.
Related
I have a working GAMS optimization model using LP. I want to modify one of my equations so that it excludes one of the terms when t = 1. Here's the simplification of this problem:
Set t "time in hours" / 1 * 8760/ ;
If t = 1:
vDemand(t) =e= p1*(vInternal(t) - pAmbient(t))
else:
vDemand(t) =e= p1*(vInternal(t) - pAmbient(t)) + p2*(vInternal(t) - vInternal(t-1))
How do I modify this vDemand equation while keeping my optimization linear?
I looked up and tried the different ways to incorporate conditional statements on GAMS, but not successful so far.
vDemand(t) =e= p1*(vInternal(t) - pAmbient(t)) + (p2*(vInternal(t) - vInternal(t-1)))$(ord(t)>1);
The $ condition at the end of the second term makes sure, that that part is only used, if it is not the first element of the set t.
In[11]:= $Version
Out[11]= 9.0 for Linux x86 (32-bit) (November 20, 2012)
In[12]:= DSolve[{f[0] == d, f'[0] == v0, f''[t] == g*m2/f[t]^2}, f, t]
DSolve::bvimp: General solution contains implicit solutions. In the boundary
value problem these solutions will be ignored, so some of the solutions will
be lost.
Out[12]= {}
The code above pretty much says it all. I get the same error if I replace g*m2 with 1.
This seems like a really simple DFQ to solve. I'd like to tell DSolve to assume all variables are real and that d, g, and m2 are all greater than 0, but there's unfortunately no way to do that.
Thoughts?
You are trying for a symbolic solution. And unfortunately, symbolic integration is hard (while symbolic differentiation is easy).
The way this integration works is to obtain the energy functional by integrating once
E = 1/2*f'[t]^2 + C/f[t]
and then to isolate f'[t]. The resulting integral is not easy to solve and leads to the mentioned implicit solutions.
Did you really want to get the symbolic solution or only some function table to plot the solutions or compute other related quantities?
Since it was clarified that the requested quantity is the maximum of certain solutions: This can be computed by setting v=0 in the energy equation
C/x = E = 1/2*v0^2 + C/x0
or
x = C*x0/(C + 1/2*v0^2*x0 )
One would have to analyze the time aspect to make sure that this extremum is reached before passing again at the initial point x0.
I am trying to solve the following equation in my program:
7.7^2 x 0.012^2/(0.2145 x 1.67^(16/3))
That should equal : 0.002582 (this is verified w/ google & scientific calculator)
This is the code that I am using
CGFloat eX1 = pow(7.7, 2) * pow(0.012, 2)/(0.2145 * pow(1.67, (16/3)));
NSLog(#"%f",eX1);
And even though, I believe my code should give me the same results, it's actually giving me:0.002679
What am I doing wrong? What can I do to obtain the correct answer?
Change (16/3) to (16.0/3.0). Otherwise 16/3 results in 5, not 5.33333349.
And you have 7.2 instead of 7.7 at the start.
I finally got the formula for the distance from a curve to a point running:
approx = 2 * (b * (Math.Log(a) * (Math.Log(k) * Math.Pow(k, (b * cycleX))) * Math.Pow(a, (Math.Pow(k, (b * cycleX)))) * (Math.Pow(a, (Math.Pow(k, (b * cycleX))))) - points[i].Y) + cycleX - points[i].X);
So, as approx goes closer to 0, the cycleX gives me the right coordinate from which to calculate the distance to the point.
The only issue here is defining a way to modify cycleX. I tried using a series of if's, but with them sometimes approx ends up jumping on to positive numbers (coming from negatives). What should I do to get the right modification to the value of cycleX?
Note: It usually needs to come down to 0.0001 to get something within the range of -1 to 1.
For this kind of problem, it's often useful to know about Newton's method:
Of course, the forumula for that is
Of course, besides the fact that for some functions this quite unstable (I don't expect yours to be, though), implemented purely for your case, it would mean you would need to calculate yet another derivative (of your derivative)! However, I think for your case, you might be able to just approximate the derivative.
You didn't mention the language your implementation would eventually be in, so I'll just use javascript for convenience.
To estimate your derivative, simply choose a deltaX that would be convenient.
So if you have a function
var df = function (cycleX) {
return 2 * (b * (Math.log(a) * (Math.log(k) * Math.pow(k, (b * cycleX))) * Math.pow(a, (Math.pow(k, (b * cycleX)))) * (Math.pow(a, (Math.pow(k, (b * cycleX))))) - Y) + cycleX - X);
};
you can estimate it's derivative via
y = df(cycleX);
y1 = (df(cycleX + deltaX) - y) / deltaX;
And then proceed via.
cycleXnew = cycleX - y / y1;
And then it's just a matter of looping until it converges (or not).
See example jsFiddle: http://jsfiddle.net/jfcox/3wRtj/
Edit: I give no guarantees as to how fast it might converge or even how well an estimated derivative would work with respect to Newton's method. For the parameters I've tried given your function f(x) = a^(k^(bx)), it seems to work well, but I haven't tried much.
Edit II. Of course, the above jsFiddle also assumes only a single solution that we'd need to search for.
The following is the pseudocode I got from a TopCoder tutorial about binary search
binary_search(A, target):
lo = 1, hi = size(A)
while lo <= hi:
mid = lo + (hi-lo)/2
if A[mid] == target:
return mid
else if A[mid] < target:
lo = mid+1
else:
hi = mid-1
// target was not found
Why do we calculate the middle value as mid = lo + (hi - lo) / 2 ? Whats wrong with (hi + lo) / 2
I have a slight idea that it might be to prevent overflows but I'm not sure, perhaps someone can explain it to me and if there are other reasons behind this.
Although this question is 5 years old, but there is a great article in googleblog which explains the problem and the solution in detail which is worth to share.
It's needed to mention that in current implementation of binary search in Java mid = lo + (hi - lo) / 2 calculation is not used, instead the faster and more clear alternative is used with zero fill right shift operator
int mid = (low + high) >>> 1;
Yes, (hi + lo) / 2 may overflow. This was an actual bug in Java binary search implementation.
No, there are no other reasons for this.
From later on in the same tutorial:
"You may also wonder as to why mid is calculated using mid = lo + (hi-lo)/2 instead of the usual mid = (lo+hi)/2. This is to avoid another potential rounding bug: in the first case, we want the division to always round down, towards the lower bound. But division truncates, so when lo+hi would be negative, it would start rounding towards the higher bound. Coding the calculation this way ensures that the number divided is always positive and hence always rounds as we want it to. Although the bug doesn't surface when the search space consists only of positive integers or real numbers, I've decided to code it this way throughout the article for consistency."
It is indeed possible for (hi+lo) to overflow integer. In the improved version, it may seem that subtracting lo from hi and then adding it again is pointless, but there is a reason: performing this operation will not overflow integer and it will result in a number with the same parity as hi+lo, so that the remainder of (hi+lo)/2 will be the same as (hi-lo)/2. lo can then be safely added after the division to reach the same result.
Let us assume that the array we're searching in, is of length INT_MAX.
Hence initially:
high = INT_MAX
low = 0
In the first iteration, we notice that the target element is greater than the middle element and so we shift the start index to mid as
low = mid + 1
In the next iteration, when mid is calculated, it is calculated as (high + low)/2
which essentially translates to
INT_MAX + low(which is half of INT_MAX + 1) / 2
Now, the first part of this operation i.e. (high + low) would lead to an overflow since we're going over the max Int range i.e. INT_MAX
Because Unsigned right shift is not present in Go programming, To avoid integer overflow while calculating middle value in Go Programming language we can write like this.
mid := int(uint(lo+hi) >> 1)
Why question is answered but it is not easy to understand why solution works.
So let's assume 10 is high and 5 is low. Assume 10 is highest value integer can have ( 10+1 will cause overflow ).
So instead of doing (10+5)/2 ≈ 7 ( because 10 + anything will lead overflow).
We do 5+(10-5)/2=> 5 + 2.5 ≈ 7