Carl Love

Carl Love

28070 Reputation

25 Badges

13 years, 34 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@vv

Vote up.

I was able to improve your procedure, making it

  • take less time and memory,
  • handle the degenerate cases k > n and k = 0, and
  • more robust by doing type checking and by using a local variable.

Here's the code:

#VV's method, modified by Carl
rcomb2:= proc(n::nonnegint, k::nonnegint)
local i;
     if k > n then ()
     elif k=0 then []
     else
          proc(n,k,p:= [])
               if k=n then [seq(1..n), p[]]
               elif k=1 then seq([i,p[]], i= 1..n)
               else thisproc(n-1, k, p), thisproc(n-1, k-1, [n,p[]])
               fi
          end proc(n,k)
     fi
end proc:

With these modifications, the above is a tiny bit faster than my seq method, but uses more memory. I modified my Answer above to include both your original version and my modification in the overall comparison.

 

@vv Your rcomb seems to produce the correct number of tuples, but most of them are shorter than they should be:

rcomb(5,3);

     [1, 2, 3], [1, 2], [1, 3], [2, 3], [1, 2], [1, 3], [2, 3], [1, 4], [2, 4], [3, 4]

@Joe Riel Since I thought about it so long and hard, please let me know if you know of any way that uses the OP's simple recursion, but using tables or rtables rather than sets or lists.

@sand15athome 

So, I see that you figured out how to use ||, which allows you to combine some features of both indices and subscripts. In general, there are a few drawbacks to using ||, but they don't apply to your situation. The two drawbacks that I can think of to using || are

  • variables created with || are always global, and
  • if you use hundreds or thousands of such variables, you will notice a slowdown that won't happen if you use indexed variables.

Here is your worksheet with my ideas for improvement:

restart:

with(Statistics):
N := 2:
for n in ['n', $1..N] do
#     ^^^^^^^^^^^^^^^
   X__E__||n := RandomVariable(Normal(mu__E__||n, sigma__E__||n));
end do:

PDF(X__E__1, x__E__1);  # good, I wanted this

(1/2)*2^(1/2)*exp(-(1/2)*(x__E__1-mu__E__1)^2/sigma__E__1^2)/(Pi^(1/2)*sigma__E__1)

n := 'n':
PDF(X__E__||n, x__E__||n); # I thought to obtain the same output as befor with subscript n instead of 1

(1/2)*2^(1/2)*exp(-(1/2)*(x__E__n-mu__E__n)^2/sigma__E__n^2)/(Pi^(1/2)*sigma__E__n)

Product(PDF(X__E__||n, x__E__||n), n=1..N); # which does not work due to the previous "problem"

Product((1/2)*2^(1/2)*exp(-(1/2)*(x__E__n-mu__E__n)^2/sigma__E__n^2)/(Pi^(1/2)*sigma__E__n), n = 1 .. 2)

mul(PDF(X__E__||n, x__E__||n), n=1..N);   # mul instead of `*` as suggested by Carl
#I suggested that you use `mul` instead of `product`, not instead of `*`.

(1/2)*exp(-(1/2)*(x__E__1-mu__E__1)^2/sigma__E__1^2)*exp(-(1/2)*(x__E__2-mu__E__2)^2/sigma__E__2^2)/(Pi*sigma__E__1*sigma__E__2)

# but what this does not give the same result ?

product('PDF(X__E__||n, x__E__||n)', n=1..N);
#       ^                         ^
#Quotes needed to prevent premature evaluation; but, better to use `mul` instead.

(1/2)*exp(-(1/2)*(x__E__1-mu__E__1)^2/sigma__E__1^2)*exp(-(1/2)*(x__E__2-mu__E__2)^2/sigma__E__2^2)/(Pi*sigma__E__1*sigma__E__2)

 


Download WhatHappensHere3.mw

 

@vv

With Maple, modifying the code for experimentation is easy. Maple's arbitrary-length integer arithmetic is quite fast; it uses GMP. Maple's memory management isn't the greatest, but at least you get automatic garbage collection on parallel processors. I suspect that things like reversing the digits of an arbitary-length integer in an arbitrary base are very tedious in C.

If I was going to write a program intended to run for weeks or months operating on numbers with millions of digits, I'd use C. But I'd definitely write that program first in Maple, perfect it, and then hand translate it to C.

@Matt C Anderson Okay, either Maple 13 or Maple's 2D Input doesn't allow ()-> if .... Change this section of code:

(()-> if M > MLim then "Memory"
           elif T-st > TLim then "Time"
           elif k > Count then "Length"
           else "No"
           end if
 )()

to

proc()
     if M > MLim then "Memory"
     elif T-st > TLim then "Time"
     elif k > Count then "Length"
     else "No"
     end if
end proc()

Don't forget the () at the end.

@paulinastm If you decrease the list length, then listM needs to be reinitialized before doing the shorter list. The easiest thing is to just begin your code with restart. That'll inilialize everything. To just initialize listM, do

listM:= 'listM';

The second form that I posted doesn't use listM, so it doesn't have this problem.

Here's an extension of the idea to arbitrary bases. Let me know if this won't run in your Maple 13. If so, I'll try to modify it.

Lychrel numbers, arbitrary base

https://en.wikipedia.org/wiki/Lychrel_number

Carl Love 2016-Oct-09

 

Based on http://www.mapleprimes.com/posts/206867-The-Growing-Sequence-Of-196 by Matt C Anderson.

 

Revnum:= proc(n::nonnegint, {base::And(posint, Not(1)):= 10})
description
     "Reverse the digits of a number in any base and"
     "return results as an ordinary integer."
;
local L,S;
     if base=10 then #Use faster StringTools method.
         parse(StringTools:-Reverse(sprintf("%d", n)))
     else
         L:= ListTools:-Reverse(convert(n, ':-base', base));
         convert(L, ':-base', base, base^nops(L))[]
     end if
end proc:

 

Lychrel:= proc(
     n::nonnegint,
     {Count::posint:= infinity}, #max list length to compute
     {TLim::positive:= 99}, #time limit (seconds)
     {MLim::posint:= 2^30}, #memory limit (bytes)
     {base::And(posint, Not(1)):= 10}
)
local
     st:= time(), T:= time(), M:= kernelopts(bytesalloc),
     N:= n, r:= Revnum(N, ':-base'= base),
     L:= Vector([N]),
     k
;
     for k from 2 to Count while r <> N and T-st <= TLim and M <= MLim do
          N:= r+N;
          L(k):= N;
          T:= time();
          M:= kernelopts(bytesalloc);
          r:= Revnum(N, ':-base'= base)
     end do;
     userinfo(
          1, Lychrel,
          (()-> if M > MLim then "Memory"
               elif T-st > TLim then "Time"
               elif k > Count then "Length"
               else "No"
               end if
          )(), "limit reached."
     );
     convert(L, list)
end proc:
  

infolevel[Lychrel]:= 1:


LS:= Lychrel(708, TLim= 10, base= 5):

Lychrel: Time limit reached.

nops(LS);

3202

ilog10(LS[-1]);

1009

 

Download Lychrel_number.mw

@Carl Love I thank you very much for doing the honorable thing by restoring the original Question.

@Carl Love I thank you very much for doing the honorable thing by restoring the original Question.

@nm I agree strongly about the need for more examples on the help pages. However, here on MaplePrimes, there have been hundreds, perhaps thousands, of Questions about third-order BVPs.

I will Answer your Question below, but you must promise to not ever edit or delete the Question.

@maria182 Please don't ever remove a Question after it has been Answered!

Please don't ever remove or substantially edit a Question that has already been Answered!

Note that the given Answer now makes no sense following your now-"sterilized" Question. I find this incredibly disrespectful to the person who took the time to Answer.

@taro The :- is not attached to the procedure header it comes after; rather, it's attached to the variable it comes before. It means that the following variable is a global variable even if it has a name that would ordinarily be overridden by a local variable or module export of the same name.

First 380 381 382 383 384 385 386 Last Page 382 of 709