Carl Love

Carl Love

28085 Reputation

25 Badges

13 years, 98 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Yes, Maple has a command nearly tailor-made for this job: Iterator:-TopologicalSorts (I don't know where that name comes from (and I've taken four graduate courses in topology)).  Here is the procedure code, and I'll provide some commentary after it. Warning, this is quite dense code, but it's super fast.

L:= proc(c::posint, L::And(list, satisfies(L-> nops(L)>=2*c)))
local p:= L[], A:= p[1+c..-c-1], P:= (p[1..c], p[-c..-1]); 
     [seq(
          [P[[seq(p[1..c])]], A, P[[seq(p[-c..-1])]]],
          p= Iterator:-TopologicalSorts(
               2*c, rhs~(op(3, rtable((1..c)$2, (i,j)-> i<c+j, 'storage'= 'triangular'['upper'])))
          )
     )]
end proc:

Examples of usage:

L(3, [a1,a2,a3, a,a, b1,b2,b3]);
       (output omitted)

nops(%); #Count entries of previous output.
       57

Many of your input parameters are redundant (which is dangerous in computer code). All that's needed is the value of and the list of objects to permute that has at least 2*c entries. The list length m isn't needed. The as in the center are not needed, nor their count, and they don't even need to be the same. Also is not needed. All that information comes from the input list itself.

Here's a speed test:

Perms:= CodeTools:-Usage( #command that measures time and memory usage
     L(6, [a||(1..6), b||(1..6)])
): #Very important! End this with a colon because the output is huge!

memory used=2.10GiB, alloc change=495.45MiB, cpu time=22.97s, real time=12.52s, gc time=13.78s
nops(Perms);
                            1566813

So, that's more than 1.5 million length-12 permutations in less than13 seconds.
 

Since it's such a common Question, it bears repeating that any number of plots with the same number of dimensions (2 or 3) can be combined with plots:-display as Kitonum has shown. However, for this common situation of showing a curve along with some related points, I prefer to do it with a single plot command, like this

X:= <0, 3.38, 5.21, 6.97, 8.4108, 10.099, 10.9232, 11.8091>:
Y:= <0, 0.760e-1, .1275, .1994, .2286, .3222, .3637, .999>:
h1:= solve(Vdc = 0.15e-2*sqrt(2.53669508e8*u^3-6.06101011e8*u^2+3.46343435e8*u), u):
nC:= nops([h1]): #number of branches
plot(
   [h1, <X|Y>], Vdc= 0..11.5, thickness= 0, color= [magenta$nC, blue], 
   style= [line$nC, point], symbol= asterisk, symbolsize= 24
);

 

The CDF of NegativeBinomial(r,p) can be expressed in terms of an analytic function, the regularized incomplete beta function Ip(rx+1). This function isn't directly implemented in Maple, but it can be expressed as an integral "regularized" by dividing by an ordinary Beta function. So,

Statistics:-CDF(NegativeBinomial(r,p), x) = 
   Int(t^(r-1)*(1-t)^floor(x), t= 0..p)/Beta(r, floor(x)+1);
NB_CDF_1:= unapply(rhs(%), [r,p,x]):

A relevant identity is Ip(r, x+1) = 1 - I1-p(x+1, r), which seems to work better for finding large quantiles for small pSo, we also have

NB_CDF_2:= (r,p,x)->
   1 - Int(t^floor(x)*(1-t)^(r-1), t= 0..1-p)/Beta(floor(x)+1, r);

You may confirm that either of these functions produce CDF plots identical to what you showed.

plot(x-> NB_CDF_1(1.965, 0.5, x), 0..10, view= [default, 0..1]);

The quantiles can be found by applying a continuous root finder to either of these CDFs. As I said, I found the second worked better in the region of interest. I used this as my quantile function:

NegativeBinomialQuantile:= proc(
   r::nonnegative, #"number of failures" parameter
   p::And(positive, satisfies(p-> p < 1)), #probability of success of each trial
   P::And(positive, satisfies(P-> P < 1))  #percentile
)
local t;
   Digits:= max(10, Digits);
   #Use common sense! Remove `floor` from strictly monotonic
   #functions passed to continuous root finders. Instead, use
   #`ceil` after root is found.   
   ceil(RootFinding:-NextZero(
      Q-> (1-P)*Beta(Q+1,r) - int(t^Q*(1-t)^(r-1), t= 0..1-p, numeric),
      0, guardDigits= max(5, 15-Digits), maxdistance= 10^Digits, _rest
   ))
end proc:

And I used it to make this plot:

plots:-loglogplot(
   p-> NegativeBinomialQuantile(1.965, p, 0.98), 1e-5..0.5,
   labels= [p, `98th %tile`], labeldirections= [horizontal,vertical],
   title= "The 98th %tile of NegativeBinomial(1.965, p) vs p",
   numpoints= 49
);

The best place to get help with Maple is right on this forum, MaplePrimes. So, ask a Question. I'd guess there are about a hundred plotting commands. Probably the best to start with is plot:

Example:
plot(x^2 + 1, x= -2..2);

The command is implicitdiff. Note below that I changed your assignment to w into an equation, and I added a multiplication sign to your second equation:

restart:
FuncRels:= { #Define implicit functions via set of equations:
   w = exp(exp(x*b)*(r-1)/(1+varphi*exp(x*b))), 
   ln(r) = varphi*exp(x*b)*(r-1)/(1+varphi*exp(x*b))-1
}:
Funcs:= {w,r}: #Define which *two* are considered dependent variables.
dwdb:= Diff(w(b,varphi,x), b) = #This line is just an inert label.
   implicitdiff(FuncRels, Funcs, w, b); #compute dw/db
dwdvarphi:= Diff(w(b,varphi,x), varphi) = #This line is just an inert label.
   implicitdiff(FuncRels, Funcs, w, varphi); #compute dw/dvarphi

The hard part is deciding which two are the dependent variables. Obviously w is one, but why is r the other? The only answer that I can give to that is that I tried {w,x} and I didn't like the results.

The lines that I called "inert labels" are strictly for your future (programmatic) reference. You can change them to whatever you want or eliminate them entirely.

A note on your terminology: This is called finding an (implicit) derivative. "Solving a differential equation" refers to solving an equation (or set of equations) that already has derivatives in it to obtain expressions for the dependent variables (or functions).

I was the author of the earlier Answer that you linked. Yes, that algorithm was optimized for and only possible for p=2.

Here's an implementation of Lucas's theorem for any prime p:

`mod/Binomial`:= proc(N::nonnegint, K::nonnegint, p::prime)
description "Computes binomial(N,K) mod p, p::prime, by Lucas's theorem";
option
   author= "Carl Love <carl.j.love@gmail.com> 30-Oct-2018",
   reference= "https://en.wikipedia.org/wiki/Lucas%27s_theorem"
; 
local r:= `if`(K > N, 0, 1), n:= N, k:= min(K, N-K);
   while k > 0 and r > 0 do 
      r:= r*irem(binomial(irem(n,p,'n'), irem(k,p,'k')), p) 
   od;
   r mod p
end proc:

Example of usage:

Binomial(100000, 50000) mod prevprime(50000);
      4

If you know that the number of boundary conditions (BCs) required for the system should be n (because you know how to count the differential order) and the error message says that you need more than n, then the cause is an extra symbolic parameter (symbolic = not numerically specified). This is often because you've spelled a parameter name different ways in your input.

You can list, in order[*1], all the "top-level"[*2] names used in any Maple expression expr (including a container expression such as a list or set of differential equations) by

indets(expr, name); 
lprint(%);

(The command lprint(%) simply makes the output of whatever immediately previous command easier to read "with a fine-tooth comb", and it's not necessary if the first command already makes what you're looking for obvious.)

The reason that dsolve complains the way that it does (rather than just saying "unspecified parameter found") is that you can have dsolve(..., numeric) solve for unspecified parameters of ordinary differential equation (ODE) boundary value problems (BVPs) by giving one extra BC for each such parameter.

Read my recent Post "Numerically solving BVPs that have many parameters". Just concentrate on the first few sections that cover the inputting of the BVP system. The later sections cover elaborate plotting techniques that may be "too much information" for you at this point.

[*1]The order is fixed and chosen by Maple, but it usually bears some resemblence to alphabetical order.

[*2]Names that only occur in indices are not "top-level" and are not listed seperately. Since they're listed with their "parent" names anyway, this is usually not an issue of concern. (Example: For t[final]final is the index and t[final] is the parent. The indets command that I gave would only list the latter.)

The bounds used to plot a function of two variables (by any of the numerous commands that do that) can usually be specified as the limits of integration of the corresponding iterated (double) integral, as in Kitonum's answer. This remains true in alternate coordinate systems: sphericalcylindrical, etc. I find this knowledge to be a great help to "solidifying" my mental visualization of 3-D problems.

It can be done like this:

subsop((indexList=~ ())[], L);

However, this is an inefficient operation for long lists, so if you find yourself needing to do this often, consider replacing lists with tables or Vectors.

It can be done like this:

(n,k):= (6,2);
mul(add~(combinat:-choose([x||(1..n)], k))) = 0

 

The command plot3d is for plotting objects that are locally two-dimensional (what we commonly call surfaces) in three-dimensional space. What you want to plot in 3-D is an object that is locally one-dimensional (commonly called a curve). The command for that is plots:-spacecurve.

If you can figure out how to use it in this case, great, please post the results. If you have trouble figuring it out, I will provide further help.

I can't reproduce your situation; however, this may help, so please try it and let me know how it goes: A restart command should always be separated into its own execution group. The problems that can arise if you don't do this are often weird and difficult to explain and often involve the display of output.

Also: Although it is not an error and certainly not a source of any print problems, you should remove the line iter:= iter+1 from the loop. The for statement automatically increments its index variable for each iteration of the loop. (This is also true for the for statements in every other computer language that I know that has a for statement.) You should always strive to avoid making assignments to a for loop index inside the loop. It itself is not an error, but it is frequently a source of erroneous results.

Consider changing your style to something like this:

eps:= 1e-12; itermax:= 10; Error:= 10;  
for iter from 0 while Error>eps and iter<itermax do
   print("iteration", iter, "Error", Error); 
   Error:= Error*0.1;      
end do;

or this:

eps:= 1e-12; itermax:= 10; Error:= 10;  
for iter from 0 to itermax-1 while Error>eps do
   print("iteration", iter, "Error", Error); 
   Error:= Error*0.1;      
end do;

These are more-normal styles than what you had, and are easier for humans to read.

Records are simplified modules, and they're indexed exactly the same way: r:-ar:-bYou're missing the second character of the indexing operator.

Unfortunately, convert(v, float) doesn't do anything when v is a string. To convert a string that represents a number to a float, you can use evalf(parse(v)). The whole code is

v:= GetProperty(TextAreaRadian,value);
exv:= evalf(parse(v));
SetProperty(TextAreaDegree, 'value', `if`(exv::numeric, sprintf("%6.2f", evalf(exv*180/Pi)), NaN))

This is my first time coding and embedded table, so there's no doubt a better way to do this.

The parse will give an error for strings that don't represent valid Maple expressions. Perhaps that's okay. If that's not okay, the error can be trapped with try.

This is called floating-point contagion. Once even one decimal point is placed into an expression, they tend to infect all expressions derived from that expression, and they tend to spread further around within those derived expressions.

Some tips:

  1. Never use decimal numbers where a simple fraction will do. Most especially, don't do it in exponents.
  2. Put off as long as possible the introduction of any decimal numbers at all into the computations. It's fine (and even a good idea) to enter required decimal data at the beginning of a worksheet and even to give those numbers names. Just don't use them in the early computations.
First 158 159 160 161 162 163 164 Last Page 160 of 395