Joe Riel

9660 Reputation

23 Badges

20 years, 3 days

MaplePrimes Activity


These are answers submitted by Joe Riel

How do you want the component to behave?  You could add a hard stop in parallel with the spring to prevent it from compressing to zero.

Unless the integral is zero over the interval, there is no reason to expect that the integral values should match at the end points.

One way to find the answer is to enter a floating point, right click on the output. The context sensitive menu includes a Conversions menu which includes rational and exact rational.  Selecting either one enters the appropriate command in an input section.

You could declare them as exports.  Because the module has option package, they will be automatically protected.

What are you hoping to accomplish?  Is this for math input, or purely notational?  In 2D math I can type a^~, which generates an a with a tilde superscript and is parsed as an inert form: `#msup(mi("a"),mo("˜"))`.  

A likely cause is that you were not comparing the numbers directly, but rather as part of a larger structure.  For example

evalb( 20 = 20. );
                              true
evalb( [20] = [20.] );
                              false

For this you could use verify

verify([20], [20.], list);
                                      true

 

A standard matrix representation of a state-space system, which is what DynamicSystems uses, cannot represent the derivative of an input signal. It could be handled by replacing the derivative with an independent signal, call it du(t), but then you would have to supply two inputs, u(t) and du(t).  The transfer function form can handle this, though it could (not in this case) result in one with an improper transfer function. A system with an improper transfer function (degree of numerator greater than degree of denominator) cannot be converted to a state-space system.

The conversion to a state-space system could be modified to use the Transfer Function approach if a direct conversion fails; some of the routines in DynamicSystems already do this. 

Try using LibraryTools:-Save to save the package.  It should be saved to a .mla file, not a .m file. You should be able to do something like

LibraryTools:-Save('HINHHOC9', cat(url, "/HINHHOC9.mla"));

 You'll want to delete the HINHHOC9.m file that you previously created.

 

NOTE: Save (not SaveLib) is the procedure you want. Fixed example.

A more efficient technique is to use the Iterator package available in the Maplesoft Application Center.  For example

with(Iterator):
m := 2:
n := 3:
P := MixedRadixTuples([3 $ m*n]):
(h,g) := ModuleIterator(P):
# Create a Matrix alias to the Vector used by the iterator
M := ArrayTools:-Alias(g(),[m,n]):
in P do printf("%{}d\n\n",M); end do:
0 0 0
0 0 0
0 0 0
0 0 1
0 0 0
0 0 2
0 0 1
0 0 0
0 0 1
0 0 1
...

In the following code I used the BinaryGrayCode export of the Iterator package, available in the Maple Application Center, to implement the Ryser algorithm. 

 

permanentRyser4 := proc(M::Matrix)
local G, V, aj, g, h, i, j, k, m, n, s, sj, sig;
m, n := op(1, M);
if m <> n then
error "expecting a square Matrix, got dimensions %1, %2", m, n
end if;
   G := Iterator:-BinaryGrayCode(n,'ret_delta');
V := Vector(n);
s := 0;
(h,g) := ModuleIterator(G);
j := g();
h();
sig := -1;
while h() do
sj := sign(j[1]);
aj := abs(j[1]);
for i to n do
V[i] := V[i] + sj * M[i,aj];
end do;
s := s + sig*mul(V[k], k=1..n);
sig := -sig;
end do;
expand((-1)^n*s);
end proc:
M := Matrix(20,rand(10)):
CodeTools:-Usage(permanentRyser4(M));
memory used=1.73GiB, alloc change=32.00MiB, cpu time=30.68s, real time=30.77s, gc time=1.64s
15220180698446432599207679453939
CodeTools:-Usage(LinearAlgebra:-Permanent(M));
memory used=3.18GiB, alloc change=0.73GiB, cpu time=49.49s, real time=44.12s, gc time=11.44s
15220180698446432599207679453939

I prefer an analytical (Lagrangian) approach. 

# Consider a ramp of mass M with angle from horizontal alpha
# that can slide along the x-axis and a block of mass m
# that slides along the ramp. Coefficient of friction
# between block and ramp is mu1, between ramp and ground
#
# M = mass of ramp
# m = mass of block
# alpha = ramp angle
# mu1 = coefficient of friction between ramp and block
# mu2 = coefficient of friction between ramp and ground
# g = gravitational acceleration
# Fx = x-component of external force applied to ramp
# Fy = y-component of external force applied to ramp

# Choose generalized coordinates u and v
#
# u = the x-distance from origin to tip of ramp,
# v = the distance of block along ramp, from tip.
# Assign an alias and some shortcuts
alias(u=u(t), v=v(t));
du := diff(u,t):
dv := diff(v,t):
# The kinetic energy is
T := 1/2*M*du^2 + 1/2*m*((du+dv*cos(alpha))^2 + (dv*sin(alpha))^2);
Tu := frontend(diff, [T,du]);
# normal force between ramp and ground
Fn2 := M*g + m*(g + diff(v,t,t)*sin(alpha)) - Fy;
eq2 := simplify(diff(Tu,t)) = Fx - signum(du)*mu2*Fn2;
Tv := frontend(diff, [T,dv]);
# normal force between block and ramp
Fn1 := m*g*cos(alpha) - m*diff(u,t,t)*sin(alpha);
eq1 := simplify(diff(Tv,t)) = -m*g*sin(alpha) - signum(dv)*mu1*Fn1;
eqs := [eq1,eq2];
eqs := map(lhs-rhs, eqs);
eqs := map(collect, eqs, [diff(u,t,t),diff(v,t,t)]);

 Here I substitute some arbitrary values for the parameters and initial conditions and plot u and v

deqs := subs([m=1,M=10,g=1,alpha=Pi/4,Fy=0,Fx=0,mu1=0,mu2=0.1]
, {seq(eq=0,eq=eqs), eval(u,t=0)=0, eval(v,t=0)=0, D(op(0,u))(0)=1, D(op(0,v))(0)=1});
dsol := dsolve(deqs,numeric);
plots:-odeplot(dsol, [[t,u],[t,v]], 0..10);

 

MapleSim currently does not handle complex values.  At best you might get sections of a plot where a signal is undefined when it is complex. If the complex signal is not used by the model, you might be able to extract the data from the model and then post process it.

@Bendesarts How do you want that function to effect the amplitude?  As a factor?  You could use a multiply block to multiply the output of the Chirp with your signal.

One way to generate the amplitude signal is via a Modelica code. Attach the Modelica Custom Component template, replace the content of the code block with the following (I've modified your equations slightly, but you can change this to whatever is desired):

model Amplitude
    import SI = Modelica.SIunits;
    extends Modelica.Blocks.Interfaces.SO;
    parameter SI.Duration Tstart = 1;
    parameter SI.Duration Tstop = 10;
protected
    parameter SI.Duration Trise = Tstop - Tstart;
equation
    y =  if time < Tstart then 0
        elseif time < Tstart + Trise/2 then
            2*((time - Tstart)/Trise)^2
        elseif time < Tstop then
            -2*((time - Tstart - Trise/2)/Trise)^2 + (time - Tstart - Trise/2)/Trise + 1/2
        else
            1;
end Amplitude;

Click the Generate Component from Source button and drag the component into the worksheet. A better way to do this may be to incorporate the Chirp block in this Modelica code, however, I'm not sure what you eventually want to achieve.

In Maple, a list (similarly a set and lots of other things) is not a mutable structure. When a list is modified an entirely new list is created. The original list continues to exist in memory, until no longer referenced and garbage collected.  The subsop procedure isn't necessarily anymore efficient at creating a new list. While direct assignment is syntactically allowed for lists with less than 100 elements, it probably should not be. I strongly discourage using the direct assignment method. If you need a mutable structure, use one: a one-dimensional Array or Vector is much more efficient for this.

As for your question, yes, Maple will raise an error if you attempt to modify an element of a list with more than 100 elements:

L := [0$101]:L[1] := 1;

Error, assigning to a long list, please use Arrays

You may be wondering why this is the case. It has to do with the fundamental design of Maple, particularly with its Simplification table. Expressions in Maple are stored in the Simplication table. For immutable objects, only one expression is stored for a given entity.  For example, there will only ever be one list identical to [1,2,3] stored in the table; similarly the expression a+3. If you later create another list identical to [1,2,3], Maple will use the original list (more accurately, its address). This is why immutable objects are immutable; if you could modify one, you'd modify every variable that was assigned that object.

This also explains why building an expression sequence (or list or set) an element at a time is O(n^2). Consider the loop

L := NULL:
for i to 100 do
  L := L,i;
end do:

When complete, L is assigned the expression sequence 1,2,...,100. However, to get there, the intermediate expression sequences were created:
L := 1
L := 1,2
L := 1,2,3
....

Each such expression sequence is stored in the Simplification table.  The storage for the first assignment is, say, 1 unit. The storage for the second is 2 units.  The storage for the entire lot is 1+2+...+100 units = 5050, which is substantially larger than the 100 units needed by the final sequence. The memory allocated for the intermediate expressions may eventually be reclaimed by the garbage collector, but there is an immediate cost of allocating, as there is a cost to lookup/insert each intermediate expression into the Simplification table.

For this trivial example one can avoid the additional expense by doing

L := seq(1..100):

Depending on what is being computed, that isn't always feasible, at least not easily. An alternative is to allocate an Array, either a fixed size, if the total number of slots is known, or dynamically increase its size as needed.  Then one could do

A := Array(1..100):
for i to A do
   A[i] := i;
end do:
L := seq(A[i],i=1..100):

The memory/time cost of that approach is O(n) [here n = 100].

I agree that rtable_scanblock is poorly documented.  The call you want is

rtable_scanblock(A,[],(val,ind,res)->(`if`(val>=3,[ind,op(res)],res)),[]);

The procedure appends the index to the list.  The empty list at the end is to initialize 'res'.

This is an inefficient way to operate; it builds up a list an element at a time, which is O(n^2), where n is the number of elements in the final list. A more efficient approach is

V := Array(1..0): k := 0:
rtable_scanblock(A,[],proc(val,ind) global k,V; if val>=3 then k:=k+1; V(k):=ind; fi; end);
                               ''
V;
             [[1,3],[2,1],[2,2]]

 

First 26 27 28 29 30 31 32 Last Page 28 of 114