Joe Riel

8191 Reputation

22 Badges

15 years, 92 days

MaplePrimes Activity


These are answers submitted by Joe Riel

Have you looked at the ImageTools package?

One solution is

type(f(g(1),3,3,4),'And(specfunc(f), patfunc(specfunc(posint,g),posint))');
                             true

 

The annotation associated with each port defines its position.  Change the extents to

extent = {{-120, 40},{-100,60}}  // for first input
extent = {{-120, -60},{-100,-40}} // second input

Each extent has the form {{x1,y1},{x2,y2}}, the points define the diagonal of a rectangle.

Later

For a slightly nicer looking block (white background rather than see-through), add the following line, say after the model line

extends Modelica.Blocks.Icons.Block;

 

Another possiblity is to use ArrayTools:-Alias to allow access to a Matrix (or any rtable) created with a different offset.  For example

M := Matrix(3):  # 3x3 matrix
A := ArrayTools:-Alias(M, [0..2,0..2]):  # alias
A[0,0] := 23:
M[1,1];
                      23;

 

Here's how it can be solved using Syrup, which is available on the Maple Cloud:
 

with(Syrup):
ckt := [V(a+b*t+c*t^2),R,C]:
(deqs,rest) := Solve(ckt,'tran','returnall'):
dsol := dsolve(deqs):
subs(rest, dsol, v[C](t));

   -(-2*C^2*R*c+2*C*c*t+C*b+exp(-1/R/C*t)*(a/R+2*C^2*R*c-C*b))*R+c*t^2+b*t+a

 

Assuming this is a discrete system, here is one approach.

with(DynamicSystems):
K := [0.1, 0.2, 0.3, 0.4]:
# Assign the z-transform from the impulse response.
T := add(K[k]/z^(k-1), k=1..4);
sys := StateSpace(T,'discrete');
# Display the a, b, c, and d matrices
use sys in a,b,c,d; end use;
# Plot the impulse response
ImpulseResponsePlot(sys);

 

Currently there is no way to create matrix i/o using the CustomComponent template.  It wouldn't be hard to extend it to allow this.  In the meantime, you can do so by writing Modelica.  As an example, here is a block with a matrix output:

model foo
    import MBI = Modelica.Blocks.Interfaces;
    output MBI.RealOutput y[2,2] annotation (Placement(transformation(extent={{100,-10},{120,10}}))); 
equation
    y[1,1] = time;
    y[1,2] = 0;
    y[2,1] = 0;
    y[2,2] = sin(time);
end foo;

Currently the MapleSim GUI doesn't expect matrix signals; as such you won't be able to probe the output.  But you can connect it to another block that expects a Matrix input and it will work.  I've attached a simple model that does this; it uses the foo model shown above and connects it to a bar model.  MatrixIO.msim

Am not sure this is the best way to go.  It might make more sense to write a function (in the Modelica Code Editor) that returns a Matrix and then use that in a block. 

This is available via the Iterator:-Permute function.

P := Iterator:-Permute([2,1,1,3]):
for p in P do printf("%d\n", p); end do:
1 1 2 3
1 1 3 2
1 2 1 3
1 2 3 1
1 3 1 2
1 3 2 1
2 1 1 3
2 1 3 1
2 3 1 1
3 1 1 2
3 1 2 1

 

Using Kitonum's suggestion to answer the second question:

expand_power := proc(ex) 
local b,p; 
    (b,p) := op(ex); 
    if    p :: posint then `%*`(b $ p); 
    elif p :: negint then 1/`%*`(b$(-p)); 
    else ex; 
    end if; 
end proc:

y := x^2/z^3:
subsindets(y, `^`, expand_power);
      x %* x
     -----------
 z %* z %* z

 

Not quite sure what you mean by white space in this context; ReadFile returns a string with newline characters. You could do, for example,

str := FileTools:-Text:-ReadFile(somefile):
lines := StringTools:-Split(str, "\n");

to create a list of strings, one for each line in the original file.

The Syrup package, which is available on the Maple Cloud, has a ladder input notation that can be used to generate images of certain types of circuits.  For the example above you could do

ckt := [ (R1(4) &+ V1(3)) &// R2(3) &// (R3(1) &+ V2(4))]: 
Syrup:-Draw(ckt);

It's not the nicest looking rendition but is fast and easy to enter.

Differentiating the sliding average returns a delay-differential equation that dsolve can handle numerically.  That is,

deq := diff(xavg(t),t) = (x(t) - x(t-T))/T

You could then do, for the first case

dsol := dsolve(subs(T=1/2), [deq, xavg(0) = 0]), 'numeric'):
plots:=odeplot(dsol, 0..3);

The plot is shifted vertically because I set xavg(0) = 0.

You can enter the system using the ZeroPoleGain form:

with(DynamicSystems):
zpk := ZeroPoleGain([1],[1,2],1):

Alas, when converting to other forms the zero/pole will get cancelled.  Note that the cancellation option is normally false; it is used to actively cancel pole/zero pairs that are within a given distance, set by the relativeerror option.  So that won't help you.  What you can try, as a workaround, is to enter an offset as a symbolic parameter and give it a default of 0:

zpk := ZeroPoleGain([1+delta],[1,2],1, parameters=[delta=0]):

The parameter values are used with certain operations such as when generating plots, etc.  Here is the State Space representation.

ss := StateSpace(zpk):
use ss in a,b,c,d end use;
   Matrix(2, 2, [[0, 1], [-2, 3]]), Matrix(2, 1, [[0], [1]]), Matrix(1, 2, [[-1 - delta, 1]]), Matrix(1, 1, [[0]])

To avoid the issue, you can pass additional arguments to ResponsePlot:

p2:=DS:-ResponsePlot(sys_filter2, DS:-Step(), duration=0.0001,color=blue,legend="step2", dsolveargs=[stiff=true]):

 

For an Array that could be done by passing a sorting procedure to the sort procedure.  Alas, the DataFrame object assigns the sort method that it uses and it currently doesn't provide for an option for a sorting procedure.  One workaround is to apply the regular sort procedure to the list of row indices of the DataFrame and then use the resulting permutation to sort the DataFrame. Here's an example, using the Flashlight example you pointed to

Prows := [seq(1..upperbound(Flashlight,1))]:
CostMax := max(Flashlight["Cost"]):
P := sort(Prows, 'key' = proc(i) Flashlight[i,"Batteries"]*(CostMax+1) + Flashlight[i,"Cost"] end proc):
Flashlight[P,..]; # permute the rows 

Note that the example used a key function rather than a sorting function; doing is more efficient in that it only has to be evaluated once for each row.

1 2 3 4 5 6 7 Last Page 1 of 104