Joe Riel

9560 Reputation

23 Badges

18 years, 324 days

MaplePrimes Activity

These are answers submitted by Joe Riel

The best way to do this is put the Maple source in ascii files and use version control on them.  Use either a read statement in a worksheet to read the source, or, better, create an mla (Maple Library Archive file) from the source, install it in a custom toolbox and use it from any Maple interface. 

Did you try what I suggested for your related question?  You should be able to use the same technique for a completely custom port, just enter the name you gave for the custom port in the text area. Hmm.  I see that there is a bug.  You can work around it by first inserting a copy of the custom port you created onto the main MapleSim canvas, then reclicking the Apply Custom button in the Custom Component Template (see my directions at your other post).

  1. Add a port
  2. In the Type: combo-box, select Custom (it's the last choice).
  3. In the text-area below that, enter Modelica.Thermal.FluidHeatFlow.Interfaces.FlowPort
  4. Click the Apply Custom button

The rest should be handled as any other port.  You'll see signals for the pressure, enthalpy, mass flow rate and enthalpy flow rate.

Use evalf:

sol := solve(g(x)>0,[x]):
                    [[x < -0.3399702769], [1.278826630 < x]]

Pass a positive integer as the second argument to evalf to select the number of digits

evalf(sol, 20);

Can you give an example?  If it is a differential equation you might be able to use DynamicSystem:-Linearize.

There are several things wrong with your usage:

  1. S, L, and B are not parameters, they are variables.  In the equations they should appear as S(t), etc. The use of ODETools[declare] might avoid that, but makes specifying the initial conditions more difficult.
  2. gamma has special meaning in Maple; use another variable (I used g)
  3. initial conditions must be equations, not inequalities

I may have forgotten another.  Here is a corrected version

init_conds := S(0) = 0, L(0) = 0, B(0) = 0;
sys := {init_conds
        , diff(B(t), t) = L(t)*g-g*mu
        , diff(L(t), t) = L(t)*S(t)*beta-(g+mu)*S(t)
        , diff(S(t), t) = -L(t)*S(t)*beta-`μS`+mu
sol := dsolve(sys, 'numeric', 'parameters' = [mu, `μS`,beta, g], 'method = rkf45');

First, it is usually better to upload your worksheet (use the green arrow), that makes it much easier for us to try what you've done.

You can create an Array with elements from -5 to 5: 

n := 5:
U := Array(-n .. n, -n .. n):

You are executing convert(U, Matrix). By itself that returns a Matrix, however, it does not affect U, which remains an Array. That is fine, since a Maple Matrix always has indices that start at 1.

The pathname you show is almost certainly wrong in that backslashes (is this a Windows server?) need to be escaped in a Maple string. For  your example, the appropriate string would be "\\drivename\\filename.txt".  Using single forward slashes (Unix path separators) will generally work.

Part of the problem is that either computation is so fast it will be hard to see a difference. The other part is that your algorithm won't create separate tasks, you've done the entire computation in one thread. It looks to me like you are computing the sum of an integral for parameters in an array. A better way to write that would be the following, which allows computing each integral in a separate thread.

L1 := 10:
f := x ->evalf(Int(sin(beta)/(100 + ZZ*sin(beta) - x*cos(beta))^(5/2), beta = 0 .. 1, ZZ = 0 .. L1, 'epsilon' = 0.01, method = _cuhre)):

# Create a large array of parameters 
xx := Array(RandomTools:-Generate(list(float(range=0..98),10000))):
# Perform the computations and compare the times
CodeTools:-Usage(add(f(x), x=xx));
CodeTools:-Usage(Threads:-Add(f(x), x=xx));

With that, I get a real time speed up of about 2x

Yes, the model incorporates back-emf.  The K constant is used to compute the back emf from the rotational velocity, as well as the torque from the current. The device equations are shown in the help page.

However, you shouldn't believe me---it's better to test the model yourself.  Do it the same way as you'd measure the back-emf in an actual motor:  turn the shaft and measure the open-circuit voltage.

@Earl The form you gave is a discrete event with a conditional trigger.  Discrete events occur during event iteration, which only occurs when there are discrete variables.  Event iteration is initiated by a continuous trigger.

Here's a brute force attempt to solve this. To make it checkable, I generalized the problem to an n-sided die, with markings from 1 to n. To make the run-time reasonable, the procedure Check, which checks whether all the digits have occurred, is compiled. For n = 5 it runs in about 1 minute. I haven't tried it with n=6, but expect it to take quite a while. The print statement prints the length of the current run that is being tested, that is there to give a relative feedback on progress.

Straight := module()
    ModuleApply := proc(n :: posint)
    local C, N, R, T, cnt, len;
        C := Array(1..n, 'datatype' = integer[4]);
        for len from n do
            N := n^len;
            R := Iterator:-MixedRadixTuples([n $ len]);
            cnt := 0;
            for T in R do
                C[] := 0;
                if Check(T,C,len,n) then
                    cnt := cnt+1;
                end if
            end do;
            if cnt/N >= 1/2 then
                return len;
            end if;
        end do;
    end proc;

    Check := proc(T :: Array, C :: Array, len :: posint, n :: posint)
    option autocompile;
    local k;
        for k to len do
            C[T[k]+1] := 1;
        end do;
        for k to n do
            if C[k] = 0 then
                return false;
            end if;
        end do;
        return true;
    end proc;

end module:


While it presumably won't help here as the suggested solutions are efficient and avoid set building altogether, since Maple 2016 there is an object, MutableSet, that has efficient methods for manipulating sets in Maple.

Use profiling.  There are exports in CodeTools:-Profiling that will help, but I generally use the low level commands.  For example

foo := proc(n::posint)
local i;
   # inefficient way to build a sequence
   s := NULL; 
   for i to n do
       s := s,i;
   end do;
end proc:
# set up profiling on foo
debugopts('traceproc' = foo):
# execute the procedure
# display the results
printf("%s\n", debugopts('procdump'=foo)):
foo := proc(n::posint)
local i, s;
     |Calls Seconds  Words|
PROC |    1   0.000   5447|
   1 |    1   0.000      0| s := NULL;
   2 |    1   0.000      0| for i to n do
   3 |  100   0.000   5447|     s := s, i
                            end do;
   4 |    1   0.000      0| s

That example wasn't particularly enlightening, but try it on your own procedure. Depending on what your procedure does, you might want to set debugopts('tracerealtime'=true) first, it causes the profiler to measure the actual elapsed time, versus the time taken in the Maple kernel.

The call to evalf is outside your loop.  When the loop exits, i is assigned 9 (1 more than the to value).

First 13 14 15 16 17 18 19 Last Page 15 of 114