Carl Love

Carl Love

24788 Reputation

25 Badges

10 years, 110 days
Natick, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Here's a constructor for the multiplicative group modulo n, regardless of whether n is prime:

#Constructor for the multiplicative group modulo n
MultGroup:= (n::And(posint, Not(1)))->
local G:= select(k-> igcd(n,k) = 1, [$n]), o:= nops(G), J:= table(G =~ [$o]);
    (
        GroupTheory:-CayleyTableGroup(
            Matrix(o$2, (i,j)-> J[modp(G[i]*G[j], n)], shape= symmetric), 
            labels= G, check= false
        ), 
        subs(_o= o, (k::integer[1.._o])-> G[k])
    )
:
(g,G):= MultGroup(12);
    g, G := < a Cayley table group with 4 elements >, k-> G[k]

GroupTheory:-DrawCayleyTable(g, labels= G);

All you need is this:

ABC:= <
    -3,  1,  2; # your A as a matrix row
    -2, -1,  1; # ...  B ...
     0,  3, -3  # ...  C ...
>:
alpha:= <2 | -1 | 1>: # your weights as a row vector
 
alpha.ABC/add(alpha);

The spacing and line breaks in the matrix entry are only for enhanced readability. You could just as well enter it as

ABC:= <-3, 1, 2; -2, -1, 1; 0, 3, -3>:

Then all you need to type is

X^n

You asked:

  • Where can I see  in the lprint output that the first argument is of type uneval?

Since sqrt(x) is inherently unevaluated, you can't explicitly see that in this case. If you replace x by 4, then you'll see the difference.

  • Is sqrt(x) the first argument?

Yes. For any function f(a1, a2, ..., an)a1 is the first argument.

  • What does mi do?

It displays a variable in italic. All the Typesetting commands beginning with m are from the MathML language, and you can find them documented on numerous public websites.

Like this:

M:= DataFrame(<a,b,c; b,c,a; c,a,b>, rows= [a,b,c], columns= [a,b,c]);

M[b,c];

In the default prettyprinted display of a DataFrame, the displayed first row is the column indices and the displayed first column is the row indices. These mustn't be confused with the entries of the matrix itself.

The operation that you want to perform is called catenation. Maple has essentialy three catenation operators: The first two that I'll discuss are a binary infix operator || (two vertical bars) and a functional prefix operator cat. Those two are mostly interchangeable, but there are some quirky differences regarding which operands are evaluated and which are just taken verbatim. I'll get to the 3rd catenation operator(s) later.

Definitions of some "types" that are relevant to your main question:

"indexed" vs. "suffixed": First, some vocabulary about some formal terms in Maple's "type" system that are relevant to this. I'm doing this because although know perfectly well what you mean by "indexed", your usage of that word is not consistent with its formal definition in Maple. Thus, there's a (small) risk of causing confusion by using that word as you have. A better word would be suffixed, and fortunately that word means exactly the same thing in common English as its formal definition in Maple (see help page ?type,suffixed).

"symbols" as "variables"; "pure" symbols: What you're calling "variables" are formally known as objects of type symbol. There's not much risk of confusion if you say "variable" because that word has no formal Maple-wide definition (it often has command-specific definitions, such as a variable with respect to which a derivative is computed). However, note that named constants such as Pi are also considered symbols, although they don't "vary". As you're very likely aware, Maple's symbols can be used quite effectively either with or without assigned values. The ability to manipulate "pure" (i.e., unassigned) symbols is what makes Maple a Symbolic Computation System. In many computer languages, the tokens that represent "variables" are called "identifiers" (which also has no formal definition in Maple).

"names", "indexed names": If you take a symbol such as your Rand it has no assigned value (very important!), and you follow it by a pair of square brackets containing a comma-separated sequence of zero or more items (of any type whatsoever), then you've created what Maple calls an indexed name (i.e., it has type indexed and type name). This can be followed by more sequences of indices in square brackets and it'll still be an indexed name. A plain (unindexed) symbol is also considered a name (see help page ?name). All names could be considered "variables", since they can be assigned values; thus the word name is much more common in Maple discussions than symbol. Names that aren't constant are Maple's primary representation of the abstract mathematical concept of "variable". But for our main topic, catenation, we can only use symbols. A vast number of Maple objects other than names can be indexed with square brackets, which is why it's important to know that your symbol is unassigned before you try to make an indexed name from it. Not heeding this advice is a leading cause of newbie errors reported here on MaplePrimes. (See help pages ?type,indexed, ?type,name, and ?type,symbol.)

Examples: R, R1, _R, R_1, and R__1 are symbols. R[]R[1]R[1,x], and R[1][x] are indexednames, and Not(symbol).

Warning about catenation:

All names formed by any of the forms of catenation are global! That's true even if the pieces that are put together are local! But inappropriate use of indexed names is a far more common source of errors than is the globalness of catenations.

By way of contrast, an indexed name is local as long as its beginning symbol is local, and global if its beginning symbol is global.

Catenation:

The II binary infix operator: Referring to the specific example from your question, if your n is either explicitly a positive integer or is assigned a specific positive integer, then what you asked for can be done as simply as this:

R||(1..n)

The suffixes need not be positive integers, nor in order. These all work:

R||(5, 7, 3);  R||(start, finish);  R||(a,b,c);
R||(1,2,3)||(a,b,c); #This makes 9 symbols.
S:= {seq(2*k, k= 1..5)};  R||(S[]);

If has an assigned value, it's ignored.

See help page ?||.

cat: You can also do 

cat(R, 1..n);  cat~(R, [a,b,c])[];  cat~(R, S)[];
cat~(R, [1,2,3], [a,b,c])[]; #This makes 3 symbols.
cat(R, 1..3, a..c); #This makes 9 symbols.

Warning: For cat, if the first argument R has an assigned value, it's NOT ignored.

The help page ?|| "discourages" you from using ||, advocating cat instead. I strongly disagree with that advice. Both commands have numerous legitimate uses. In the cases where either can be used, I use ||.

Both || and cat work with both symbols and strings. Whether the resulting object is a symbol or string depends on the type of the first argument or operand.

nprintf, sprintf: These are the third way that I mentioned earlier. Sophisticated catenations using format codes can be made with these commands. The syntax is a generalization of sprintf from the C language or FORMAT from Fortran. The only difference between them is that nprintf creates symbols and sprintf creates strings.

Subscripting:

You can use catenation to create symbols which will prettyprint (i.e., display in Maple's 2D GUI output display (the centered and mostly italicized blue output you see in your worksheets)) with subscripts. This is done by including __ (two underscores) in the symbol. Examples:

R__1;  R__||(1..3);  t__start; 

(The 1st and 3rd examples are ordinary symbols, not catenations).

This is usually the best way to avoid those common newbie errors caused by the incorrect use of indexed names that I mentioned earlier. Much documentation refers to these as "atomic" variables. I disapprove of that term for the sole reason that atomic has a long-standing formal definition as a Maple type and that definition conflicts with the usage for subscripting because all names, whether indexed or plain symbol are type atomic.

It can be done with the anames command (i.e., assigned names) like this:

save ({anames}(user) minus {anames}(procedure))[], "some_file_name";

In Maple 2022.2, your indets command returns the empty set, which I guess is what you mean by "proper form".

That's difficult (sometimes impossible) to do in the the most-general cases, but easier in the cases that I think you're interested. The error message comes from line 52 of `D/procedure`, so you can read around there for a general answer. It looks like you'll need to read at least lines 25-65 to understand the general case.

The simpler case: operator procedures: The parameter sequence of a procedure f can be extracted via op(1, eval(f)). If f is also an operator (which'll always be true if it's constructed with ->), the parameters can't be "too complicated". All of the following are disallowed:

  • the end-of-parameters marker,
  • keyword parameters,
  • parameters with default values assigned directly within the parameter sequence.

So, those easier cases can be handled by

Nparams:= (f::And(operator, procedure))-> nops([op](1, eval(f))):
q:= (u,v)-> u^2+v^2:
Nparams(q);

 

The information about a graph G's edges is stored in an Array as op(4,G). Although this structure doesn't seem to have a formal documented name, I find it to be the most convenient and most efficient way to access the edge infomation from a graph. Suppose that there are n vertices. Then op(4,G) is an Array indexed 1..n such that A[k] is the set of the indices of the neighbors of the kth vertex. In the code below, I construct this Array as a means to construct your graph. However, if the graph was constructed some other way, this Array could still be accessed as op(4,G)

restart:

GT:= GraphTheory:

Vs:= [x,y,z,w]:

n:= [$nops(Vs)]:

 

Popvs:= [-2, 1, 6, 3]:

Nbs:= Array([{2}, {1,3,4}, {2,4}, {2,3}]):

X:= GT:-Graph(Vs, Nbs);

GRAPHLN(undirected, unweighted, [x, y, z, w], Array(1..4, {(1) = {2}, (2) = {1, 3, 4}, (3) = {2, 4}, (4) = {2, 3}}), `GRAPHLN/table/1`, 0)

GT:-SetVertexPositions(X, [[0,0], [1,0], [1.5,1], [2,0]]):

newX:= GT:-RelabelVertices(X, [seq](cat(Vs[i], "=", add(Popvs[[i, Nbs[i][]]])), i= n));

GRAPHLN(undirected, unweighted, [`x=-1`, `y=8`, `z=10`, `w=10`], Array(1..4, {(1) = {2}, (2) = {1, 3, 4}, (3) = {2, 4}, (4) = {2, 3}}), `GRAPHLN/table/1`, 0)

GT:-DrawGraph(newX);

 

NULL

Download NeighborArray.mw

Your integrations are performed with respect to epsilon. Thus, it doesn't make sense to substitute a numeric value for epsilon. You've substituted 5000.

It's done with the background option, like this

plots:-display(ttt0, background= U1, axes = none, size = [400, 160]);

You needn't use ImageTools; you could just as well do this

U1:= "C:/Users/S/Desktop/StarPicture.jpg":
plots:-display(ttt0, background= U1, axes = none, size = [400, 160]);

The Maple command is gcdex. See help page ?gcdex. For example,

gcdex(x^3-1, x^2+2, x, 'a', 'b'): 'a'(x)=a, 'b'(x)=b;
                           

Maple currently has 6 inert infix arithmetic operators: %^%.%*%/%+, and %-. These have the same algebraic rules (precedence and associativity) as their non-inert counterparts. In addition any name---whether it be a function, procedure, or just a variable or named constant---can be made inert by prepending the name with %. In some cases, such as a non-alphanumeric name, the must be prepended inside back quotes (such that the entire name is in back quotes). Any number of prepended may be used, each of which represents a "level" of inertness. The value command removes one level of inertness from an expression.

Operators other than the 6 listed above can be made inert by using their prefix functional forms and including a %. For example, 

`%=`(a, b)

Your parameter values p3 contains cos gamma = 1/sqrt(2). That needs to be cos(gamma) = 1/sqrt(2).

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