Carl Love

Carl Love

16944 Reputation

24 Badges

7 years, 233 days
Mt Laurel, New Jersey, United States
My name was formerly Carl Devore. I was in the PhD math program at University of Delaware until 2005. I was very active in the Maple community at that time.

MaplePrimes Activity


These are answers submitted by Carl Love

To ban repeats, use

Z::And(list(identical(a,b,c,d)), 2 &under nops, 2 &under (nops@{op}))

The second clause restricts list length to 2. The third clause says that the length should still be 2 even if were converted to a set. Those clauses could be combined as

Z::And(list(identical(a,b,c,d)), [2,2] &under [nops, nops@{op}])

In the second procedure, the line a:= b causes a to be an implicit local (for the entire execution of the procedure), so it no longer has any connection to the global a. It's not the mere presence of a that makes it implicit local, it's that you make an assignment to it. Since the first procedure does not assign to a, global a is used. If you want a to be global in the second procedure, either declare global a, or use it as :-a.

Advice: Whenever you get a message about implicit locals, correct the code immediately.

Suppose that is your polynomial, is its set of coefficients, and S is the set of coefficients that you want to keep. Then do

eval(P, (C minus S)=~ 0)

If for some reason it's more convenient to store and S as lists, then do

eval(P, ({C[]} minus {S[]})=~ 0)

For large-scale programs it may be desirable to minimize list/set conversions.

 

SumList:= proc(L::{list, set})
local r:= 0, x;
    for x in L do r+= x od;
    r
end proc:

Factorial:= (n::nonnegint)-> local r:= 1, k:= 0; do r*= ++k until k>=n;

while loop could just as well be used in the second procedure. I just wanted to show you the possibility of an until loop. Since a do-until loop is guaranteed to execute at least once, the second procedure doesn't need to specify a return value after the loop.

g:= x-> 'g'(-x):

Or, starting from a known function f, its even part is

g:= x-> (f(x)+f(-x))/2:

These solutions use Maple tables, and they work for any modulus (your 8). 

PrimesByClass:= proc(N::posint, m::posint)
local p:= 2, L;
    while (p:= nextprime(p)) < N do L[irem(p,m)][p]:= () od;
    [indices]~(L, 'nolist')
end proc
:
CountPrimesByClass:= proc(N::posint, m::posint)
local p:= 2, L:= table(sparse);
    while (p:= nextprime(p)) < N do L[irem(p,m)]++ od;
    [indices](L, 'pairs', 'indexorder')
end proc
:
MaxClass:= (L::list(anything=realcons))-> lhs(L[max[index](rhs~(L))])
:
L:= PrimesByClass(100,8);
L:= TABLE([1 = [17, 41, 73, 89, 97], 3 = [3, 11, 19, 43, 59, 67, 83], 
  5 = [5, 13, 29, 37, 53, 61], 7 = [7, 23, 31, 47, 79, 71]])

CountPrimesByClass(100,8);
                  [1 = 5, 3 = 7, 5 = 6, 7 = 6]

MaxClass(CountPrimesByClass(10^6, 8)); 
                               7

 

@radaar wrote:

  • restart;
    i:=2:
    ff:=proc()
          i:=i+2:      #### implicit local 
          return i
    end proc:
    ff()

    output: i+2

    if we assign the output to another variable and try to output the variable it shows too many level of recursion

It's an interesting phenomenon. I wouldn't call it a bug, although I'd accuse a programmer who---through sloppy programming---relied on this to be creating their own bugs.

To analyze this, let's first cut away the bloat that has nothing to do with it:

  • That i has been globally assigned has nothing to do with this.
  • That the in the proc is implicitly local rather than declared local has nothing to do with this. Indeed, there's no runtime difference between the two, and a clean programmer should never rely on implicit locals.
  • Explicit return statements aren't needed.
  • Procedures don't need names; they can be anonymous.
  • Whether the output is assigned to another variable is irrelevant.
  • It's totally legitimate for a procedure to return an unevaluated local or an expression containing such. Such a local is called an escaped local. That local can happily live in the same lexical space as the global whose name is spelled the same. Indeed, there's a command specifically for creating such a local: convert(..., `local`). It'd be very instructive for you to study the very brief code of this command: showstat(`convert/local`). I recall that deconstructing that really opened my mind when I was first learning Maple.

Okay, let's look at some examples that all generate related error messages:

restart;
i:= i+2;

Are you satisfied that that causes a "recursive assignment" error? I am. If you truly want to use recursive assigments (at the top level), this works:

i:= ' 'i' + 2';
seq(eval(i, k), k= 1..9);

I find that to be a useful way to experiment with complicated recurrence relations because it gives you the ability to "single step" through them---no debugger needed.

Your example:

restart: #This is identical to your example, without the bloat:
proc() local i; i:= i+2 end proc();
%;

The exact same thing can be done with a global:

restart;
proc() :-i:= :-i + 2 end proc();
%;

Both give the "too many levels of recursion" error.  Are you satisfied with that?
 

Your examples are straying far enough away from your original Question that I think that they deserve their own thread.

You will learn a lot by trying to remove from your examples any factors that are irrelevant to the observed phenomena---those factors that I called "bloat" above.

It's a very good Question. Vote up. I can Answer it mostly, but there are some small details that I can't explain with certainty because they are not documented.

In the expressions seq(k, k= 1..5) and int(k, k= 1..5), the k is called a bound variable (see the Wikipedia article "Free variables and bound variables"). Note that bound, as used in this context, is the past-participle adjective form of the verb to bind; it is not the noun bound as used in "lower bound" and "upper bound", nor is it the past participle of to bound (which is bounded) as in "The functions have bounded derivatives"; nor is it directly related to binding as that verb is used in the context of the with command binding exports to globals. This classification of variables comes from formal logic, and it's used in a variety of fields such as mathematics, computer science, and even linguistics (where, for example, pronouns are the variables); it's not anything specific to Maple. Anyone who programs in a symbolic language such as Maple must be at least implicitly aware of this classification to be successful.

There are a huge number of stock Maple commands that can or must use bound variables in their calling sequence (such as diffplotlimitsum), and you can easily write your own procedures that use them. It is not a special declaration that makes them bound; it's a property of the meta-logic of the procedure.

There are three Maple commands where the bound variable has a special status, and that status is the same in all three: seqadd, and mul. There is no formal name that I'm aware of for this special status; this is very poorly documented. For the sake of this article, I'll call it PLBV (partially local bound variable), although that's not a precise description. It's only those three commands that use a PLBV. There's no formal mechanism whereby you can create your own procedure that uses a PLBV, although I wouldn't be surprised if it were informally possible with the "hackware" commands (addressofdisassembleassemble, and pointto).

In many ways (but definitely not all ways), PLBVs act like local variables. This is the reason for the anomaly that you reported. You can think of the ii in ii:= 50 and the ii in the seq command as different variables. It is not necessary to use a bound variable in a seq command. If you want to repeat ii five times, you can use seq(ii, 1..5).

Use add instead of sum.

Here's what's happening: sum does symbolic summation. The symbolic summation formula for sum(c, k= a..b) (where c doesn't depend on k) is c*(b+1-a). In constrast, add just does brute-force naive computation.

The integral can be done completely by

value(IntegrationTools:-Expand(Int(test, r)));

The imaginary unit in Maple is I (uppercase), not (lowercase).

There are some commands that were commonly used when your textbook was written that have been superceded by newer commands. Three of those are arrayvector, and matrix (all begin with a lowercase letter). These have been superceded by ArrayVectorMatrix, and rtable. While the older forms continue to work, you shouldn't use them; formally we refer to them as deprecated.

A simpler alternative to Array(1..3, 1..4, (i,j)-> i^j) is Array(1..3, 1..4, `^`). I prefer to group the indices with parentheses for clarity:

Array((1..3, 1..4), `^`)

The extra parentheses are a purely syntactic addition; they have no effect on performance.

The computational problem (as opposed to the mathematical-display problem) can be addressed by iterating mul over a set or list of indices:

  • mul(lambda[i] - lambda[k], k= {$1..n} minus {i}) (set of indices)
  • mul(lambda[i] - lambda[k], k= [$1..i-1, $i+1..n]) (list of indices)

 

There is a formal paradigm that applies here called "Scales (or Levels) of Measurement". The scale determines which arithmetic and statistical operations can be performed on the measurements.

The basic (Stevens's four)[*1] scales of measurement are (this is now often taught on day 1 in "Statistics 101"):

  1. Nominal (aka Categorical): Objects being measured can be categorized into a finite number of categories, but there's no numerical relationship between the categories. Examples: {female, male}, {usable, repairable, discardable}, {too sick to be worth treating---going to die anyway; should be medically treated; not sick enough to be worth treating---going to get well anyway}. Allowed operations are set membership and set cardinality.
  2. Ordinal: Objects can be placed in order on some scale, but other arithmetic operations are not appropriate. Examples: hardness scales of materials, such as MOHS; Beaufort scale of hurricane strength. Allowed operations now include <, <=, and the like.
  3. Interval: Objects are measured in such a way that the differences of measurements make sense and can be compared by ratio, but the ratios of individual measurements make no sense. Examples: calendar year, Fahrenheit temperation, Celsius temperature.
  4. Ratio: Measurements can be compared by ratio. Examples: the vast majority of standard measurements with units, such as years or Kelvin temperature.

Although there is much debate over the details of this paradigm, the vast majority of it is that there need to be more levels[*1]; there's wide acceptance of the ideas that there are Levels of Measurement and that some classification of them is useful. Personally, I would always include a logarithmic level for scales such as pH, dB, Richter, etc.

When you do a units conversion in Maple, it is operating on the ratio scale. Suppose I said "The temperature of the solution increased by 18 Fahrenheit degrees. What's that in Celsius?" The answer is 10 Celsius degrees. That's not the same computation as a conversion of absolute temperatures on scales that don't have equal 0 points.

[*1] See Wikipedia article "Level of measurement".

Your method is not even close to something that would work. You need to make 2 implicitplots, one of each color.

restart:
S1:= (x,y,z)-> x^2 + y^2 + z^2 - 16:  
S2:= (x,y,z)-> (x+4)^2 + y^2 + (z-2)^2 - 49:
S1S2intersect:= solve([S1,S2](x,y,z), [x,y,z], explicit):
IntPlaneX:= unapply(rhs(S1S2intersect[1][1]), (y,z));
p1:= (x,y,z)-> `if`(x <= IntPlaneX(y,z), S1(x,y,z), undefined): 
p2:= (x,y,z)-> `if`(x > IntPlaneX(y,z), S2(x,y,z), undefined):
plots:-display(
    plots:-implicitplot3d~([p1,p2], -12..5, (-7..7)$2, grid= [50$3], color=~ [red, blue]),
    style= surface
);

1 2 3 4 5 6 7 Last Page 1 of 292