Joe Riel

9530 Reputation

23 Badges

20 years, 26 days

MaplePrimes Activity


These are answers submitted by Joe Riel

?NLPSolve doesn't handle symbolic parameters. The variable a must be assigned a numeric value.

Here's an example of computing the minimum velocity of thrown object

deqs := { NULL
          , vx(t) = diff(x(t),t)
          , vy(t) = diff(y(t),t)
          , diff(vx(t),t) = 0
          , diff(vy(t),t) = -1
        }:

ini := { NULL
         , x(0) = 0
         , y(0) = 0
         , vx(0) = 1
         , vy(0) = 1
       }:

proceqs := dsolve(deqs union ini, 'numeric', 'output=listprocedure' ):

Vx := eval(vx(t), proceqs):
Vy := eval(vy(t), proceqs):

V := t -> sqrt(Vx(t)^2+Vy(t)^2):

Optimization:-Minimize(V, 0..2);
[1.00000000000000, [0.999999968364665]]

The problem is that the solution contains symbolic F (F[4]), so you cannot assign the result to F.  For example

F := F[4];
Error, recursive assignment

Just change the lhs

dsol := dsolve(...);

Here's the routine I'd use. It uses some low-level Maple operations to make this reasonably efficient, those might not be suitable for the course you are taking (it sounds like a general programming course).

MergeSort := proc(L1::list, L2::list)
local i,i1,i2,n1,n2,V;

    # Handle empty lists
    if   L1 = [] then return L2;
    elif L2 = [] then return L1;
    end if;
    # Neither list is empty, so we do the merge.
    n1 := numelems(L1);
    n2 := numelems(L2);

    # Allocate Vector to store merged items
    V := Vector(n1+n2);

    # Initialize indices used for L1 and L2.
    i1 := 1;
    i2 := 1;

    # i is the index used for V
    for i to n1+n2 do
        if L1[i1] < L2[i2] then
            V[i] := L1[i1];  # move smaller item to V
            i1 := i1+1;      # increment i1
            # check whether there are more items in L1
            if i1 > n1 then
                # L1 is empty, so the rest comes from L2.
                return [seq(V[i], i=1..i), op(i2..,L2)];
            end if;
        else
            V[i] := L2[i2];
            i2 := i2+1;
            if i2 > n2 then
                # L2 is empty, so the rest comes from L1.
                return [seq(V[i], i=1..i), op(i1..,L1)];
            end if;
        end if;
    end do;
end proc:

Here is the basic idea

MyMod := module()
option package;
export A,B;
   (* assign A and B *)
end module:
LibraryTools:-Save(MyMod, "somewhere/mylib.mla"):

If the directory to "somewhere" is in ?libname, Maple will then find the mla and load it when you do with(MyMod).

To assign libname, you do so in an initialization file. You could, instead, use an explicit assignment in each worksheet you open, but that quickly becomes a pain.  To avoid dealing with the initialization file, you could put the library in a place where Maple should be looking anyway.  The following should work (I use a linux system, so those with Windows may need to tweak this, though forward slashes usually work).

dir := sprintf("%s/maple/toolbox/MyStuff/lib", kernelopts('homedir'));
FileTools:-MakeDirectory(dir, 'recurse');
file := sprintf("%s/MyMod.mla", dir);
LibraryTools:-Save(MyMod, file);

The procedure getListSize is about the worst way to get the size of a list.  Try using ?numelems (or ?nops).

Since this is an assignment, I'm reluctant to just post a solution, but will help if you post some progress. The basic algorithm of a merge sort is pretty straightforward. Keep three indices, one for the output and one for each input list. Compare the associated input list elements, pick the smaller (assuming you are sorting from smallest to largest), move it to output, increment the selected input index and output index.  When one list runs out of items, you can then move the rest of the other list to the output.  Use a Vector for the output structure (you know its size), then convert to a list when done. Before starting the comparison loop, check whether either input list is empty, if so, just send the other to the ouput.

Consider factoring the exponent and solving for those polynomials.

p := 2017*x^2013+2015*y^2013-2033*z^2013-2011:

e := 2013:
F := map2(op,1,ifactors(e)[2]);
                          F := [3, 11, 61]

isolve(subs(e=F[1], p));
isolve(subs(e=F[2], p));
isolve(subs(e=F[3], p));

isolve returns NULL for each.  That doesn't mean there necessarily isn't a solution...

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.

First 40 41 42 43 44 45 46 Last Page 42 of 114