Carl Love

Carl Love

28035 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

I think that you may have the mistaken idea that a "statement" needs to be on a single line. Actually, there's no practical limit to the number of lines that it can take, the number of substatements internal to it, or the depth of their nesting.

Change

if m1 <= 2^(2*k-1) then t1 := (C+(-A1*(m1^2)))/A2 end if;
Do (t1);

to

if m1 <= 2^(2*k-1) then
   t1 := (C+(-A1*(m1^2)))/A2;
   Do (t1)
end if;

And do likewise for the other if-then blocks.

The line

E2:= V(x2);

should be

E2:= V(x2(i));

 

It's not a source of the error, but I'm concerned about your use of Seed. What is its significance? Why not use rand()?

You should not use randomize() until you have your code running correctly without it because its use will make some bugs harder to find.

Please post code in plaintext form, or post a worksheet. I was unable to test my answer above because I couldn't run your code because it's in a form that can't be copied-and-pasted.

If the function has a Taylor series at x=a, then that's what's returned. For complex-valued functions (which most functions are), having a Taylor series at x=a is equivalent to the function being differentiable throughout an open set containing x=a. Next, if it has a Laurent series at x=a, then that's what's returned. Having a Laurent series at x=a is equivalent to there being a positive integer n such that (x-a)^n*f(x) has a Taylor series at x=a. Finally, if a more-generalized type of series can be found, then that's what's returned. I don't know the details of these more-generalized series, but my first guess is that they're always of the form M((x-a)*g(x-a)), where M(z) is a Maclaurin series and g(x) is a relatively simple function (such as ln(x) or x^r for some r, 0 < |r| < 1) that is not differentiable at x=a.

Here's a somewhat systematic approach to reducing arctrig(algebraic number) to a rational multiple of Pi.
 

restart:

x1:= arcsin(1/2*(2+(2+(2+2^(1/2))^(1/2))^(1/2))^(1/2));

arcsin((1/2)*(2+(2+(2+2^(1/2))^(1/2))^(1/2))^(1/2))

p:= evala(Norm(z-convert(op(x1), RootOf)));

z^16-4*z^14+(13/2)*z^12-(11/2)*z^10+(165/64)*z^8-(21/32)*z^6+(21/256)*z^4-(1/256)*z^2+1/32768

d:= degree(p);

16

p2:= combine(eval(p, z= invfunc[op(0,x1)](x)));

(1/32768)*cos(16*x)

s:= solve(p2, allsolutions);

(1/32)*Pi+(1/16)*Pi*_Z1

Z:= indets(s, And(name, Not(constant)))[];

_Z1

S:= [seq(eval(s, Z= k), k= 0..d-1)];

[(1/32)*Pi, (3/32)*Pi, (5/32)*Pi, (7/32)*Pi, (9/32)*Pi, (11/32)*Pi, (13/32)*Pi, (15/32)*Pi, (17/32)*Pi, (19/32)*Pi, (21/32)*Pi, (23/32)*Pi, (25/32)*Pi, (27/32)*Pi, (29/32)*Pi, (31/32)*Pi]

S[min[index](abs~(x1 -~ S))];

(15/32)*Pi

 

Download arctrig_of_algebraic.mw

I consider that last step to be "exact and symbolic" because the min is exactly 0.

The more-typical (but more difficult to implement) solution to this error is to introduce a coefficient called a continuation parameter. The coefficient is usually applied to the more-complicated terms of the ODEs, but it can appear anywhere, and in multiple locations. In this case, I applied it to the nonlinear terms. I used CONT for the coefficient, and changed your first ODE to

ODEforNum1:= 
   diff(u(eta), eta$4) +
   2/(eta+k)*diff(u(eta), eta$3) -
   1/(eta+k)^2*diff(u(eta), eta$2) +
   1/(eta+k)^3*diff(u(eta), eta) +
   CONT*e1*(
      -k/(eta+k)*(diff(u(eta), eta)*diff(u(eta), eta$2)-u(eta)*diff(u(eta), eta$3)) -
      k/(eta+k)^2*(diff(u(eta), eta)^2-u(eta)*diff(u(eta), eta$2)) -
      k/(eta+k)^3*u(eta)*(diff(u(eta), eta))
   ) = 0
;

The only (mathematical) change that I made was the introduction of CONT. The rest is just formatting so that I could easily read the input.

After that, you just need to declare the continuation parameter in the dsolve command:

numsol1:= dsolve(
   {BCSforNum1, BCSforNum2, ODEforNum1, ODEforNum2},
   numeric, output= listprocedure, continuation= CONT
);

The continuation is a kind of bootstrapping. The coefficient starts at 0, which eliminates the complicated terms, and it's gradually increased to 1, which returns the original ODEs. Obviously, in order for this to produce correct results, the parameter can only be used as a coefficient.

To do it with arrow notation:

Vector[row](6, i-> 4*i)

Like this:

plots:-display(
   plot(1/ra, x= 0..0.5, filled),
   plot(1/ra, x= 0.5..1),
   plot([[0.5, 0], [0.5, eval(1/ra, x= 0.5)]]), #vertical line segment
   view= [DEFAULT, 0..10] #Limit the vertical extent.
);

Is that what you mean?

Your subs commands treat y as if it were a function (expression), but it is just a free variable because it is not defined anywhere in your code. Your plot commands treat Psi as if it were a free variable, but it is a function (expression) that you have defined.

Here's a solution that can be easily generalized to higher dimensions and an arbitrary number of bodies.
 

restart:

List the names of the space dimensions. The number of these can be changed.

Space:= [x,y]:

The exponent to use on the distance  in the denominators. Using 3 corresponds to ordinary gravity.

expon:= 2:

Declare the objects that are moving. I prefer letter names over numbers for the objects. Each object has an inital position and velocity and a mass. The number of objects can be changed.

ObjProps:= table([
   a = Record(r0= [1, 1], v0= [0, 0.8], mass= 1),
   b = Record(r0= [1.5, 2], v0= [1, 1.4], mass= 1),
   c = Record(r0= [2.5, 3], v0= [0.2, -1], mass= 1)
]):

Objs:= {indices(ObjProps, nolist)};

{a, b, c}

Procedure to subscript the elements of  the Space vector with a particular object.

SpaceObj:= ob-> map(`?[]`, Space, [ob]):

Construct the ODEs.

ODEs:= {
   seq(
      seq(
         diff(V[Ob](t), t$2) =
         add(
            ObjProps[ob][mass]*(V[ob]-V[Ob])(t)/
               LinearAlgebra:-Norm(
                  <(SpaceObj(ob) - SpaceObj(Ob))(t)>,
                  Euclidean, conjugate= false
               )^expon          
           ,ob= Objs minus {Ob}
         )
        ,Ob= Objs
      )
     ,V= Space
   )
}:
'ODEs' = <ODEs[]>;

ODEs = (Matrix(6, 1, {(1, 1) = diff(diff(x[a](t), t), t) = (x[b](t)-x[a](t))/((x[b](t)-x[a](t))^2+(-y[a](t)+y[b](t))^2)+(x[c](t)-x[a](t))/((x[c](t)-x[a](t))^2+(-y[a](t)+y[c](t))^2), (2, 1) = diff(diff(x[b](t), t), t) = (-x[b](t)+x[a](t))/((-x[b](t)+x[a](t))^2+(y[a](t)-y[b](t))^2)+(x[c](t)-x[b](t))/((x[c](t)-x[b](t))^2+(-y[b](t)+y[c](t))^2), (3, 1) = diff(diff(x[c](t), t), t) = (-x[c](t)+x[a](t))/((-x[c](t)+x[a](t))^2+(y[a](t)-y[c](t))^2)+(-x[c](t)+x[b](t))/((-x[c](t)+x[b](t))^2+(y[b](t)-y[c](t))^2), (4, 1) = diff(diff(y[a](t), t), t) = (-y[a](t)+y[b](t))/((x[b](t)-x[a](t))^2+(-y[a](t)+y[b](t))^2)+(-y[a](t)+y[c](t))/((x[c](t)-x[a](t))^2+(-y[a](t)+y[c](t))^2), (5, 1) = diff(diff(y[b](t), t), t) = (y[a](t)-y[b](t))/((-x[b](t)+x[a](t))^2+(y[a](t)-y[b](t))^2)+(-y[b](t)+y[c](t))/((x[c](t)-x[b](t))^2+(-y[b](t)+y[c](t))^2), (6, 1) = diff(diff(y[c](t), t), t) = (y[a](t)-y[c](t))/((-x[c](t)+x[a](t))^2+(y[a](t)-y[c](t))^2)+(y[b](t)-y[c](t))/((-x[c](t)+x[b](t))^2+(y[b](t)-y[c](t))^2)}))

Construct the initial conditions.

ICs:= op~({
   seq(
      [SpaceObj(Ob)(0) =~ ObjProps[Ob][r0], D~(SpaceObj(Ob))(0) =~ ObjProps[Ob][v0]][],
      Ob= Objs
   )
});

{x[a](0) = 1, x[b](0) = 1.5, x[c](0) = 2.5, y[a](0) = 1, y[b](0) = 2, y[c](0) = 3, (D(x[a]))(0) = 0, (D(x[b]))(0) = 1, (D(x[c]))(0) = .2, (D(y[a]))(0) = .8, (D(y[b]))(0) = 1.4, (D(y[c]))(0) = -1}

Sol:= dsolve(ODEs union ICs, numeric):

Plot of trajectories:

plots:-odeplot(
   Sol, SpaceObj~(Objs)(t), t= 0..10,
   legend= [Objs[]], scaling= constrained
);

Animation:

plots:-display([
   seq(
      plot(
         subs(Sol(t), (`[]`@SpaceObj)~(Objs)('t')),
         style= point, symbol= solidcircle, symbolsize= 12,
         color= [red, blue, green]
      ), t= 0..10, .1
   )], insequence
);

 


 

Download Three-body.mw

You misplaced the closing brace. You have

pds:= pdsolve({eq1, eq2, IBC, numeric, spacestep = 1/10});

It should be

pds:= pdsolve({eq1, eq2}, IBC, numeric, spacestep = 1/10);

Then there's a more-subtle problem with your initial/boundary conditions. You have D[1](u)(x,0). Are you sure that that shouldn't be D[2](u)(x,0)? The former can't be handled by pdsolve(..., numeric).

When entering the expression, you must explicity enter the dot:

p:= C.A + A;

This will indicate that you want noncommutative multiplication.

It seems that you don't really want plots. What you want is a 50x1000 matrix of computed y values for evenly spaced values of a and x. Each y value can be computed with fsolve, like this

R0:= gamma+2*ln(2)+Re(Psi(1/2+(1+I)*tanh((1+I)*x)/((tau+0.25e-1*a)*y)))+ln(y):
tau:= 9.975:
R0p:= unapply(R0, [a,x]):
R0f:= proc(a,x)
local r:= fsolve(R0p(a,x), y= 0..1);
   `if`(r::float, r, Float(undefined))
end proc:
M:= Matrix(
   (50,1000),
   (i,j)-> R0f(1 + (i-1)*(1-0)/(50-1), 0 + (j-1)*(5-0)/(1000-1)),
   datatype= float[8]
);

This took about a little less than 2 hours on my system, using Digits = 15. It make take less time with a lower value of Digits.

If you actually do want a plot, it will be trivial to generate it from the matrix. It can be a 2D or 3D plot.

eq1:= diff(s(t),t) = (1-phi)*epsilon+(1-rho)*a+(1-f)*alpha*v(t)-(lambda+theta[1]+a+epsilon)*s(t);
eq2:= diff(v(t),t) = phi*epsilon+rho*a+theta[1]*s(t)-((1-f)*alpha+f*theta[2]+a+epsilon)*v(t);
eq3:= diff(e(t),t) = lambda*s(t)-(delta+a+epsilon)*e(t);
eq4:= diff(r(t),t) = eta*i(t)+v(t)*f*theta[2]-(a+epsilon)*r(t);
dsolve({eq1,eq2,eq3,eq4});

The answer is quite lengthy. However, this is a linear system, so the solution is fundamentally simple. If you use dsolve again with numeric values for the parameters, you'll get a simpler solution.

Here is the complete solution done by exhaustive search. My results are identical to what you got with Palisades Evolver, so I'd say that the published paper is wrong! The seven-day problem took 5 seconds; the five-day problem took 41 seconds. How much time did Palisades take?

So people actually make money doing this and they can even publish papers on solution to individual problems? Hmmm, maybe I can find work like that.
 

Finding the minimal distance for a floral farm's delivery truck

 

Author: Carl Love <carl.j.love AT gmail>, 2017-May-13

Keywords: combinatorics, logistics, truck routing problem, real-world business problem

 

Scenario: A florist's farm truck needs to make deliveries to 14 satellite locations every week. At most 3 deliveries can be made per day. Each delivery day must start and end at the central location, the farm.

restart:

N:=14: #Number of delivery destinations. Index 1 represents the delivery origin (the farm).

Distance matrix.  c[i,j] is the distance from location i to location j.

c:= Matrix(
   (N+1)$2, shape= symmetric, scan= triangular,
   [0, op]~([[222,65.4,217,136,115,119,47.9,206,56.5,73,119,189,25.2,104],
                   [251,24.4,284,262,103,213,23,204,155,266,29.2,246,131],
                   [247,76.8,47.4,148,109,235,47.9,103,58.9,218,61.5,168],
                         [279,258,98.9,247,45.1,199,151,261,32.6,242,153],
                             [31.8,181,184,267,80.4,135,41.3,251,137,201],
                                    [159,162,246,59,113,38.9,230,109,179],
                                       [148,87.1,101,53,163,70.9,144,139],
                                          [189,104,102,165,205,53.4,82.3],
                                               [187,139,249,35.2,230,108],
                                                   [55,62.6,171,80.9,121],  
                                                        [117,123,98,93.1],
                                                            [233,120,183],
                                                                [214,135],
                                                                    [123]]                                                                  
));

c := Matrix(15, 15, {(1, 1) = 0, (1, 2) = 222, (1, 3) = 65.4, (1, 4) = 217, (1, 5) = 136, (1, 6) = 115, (1, 7) = 119, (1, 8) = 47.9, (1, 9) = 206, (1, 10) = 56.5, (1, 11) = 73, (1, 12) = 119, (1, 13) = 189, (1, 14) = 25.2, (1, 15) = 104, (2, 2) = 0, (2, 3) = 251, (2, 4) = 24.4, (2, 5) = 284, (2, 6) = 262, (2, 7) = 103, (2, 8) = 213, (2, 9) = 23, (2, 10) = 204, (2, 11) = 155, (2, 12) = 266, (2, 13) = 29.2, (2, 14) = 246, (2, 15) = 131, (3, 3) = 0, (3, 4) = 247, (3, 5) = 76.8, (3, 6) = 47.4, (3, 7) = 148, (3, 8) = 109, (3, 9) = 235, (3, 10) = 47.9, (3, 11) = 103, (3, 12) = 58.9, (3, 13) = 218, (3, 14) = 61.5, (3, 15) = 168, (4, 4) = 0, (4, 5) = 279, (4, 6) = 258, (4, 7) = 98.9, (4, 8) = 247, (4, 9) = 45.1, (4, 10) = 199, (4, 11) = 151, (4, 12) = 261, (4, 13) = 32.6, (4, 14) = 242, (4, 15) = 153, (5, 5) = 0, (5, 6) = 31.8, (5, 7) = 181, (5, 8) = 184, (5, 9) = 267, (5, 10) = 80.4, (5, 11) = 135, (5, 12) = 41.3, (5, 13) = 251, (5, 14) = 137, (5, 15) = 201, (6, 6) = 0, (6, 7) = 159, (6, 8) = 162, (6, 9) = 246, (6, 10) = 59, (6, 11) = 113, (6, 12) = 38.9, (6, 13) = 230, (6, 14) = 109, (6, 15) = 179, (7, 7) = 0, (7, 8) = 148, (7, 9) = 87.1, (7, 10) = 101, (7, 11) = 53, (7, 12) = 163, (7, 13) = 70.9, (7, 14) = 144, (7, 15) = 139, (8, 8) = 0, (8, 9) = 189, (8, 10) = 104, (8, 11) = 102, (8, 12) = 165, (8, 13) = 205, (8, 14) = 53.4, (8, 15) = 82.3, (9, 9) = 0, (9, 10) = 187, (9, 11) = 139, (9, 12) = 249, (9, 13) = 35.2, (9, 14) = 230, (9, 15) = 108, (10, 10) = 0, (10, 11) = 55, (10, 12) = 62.6, (10, 13) = 171, (10, 14) = 80.9, (10, 15) = 121, (11, 11) = 0, (11, 12) = 117, (11, 13) = 123, (11, 14) = 98, (11, 15) = 93.1, (12, 12) = 0, (12, 13) = 233, (12, 14) = 120, (12, 15) = 183, (13, 13) = 0, (13, 14) = 214, (13, 15) = 135, (14, 14) = 0, (14, 15) = 123, (15, 15) = 0}, storage = triangular[upper], shape = [symmetric])

The length of a round trip starting and ending at position 1:

tour_length:= (T::list(And(posint, Not(1))))->
   c[1,T[1]] + add(c[T[i-1],T[i]], i= 2..nops(T)) + c[T[-1],1]
:

The minimal Hamiltonian circuit of a set of delivery destinations:

MinOneTrip:= proc(S::set(And(posint, Not(1))))
option remember;
local P:= combinat:-permute([S[]]), T:= tour_length~(P), k;
   k:= min[index](T);
   HC(S):= P[k]; #Save minimal Hamiltonian circuit for later.
   T[k] #Return length of minimal Hamiltonian circuit.
end proc:   

The minimum distance for a partition:

MinPart:= proc(B::list(posint))
local min:= infinity, minpart, p, pp, d, P, PS:= ListTools:-PartialSums([0,B[]]), n:= nops(B), k;
   for p in Iterator:-SetPartitionFixedSize(B) do
      pp:= p+~1; #Shift indices (1-14) to (2-15)
      P:= convert~({seq(pp[PS[k]+1..PS[k+1]], k= 1..n)}, set);
      d:= add(MinOneTrip~([P[]]));
      if d < min then
         min:= d;
         minpart:= P
      end if
   end do;
   min, HC~(minpart)
end proc:

The first problem:

CodeTools:-Usage(MinPart([2$7]));

memory used=503.54MiB, alloc change=44.01MiB, cpu time=4.67s, real time=4.70s, gc time=375.00ms

2041.8, {[2, 9], [3, 14], [4, 13], [5, 6], [7, 11], [8, 15], [10, 12]}

The second problem:

CodeTools:-Usage(MinPart([3$4, 2]));

memory used=3.92GiB, alloc change=0 bytes, cpu time=40.44s, real time=40.44s, gc time=3.27s

1552.6, {[8, 14], [3, 10, 11], [4, 2, 13], [6, 5, 12], [7, 9, 15]}

``


 

Download Floral_truck_routing_problem.mw

@Febar You should use = (in various places) instead of :=. Something like this:
 

 

restart:

D__T := D__N+D__R:

 

D__N := -D__R*alpha-b*d__2-d__1*p__N+d__0:

 

 

 

Demand not directly related to sales price and second-market demnad

NULL

Sales returns, consumer's return requests

NULL

D__R := theta*R:

S := (1-theta)*R:

NULL``

Refurbishing proportion among returned items

theta := t*(p__N-p__R):

T__N := w__N*D__N:

T__R := w__R*D__R:

NULL

``

Profit of manufacturing process

Pi__m := -D__N*c+T__N:

Pi__s := p__N*D__N-T__N-(p__N-b)*R+T__R-g*S:

Pi__r := D__R*p__R-D__R*u-T__R:

 

 

MSR: Integration of manufacturing, selling, and refurbishing processesNULL

Pi__MSR__M := Pi__m+Pi__s+Pi__r:

diff(Pi__MSR__M, p__N)

-(-R*alpha*t-d__1)*c-t*(p__N-p__R)*R*alpha-b*d__2-d__1*p__N+d__0+p__N*(-R*alpha*t-d__1)-R+g*t*R+t*R*p__R-t*R*u

NULLNULL

solve(%, p__N);

(1/2)*(R*alpha*c*t+R*alpha*p__R*t+R*g*t+R*p__R*t-R*t*u-b*d__2+c*d__1-R+d__0)/(R*alpha*t+d__1)

eval(%, R= r__0 - r__1*b);

(1/2)*((-b*r__1+r__0)*alpha*c*t+t*(-b*r__1+r__0)*p__R*alpha+g*t*(-b*r__1+r__0)+t*(-b*r__1+r__0)*p__R-t*(-b*r__1+r__0)*u-b*d__2+c*d__1+r__1*b-r__0+d__0)/(t*(-b*r__1+r__0)*alpha+d__1)

simplify(%, {d__0 - d__2*b = D__0, r__0 - r__1*b = R});

((-1+((c+p__R)*alpha+g-u+p__R)*t)*R+c*d__1+D__0)/(2*R*alpha*t+2*d__1)

``

Download Joint_Pricing_Sol_.mw

This isn't the final simplified form that you were hoping for. But surely you can see that it's impossible to eliminate the variables alpha, g, u, and t using solely the information that you've provided.

Note that my simplify command is in the "simplify with side relations" form that Robert Lopez mentioned.

First 193 194 195 196 197 198 199 Last Page 195 of 395