Carl Love

Carl Love

28050 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@pik1432 

S:= seq(diff~(v,W), v= V);
S[1]; #the first matrix
S[2]; #the second

@amirhadiz You must have a Maple version earlier than Maple 2018. In that case, use Kitonum's Answer instead.

@Carl Love The gradient can be also can obtained with diff~, which is similar to your original map(diff, ...). The equality of two matrix or vector expressions and can be verified by andmap(is@`=`, A-B, 0) (there are a great number of variations of this equality verification). 

restart:
n:= 2:
X:= Vector(n, symbol= x);
W:= Matrix(n$2, symbol= w);
G:= diff~((W.X)^+.(W.X), X); #gradient
andmap(is@`=`, G - 2*W^+.W.X, 0);

Notes:

  1. Vectors and Matrices with symbolic indexed entries can be created with option symbol.
  2. The transpose operator can be written ^+ rather than ^%T in some input modes.
  3. The diff~ operation is equivalent to map2(diff, (W.X)^+.(W.X), X).
  4. The above code requires no packages---neither LinearAlgebra nor VectorCalculus.

@awass The page ?plot,options would be too long if there were elaborate or multiple examples of each option. So, many of the options have links to supplemental help pages. The info on the linked page ?plot,typesetting applies to titles as well as to captions. This is stated in the second sentence on that page.

@mehran rajabi For example, 

eval(B, [t[0]= 0, t[1]= 1]);

This creates a new Matrix, without changing itself; i.e., it doesn't operate inplace.

By the way, it's not clear from your original Question which t you want to change to t[1] and which to t[2] and whether you only want two new variables.

@Mac Dude  @Earl

I appreciate the interest in my Answer, but retrofits of my code to earlier versions of Maple are not needed or wanted. The OP uses Maple 2019, and I knew that from the start. The power of the syntax innovations of Maple 2018 and Maple 2019 is so far beyond earlier versions that it's painful for me to retrofit. I guess that I should start code with the warning "This code requires Maple 2019 and Maple Input (aka 1-D input)."

Here is the cache-based application that I was talking about. It generates an evaluator procedure for an input recurrence relation. The evaluator uses a cache as a circular buffer. It's mind-blowing to me that this type of meta-programming with sophisticated memory management can be accomplished in Maple in only 18 lines of code. 

Several commands from the Cache package (as mentioned by Acer) are used: 

  1. AddPermanent is used to set the initial values.
  2. Resize is used to limit the size of the circular part of the cache to the order of the recurrence.
  3. TemporaryIndices is used to decide whether a short cut can be taken for particular evaluations.

Since the returned evaluator is a procedure local to the main procedure, it and its cache get garbage collected once there are no external pointers to it (such as when the ad hoc name that it's assigned to gets used for something else).

restart
:

(*--->.............................................................
! MakeProc:                                                       !
!     Fast cache-based evaluation of recurrence relations of      !
!     fixed-but-arbitrary order (similar to rsolve(..., makeproc))!
!                                                                 !
! Parameters:                                                     !
!     F :: name=procedure                                         !
!        The recurrence formula, given as name=procedure where    !
!        the procedure uses the name recursively,                 !
!        e.g., Fibo = (n-> Fibo(n-1)+Fibo(n-2))                   !
!     n0 :: integer                                               !
!        The smallest value of the independent variable for which !
!        an initial value is given                                !
!     iv :: list                                                  !
!        The initial values. The number of them must equal the    !
!        order. They do NOT need to be numeric.                   !
.............................................................<---*)
MakeProc:= proc(F::name=procedure, n0::integer, iv::list)
option `Author: Carl Love <carl.j.love@gmail.com> 18-Jan-2020`;
uses C= Cache;
local k:= nops(iv), R;
    R:= subs(
        _n1= n0+k,
        _F= subs(lhs(F)= _R, eval(rhs(F)))(_i),
        _R= :-thisproc,
        proc(n::And(integer, satisfies(n-> n >= n0)))
        option cache;
        local _i, j, m:= max(_n1, op~([C:-TemporaryIndices(R)])[]);
            for _i from `if`(n > m, m, _n1) to n do R(_i):= _F od
        end proc
    );
    R(n0):= iv[1]; #Force creation of cache.
    C:-Resize(k, R);
    C:-AddPermanent~(R, `[]`~([$n0..n0+k-1]), iv);
    eval(R)
end proc
:

First, I verify that the above works by generating a very large fibonaci number and comparing it to the known value.

F:= MakeProc(Fib= (n-> Fib(n-1)+Fib(n-2)), 0, [0,1]):

f1:= CodeTools:-Usage(F(9999)):

memory used=5.17MiB, alloc change=32.00MiB, cpu time=31.00ms, real time=26.00ms, gc time=0ns

f2:= combinat:-fibonacci(9999):

ilog10(f1); f1-f2; #Verify size and equality.

2089

0

Fibonaci numbers are too easy though because there's a fast matrix-based algorithm for linear homogenous constant-coefficient recurrences. Here's a nonlinear Fibonaci-like recurrence:

rec:= f(n) = f(n-1) + f(n-2) + igcd(f(n-1), f(n-2)),
    [f(1)=1, f(2)=1]:

F1:= rsolve({rec[1], rec[2][]}, f(n), makeproc):

F2:= MakeProc(G= (n-> G(n-1)+G(n-2)+igcd(G(n-1),G(n-2))), 1, [1,1])

proc (n::(And(integer, satisfies(proc (n) options operator, arrow; n0 <= n end proc)))) local _i, j, m; option cache; table( [( temporary::(1) ) = 1, ( permanent::(2) ) = 1, ( permanent::(1) ) = 1 ] ) m := max(3, `~`[op]([Cache:-TemporaryIndices(R)])[]); for _i from `if`(m < n, m, 3) to n do R(_i) := thisproc(_i-1)+thisproc(_i-2)+igcd(thisproc(_i-1), thisproc(_i-2)) end do end proc

gc():
f1:= CodeTools:-Usage((()-> local r:= F1(99999): (r, gc()))()):

memory used=2.33GiB, alloc change=27.49MiB, cpu time=4.75s, real time=4.02s, gc time=2.98s

gc():
f2:= CodeTools:-Usage((()-> local r:= F2(99999): (r, gc()))()):

memory used=2.33GiB, alloc change=32.00MiB, cpu time=4.47s, real time=3.50s, gc time=3.06s

ilog10(f2), f2-f1; #Verify size and equality.

23855, 0

The cache technique excels for "deep" recursions--those that go back many terms.

rec:= f(n) = irem(n,5)+f(n-1)+f(n-69)/n, [seq(f(k)=k, k= 1..69)]:

F1:= rsolve({rec[1], rec[2][]}, f(n), makeproc):

F2:= MakeProc(G= (n-> irem(n,5)+G(n-1)+G(n-69)/n), 1, [$1..69]):

gc():
f1:= CodeTools:-Usage((()-> local r:= F1(9999): (r, gc()))()):

memory used=1.04GiB, alloc change=0 bytes, cpu time=21.20s, real time=21.08s, gc time=1.19s

gc():
f2:= CodeTools:-Usage((()-> local r:= F2(9999): (r, gc()))()):

memory used=0.52GiB, alloc change=0 bytes, cpu time=10.74s, real time=10.68s, gc time=718.75ms

f1-f2;

0

ilog10(denom(f2));

22683

 


 

Download RecMakeProc.mw

@Agha So far, I've looked in three statistics textbooks, the Wikipedia article "Quartile", and a journal article referenced in that Wikipedia article. So far, I have found ZERO evidence to support your claim of the universality of the method that leads to 2.5. Instead, I find statements like "there is no universal agreement on selecting the quartile values" (Wikipedia) and "there are a large number of different definitions used for sample quantiles in statistical computer packages" (very first sentence of referenced article 3).

@acer 

And although Collect is not coded to call Tally, it's effectively true that

ListTools:-Collect:= [op]~@Statistics:-Tally

Indeed, if I may indulge in a little "code golfing", in Maple 2019 Collect can be replaced by this:

Collect:= (L::list)-> 
    local t, T:= table(sparse);
    ([op]~@op@table)(L=~ `+=`~(subs(t= T, `?[]`~(t,`[]`~(L)))))
:

which doesn't use any library code, only built-in code. That goes to show the awesome power of the updating assignment operators, such as += above, which were introduced in Maple 2019.

@barxque What is the file size, in bytes, of the worksheet? Save it before you check.

@Melda Here is what I mean, in a Maple worksheet:

Download SimpleDsolve.mw

For reasons that I don't know, the above won't display inline on this site, but you can download it to see.

Or, just enter these commands into Maple:

ode_sys:= diff(y(x),x$2)-y(x)=0, y(0)=0, y(1)=1;
dsolve({ode_sys});
convert(normal(%), sinh);

 

 

What is the subexpression int(U(x,z), x, z) supposed to mean? What are the limits of integration? Numerical integration without limits is not "a thing". And what is a?

@Stretto What part of 

  • This is just an info-gathering experiment; I'm not claiming that this [restart] will or won't solve your blank-line problem!

don't you understand?

You wrote:

  • It doesn't matter about restart: I always put it at the top so I can easily clear stuff if need be but it is ultimately irrelevant to the problem.

How could you possibly know whether the information that I get by you simply answering my diagnostic questions about what happens when you do restart is relevant or not? 
 

Now, go to menu Tools => Options => Display. The 4th checkbox from the bottom is "Always insert new execution group after executing". Is that box checked? If it is checked, uncheck it, and see how that affects your blank-line problem. Also, tell me the result that you get from the commands

interface(echo); interface(prompt);

@Agha So why haven't you responded to my Answer, which gets you the 2.5 that you want? 

@Stretto You wrote:

  • I was using this
        global _Hist
        _Hist := [N, op(_Hist[1..-2])];

I'm impressed. Yesterday I wrote a caching application that does just that. It's a tiny bit more efficient (for a small cache) than those list operations and much more efficient for a large cache, and, of course, more robust than using globals. It's on another computer. I'll post it in a few hours, after my wife wakes up (the computer is on the bed).

I know that you're a fan of terse syntax, as am I. So, the code op(_Hist[1..-2]) can replaced by _Hist[..-2][]

  • What you say about option remember, system; Generally how often? Every time memory or numbers , change?

Yes, every time that you see those numbers change, there has been a garbage collection (gc()).

  • They change all the time when I do any computation, this may be a bit excessive if it is constantly collecting.

The frequency is based on the amount of garbage waiting to be collected; it isn't time based. So, you must be generating a lot. The algorithm is AFAIK highly optimized, and it helps that it runs in parallel threads (generally 4 threads--but you can set it). Go to ?kernelopts and read about the eight gc options (but gcfreq does nothing at all in Maple 2019). 

First 224 225 226 227 228 229 230 Last Page 226 of 709