Carl Love

Carl Love

28035 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

@sigl1982 It's quite refreshing to see such neatly written code posted here.

I suspect that there is some intentional randomization somewhere in the mod code that your program uses, perhaps in `mod/Factors`. Do this test with randomize: Make the first statement of your procedure randomize(1). Run the procedure several times with the same input. (Q1) Do you get identical results? Then change the first statement to randomize(2). (Q2) Do you now get different results?

  • If Q1 and Q2 are both "yes", that's very very strong evidence that intentional randomization is being used somewhere.
  • If Q1 is "no", then there's no point in asking Q2, and you have strong evidence that intentional randomization is not being used. Back to the drawing board.
  • If Q1 is "yes" and Q2 is "no", then try changing the 2 to other numbers and re-asking Q2 until the answer is "yes". If you can't make the answer "yes" by changing the argument to randomize, then the test is inconclusive.

I recommend that you turn off the ASSERTion checking while doing this simply to reduce the volume of infomation that you need to look through.

Randomized algorithms are commonly used in finite-field polynomial arithmetic. No doubt you can find several such algorithms in the book Modern Computer Algebra by von zur Gaithen and Gerhard. (Gerhard works at Maplesoft, by the way.)

 

As usual, it'd help if you post your code.

In general, the order of sets of immutable objects (such as algebraic expressions, numbers, sets, lists) is fixed, and it doesn't change between runs, even runs on different computers. However, if your sets contain mutable objects like Vectors, Matrices, or tables, then the ordering may be based on address---I'll need to research that---and of course addresses change between runs. Mutable objects also possibly include modules (which includes Objects and Records); I'll need to research that also.

However, even if your set order is based on something ephemeral like addresses, there's no way that the order is being changed by set operations such as union, minus, and indexing. The order within any given session (i.e., between restarts) is fixed.

In command-line Maple there's a command-line flag that causes Maple to use different set orders. The purpose of this is to test whether one's code depends on set order.

I think that you'll get a better efficiency gain by switching to irem on the inside:

mods(mul(irem(coeff(g[i], x, 0), p), i= S), p);

You just need to wait for the result. On my computer it took about 5 minutes.

Just a small change is needed: taylor(y(t__n+h), h, 4). This is equivalent to making h the main variable (the differentiation variable) and expanding around h=0.

The keys to doing this are using the Units package, the function-definition operator ->, and the commands solve and evalf. A benefit of using Units is that if the units come out correct, that's a fairly good check that you've set up the problem correctly.

The additional key to doing it neatly is to use eval to substitute numeric values so that that step can be put off until the end of each computation.

Glossary:

p = air density (kg/m^3)

v = velocity (m/s)

A = wing area (m^2)

C__d = drag coefficient (Units: 1)

F__d = drag force (N)

F_l = lift force (N)

C_ = lift coefficient (Units: 1)

g = acceleration due to gravity (N/kg)

m = plane's mass (kg)

 

restart:

F__d:= v-> 1/2*C__d*p*A*v^2;

proc (v) options operator, arrow; (1/2)*C__d*p*A*v^2 end proc

F__l:= v-> 1/2*C__l*p*A*v^2;

proc (v) options operator, arrow; (1/2)*C__l*p*A*v^2 end proc

with(Units:-Standard):

 

a) When an aircraft flies horizontally, the lift force F__l must balance the force of gravity m*g, where m is the aircraft’s mass and g = 9.81m/s^2 the gravitational acceleration. Compute the velocity, v__0, of a sport airplane at an altitude of h__0 = 1 000 m, where air’s density is p= 1.10 kg/m^3. The plane has mass m = 750 kg, wing area A = 18 m^2 and lift coefficient C__l = 0.35 .

Vals:= {g = 9.81*Unit(N/kg), p = 1.1*Unit(kg/m^3), m = 750*Unit(kg), A = 18*Unit(m^2), C__l = 0.35*Unit(1)};

{A = 18*Units:-Unit(('m')^2), C__l = .35, g = 9.81*Units:-Unit(('N')/('kg')), m = 750*Units:-Unit('kg'), p = 1.1*Units:-Unit(('kg')/('m')^3)}

solve({F__l(v__0) = m*g}, {v__0});

{v__0 = 2^(1/2)*(A*C__l*p*m*g)^(1/2)/(A*C__l*p)}, {v__0 = -2^(1/2)*(A*C__l*p*m*g)^(1/2)/(A*C__l*p)}

#Select positive branch; ignore negative branch.
evalf(eval(%[1], Vals));

{v__0 = 46.0801109306027*Units:-Unit(('m')/('s'))}

Vals:= Vals union %:

 

b) The propeller of an aircraft transmits power from the engine to the surrounding air. This power is used entirely to overcome the drag force. Compute the engine’s power P0 = F__d*v of the sport plane when it flies at a velocity v = v0 if the drag coefficient (based on the wing area) is C__d = 0.030.

Vals:= Vals union {C__d = 0.03*Unit(1)}:

P__0 = F__d(v__0)*v__0;

P__0 = (1/2)*C__d*p*A*v__0^3

evalf(eval(%, Vals));

P__0 = 29060.0928147354*Units:-Unit('W')

Vals:= Vals union {%}:

evalf[2](Vals);

{A = 18.*Units:-Unit(('m')^2), C__d = 0.3e-1, C__l = .35, P__0 = 0.29e5*Units:-Unit('W'), g = 9.8*Units:-Unit(('N')/('kg')), m = 0.75e3*Units:-Unit('kg'), p = 1.1*Units:-Unit(('kg')/('m')^3), v__0 = 46.*Units:-Unit(('m')/('s'))}

Something that bothers me about the above: Isn't the cross-sectional area in the lift direction different from the cross-sectional area in the drag direction?

 

 

Download airplane.mw

I've made an extensive investigation of this twice over the years. I haven't reinvestigated with Maple 2016, so this may have changed. What I found was:

  • The primary order of layering of the objects when a PLOT structure is displayed is determined by the object type (CURVES, POLYGONS, POINTS, etc.).
  • The order cannot be changed by changing the order that the objects appear in the PLOT structure.
  • The objects most in the background are those of two topological dimensions such as area fillls.
  • Next are objects of one topological dimension such as CURVES and the boundaries of POLYGONS.
  • Next are objects of zero topological dimension: POINTS.
  • Next is plotted text.
  • The object most in the foreground are the axes.
  • Within each class of objects, the order of layering can be changed by changing the order in the PLOT structure, which can in turn be controlled by the order that objects appear in a display command.

 

The plot that you want can be obtained through numeric differentiation with command fdiff:

fy:= y0-> fdiff((r-> rhs(r[-1]))@pds:-value(f(x,y), x=0), [1], [y0]):
plot(fy, 0..10, labels= [y, ``]);


You need to define an "epsilon cloud" around each integer so that if x is sufficiently close to an integer, then f(x) will be 1.

f:= x-> piecewise(abs((x-round(x))/x) < Float(6, 1-Digits), 1, 0);

The value Float(6, 1-Digits) = 6*10^(1-Digits) is often used as the target accuracy for floating-point computation.

Try any of

numtheory:-cfrac([1,1,2]);
seq(numtheory:-cfrac([1$k, 2]), k= 1..3);
Value(NumberTheory:-ContinuedFraction([1,1,2]));
seq(Value(NumberTheory:-ContinuedFraction([1$k, 2])), k= 1..3);

When using Maple's 2D Input, you can't have a space between a function name and the following left parenthesis. These extra spaces get translated as multiplication operators, which is why you see * after sphereplot and fieldplot above.

The trouble with your method is that you repeatedly add elements to existing lists or sets. Unfortunately, that operation is very inefficient in Maple. It is so natural to approach this problem recursively; however, I can't think of any way to efficiently do it recursively in Maple, even after thinking about it for hours.

Here is a way to do it using seq. This method is faster than Iterator. (In fairness, I must say that I learned this technique from a post by Joe Riel where he applied it to Cartesian products.) I also show a better way to do your indexing procedure TkSubSetList. And I also compare with VV's recursive method.

A better way of listing combinations

Carl Love 2016-Oct-10


restart:

 

Observe how the three nested loops below produce all size 3 sublists of [1..5].

 


n:= 5:
S:= [seq(seq(seq([k,j,i], i= j+1..n), j= k+1..n), k= 1..n)];

[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]

 

So what we need to do is build an arbitrarily deeply nested seq statement.


nkSubsetL:= proc(n::nonnegint, k::nonnegint)
description "Returns a list of all sublists of [1..n] of size k.";
local Seq,i,j;
     if k > n then return [] end if;
     if n*k=0 then return [[]] end if;
     [eval](
          subs(
               Seq= seq,
               foldl(
                    Seq,
                    [seq(i[j], j= k..1, -1)], #the k-tuple
                    seq(i[j]= i[j+1]+1..n, j= 1..k-1), i[k]= 1..n
               )
          )
     )
end proc:


nkSubsetL(5,3);

[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]


#VV's recursive method
rcomb:= proc(n, k, p:= [])
     if k=n then return [seq(1..n),op(p)] fi;
     if k=1 then return seq([i,op(p)],i=1..n) fi;
     rcomb(n-1,k,p),rcomb(n-1,k-1,[n,op(p)])
end:


rcomb(5,3);

[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5], [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]


#VV's method, modified by Carl
rcomb2:= proc(n::nonnegint, k::nonnegint)
local i;
     if k > n then ()
     elif k=0 then []
     else
          proc(n,k,p:= [])
               if k=n then [seq(1..n), p[]]
               elif k=1 then seq([i,p[]], i= 1..n)
               else thisproc(n-1, k, p), thisproc(n-1, k-1, [n,p[]])
               fi
          end proc(n,k)
     fi
end proc:
     


rcomb2(5,3);

[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4], [1, 2, 5], [1, 3, 5], [2, 3, 5], [1, 4, 5], [2, 4, 5], [3, 4, 5]

 

Below are procedures that use the seq method to form combinations from arbitrary sets/lists.


#Returns a list of all k-sublists or k-subsets of an arbitrary set or list.
TkSubsetL:= (T::{set,list}, k::nonnegint)-> map2(`?[]`, T, `[]`~(nkSubsetL(nops(T), k))):

#An abbreviation of the original TkSubSetList.
TkSubSetList:= (T,k)-> map(A-> map(i-> T[i], A), nkSubsetL(nops(T), k)):


TkSubsetL({a,b,c,d,e}, 3);

[{a, b, c}, {a, b, d}, {a, b, e}, {a, c, d}, {a, c, e}, {a, d, e}, {b, c, d}, {b, c, e}, {b, d, e}, {c, d, e}]


TkSubSetList({a,b,c,d,e}, 3);

[[a, b, c], [a, b, d], [a, b, e], [a, c, d], [a, c, e], [a, d, e], [b, c, d], [b, c, e], [b, d, e], [c, d, e]]

 

Time tests:


(n,k):= (22,11):

#Old Maple recursive method:
gc(); S0:= CodeTools:-Usage(combinat:-choose(n,k)):

memory used=2.88GiB, alloc change=469.49MiB, cpu time=39.61s, real time=26.95s, gc time=19.05s

#Carl's non-recursive seq method:
gc(); S1:= CodeTools:-Usage(nkSubsetL(n,k)):

memory used=199.10MiB, alloc change=9.48MiB, cpu time=4.44s, real time=2.87s, gc time=2.08s

#New Maple non-recursive method:
gc(); S2:= CodeTools:-Usage([seq([seq(x, x= c+1)], c= Iterator:-Combination(n,k))]):

memory used=339.59MiB, alloc change=5.62MiB, cpu time=6.12s, real time=4.89s, gc time=1.59s

S2:= [{S2[]}[]]: #Compensate for the unusual order used by Iterator.

#VV's recursive method:
gc(); S3:= CodeTools:-Usage([rcomb(n,k)]):

memory used=374.76MiB, alloc change=13.46MiB, cpu time=4.50s, real time=2.92s, gc time=2.08s

S3:= [{S3[]}[]]: #Compensate for the unusual order.

#VV's recursive method, modified by Carl
gc(); S4:= CodeTools:-Usage([rcomb2(n,k)]):

memory used=337.09MiB, alloc change=13.46MiB, cpu time=4.53s, real time=2.73s, gc time=2.28s

S4:= [{S4[]}[]]:

 

These next two are indexing methods. Their times are to be compared with each other, but not with the above.

 

#Carl's indexing method, based on his seq method.
gc(); S5:= CodeTools:-Usage(TkSubsetL([$1..n], k)):

memory used=387.47MiB, alloc change=52.25MiB, cpu time=9.23s, real time=5.05s, gc time=5.08s

#The OP's indexing method, based on Carl's seq method.
gc(); S6:= CodeTools:-Usage(TkSubSetList([$1..n], k)):

memory used=0.86GiB, alloc change=14.87MiB, cpu time=13.97s, real time=8.93s, gc time=6.25s

#Verify that all results are the same.
evalb~([seq(S0=S||i, i= 1..6)]);

[true, true, true, true, true, true]

 


Download AllCombinations.mw

Indices, which are formed with square brackets, and different from subscripts, which are formed with double underscore. The two forms display pretty much the same in the GUI. However, a subscript is an integral part of the name to which it is attached, and hence it can't be substituted for an integer or anything else. A subscript is intended for display purposes, not programmatic purposes.

Additionally, you'll achieve better results with mul rather than product (lowercase p). Here's your worksheet, modified:

restart:

with(Statistics):

N := 2:
X__E__n:= RandomVariable(Normal(mu__E__n, sigma__E__n));
for n from 1 to N do
   X__E[n] := RandomVariable(Normal(mu__E[n], sigma__E[n]));
end do:

_R

#n := 'n':

PDF(X__E__n, x__E__n);  # but this one suits me
                            # compared to the first coding the desired abd undesired outputs
                            # are permuted. What is th reason for this ?

(1/2)*2^(1/2)*exp(-(1/2)*(x__E__n-mu__E__n)^2/sigma__E__n^2)/(Pi^(1/2)*sigma__E__n)

# For PDF(X__E__n, x__E__n) suits me, I fix n to 1 :

PDF(X__E[1], x__E[1]);

# Why do I not receive the previous output where n is simply replaced by 1 ?

(1/2)*2^(1/2)*exp(-(1/2)*(x__E[1]-mu__E[1])^2/sigma__E[1]^2)/(Pi^(1/2)*sigma__E[1])

# At the very end I would like to obtain the likelihood of a sample (x__E__1, x__E__2)
#
# PS : I know there exists a function "Likelihood" in the Statistics package but, for
#      some reasons, I do not want to use it.

# At a first stage, for pedagogical reason, I want to display this likelihood in
# a compact formal expression
n := 'n':
Product(PDF(X__E__n, x__E__n), n=1..'N');   # This is exactly what I want

Product((1/2)*2^(1/2)*exp(-(1/2)*(x__E__n-mu__E__n)^2/sigma__E__n^2)/(Pi^(1/2)*sigma__E__n), n = 1 .. N)

# Stage 2 : expansion of this likelihood

combine(mul(PDF(X__E[n], x__E[n]), n=1..N));  # does not returns the result I was expecting for
                                         # ... probably "normal" but I do not understand why

(1/2)*exp(-(1/2)*(x__E[1]-mu__E[1])^2/sigma__E[1]^2-(1/2)*(x__E[2]-mu__E[2])^2/sigma__E[2]^2)/(Pi*sigma__E[1]*sigma__E[2])

 


Download WhatHappensHere.mw

Here's a much-simplified version of your code:

funcs := [x, 3*x, x^2, 5*x];
for i to nops(funcs) do listM[i] := diff(funcs, [x $ (i-1)]) end do;
M := convert(convert(listM, list), matrix);
linalg:-det(M);

P.S. Here's a more-direct way:

M:= matrix([seq(diff(funcs, [x$(i-1)]), i= 1..nops(funcs))]);

You think that D[3](y)(L) refers to the 3rd derivative with respect to the first variable. That's incorrect: Rather, it refers to the 1st derivative with respect to the 3rd variable (regardless of the fact that y is a univariate function). There are several ways to represent the 3rd derivative with respect to the first (and only) variable:

(D@@3)(y)(L)
D[1,1,1](y)(L)
D[1$3](y)(L)

Likewise for the 2nd or any other order of derivative.

First 207 208 209 210 211 212 213 Last Page 209 of 395