Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are answers submitted by Joe Riel

If the pendulum is created with Multibody components then there currently is no way to do this. If you created the pendulum with a custom Modelica component, then it is doable.  Here is a model of a simple pendulum whose angular velocity is reversed at a given time.

model Pendulum "angle is reinitialized at t=4"
    import pi=Modelica.Constants.pi;
    parameter Real g = 10 "gravitational acceleration";
    parameter Real r = 1  "radius of pendulum";
    Real theta "angle from straight down";
    Real omega "angular velocity";
initial equation
    theta=pi/4;
equation
    omega = der(theta);
    der(omega) = -g/r*sin(theta);
    when time > 4 then
// A reinit can only be used inside a when-statement
reinit(omega, -omega);
    end when;
end Pendulum;

You could make the condition to the when-statement (here 'time > 4') a boolean input signal and the new angle a real input signal, then use that to reinitialize to the desired angle.

Followup

I was wrong; it is possible to reinitialize a Multibody component.  The technique is to monitor the quantity of interest and reinitialize it using the method shown above.  This model, reinit-pendulum.msim, demonstrates the technique.

Consider using ?odeplot

odeplot(soln, [t, r(t)], 0..10, numpoints=1000);
(**) f := proc(L) local el; `or`(seq(`and`(el[]), el = L)) end proc:
(**) L := [[x>5, x<10], [x < 0]]:                                   
(**) f(L);                                                          
                                  5 < x and x < 10 or x < 0

The immediate problem is that the second argument to the subs includes the expression p1(k).  k is purely symbolic, so U(k), in p1, will not terminate. There is also a call to p0(k-1), with p0 not assigned.

While presumably you are supposed to write a procedure to solve this numerically, we can, instead, use Maple's ?rsolve procedure to solve this linear recurrence:

eqs := { A(n+1)=2*A(n), A(0)=70 }:
rsolve(eqs,A(k));
                                         k
                                     70 2

That should enable you to check the result.  I'll implement a slightly different recurrence to demonstrate the basic technique. Say we were given

eq := B(n+2) = 2*B(n+1) + B(n):
ini := { B(0) = 0, B(1) = 1 }:

First, transform the equation so that it expresses B(n) in term of lower values of n:

eq1 := eval( eq, n = n-2);
                        eq1 := B(n) = 2 B(n - 1) + B(n - 2)

Use ?unapply to convert the right-hand side of eq1 to a procedure

 B := unapply(rhs(eq1), n, 'proc_options=remember');
                      B := proc(n) option remember; 2*B(n - 1) + B(n - 2) end proc

Assign the initial values (this is actually a bit tricky in that it is assigning values to B's remember table).

B(0) := 0:
B(1) := 1:

Evaluate the procedure

B(100);
                   66992092050551637663438906713182313772

My guess is that you are supposed to include the initial values in the procedure. That could be done by writing the procedure manually

B := proc(n)
option remember; # improves efficiency for large n. Try without it.
    if n = 0 then 0;
    elif n = 1 then 1;
    else 2*B(n-1) + B(n-2)
    end if;
end proc:

B(100);
                    66992092050551637663438906713182313772





Note that the symbolic variable t is included in your expression.  That will prevent evalf from returning a result.

 

I prefer to either use the ?read command:

read "some_maple_script":

or

pass the filename on the command line when launching the application:

cmaple -F some_maple_script

The -F option prevents Maple from exiting after reading the file.

In X (linux), text can be pasted with the middle button of the mouse, at least with an xterm. That won't work on Windows. I think you can click on the upper left corner and bring up a menu that has an option for copy/paste, however, its been a while since I've used Windows and cut-n-paste into a dos shell was always a pain.

 

 

There are a few packages for doing this.  I wrote one years ago, called "glyph", however, it was written for Maple V release 5, so you will probably have issues installing it.  It's in the Maple Application Center. Rafal Ablamowicz has written a package named Clifford, but I haven't looked at in quite a while.

A different way to do this is

add(charfcn[-infinity..-1](x), x = L);

Use y1(t) where you have y1.  What is the y2 doing there?  Why are there different equations for the initial condition y1(0)? Maybe you meant to specify D(y1)(0) (derivative of y1 at t=0)?

W:=add((k^(2*i))*add((e^(j))*w[i,j](r,t),j=0..2),i=0..2):
P:=add((k^(2*i+1))*add((e^(j))*w[i,j](r,t),j=0..2),i=0..2):
expand((k/(2*r))*(diff(W,r)*diff(P,t)-diff(W,t)*diff(P,r)));

                                                                0

Technically that input is but one Maple statement, a call to rtable_scanblock with four arguments. 

The first argument, M, is the rtable (Array, Matrix, etc) that will be scanned. 

The second argument, [rtable_dims(M)], evaluates to a list of ranges and specifies the portion of M to be scanned. In this case it specifies the entire rtable.

The third argument is the procedure that is used for the scanning.  It takes three arguments, val, ind, res.  During the scan, this procedure will be applied to each entry in M.  The first argument, val, will be passed the value stored in M.  The second argument, ind, will be passed a list corresponding to the index of the entry.  The third argument, res, will be passed the result of the previous call to this procedure.  The procedure itself returns a list of two items, index and value of the largest entry found so far.  If the new value is greater than what was stored, its index and value is returned, otherwise the old one is. 

The final argument to rtable_scanblock is the initial value used for the 'res' argument in the previously described procedure. The returned result of the call to rtable_scanblock is the final value of res, which is a list consisting of a list of the indices of the maximum value and the maximum value.

If you want to better understand how this operates, modify the scanning procedure so that it calls the debugger:

rtable_scanblock(M, rtable_dims(M), 
proc(val,ind,res)
DEBUG();
if val > res[2] then [ind,val] else res fi;
end proc, [[1,1],-infinity]);

then you can step through the procedure as it is called by rtable_scanblock.

There is a subtle flaw with this statement.  Can you figure out what it is?  How can it be corrected?

The Maple assignment operator is :=, so do

A[1] := B[3];

 

 

eqs := [23*c1^5 + c1^4 = 13, a*c1^5 = 2]:
x := [c1^5, c1^4]:
feq := map( x -> x = freeze(x), x):
subs(feqs, eqs);
    [23 freeze/R0 + freeze/R1 = 13, a freeze/R0 = 2]
LinearAlgebra:-GenerateMatrix(%, rhs~(feqs));
                             [23    1]  [13]
                             [       ], [  ]
                             [a     0]  [ 2]




Is this what you want?

try
   X := timelimit(1, f(...));
catch "time expired":
   X := _some_other_value;
end try;
First 41 42 43 44 45 46 47 Last Page 43 of 114