Carl Love

Carl Love

28035 Reputation

25 Badges

12 years, 323 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@taro The order attribute specifies the order that a Matrix's (or multi-dimensional Array's) entries are physically stored in the computer's memory. Are they grouped by rows? or by columns? Numerical code that accesses the entries of a large matrix in the order that they are stored runs faster because it requires fewer refreshes of the processor's memory caches. Thus the astute programmer wants to know and to be able to set the order. There are only two possible values for order: C_order (grouped by rows) and Fortran_order (grouped by columns). As an example, define these matrices and arrays:

M1:= Matrix([[1,2],[3,4]], order= C_order);
M2:= Matrix(M1, order= Fortran_order);
A1:= Array((1..2)$3, (i,j,k)-> 100*i + 10*j + k, order= C_order):
A2:= Array(A1, order= Fortran_order):

Now apply convert(..., list) to each of these and compare. As I said above, this attribute makes no difference to the final output when using convert(..., list, nested), but it's likely to be faster for large numeric matrices that use C_order.

@taro They are essentially the same, and that was part of Tom's point. The point of his code DD is to explicitly show the order.

The English word "compare" means "note the differences or absence of differences". I've noticed that even some native English speakers think that it means "note the differences".

@taro Since you say "the code of convert/list", it's not clear to me whether you mean that you looked at

showstat(`convert/list`);

or

showstat(`convert/list` :: convert_rtable_to_nested_list);

I was only refering to the latter.

I will now show here three recursive procedures that each do the same thing as that procedure. First, you need to understand what is returned by rtable_dims(A) for any Array (or Vector or Matrix) A. Read its help page. It simply returns the sequence of ranges that specify the valid indices for A.

Second, you need to understand what A[k] returns when k is a valid integer first-position index for A and A is multi-dimensional. Experiment with this until you understand. Define a 2x2 Matrix A and look at A[1] and A[2]. Then define a 2x2x2 Array A and look at A[1] and A[2]. Notice that each of these is a 2x2 Array. That's how we can process these recursively.

Third, you need to know that Maple allows for 0-dimensional Arrays. These are a degenerate case; they simply have no entries.

So here's the first recursive procedure:

NestedList1:= proc(A::rtable)
local k, D:= rtable_dims(A);
   if D = NULL then [] #empty Array, a degenerate case 
   elif nops([D]) = 1 then [seq(A[k], k= D)] # 1-dimensional case
   else [seq(NestedList1(A[k]), k= D[1])]
   fi
end proc:

We can do two things to simplify that. The first is that there are special provisions in seq so that if A is 0- or 1-dimensional, then simply [seq(A)] returns what we want. The second is that a procedure can refer to itself (for the purpose of recursion, and for some other purposes) as thisproc or procname. The semantics of these two are a little different. Usually, thisproc is better for recursion. The procedure becomes:

NestedList2:= proc(A::rtable)
local k, D:= rtable_dims(A);
   if nops([D]) < 2 then [seq(A)]
   else [seq(thisproc(A[k]), k= D[1])]
   fi
end proc:

Finally, we can use `if` instead of if and put the list brackets just once, on the outside:

NestedList:= proc(A::rtable)
local k, D:= rtable_dims(A);
   [`if`(nops([D]) < 2, seq(A), seq(thisproc(A[k]), k= D[1]))]
end proc:

All three of these procedures do the same thing as convert(A, list, nested).

Please let me know if you understand all this, or whether I can explain something further.

@Kitonum Your "check" is flawed because 365 has a palindromic bit pattern. It's just an unfortunate choice of an example number.

Which of the two orders should be considered "reversed" is debatable. Having the most-significant bit on the left seems correct only because that's how we (in some human languages) conventionally write numbers. Having the indices start with the least-significant bit is more efficient for most computational purposes.

@Kertab24 For the time being, let's ignore the coefficient 4*mu*p and just do the integral. So, I interpret the problem as integrating sqrt(x^2+y^2) over the region 0 <= x <= B/2, 0 <= y <= b/2. The region is a simple rectangle in the first quadrant with a diagonal from the origin to (B/2, b/2). Maple will not be able to finish this double integral, as you've noticed. But I can help it by (manually!) converting to polar coordinates. I get the following, which is split into a sum of two integrals, one for the part below the diagonal of the rectangle (i.e., for y <= b*x/B) and one for the part above (y >= b*x/B):

int(r^2, [r= 0..B*sec(theta)/2, theta= 0..arctan(b/B)]) +
   int(r^2, [r= 0..b*csc(theta)/2, theta= arctan(b/B)..Pi/2]);

You and/or your mother should verify how I did that, and I can guide you through that, if needed.

The resulting expression can be simplified:

simplify(%) assuming b > 0, B > 0;

You can see that we get something somewhat similar to (but definitely not equal to) your F2 (after multiplying by 4*mu*p), but there's still the issue of the disappearing Pi. Is my interpretation of the region of integration correct? I have another possible interpretation, which I'll post shortly.

Here's another interpretation of the region: It's the triangle whose vertices are [0,0], [B/2, 0], and [0, b/2] (so, a right triangle with legs along the coordinate axes). Again, I'd use polar coordinates, and the integral is

int(r^2, [r= 0..b*B/2/(B*sin(theta)+b*cos(theta)), theta= 0..Pi/2])
   assuming B > 0, b > 0;

(The assuming clause is an essential part of that command.) This can be simplified by

convert(%, ln); #gets rid of arctanh
simplify(%) assuming b > 0, B > 0;

Once again, the result (after putting back 4*mu*p) is similar to, but definitely not equal to, F2, and there's still the Pi issue.

 

 

 

@tomleslie 

To avoid any possible confusion about this: The order used by convert(A, list, nested) is fixed; it's as shown by Tom above: It doesn't depend on the order attribute of A. On the other hand, the order used by convert(A, list) does depend on that attribute.

@max125 To solve a univariate inequality when one side is a monotonic function and the other other side is constant or monotonic in the other direction, change the inequality to equality and use fsolve. Do not try to use solve for this: it is an extremely complicated command with a vast number of options and modalities. Getting solve to use assumptions (such as that n is integer) is tricky (perhaps trickier than using assumptions with any other command) and hit-or-miss. Since  fsolve solves this problem easily and efficiently, what's the point of using solve?

The function 1/(n+1)! is not entirely monotonic (using its analytic-continuation redefinition as 1/GAMMA(n+2)). It's monotonic for n >= 0. VV failed to note this, and the equation 1/(n+1)! = 0.00001 has an infinite number of solutions for n < 0. His fsolve command just happened to search for positive solutions, somewhat accidentally I guess. It should be forced to only search for positive solutions like this:

fsolve(1/(n+1)! = 0.00001, n= 0..infinity);

@Mac Dude A Maple record is a type of module. If, as you suspect, an inappropriate number of records are being created and retained, that'll show up in the MODULE row of the kernelopts(memusage).

@Kertab24 Notice that 1/Pi appears as an overall coefficient in F1, and Pi doesn't appear at all in F2. How can that possibly happen with indefinite integration? On the other hand, if the integral was done as a definite integral in polar coordinates (which would be natural for an integrand like sqrt(x^2+y^2)), that would account for the Pi.

@Kertab24 I'm sorry, I can't help anymore. The concept of an indefinite double integral is not very meaningful to me. Since Maple apparently allows it, I guess that it's meaningful to someone, and they may be able to help you further. If you can come up with limits of integration so that it becomes a definite integral, then I can continue to help.

Or, if you can provide a plaintext form of F2 so that I don't have to retype it, then I'll help by 1) substituting B= 2*x, b= 2*y, 2) differentiating with respect to x and y, and 3) comparing to F1 without its integral signs.

@Kertab24 Yes, there are easy solutions, but it's not clear to me what you're really trying to do. Are you

  1. trying to integrate the new expression---which is in terms of b and B and contains no x or y---with respect to x and y, so that you'd be integrating a constant?
  2. trying to make a variable substitution, like a u-substitution, which requires that the differentials be adjusted accordingly?
  3. trying to integrate the new expression with respect to b and B?

All of the above have easy solutions.

@Mac Dude You didn't do what I said: Measure it before and after running the suspect code and take the difference. I guess that I need to be more explicit:

MU:= proc({noGC::truefalse:= false})
   if not noGC then 
      gc(); 
      while kernelopts(gcbytesreturned) > 0 do gc() od
   fi;
   Matrix(kernelopts(memusage))  
end proc:

DeltaMU:= (MU0::Matrix(63,3))-> 
   sort(
      remove(
         r-> r[2..3] = [0,0], 
         convert(<MU0[..,1] | (MU() - MU0)[.., 2..3]>, listlist)
      ),
      key= (r-> r[3])
    )
:
   
MU0:= MU(): 
# Run suspect code here.
DeltaMU(MU0);

I don't know why the total of the third column doesn't equal what's reported on the status bar, but I'll note that the same thing happens for me and that kernelopts(bytesalloc) also doesn't equal what's on the status bar. This kernelopts(memusage) technique only reports legitimate memory usage, i.e., what the kernel has accounts for. If the problem is truly a "leak" rather than a coding error, it won't be directly reported. Some experiments posted on MaplePrimes in the past showed strong evidence that the kernel has memory leaks, such as garbage that doesn't get collected.

Of the 63 categories, at least 62 are documented (minimally!) in Appendix 1 "Internal representations" of the Maple Programming Guide. On a quick re-read, I couldn't find anything about category "temporary".

Yes, words are 64-bit words, unless you're one of the few who still has a 32-bit system. If a procedure is called a thousand times, and each time it "uses" a thousand words, that gets counted as a million words towards the total reported in the profile and by kernelopts(bytesused); but that means very little about your (legitimate) overall allocation (what's reported by kernelopts(bytesalloc)) because the vast majority is locals collected as garbage.

I'm sorry to say that your best source of information about all of this is likely a few old-timers (me included) here on MaplePrimes. My knowledge is based on about 90% extreme black-box experimentation, about 9% reading every available bit of documentation, and about 1% communication with others (including some of those old-timers) whose knowledge is more direct and less black-box. Those few who have intimate knowledge of the Maple kernel are notoriously tight-lipped about it, I guess because it's a trade secret.

@MapleMathMatt Thank you for the example. It is essentially the one that I had in mind that felt contrived to me. I'm not trying to give you a hard time about this. I think that this equivalent-equations idea can be extremely useful in matching a student's input with an instructor's template. But I think that it may need to be refined or tweaked. So, here are some ideas, not necessarily arranged in a fully coherent order (just brainstorming):

  1. I think that it may need to be specified which of the first two arguments represents the student's input and which represents the instructor's template.
  2. In your example, suppose that the second argument is the student's input. Does that mean that we allow the student to introduce arbitrary parameters as long as they cancel from both sides of the equation? It seems weird to allow that, plus we'd need to extract those parameters from the input to put into the params argument.
  3. On the other hand, suppose that the second argument is the instructor's template. Is there any good reason for the instructor to do that, to introduce a parameter?
  4. So, did you have an example of a reasonable problem that may be posed to a student in computer-generated homework or quizzes where your EquivEQ example immediately above would reasonably apply?
  5. Would it perhaps be better to pass to your procedure the symbol names that are not parameters and then let any other names be considered parameters?
  6. Would a better final criterion be indets(sol) subset {k} union params?

Here's my perspective on this: I have a good deal of experience with these systems (from various software companies) that allow students to give free-response symbolic-math answers to computer-posed problems, but my point of view is a bit unusual: neither student nor instructor nor question author nor template programmer. As a private tutor I've seen thousands of these questions from the student's point of view, mostly in statistics and calculus. I generally have a good idea what the expected form of the answer is and by how much the student can deviate from that form and still get marked correct. (I've never seen any of these systems give partial credit. These systems are usually used for homework, and the student is required to work on a problem until a correct answer is given regardless of how much time that takes, although you can set aside unfinished problems for later.) Of course, I have an excellent knowledge of computer-algebra and hence I'm aware of when those systems see (or can see) expressions as being equal. But I'm also well aware of Richardson's Theorem, which places severe theoretical limitations on the extent to which symbolic expressions can be proven equal, let alone equivalent.

Now, I can't recall any of these problems that required or allowed the student to introduce some symbol (which I guess we'll call a parameter) that wasn't already specified in the problem. But that doesn't mean that we shouldn't allow those things. We just need the appropriate template matching.

 

@MapleMathMatt Can you give an example of your intended use of a non-empty params parameter in your procedure EquivEQ? I can come up with examples where that parameter makes a difference, but they seem contrived and contrary to the intention of matching student input to a template.

@vv You're using indets, map, convert, and subs. It's a perfect situation to use subsindets:

subsindets(ex, function, convert, Diff);

First 336 337 338 339 340 341 342 Last Page 338 of 708