Joe Riel

9660 Reputation

23 Badges

20 years, 4 days

MaplePrimes Activity


These are replies submitted by Joe Riel

Please attach the msim file (use the green arrow icon).

Followup: Hmm. You did say any model; that implies a more serious issue.  Regardless, attaching a simple model that fails wouldn't hurt.

@Carl Love I submitted the SCR a short while ago, but had first inspected the current routine, noticed the restriction, and suggested that it not be used if the input is a list of integers. The more interesting question is whether a list should be restricted to a list of integers, or even integers in the base. I'd just as soon allow any list to be used.  So one could enter symbolic expressions in the list. Thus convert([a,b,c], list, decimal, b) would return a + b*b + c*b^2. Actually that would require extending the routine to allow symbolic bases, as well.  So long as extensions are being proposed, I'd consider extending the base parameter to allow a list, so mixed-radix expressions could be handled, though that might be out-of-scope.

@Carl Love Clever, but by library-based I mean a procedure that does what is desired without further manipulations.  My proposal is to extend convert/decimal to allow a list of integers as input.

I don't know of a library method. There should be one; I've frequently wanted one. Will submit an SCR.

@Carl Love Why'd you name the predicate NoNegatives?

@blink23 Did you 'with' the package so the short forms (i_, etc) are available? For example

M := module() option package; local j; export j_ := j; end module:
with(M);
                     [j_]
3*j_;
                     3 j
coeff(%,j_);
                     3

@blink23 Yes.  That was why I suggested defining i_, j_, and k_ as exports, and assigning them to the locals:

Quat := module()
option package;
export i_, j_, k_;
local i, j, k;
   i_ := i;
   j_ := j;
   k_ := k;
...
end module:

Now you can enter an expression, q := 2*i_ + 3*j_. It will appear as 2*i+3*j.  

@blink23 You probably do not want to protect them.  The reason is somewhat subtle. The variables i, j, and k are commonly used in Maple code as indices in seq commands, etc. If you protect them, they cannot be used that way, Maple will raise an error. That won't be an issue provided i, for example was declared as local when used in a procedure, however, I would not be surprised if there is some Maple library code where this was not done.  A demo of the issue:

test := proc() seq(i, i=1..5); end proc:
protect('i'):
test();
Error, (in test) attempting to assign to `i`, which is protected. ...

You could, instead, merely check whether the variables are assigned and raise an error, when loading your package, if they are. That would be done in a ModuleLoad procedure of the package.  That would also be the place to protect them, though I discourage it. 

 Followup:

Why do you want them global? If you don't need to reference them from your output, you could just declare them as local to the module. They will then appear as you'd like, and are perfectly safe. The downside is that it is a bit harder to reference them outside your module code.  You could export, say, i_, j_, and k_ and assign these to i, j, and k inside the module.  Then a user could reference the local variables via these exports.

@ verify is a little tricky here; there are alternatives. Regardless, the following works

verify(u(1,2.0), u(1.0, 2), specfunc(truefalse,u));
                                                  true

@ As mentioned in first response, this is because you are comparing structures with floats.  Maple's normal equality test only looks at the surface type; if they are numeric then it will use a numeric equality test, otherwise it uses the addresses of the structure.  The unevaluated functions u(20.0) and u(20) have different addresses.

A simple workaround may be to use 1/20 as the increment in your loop counter.

@nm I agree it should handle this. I'm submitting an SCR (software change request).

@Carl Love A clarification. That returns a Matrix of the form requested, however, the user will presumably have to assign it to M, or another variable. That is, the operation is not done inplace.  He could do map[inplace](collect, M, [a1,a2]) to update M inplace.

 

@Markiyan Hirnyk Aladjev's code does not solve the problem (notice all the repeats in the ouput).  It is also much slower and more memory intensive, as well as being nearly incomprehensible. Plus it is using deprecated Maple structures (matrices). 

Here's a comparison of using Aladjev's tuple procedure (which returns strings) vs Iterator:-MixedRadixTuples (which returns Vectors):

r := 3: n := 9:
CodeTools:-Usage(tuples([seq(0..r-1)], n)):
memory used=333.70MiB, alloc change=25.83MiB, cpu time=3.43s, real time=3.38s, gc time=212.01ms
T := Iterator:-MixedRadixTuples([r$n]):
CodeTools:-Usage(seq(t[], t=T)):
memory used=2.19MiB, alloc change=0 bytes, cpu time=32.00ms, real time=31.00ms, gc time=0ns

 

 

@acer I purposely omitted measuring the call to the constructor because it's a one-time fixed cost, independent of the problem size. For the tiny example given, it dominated the Iterator cost, but that isn't realistic for a problem where size/speed is an issue.

@Carl Love Using the Iterator package (of course):

with(Iterator):
(m,n,p):= (2,3,3):

 

P := MixedRadixTuples([p $ m*n]):
(h,g) := ModuleIterator(P):
M := ArrayTools:-Alias(g(),[m,n]):
CodeTools:-Usage([seq(M[], p in P)]):
memory used=265.26KiB, alloc change=0 bytes, cpu time=8.00ms, real time=6.00ms, gc time=0ns

Comparing to yours

CartProd:= proc(L::list(list))
local S, _i, V:= _i||(1..nops(L));
[eval(subs(S= seq, foldl(S, [V], (V=~ L)[])))]
end proc:
CodeTools:-Usage(map[3](Matrix, m, n, CartProd([[$0..p-1] $ m*n]))):
memory used=3.02MiB, alloc change=0 bytes, cpu time=24.00ms, real time=25.00ms, gc time=0ns
First 41 42 43 44 45 46 47 Last Page 43 of 195