Joe Riel

8488 Reputation

22 Badges

16 years, 61 days

MaplePrimes Activity

These are answers submitted by Joe Riel

There are a couple issues, at least if you are doing this in 1D input.  The following works.  Note that I replaced Zeta with zeta, the former is assigned a procedure and won't work.


Nx := 200;
Nt := 200;
dx := 0.5e-2;
dt := 0.2e-1;
A := Matrix(Nx, Nx);

for k to Nx do A[k, k] := -2.0 end do:
for j to Nx-1 do A[j+1, j] := 1.0 end do:
for j to Nx-1 do A[j, j+1] := 1.0 end do:

zeta := (.1*dt/dx)^2;
phi || 0 := Matrix(Nx, Nx);

fin := proc (t) options operator, arrow; cos(4*Pi*t) end proc;
phi || 0[(1/2)*Nx, (1/2)*Nx] := fin(0);
phi || 1 := (1/2)*zeta^2 . A . phi || 0;
phi || 1[(1/2)*Nx, (1/2)*Nx] := fin(dt);

phinow := Matrix(Nx, Nx);
phinext := Matrix(Nx, Nx);
phibefore := Matrix(Nx, Nx);

phinow := phi || 1;
phibefore := phi || 0;

for j from 2 to Nt do
    phinext := zeta^2 * (A . phinow + phinow . A) + 2.*phinow - phibefore;
    phi || j := Matrix(Nx, Nx);
    phinext[(1/2)*Nx, (1/2)*Nx] := fin(j*dt);
    phi || j := phinext;
    phibefore := phi || (j-1);
    phinow := phi || j
end do;


Put it into a zip file and attach that.

As Acer suggests, one way to do this is to first check whether the expression is a sum.  If so, use select, otherwise check whether it matches your target; if so return it, otherwise return 0.  An alternative method, probably not ideal but interesting, is to ensure your expression is a sum by adding a dummy term to it then using select.  An appropriate dummy term is an otherwise unused local variable to the procedure. Actually, adding a dummy term and then calling select fails for a particular corner case, can you figure out what that is, what would be returned, and devise a way to avoid it, without using a conditional?

I'm not sure what your issue is.  Do the separate worksheets share a common kernel?  That is, are you making assignments in one worksheet that are used in another?  If you are assigning procedures that are reused, you might be better served saving them to a Maple archive so they can be used by any worksheet. 

The type anything matches either factor.  Note that the type '{anything,...}', where the ellipsis indicates any types, is equivalent to the type 'anything'.  Try changing anything to indexed, then try identical(x) and identical(x^2).

When in doubt, check the manual.  In this case, the help page for type,local. See, in particular, the second paragraph.  Only symbols can be of type local. The table reference A[99] won't collide with other such expression.

Interesting question.  I may have to add an option for that, as currently Syrup does not provide a means to return the parameter values.  An alternative approach is to leave the numerical values out and substitute them afterwards. For pedagogical purposes I'll use Maple to transform your Ckt to a suitable ladder and list of parameter equations.

(**) Ckt := [v1(4), R1(50) &+ L2(0.9600), Cp(0.8200), L1(0.5000) &+ R2(0.2000), RL(1.3430) &+ LL(0.1550)]:
(**) params := map(f -> op(0,f) = op(f), indets(Ckt, 'function(numeric)'));
          params := {Cp = 0.8200, L1 = 0.5000, L2 = 0.9600, LL = 0.1550, R1 = 50, R2 = 0.2000, RL = 1.3430, v1 = 4}

(**) ckt := subsindets(Ckt, 'function(numeric)', f -> (op(0,f)));
                                        ckt := [v1, R1 &+ L2, Cp, L1 &+ R2, RL &+ LL]

(**) (sol,rest) := Syrup:-Solve(ckt, ac, returnall):
(**) P_R1_ave := (v[R1]/sqrt(2))^2/R1;
                                                    P_R1_ave := 1/2 ------

(**) subs(rest, params, P_R1_ave);
                                                            2                    2
                                           400 (0.53710000 s  + 1.26526000 s + 1)
                                               3                2                           2
                                (0.5156160000 s  + 28.06964960 s  + 64.87800000 s + 51.5430)

Actually, it wasn't necessary to transform Ckt to ckt; instead you could pass Solve the symbolic option, which tells the solver to ignore the numeric values and use the default values (the names of the parts).  You do have to be careful there, since you can use the same name for multiple parts; they will be assigned different symbols but their values will be identical.  This is useful for creating, say, an LC delay line:

(**) ckt := [V,seq('(L,C)',1..4)];
                                              ckt := [V, L, C, L, C, L, C, L, C]

(**) subs(Syrup:-Solve(ckt), v[4]);
                                              3  3  6      2  2  4          2
                                             C  L  s  + 6 C  L  s  + 9 C L s  + 1



One possibility is to use the satisfies type (it doesn't actually qualify as a structured type, but is part of Maple's type system):

(**) TypeTools:-AddType('my_sin','specfunc(sin)^And(rational,satisfies(x->(x>1)))'):
(**) type(sin(x)^(3/2),'my_sin');

(**) type(sin(x)^(1/2),'my_sin');

I generally avoid using satisfies unless there is no alternative.  Cannot immediately think of one here.

You specified the vertical range as 0..0.1, but the points are higher than that.  Try view = [0..1,0..1].

You could write a procedure to do this.  Say

keep_type := proc(x, typ :: type)
   if type(x, typ) then x;
   else select(type, x, typ);
   end if;
end proc:

More general would be a keep procedure that applies a predicate as select does,

keep := proc(fcn, x)
   if fcn(x, _rest) then x;
   else select(fcn, x, _rest);
   end if;
end proc:

You could then use this with, say

keep(type, expr, mytype_3);


Acer's response addresses an issue about which I had begun to reply but canceled. I assume that the primary motivation for testing the entire expression against the type is to handle the case when the general sum of terms is, in fact, a single term.  Using select in that case will generally produce something undesired as it will select factors from a product. Using your method (or the keep I provided) may work, but only if the predicate is properly constructed.  Constructing structured types that exactly match a desired form is challenging. An ad hoc solution is to use has or hastype as the predicate, however, if it matches a single term in a sum, it will also match the entire sum, so is useless in the keep algorithm.  The better approach, as Acer suggests, is to first explicitly test for a sum; if it is a sum select the desired terms, otherwise test a single term.

As Acer mentions, it isn't clear precisely what you want.  Further confusing the issue is your description of an expression of the form something*piecewise as a function. I'll assume you mean expression and that you want selection rather than extraction. However, one typically doesn't select from a sum because the result is another sum. I'll further assume you want the terms of the given sum that have the desired form. For the particular example, a not robust but easy way is with

mytype := 'And(piecewise,patfunc(identical(t)<numeric,anything))':
select(hastype, convert(MyExpr,'set'), mytype); 


Not quite sure what you want. Consider

P := module()
export A := module() ... end module:
export B := module() ... end module:
export C := module() ... end module:
end module:

If that's the structure, just rename B to Btmp and C to B.  If C is independent and in a library, then you should be able to just rename your B and, in P, do 

export B := C;


If you remove the square brackets from subs command the output is an algebraic expression rather than a list.

An alternative way to handle this is with the Syrup package, available on the Maple Cloud. With it you can do

ckt := [V3(1), R3(200),R49(1.3e3),1,C5(68e-12),L(3.3e-6),C4(100e-12),1,C6(8.2e-12),C2(10e-12),R8(10e3)]:
sol := Solve(ckt,ac):
subs(sol, v[2]); # I'm not sure which node voltage you are interested in.


Note that n is charge carrier density, not charge density. So

(**) B := 0.5*Unit('T'):
(**) q := Unit('e'):
(**) n := 0.15*100000./Unit('L'):
(**) d := 1*Unit('micron'):
(**) Ih := 0.1*10^(-5)*Unit('A'):
(**) Vh := Ih*B/q/n/d:
(**) combine(Vh, units);

Seems a tad large.  Better check those values.

A slight clarification; the package will be loaded, regardless; what you don't want is binding its exports into the global namespace, which is what with does.

Those two procedures, alias and macro, have different purposes.  Alias causes a global name to be displayed as its defined alias, though it also allows entering the short name.  Macro is only for simplified input.  Because macro is builtin (alias is a library procedure) I'd probably use it rather than alias if your purpose is to simplify the input. Note that using alias will change the display of a printed procedure.  For example

alias(ST = StringTools):
foo := proc(s) ST:-UpperCase(s); end proc;

         foo := proc(s) ST:-UpperCase(s); end proc


macro(ST = StringTools):
foo := proc(s) ST:-UpperCase(s); end proc;
        foo := proc(s) StringTools:-UpperCase(s); end proc



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