Joe Riel

9660 Reputation

23 Badges

20 years, 20 days

MaplePrimes Activity


These are replies submitted by Joe Riel

My reasoning was the following.  Given

  (log(x+1)/x = sum(A[k]/x^k, k=0..infinity)  as x -> infinity

The term on the left approaches 0, so A[0] = 0.  Multiply both sides by x.  Now the term on the left approaches infinity, the term on the right goes to A[1] (because A[0]=0).  This might not qualify for a proof, but it is suggestive.

You could use an Array here to match the original indices:

F := Array(0..2,0..2,(i,j)->f[i,j]);

The symbol option does not work with Arrays.

Different but interesting is

`+`(cat(f,0..2,0..2));
              f00 + f01 + f02 + f10 + f11 + f12 + f20 + f21 + f22

You could use an Array here to match the original indices:

F := Array(0..2,0..2,(i,j)->f[i,j]);

The symbol option does not work with Arrays.

Different but interesting is

`+`(cat(f,0..2,0..2));
              f00 + f01 + f02 + f10 + f11 + f12 + f20 + f21 + f22

You have the right idea, however, the limits you used are incorrect.  The outer limit has to be from 0 to 1.   The inner limit then depends on the value of the outer variable.

You have the right idea, however, the limits you used are incorrect.  The outer limit has to be from 0 to 1.   The inner limit then depends on the value of the outer variable.

I prototyped such a facility a couple years ago, though it never amounted to much.  Hmm. I cannot locate it at the moment; I suspect it resides on a disk that is currently offline. It had a few procedures for ordering types [by hierarchy] and for printing a hierarchical tree of types that match a given expression. 

What I presented was not a logical ordering but rather a terse description of the definitions of the numerical types, arranged in a partial ordering.  A more useful arrangement, I think, would be to group the types in some way.   Maple's help page format doesn't lend itself to hierarchical displays

The reason I go to the main type page is to find a type whose name I have forgotten; an alphabetical ordering is not particularly helpful.  If I knew the name I'd go directly to its help page.

Here is one method I tried (note that the subheading are arranged alphabetically, which is probably not the best choice).  This was a while ago, I'm not sure I can explain it adequately just now.

Complex
    complex      ::= complex(numeric & realcons) 
    complex(d)   ::= Re(x)::d & Im(x)::d         
    finite       ::= complex(numeric)            
    imaginary    ::= imaginary(extended_numeric) 
    imaginary(d) ::= complex(d) & (Re(x) = 0)    
                                                 
    nonreal      ::= complex(extended_numeric)   
                     & Not(extended_numeric)     
    nonreal(d)   ::= nonreal & (Re,Im)(x)::d     
                                                 
    cx_zero      ::= nonreal & (x = 0)           
                                                  

Evaluated
    complexcons ::= evalf(x)::complex 
    realcons    ::= evalf(x)::float   
                                       

Floats
    float    ::= sfloat | float[] | float[8] 
    float[]  ::= <hardware float>            
    float[8] ::= <hardware float>            
    sfloat   ::= <software float>            
                                              

Infinities
    cx_infinity      ::= nonreal & (Re & Im)(x)::infinity   
    infinity         ::= identical(infinity,-infinity)      
                         | Float( . , identical(infinity) ) 
                         | nonreal & (Re|Im)(x)::infinity   
    neg_infinity     ::= infinity & negative                
    pos_infinity     ::= infinity & positive                
    real_infinity    ::= infinity & extended_numeric        
    SymbolicInfinity ::= infinity | infinity*anything       
                                                             

Miscellaneous
    even ::= integer & (irem(x,2) = 0) 
    odd  ::= integer & Not(even)       
                                        

Radicals
    algext    ::= algext(anything)          
    algext(d) ::= RootOf(polynom(d,.))      
    algnum    ::= rational                  
                  | RootOf(polynom(algnum)) 
                  | algnum+algnum           
                  | algnum*algnum           
                  | algnum/algnum           
    algnumext ::= RootOf & algnum           
    radnum    ::= I                         
                  | rational                
                  | radnum+radnum           
                  | radnum*radnum           
                  | radnum^rational         
                                             

Rationals
    extended_rational ::= rational                                  
                          | identical(infinity,-infinity,undefined) 
    fraction          ::= integer/integer                           
    integer           ::= negint | 0 | posint                       
    negint            ::= -posint [ (-1) &* posint ]                
    nonnegint         ::= 0 | posint                                
    nonposint         ::= 0 | negint                                
    posint            ::= 1, 2, 3, ...                              
    rational          ::= integer | fraction                        
                                                                     

Reals
    extended_numeric      ::= numeric                                         
                              | identical(infinity, -infinity)                
                              | Float( . , infinity)                          
                              | undefined                                     
                                                                              
    nonnegative           ::= extended_numeric & (x >= 0)                     
    positive              ::= extended_numeric & (x > 0)                      
    nonpositive           ::= extended_numeric & (x <= 0)                     
    negative              ::= extended_numeric & (x < 0)                      
                                                                              
    negzero               ::= -0.0                                            
    poszero               ::= 0 | +0.0                                        
                                                                              
    numeric               ::= rational                                        
                              | float & Not(infinity | undefined)             
                                                                              
    undefined             ::= identical(undefined)                            
                              | Float( . , undefined )                        
                              | nonreal & (Re|Im)(x)::undefined               
                                                                              
    constant              ::= { anyfunc | + | * | ^ }(constant)               
                              | complex(numeric | infinity)                   
                              | identical(<constants>)                        
    <constants>           ::= false, gamma, infinity, true, Catalan, FAIL, Pi 
                                                                              
    embedded_axis         ::= embedded_real | embedded_imaginary              
    embedded_axis(d)      ::= (embedded_real | embedded_imaginary)(d)         
    embedded_imaginary    ::= nonreal & (Re(x) = 0)                           
    embedded_imaginary(d) ::= embedded_imaginary & Im(x)::d                   
    embedded_real         ::= complex(extended_numeric) & (Im(x) = 0)         
    embedded_real(d)      ::= embedded_real & Re(x)::d                        

I don't know whether an identity should work with multiple arguments or not.  It should accept multiple arguments, the issue is whether it returns only the first, or all the arguments.  I can see uses for both. It should return NULL if given an empty argument list, which suggests it should return all arguments. 

I suppose one could design it to accept an index that indicate which arguments to return, however, that may detract from its simplicity.  What ever form it took, I'd find it useful.

As an example, consider the simple task of converting, say,

L := [x,y,z]:

to [x=f(x), y=f(y), z=f(z)]

The way I would usually do this is either

[seq(q=f(q), q in L)];

or

map(q -> (q=f(q), L);

The seq should be slightly faster because the user-defined procedure is not called with each conversion.  However, it requires declaring a local (q), which, while not a big deal, can be a nuisance, particularly if this is embedded in some other code.  With a built-in identity, say the suggested `()`, one could do

map(`()`=f, L);

which is short, clear, probably as fast as seq and doesn't require declaring a local.  I suppose one could argue that `()` isn't as clear as, say Id, but there seems little chance of getting that as a reserved word.

While this is a really nice solution, and probably what I'd do [and suggest], I have to wonder if this is what the student should be doing.  Not a whole lot of math is being learned solving it this way.  I suppose the motivated student might do something like

 with(Student:-VectorCalculus):
 C := <[x,y,z](t)>;            
                                             C := x(t) e  + y(t) e  + z(t) e
                                                        x         y         z

 L := ArcLength(C, t=0..T);
                                          T
                                         /
                                        |   //d      \2   /d      \2   /d      \2\1/2
                                  L :=  |   ||-- x(t)|  + |-- y(t)|  + |-- z(t)| |    dt
                                        |   \\dt     /    \dt     /    \dt     / /
                                       /
                                         0

subs([x(t)=2*exp(t), y(t)=exp(2*t)*cos(t), z(t)=exp(2*t)*sin(t), T=ln(3)], L);
value(%);
 

At least with that approach one gets to see the intermediate formula used to compute arclength.  Better would probably be to enter it directly, say

 Int(Norm(diff(C,t)), t=0..T);
then show that the result is equivalent to that computed with ArcLength.  I suppose the more motivated student might also look at the result as t goes from T to 0 and then explain what that means.

While this is a really nice solution, and probably what I'd do [and suggest], I have to wonder if this is what the student should be doing.  Not a whole lot of math is being learned solving it this way.  I suppose the motivated student might do something like

 with(Student:-VectorCalculus):
 C := <[x,y,z](t)>;            
                                             C := x(t) e  + y(t) e  + z(t) e
                                                        x         y         z

 L := ArcLength(C, t=0..T);
                                          T
                                         /
                                        |   //d      \2   /d      \2   /d      \2\1/2
                                  L :=  |   ||-- x(t)|  + |-- y(t)|  + |-- z(t)| |    dt
                                        |   \\dt     /    \dt     /    \dt     / /
                                       /
                                         0

subs([x(t)=2*exp(t), y(t)=exp(2*t)*cos(t), z(t)=exp(2*t)*sin(t), T=ln(3)], L);
value(%);
 

At least with that approach one gets to see the intermediate formula used to compute arclength.  Better would probably be to enter it directly, say

 Int(Norm(diff(C,t)), t=0..T);
then show that the result is equivalent to that computed with ArcLength.  I suppose the more motivated student might also look at the result as t goes from T to 0 and then explain what that means.

This does bring up a minor annoyance.  Many of the index help pages, that is, the top-level help page of a package or particular topic, are ordered alphabetically rather than grouped by topic.  Case in point, the ?type help page.   Its utility would be enhanced, I believe, if the types were grouped together in a logical way, possibly with some overlap. For my own use I've created a help page that sorts all the numeric types by partial order, with the basic  types at the top and a backus-naur type syntax to show how those below are related.  Here's what it looks like:

Hierarchy of Numerical Types
- The following table describes the partial ordering (Definition[partialorder]
  ) of Maple numerical types. Each type is defined in terms of its minimal
  cover. A type on the left side of the definition operator (::=) is defined by
  the expression on the right side. Each type is defined by previously defined
  types (those preceding it in the table), though some definitions are
  recursive. 
- The vertical bar (|) is the or operator. The ampersand (&) is the and
   operator. 
- The symbol x is the expression being tested; it is used to indicate a
  non-type restriction or a restriction on a transformation of the expression.
  For example, Re(x) > 0 & Im(x)::integer is true when the real part of x is
  positive and the imaginary part is of type integer. 
- The term d stands for a subtype, that is, a restriction of the domain of the
  base type. 
- The point (.) stands for any appropriate expression; for example, Float( . ,
  infinity) corresponds to a float with any valid mantissa and an exponent of
  type infinity. 
- Single forward quotes around a field is used as a shorthand for the 
  identical type. For example, 'infinity' is equivalent to identical(infinity),
  which is not the same as the infinity type. 
- The fields Integer, Fraction, and Float (SFloat) refer to constructors for
  the integer, fraction, and float elements, respectively. 

    integer               ::= Integer( . )                                     
    integer[1|2|4|8]      ::= integer & representable by (1|2|4|8)-bytes (signed)       
    integer[i1..i2]       ::= integer & i1 <= x <= i2 (i1 and i2 are integers) 
    posint                ::= integer & (x > 0)                                
    nonnegint             ::= integer & (x >= 0)                               
    negint                ::= integer & (x < 0)                                
    nonposint             ::= integer & (x <= 0)                               
    even                  ::= integer & irem(x,2)=0                            
    odd                   ::= integer & Not(even)                              
    fraction              ::= Fraction( . , . )                                
    rational              ::= integer | fraction                               
    extended_rational     ::= rational                                         
                              | identical(infinity,-infinity,undefined)        
    float[]               ::= <hardware float>                                 
    float[8]              ::= <hardware float>                                 
    sfloat                ::= Float( . , . ) | SFloat( . , . )                 
    float                 ::= sfloat | float[] | float[8]                      
    numeric               ::= rational                                         
                              | Float(integer)                                 
                              | Float(integer, integer)                        
    infinity              ::= identical(infinity,-infinity)                    
                              | Float( . , 'infinity' )                        
                              | (Re|Im)(x)::infinity & (Re&Im)(x)::(infinity|numeric)   
    undefined             ::= 'undefined'                                      
                              | Float( integer , 'undefined' )                 
                              | (Re|Im)(x)::undefined & (Re&Im)(x)::(undefined|numeric) 
    extended_numeric      ::= numeric                                          
                              | identical(infinity, -infinity)                 
                              | Float( integer , 'infinity' )                  
                              | undefined                                      
    nonnegative           ::= extended_numeric & (x >= 0)                      
    positive              ::= extended_numeric & (x > 0)                       
    nonpositive           ::= extended_numeric & (x <= 0)                      
    negative              ::= extended_numeric & (x < 0)                       
    negzero               ::= '-0.0'                                           
    poszero               ::= '+0.0' | '0'                                     
    realcons              ::= evalf(x)::{float | identical(infinity,-infinity)}
    complex(d)            ::= (Re & Im)(x)::d                                  
    complex               ::= complex(numeric & realcons)                      
    finite                ::= complex(numeric)                                 
    complexcons           ::= evalf(x)::complex                                
    nonreal               ::= complex(extended_numeric) & Not(extended_numeric)                          
    nonreal(d)            ::= nonreal & (Re&Im)(x)::d                          
    imaginary(d)          ::= complex(d) & (Re(x) = 0)                         
    imaginary             ::= imaginary(extended_numeric)                      
    embedded_real         ::= complex(extended_numeric) & (Im(x) = 0)          
    embedded_real(d)      ::= embedded_real & Re(x)::d                         
    embedded_imaginary    ::= nonreal & (Re(x) = 0)                            
    embedded_imaginary(d) ::= embedded_imaginary & Im(x)::d                    
    embedded_axis         ::= embedded_real | embedded_imaginary               
    embedded_axis(d)      ::= (embedded_real | embedded_imaginary)(d)          
    algext(d)             ::= RootOf(polynom(d, . ))                           
    algext                ::= algext(anything)                                 
    algnum                ::= rational                                         
                              | RootOf(polynom(algnum))                        
                              | algnum+algnum                                  
                              | algnum*algnum                                  
                              | algnum/algnum                                  
    algnumext             ::= algnum & RootOf                                  
    radnum                ::= 'I'                                              
                              | rational                                       
                              | radnum+radnum                                  
                              | radnum*radnum                                  
                              | radnum^rational                                
    cx_infinity           ::= nonreal & (Re&Im)(x)::infinity                   
    real_infinity         ::= infinity & extended_numeric                      
    pos_infinity          ::= infinity & positive                              
    neg_infinity          ::= infinity & negative                              
    SymbolicInfinity      ::= infinity | infinity * anything                   
             
See Also 
anything, evalf, Float, Fraction, Im, Integer, Not, Re, type  

I'd like to see proposals how the other types might be arranged/presented to improve the utility of the help system.

That's clever, however, it isn't clear whether the OP wants a random permutation or a random combination.  Note that the order of a set of integers is not random.

A simpler way to pick a random combination is to use combinat:-randcomb:

combinat:-randcomb([seq(1..20)], 10);
                      [2, 4, 5, 6, 8, 12, 13, 15, 17, 18]

combinat:-randperm can be used to pick a random permutation, then select just the desired 1..n elements from it,  however, if the size of the sublist is a small fraction of the size of the permutation, the method is less efficient.  A better approach is to combine the two:

f4 := proc(n,a,b)
uses combinat;
    randperm(randcomb([seq(a..b)],n));
end proc:

That's clever, however, it isn't clear whether the OP wants a random permutation or a random combination.  Note that the order of a set of integers is not random.

A simpler way to pick a random combination is to use combinat:-randcomb:

combinat:-randcomb([seq(1..20)], 10);
                      [2, 4, 5, 6, 8, 12, 13, 15, 17, 18]

combinat:-randperm can be used to pick a random permutation, then select just the desired 1..n elements from it,  however, if the size of the sublist is a small fraction of the size of the permutation, the method is less efficient.  A better approach is to combine the two:

f4 := proc(n,a,b)
uses combinat;
    randperm(randcomb([seq(a..b)],n));
end proc:

An excellent choice, indeed.  Doug's advice is invariably clear, useful, and generous. 

First 125 126 127 128 129 130 131 Last Page 127 of 195