Carl Love

Carl Love

28020 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

What you want is signum(x). The sign command is just for polynomials, so sign(x) for unevaluated x is already 1 before x has been assigned a value.

restart:
eq1:= diff(f(eta),eta$3) - a*diff(f(eta),eta$1)^2 + b*f(eta)*diff(f(eta),eta$2) = 0:
bc:= f(0)=0, D(f)(0) = 1+c*(D@@2)(f)(0), D(f)(8)=d:
sys:= unapply({eq1,bc}, a, b, c, d):
Sol:= (a,b,c,d)-> dsolve(sys(a,b,c,d), numeric):
Incrs:= [.01, .1, 0.1, 0.1]: #Increments in a, b, c and d, respectively
nIncrs:= [2,2,2,2]:  #Numbers of increments
It:= combinat:-cartprod([seq([$1..nIncrs[k]]*Incrs[k], k= 1..nops(Incrs))]):
A:= Matrix(`*`(nIncrs[]), nops(Incrs)+1):
for row while not It[finished] do
     V:= It[nextvalue]();
     A[row,..]:= < V[], eval(diff(f(eta),eta$2), Sol(V[])(0)) >
end do:

This is an application of Huygens's gambler's ruin theorem. The probability of winning any one iteration is p = 5/12. I'll assume that you don't need any help computing that. We'll say that the player's starting "bank" is n[1] = 2 chips (two $50 bets), and, effectively, the casino's starting bank is also n[2] = 2 chips, because the game ends when either side has lost its starting bank. Then Huygens's formula for the probability that the casino loses its bank first is

(1 - (1/p-1)^n[1])/(1-(1/p-1)^(n[1]+n[2]));
                                 

eval(%, [p= 5/12, n[1]= 2, n[2]= 2]);
                              25/74

See this Wikipedia article

See the section entitled "Unfair coin flipping".

The inner loop is performed two times regardless of whether the n is actually accessed in the loop. Indeed, your double loop could just as well be expressed as

QQ:=Matrix([[3],[4],[1]]);

for m from 1 to 2 do
     to 2 do
          QQ:= (QQ*m)+QQ
     end do
end do:

Yes, it is easy. But is there any significance to the brackets? If there is no significance, then do

`and`(ListTools:-Flatten(L)[])

where L is your original list.

Brian,

My program can be easily modified to work with lists instead of sets, and real numbers instead of integers. Here is is:

S:= [3, 4, 5, 6, 8, 9, 28, 30, 35]:
SL:= [A,B,C,D,E,F,G,H,I]:
assign(Labels ~ (S) =~ SL); #Create remember table.
AllP:= combinat:-setpartition(S,3):
lnp:= evalf(ln((`*`(S[]))^(1/3))):

Var:= (P::({list,set}({list,set})))->
     evalf(`+`(map(b-> abs(ln(`*`(b[]))-lnp), P)[]))
:

Min:= proc(S::{list,set}, P::procedure)
local M:= infinity, X:= (), x, v;
     for x in S do
          v:= P(x);
          if v < M then  M:= v;  X:= x  end if
     end do;
     X
end proc:

ans:= Min(AllP, Var);
              
subsindets(ans, realcons, Labels);

Instead of using the linear model y = a + b*x, use y = b*x. If you're using Statistics:-LinearFit, then the command is

Statistics:-LinearFit(b*x, X, Y, x);

where X is your list or array of x data and Y is your list or array of y data. If you're using CurveFitting:-LeastSquares, then the command is

CurveFitting:-LeastSquares(X, Y, x, curve= b*x);

 

Surely this problem was contrived to point out the flaws in a floating-point arithmetic system. In particular, this problem looks contrived specifically to dupe Maple because the error occurs right at 10 decimal places, which is Maple's default. So I can't believe that it is truly a BIG problem for you.

The problem occurs just in the computation of

.5 - 1234567892;

This value requires 11 digits to represent, obviously, but you only have 10 digits to work with (by default). It is easy to increase the default:

Digits:= 11;

Now you will get accurate results for this computation.

Another option is to use exact arithmetic:

convert(.1234567891, rational, exact)*10^10 +1/2 - 1234567892;

Exact arithmetic works accurately regardless of the value of Digits.

I managed to make it into a simulation for any number of doors and still simplify and speed up the code some.

# Proc to make a uniform random selection from a set.
Rand:= (S::set)-> `if`(nops(S) < 2, S[], S[(rand() mod nops(S)) + 1]):

# Simulation for the n-door Monty Hall problem.
# Returns the number of trials the player wins.
MontyHall:= proc(
     {trials::posint:= 10000},
     {doors::posint:= 3},
     {switches::list(truefalse):= [true]},
     $
)
local
     k, wins:= 0, Doors,
     PrizeDoor, #The door with the prize behind it.
     PlayersDoor,  # The door the player picks.
     AllDoors:= {$1..doors}   
;
     to trials do
          Doors:= AllDoors;
          PrizeDoor:= Rand(Doors);
          PlayersDoor:= Rand(Doors);
          for k to doors-2 do
               # Monty opens a door, which is thus removed from the set
               # of available doors.
               Doors:= Doors minus {Rand(Doors minus {PrizeDoor,PlayersDoor})};       
               if switches[k] then
                    PlayersDoor:= Rand(Doors minus {PlayersDoor})
               end if
          end do;
          if PlayersDoor = PrizeDoor then  wins:= wins+1  end if
     end do;
     wins
end proc:     

MontyHall(trials= 100000, doors= 5, switches= [false,false,true]);
                             79904

For longer sections of code within a worksheet, use Code edit Regions. These are available from the Insert menu. They do allow the tab key. They offer syntax-based color coding and highighting and bracket matching.

One drawback: In M17, Code Edit Regions do not place the cursor near a syntax error when you make one; you're on your own for finding syntax errors. This is a major drawback that M16 did not have.

To excecute a Code Edit Region, use Ctrl+E. The option is also accessible from the context menu.

Here is my solution to the 4-door Monty Hall problem. I managed to simplify the code a lot compared to my 3-door solution.

# Proc to make a random selection from a set.
Rand:= (S::set)-> S[(rand() mod nops(S)) + 1]:

# Simulation for the 4-door Monty Hall problem. N is the number
# of trials. Returns the number of trials the player wins.
MontyHall4:= proc(
     N::posint,
     {switch1st::truefalse:= false},
     {switch2nd::truefalse:= false},
     $
)
local
     k, wins:= 0, Doors,
     PrizeDoor, #The door with the prize behind it.
     PlayersDoor,  # The door the player picks.
     AllDoors:= {$1..4}   
;
     to N do
          Doors:= AllDoors;
          PrizeDoor:= Rand(Doors);
          PlayersDoor:= Rand(Doors);
          # Monty opens a door, which is thus removed from the set
          # of available doors.
          Doors:= Doors minus {Rand(Doors minus {PrizeDoor,PlayersDoor})};       
          if switch1st then
               PlayersDoor:= Rand(Doors minus {PlayersDoor})
          end if;
          # Monty opens another door:
          Doors:= Doors minus {Rand(Doors minus {PrizeDoor,PlayersDoor})};
          if switch2nd then
               PlayersDoor:= Rand(Doors minus {PlayersDoor})
          end if;
          if PlayersDoor = PrizeDoor then  wins:= wins+1  end if
     end do;
     wins
end proc:     

MontyHall4(100000);
                             25092
MontyHall4(100000, switch1st);
                             37562
MontyHall4(100000, switch1st, switch2nd);
                             62565
MontyHall4(100000, switch2nd);
                             74751

If the blocks of a partition cannot be made to have equal products, then we seek to minimize the "variation" (defined below). I will use Brian's example set

S:= {3, 4, 5, 6, 8, 9, 28, 30, 35}.

First, I compute the ideal target product for a block---the cube root of the product of the elements of S. Call this p. Then for each block b, I measure its deviation from this ideal as abs(ln(`*`(b[]) - ln(p)). I use ln because I think that being a factor of x too large should be considered the same deviation as being a factor of x too small. For each partition P, I measure the variation as the sum of the deviations of its blocks.

The partitions are generated with Joe's Iterator package. You'll need to download this from the Maple Applications Center if you don't already have it.

restart:
S:= {3, 4, 5, 6, 8, 9, 28, 30, 35}:
AllP:= [seq(P, P= Iterator:-SetPartitions(S, [[3,3]], compile= false))]:
lnp:= evalf(ln(`*`(S[])^(1/3))):
Var:= proc(P::list(set))
local r:= evalf(`+`(map(b-> abs(ln(`*`(b[]))-lnp), P)[]));
end proc:
sort(AllP, (x,y)-> Var(x) < Var(y))[1];
              [{3, 9, 35}, {4, 8, 28}, {5, 6, 30}]
---which agrees with Brian's result.

Rather than using sort, I wanted to use Joe's trick of setting the attribute of a float and then using min. But this does not work:

Var:= proc(P::list(set))
local r:= evalf(`+`(map(b-> abs(ln(`*`(b[]))-lnp), P)[]));
     setattribute(r,P)
end proc:

The procedure returns garbage which displays as a question mark. I am hoping that Joe can tell me why.

@fluff

Forget about the identical(0,1,2) thing. It won't work, because I didn't realize that you allowed the possibility of the player not switching in the first round and then switching in the second. You need two switch parameters:

MontyHall:= proc(N::posint, {switch1st::truefalse:= false}, {switch2nd::truefalse:= false})

Then is the code you'll have

if switch1st then
. . .

if switch2nd then
. . .

Also, you still need to correct rendomize to randomize, as pointed out by Acer.

It looks like the command defining params is not being executed. Try placing the restart in its own execution group.

Your newsys is a list. In order to use it with union, it must be a set. In your dsolve command change newsys to {newsys[]}.

First 327 328 329 330 331 332 333 Last Page 329 of 395