Carl Love

## 25831 Reputation

10 years, 358 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

## Iterator:-SetPartitions...

Assuming that you don't care about the order in which the output appears, I think that the following does what you want:

```SumPartitions:= proc(S::{set, list})
local p, J:= Iterator:-SetPartitions(nops(S)), `&<`:= curry;
{seq}((sort @ add~ @ map&<(map2,index,S) @ [op]~ @ J:-ToSets)(p), p= J)
end proc
:
#Examples of usage:
SumPartitions([a,b,c,d]);
{[a + b + c + d], [a, b + c + d], [b, a + c + d], [c, a + b + d],
[d, a + b + c], [a + b, c + d], [a + c, b + d], [a + d, b + c],
[a, b, c + d], [a, c, b + d], [a, d, b + c], [b, c, a + d],
[b, d, a + c], [c, d, a + b], [a, b, c, d]}

SumPartitions([a,a,b,c]); #Joe's multiset example
{[2 a + b + c], [a, a + b + c], [b, 2 a + c], [c, 2 a + b],
[2 a, b + c], [a + b, a + c], [a, a, b + c], [a, b, a + c],
[a, c, a + b], [b, c, 2 a], [a, a, b, c]}

SumPartitions([a,b,c]);
{[a + b + c], [a, b + c], [b, a + c], [c, a + b], [a, b, c]}

```

## Complex conjugation...

All symbolic (or unassigned) variables in Maple are by default assumed to represent complex numbers unless something is used that changes that default. Usually this is transparent (making no difference to final results) when the variables are only intended to represent reals. One case where it isn't completely transparent is when doing the dot product of two vectors of the same orientation with one or both containing variables. In that case, the definition of u.v is the inner product of conjugate(u) and (if they're column vectors) or of u and conjugate(v) (if they're row vectors). (There's a definition of complex conjugate in a paragraph below.) (By inner product, I mean the sum of the elementwise products.) The overbar is a symbol for the conjugate. This has no effect if the variables represent reals (conjugate(x) = x for x real), so it's still essentially (or mathematically) transparent except for the possibly unwanted visual presence of the overbar.

As you've noticed, this doesn't happen when you multiply a row vector by a column vector (with the row being the left operand!). A much simpler syntax for multiplying the two columns of Q is

Q[.., 1]^%T . Q[.., 2]

The .. means "all rows"; the ^%T means the transpose. In 1D input, ^+ can also be used (and perhaps this now works in 2D also). Likewise ^%H or ^* can be used for the conjugate (aka Hermitian) transpose.

The complex conjugate of x + I*y (with x and real) is defined as x - I*y. The Maple command is conjugate. An overbar is the standard typeset representation of an unevaluated complex conjugate, just like a pair vertical bars is the standard typeset representation for an unevaluated absolute value. Applying conjugate to a vector or matrix just means that the operation is mapped over the elements.

There are numerous other ways to either avoid or remove the overbars. I think the best overall way is to multiply (row . column), as shown above.

## solve(..., parametric)...

Since all the inequalities are polynomial, I think that this problem can be done by the solve command, assuming that the absence of a result without any warning can be taken for certain to mean that there's no solution.

First, let's do some rearrangement of logical formulas:

```restart:
Prop:= eval(
Logic:-BooleanSimplify(
Logic:-Canonicalize(&not((p1 &and p2) &implies (p3 &and p4)), [p||(1..4)])
),
[Logic:-`&and`, Logic:-`&or`, Logic:-`&not`]=~ [And, Or, Not]
);

V:= {a, b, c, d}:
p1:= S1 > 0:
not_p3:= S3 <= 0:
not_p4:= S4 <= 0:
d1:= {p1, p2, not_p3}; d2:= {p1, p2, not_p4};

solve(d1, V, parametric, real);
[]

solve(d2, V, parametric, real);
[]

```

Therefore exists(V, Prop) is false. Therefore forall(V, not Prop) is true, where not Prop is the original implication that you wanted to prove.

However, MathematicalFunctions:-Coulditbe gives the opposite result, while using 124 times as much computation time as the solves. I don't trust it though.

```CodeTools:-Usage(
MathematicalFunctions:-Coulditbe(And(d1[])) assuming V[]::~real
);
memory used=7.03GiB, alloc change=136.82MiB,
cpu time=3.61m, real time=3.47m, gc time=14.47s

true
CodeTools:-Usage(
MathematicalFunctions:-Coulditbe(And(d2[])) assuming V[]::~real
);
memory used=10.76GiB, alloc change=98.64MiB,
cpu time=4.73m, real time=4.28m, gc time=33.34s

true

```

I tried a million random numerical evaluations in an attempt to find a witness to the above true results, but none were found:

```R:= rand(-2. .. 2.):
to 10^6 do
r4:= 'R'()\$4:
if andmap(evalb, eval(d1, V=~ r4)) or andmap(evalb, eval(d2, V=~ r4)) then
print(r4);
break
fi
od:
```

## It's not autonomous...

Your system of ODEs is not autonomous because the coefficients of the dependent variables x1(t) and x2(t) depend on the independent variable t.

## return...

The 2 after break doesn't make sense because you only have one loop; break only works for do-loops. I'm guessing that you want to "break" out of the whole procedure. The command for that is return.

Also, if you're using 2D Input: Multi-level break doesn't work in 2D Input, as noted on the ?break help page. None of the syntax enhancements made in the last 5 or so years work in 2D Input.

## Clearly an oversight and a bug...

Looking at the code with showstat(GraphTheory:-IsHamiltonian) clearly shows that there's no mention of tsp nor use of any algorithm akin to solving a traveling-salesman problem. So, the help page is clearly wrong. There is a procedure GraphTheory:-TravelingSalesman, it has a help page, and I tested it 6 days ago (in response to this Question: "Traveling-salesman problem").

It seems necessarily inefficient to me to use a minimizing algorithm if you just want any Hamiltonian circuit. However, if you want, I could easily (30 - 60 minutes) write a patch for you to implement method = tsp in IsHamiltonian. So, let me know if that's what you want.

## Regular expressions...

The StringTools package can process so-called regular expressions (such as are commonly used in Linux shell scripts). Let's say that you want to extract a number (possibly including periods) in parentheses from the end of a string.

```StringTools:-RegMatch("\\([0-9.]*\\)\$", L1, 'c');
true

c:= c[2..-2]; #Strings can be indexed like Arrays and lists.
c := "2.13"
#Even more slick:
StringTools:-RegMatch("\\(([0-9.]*)\\)\$", L1, 'c', 'c'), c;
true, "2.13"
â€‹â€‹â€‹
```

## Save statement...

All that you need is

save u11, "C:/double/u11.txt";

The formatting, printing, and file closing statements are all unnecessary. You can also save all the variables to one file like this

save u1||(1..10), "C:/double/u.txt";

All necessary punctuation (u11:= ..., semicolons, line breaks) will be included so that the file can both be read by a human as text and read back into Maple as executable code.

## Symbolic Moore-Penrose pseudoinverse is ...

I've never a practical (useful) case of a nonsingular matrix with symbolic entries whose Moore-Penrose pseudoinverse could be calculated in a reasonable amount of time.

## Jacobian...

The analog of "gradient" for a vector field is called jacobian. It is a matrix. It is available as command Jacobian in the VectorCalculus and Student:-VectorCalculus packages.

## Done "on the fly" with Explore...

If the animation is produced with the Explore command, as shown below, the frames are displayed "on the fly" (i.e., as they are produced). So, unlike Maple's other animation commands, this has the benefit of starting play immediately. The memory used by the kernel for this is trivial, under 50 Mb; however, the memory used by the GUI grows unboundedly. I killed the below (just by pressing the stop button under the animation) when my GUI was using about 8 Gb. Still, it displayed a few thousand frames. (If you delete the Explore window after stopping it, those Gigs of memory will soon be garbage collected and returned to the O/S.)

The trick that I show in the code below---using ArrayTools:-Alias to create a direct memory link to the animation frame---can only work if the frames are displayed on the fly.

```restart:
#
#Build unit sphere as static background for the animation. The back half is
#opaque, and the front half is wire mesh, so we can see inside.
#
Sphere:= plots:-display(
plot3d~(
1, [-Pi..0, 0..Pi], 0..Pi, coords= spherical, style=~ [patch, wireframe],
lightmodel= light1, grid= [100\$2], axes= normal, orientation= [60,80,10]
)
):
N:= 5000: #number of points and animation frames
#Construct matrix each column of which is a random point on unit sphere:
Pts:= rtable(1..3, 1..N, frandom(-1..1), datatype= hfloat, subtype= Matrix):
Pts[3]:= csgn~(Pts[3])*~(1 -~ Pts[1]^~2 -~ Pts[2]^~2)^~(1/2):
Z:= Vector(3, 0, datatype= hfloat): #the origin
Frame:= plots:-display( #Construct one animation frame
Sphere, plots:-pointplot3d(<Z | Pts[.., 1]>, style= pointline, color= red)
):
#Create a direct memory link to the 2x3 matrix inside the pointplot3d structure.
#Thus, we can change the frame simply by changing the matrix.
A:= ArrayTools:-Alias(indets(Frame, Matrix)[]):
#
#Procedure that changes the frame:
P:= k->
if k::posint then :-A[2]:= :-Pts[..,k]^+; :-Frame
else 'procname'(k)
fi
:
Explore(
P(k), parameters= [[k= 1..N, shown= false, animate]], autorun, numframes= N,
initialvalues= [k= 1]
);
```

One frame: