Carl Love

## 26386 Reputation

11 years, 144 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

## Repost the Question...

Please repost the Question (by editing this Question). If someone thinks it's a duplicate, they ahould post some evidence of that, such as a link. Anyway, I think it was a great Question.

## I hate that tag!...

I hate all such meta-tags, I never use them, and I wish that they were forbidden! If a Moderator is sure that something is a duplicate, they should delete it. Anything less is sniveling passive aggression.

I don't recall ever seeing a duplicate to your original Question.

## Why is exp(x^2) not real??...

I don't understand what mathematical principle allows you to discard exp(x^2) as being "not real". Perhaps you want to discard it because it can't be 0? That's a separate issue. If that's what you mean, let me know.

While it's true that real is not a Maple type, it is a Maple property, and properties are the primary modality of assuming.

## nops({op~(...)[]})...

@emendes Change

nops(convert(Models_4,set));

to

nops({op~(Models_4)[]});

1170

## Embedded loops...

I didn't mention this before because you use Maple 2015 (at home), which I don't think supports embedded do loops. But for completeness and for when you're not at home, these are IMO the best replacementas for your loop:

L1L2:= [while not T['finished'] do T['nextvalue']() od]:

or if you know that the Cartesian product is nonempty

L1L2:= [do T['nextvalue']() until T['finished']() od]:

or if you know that it has n elements

L1L2:= [to n do T['nextvalue']() od]:

## color, mathcolor...

@sand15 I had noticed the things that you said about color and mathcolor. The only reason that I didn't mention them is that I wasn't sure that I'd tried ever possible combination of syntax to make it work, including variations on representing red in RGB hex as FF0000ff0000, etc.

I also noticed on MathML websites that mathcolor is deprecated. Using color in the Typesetting constructions works. And I suspect that any of the ColorTools color specifications would work also. Specifying a color outside of the MathML constructions is almost worthless because you can't control the exact part that is colored.

## Unforgiving syntax...

@sand15 The advantage of Typesetting is that it follows the usual Maple syntax regarding white space and punctuation whereas the form `# ... ;` has brutally unforgiving and undocumented rules for spacing. For example, if you take your construction and add the usual spaces after commas, it won't work.

## I can't duplicate complex result...

Using Maple 2023.2, I can't duplicate your complex result. I tried many different orders for introducing the floating-point part of the computation, and I always get 6.294...*10^7. That being said, it's not unusual and not considered a bug when a floating-point calculation whose exact counterpart is known to be purely real returns a result whose imaginary part is many orders of magnitude smaller than its real part.

## Did you use it?...

@Carl Love Have you been able to implement my Answer?

## 723,957 models in under 2 seconds...

@emendes Yes, I knew that you actually wanted to multi-thread the code at a higher level. Doing so is even easier than my previous multi-threaded example because it requires no changes whatsoever to bulidAllPossibleModels. The following test is just to show the multi-threaded time. I started with a random list of 12,701 models of 3 entries and 3 monomials, and extended each to 57 models with 4 monomials.

```restart:
MakeMonoList:= proc(alpha::symbol, V::list(symbol), dim::nonnegint)
local i, k, T;
unapply(
sort([T], rcurry(Groebner:-TestOrder, 'tdeg'(V[])))
*~ [seq](alpha[i,k], k= 0..binomial(nops(V)+dim, dim)-1),
i::posint,
'proc_options'= 'remember'
)
end proc
:
M:= MakeMonoList(alpha, [z,y,x], 3);

buildAllPossibleModels:= (model::list, M::procedure)->
[for local i,m in model do
map(subs, m=~ m+~ subs({`if`}(m::`+`, op(m), m)=~ (), M(i)), model)[]
od]
:
R20:= rand(1..20):
Models_3:= CodeTools:-Usage([to 12701 do [seq](M(i)[R20()], i= 1..3) od]):
memory used=2.04MiB, alloc change=0 bytes,
cpu time=47.00ms, real time=52.00ms, gc time=0ns

Models_4:= CodeTools:-Usage(
):
memory used=507.36MiB, alloc change=437.06MiB,
cpu time=12.11s, real time=1.64s, gc time=21.59s

```

## More verbose code...

• Sorry for insisting on an explanation of how you built the function, but could you provide more details?

Here is some more-verbose and likely slightly less-efficient code that does the same thing, in essentially the same order:

```Student_buildAllPossibleModels:= proc(model::list, M::procedure)
local d:= nops(model), Models:= Array(1..d), i, m, Keep, mm;
for i from 1 to d do
m:= model[i];
Keep:= {M(i)[]} minus {`if`(type(m, `+`), op(m), m)};
Models[i]:= seq(subsop(i= m + mm, model), mm= Keep)
end do;
return [seq(Models)]
end proc
:
```

Let me know if that helps.

## Make M a function of i...

• If I give values to in other packages of the worksheet, would that somehow interfere with the results in buildAllPossibleModels

Yes, that interference would very likely happen and be problematic. It can be easily avoided by making a function of i. This would also avoid the need to pass i as a parameter. Here is a way to do it:

```restart:
MakeMonoList:= proc(alpha::symbol, V::list(symbol), dim::nonnegint)
local i, k, T;
unapply(
sort([T], rcurry(Groebner:-TestOrder, 'tdeg'(V[])))
*~ [seq](alpha[i,k], k= 0..binomial(nops(V)+dim, dim)-1),
i
)
end proc
:
#The order [z,y,x] is needed to duplicate your original monomial list:
M:= MakeMonoList(alpha, [z,y,x], 3);

model:= [x^2*y*alpha[1, 11], x*z^2*alpha[2, 15], y^2*z*alpha[3, 17] + y*z*alpha[3, 8]]:
buildAllPossibleModels:= (model::list, M::procedure)->
[for local i,m in model do
map(subs, m=~ m+~ subs({`if`}(m::`+`, op(m), m)=~ (), M(i)), model)[]
od]
:
models:= CodeTools:-Usage(buildAllPossibleModels(model, M));
```

I included the parameter dim in MakeMonoList because I didn't know whether your dimension was always the same as the number of variables [x, y, z]. If they're always the same, the parameter can be removed and dim replaced with nops(V) in the code.

@acer What about controllers other than sliders (for example, dials)? Is any customization possible for those?

## Need to pass in i...

@emendes You need to pass in the index i, because it's not local. Like this:

```buildAllPossibleModels:= proc(model::list, M::list, i::name)
description "This function returns all models generated from a given model and set of monomials.";
local k,m;
[for k,m in model do
map(subs, m=~ m+~ subs(i= k, {`if`}(m::`+`, op(m), m)=~ (), M), model)[]
od]
end proc:

buildAllPossibleModels(model, M, i);
```

```buildAllPossibleModels:= module()
description "This function returns all models generated from a given model and set of monomials.";
local
ModuleApply:= (model::list, M::list, i::name)-> local k;
map(subs, (m:= model[k])=~ m+~ subs(i= k, {`if`}(m::`+`, op(m), m)=~ (), M), model)[],
k= 1..nops(model)
);
end module
:
buildAllPossibleModels(L1, L2, i);
```

## Inefficiency of iterative appending...

@mmcdara Due to idiosyncracies of Maple, building a set, list, or sequence in a loop by appending to an existing set, list, or sequence is extremely inefficient: The execution time of each iteration is proportional to the current length of the set, list, or sequence.  Thus the time for the whole loop is proportional to the square of the final length.

That's not to say that it's always inefficient to build sets, lists, or sequences in loops; the inefficiency comes from building them by appending to an existing set, list, or sequence; it's not something inherently inefficient about loops.

This code of yours:

```L1L2 := NULL:
while not T[finished] do
L1L2 := L1L2, T[nextvalue]()
end do:
L1L2 := [L1L2]:```

can be replaced by the far more efficient single line:

`L1L2:= [seq](T[nextvalue](), 1..nops(L1)*nops(L2));`
 1 2 3 4 5 6 7 Last Page 3 of 687
﻿