Carl Love

Carl Love

28035 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

As you probably realize at this point, the inverse of a in Zp can be computed simply by

b:= 1/a mod p;

and this is not done by the "brute force" method of checking every possibility. It can be done as a byproduct of computing the gcd of a and p by the Euclidean algorithm. Of course, this gcd is 1; but with slight additions to the standard algorithm, the Bezout coefficients can also be computed. The Bezout coefficient of a, reduced mod p, is the inverse.

The command igcdex will tell you the Bezout coefficients, but unfortunately the method that it uses is totally fake and inefficient. I'll post a decent algorithm based on first principles in a little while.

 

@vv Yes, of course they aren't independent for fixed p.  If they were, there'd be little point in doing these computations. I just lacked the mathematical vocabulary to state my asymptotic intuition precisely. Do you have any intuition about it, or about how difficult it would be to prove? Do you have any intuition about the residual bounds?

@acer 

I accept your point about the obsfuscation clouding my judgment, but I'll point out that what Christian did could only be considered obsfuscation because of the simplicity of the example. Otherwise, what he did would just be considered normal procedure coding without raising an eyebrow.

I very often (daily) write procedures that take procedures as arguments. In almost all cases, I'd like that code to continue to work if the argument is replaced by an expression that can be treated like a procedure. I don't like the idea of handling the distinction via a local variable in the parent procedure. I'd rather place the onus on the one passing the procedure-like expression to do something to ensure correct behavior. That something is usually making it a procedure. This can usually be done ad hoc in the same line of code. Here's an example that I posted last night, in response to another Question:

MetaOp:= (gen, n::nonnegint, pred, EA)-> ()-> EA(select(pred, ['gen()'$n])): 

#The original, erroneous, code:
Op1:= MetaOp(rand(1..100), 20, x-> x::even, [add, add/nops]):

#The corrected code:
Op2:= MetaOp(rand(1..100), 20, x-> x::even, x-> (S-> (S, S/nops(x)))(add(x))):

The only difference between the two being the fourth argument, passed to MetaOp's parameter EA. As you can see, I made it into a double procedure, which both corrects the issue being discussed in this thread and avoids duplicating the computation done by add.

You can see in MetaOp that the obsfuscation (of the argument-distribution issue) is unintentional, yet it's several levels deeper than Christian's example: the random-numerator generation survives as an unevaluated expression all the way until it's passed to add (twice) and nops.

@Nata Red Grand 

I realize that the example of an external accountant procedure that I gave in my Answer---

x-> (S-> (S, S/nops(x)))(add(x))

---is a bit over-the-top, but that's because my goal was exploring the possibilities rather than directly doing your homework. You, on the other hand, should still be capable of writing a simpler external accountant procedure and passing it in. Here's an example:

SumAndAverage:= proc(Data::list(algebraic))
local S:= add(Data), n:= nops(Data);
   'Sum' = S, 'Average'= `if`(n=0, undefined, S/n)
end proc:

In addition to what Joe said: Unless the package is huge (like more than, say, 100,000 lines of code), there's no noticeable benefit to "updating" as opposed to "entirely recreating from the source code", because the Maple parser/"compiler" is so fast.

@Kitonum I'm not exactly sure what the OP's teacher means by "external accountant", but my guess is that they mean that there should be a separate procedure that does the sum and average and that that procedure should be passed into the final procedure.

One very small potential problem with your code is that it may fail if L1 is never created as a table because none of the numbers are even. You can get around that by explcitly declaring L1:= table() at the start.

@Christian Wolinski 

I like your example because I can look at it and immediately say Surely Op and Op2 ought[*1] to produce equivalent output for any input for which they both produce output (not counting error messages as output). If there were cases where Op returned an error message or warning while Op2 returned regular output, I wouldn't be as upset.

[*1]I mean ought in the moral sense, as I always mean it.

@Joe Riel I see what you're saying, Joe, and perhaps if all examples were like Acer's example---the direct application of an expression as if it were a procedure---then I wouldn't be so concerned about it. But in my indirect example, I want the second argument of Op to be a procedure or anything that can be used as if it were a procedure.

@acer I thank you Acer for coming up with an example even terser than mine of this horrifying phenomenon. Yes, it seems wrong! Unless some other evaluation rule has been explicitly declared, I expect arguments to be evaluated before being passed, as we've each told the lesser-experienced members of this group perhaps hundreds of times. It's like a fundamental rule of Maple. In your example, g() is the argument.

@acer Great, vote up, and an Answer to save with my other examples of how to use the extensive undocumented features of Typesetting. It would be great if you'd

  1. change uses Typesetting to uses T= Typesetting (or some such) and then explicitly highlight the members of that package that are used;
  2. make the function symbol print in grey rather than blue, as is traditional for Maple's prettyprinted inert functions.

@Rohith I'm sorry, but what you're asking makes "absolutely" no sense to me: You say that you want to "ignore" abs, yet what you show as your desired extracted term still contains abs! So, please clarify for me how you define "ignore".

If you've assigned
expression:= log(sin(abs(a+b*c)));
and you want to extract
sin(abs(a+b*c))
from it, that can be done simply by
op(expression)
or (being more precise)
op(1, expression).

(I must point out that you've changed the expression from your original Question. There it was sin(abs(log(a+b*c))).)

My command indets(expr, function(Not(function)))[] extracts the innermost function(s). For the present example, that is of course abs(a+b*c).[*1]

If, on the other hand, you want to ignore abs, then it can be removed entirely from expression by
eval(expression, abs= (()-> args));
and the same will work for any function symbol[*2] (the abs being the function symbol in this case[*3]).

If you want to convert abs to an inert form without entirely removing it, that can be done by
subs(abs= %abs, expression);

The reason that I gave special attention to sqrt was because I suspected that it would come up in one of your future example expressions. If it does come up, it will need special treatment; it can't be handled in the same way as I've handled abs above.

[*1]The arithmetic operators such as and  * are not considered functions in the specific Maple sense of that word; however, when they're in their inert forms, they are functions to Maple.

[*2]Provided that that function actually appears in the expression after it's automatically simplified, which is why I gave special mention to sqrt.

[*3]In the way that the word function is used in Maple code (as opposed to Maple documentation), f(x) is a function, and the f itself is considered to be just the function symbol.

@acer The OP means the he wants to prettyprint an inert form of maximize, as he's displayed it in his Question, akin to Maple's ability to prettyprint inert limits. The words "type sign" in his title are his back-translation of "prettyprint". He doesn't care about the specific function (2*x-3)/(x-2) or about limits; those were just examples showing Maple "doing the right thing" wrt prettyprinting an inert expression.

@torabi That ODE BVP system in the paper is equivalent to

Eq17:= 
   1/r*diff(r*diff(theta(r),r), r) + Nb*diff(sigma(r),r)*diff(theta(r),r) 
   +  Nt*diff(theta(r),r)^2 = 0
;
Eq18:= diff(r*(Nb*diff(sigma(r),r) + Nt*diff(theta(r),r)), r) = 0;
BCs:= theta(1) = 0, sigma(1) = 0, D(theta)(0) = 0, D(sigma)(0) = 0;

That's substantially different from the BVP system in your Question. In particular, you've missed all the terms that contain the independent variable (r in this case) as a factor.

Note that because of the product rule for derivatives, in diff(r*f(r), r)/r the rs do not cancel.

If you at least enter problem #26, I'll be happy to show you how to solve it. Just type in the problem if you need to, for example "26) The integral from 0 to infinity of e to the -2x power, with respect to x".

@vv 

Vote up for a very compact solution! Your commented variation rand(1..6)$2 is definitely better (as you probably know). You can verify that by

(a,b):= (rand(1..6), rand(1..6));
addressof(eval(a)), addressof(eval(b));

(a,b):= rand(1..6)$2;
addressof(eval(a)), addressof(eval(b));

 

First 302 303 304 305 306 307 308 Last Page 304 of 708