acer

32363 Reputation

29 Badges

19 years, 332 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

I realize that this has some flaws; it can't get by discontinuities in the numeric solving, due to the set-up. But perhaps it might inspire you.

(I can't help but feel that I once knew some better way, but right now cannot recall it. I'm sure I'll kick myself, shortly.)

restart;

with(plots): interface(warnlevel=0):

epsilon := .01:

pot := 1/sqrt(x^2+y^2+epsilon)-1/sqrt((x-.25)^2+y^2+epsilon):

CP := contourplot(pot,x=-.1..0.35,y=-.25..0.25,contours=15,color="Burgundy"):

ds := dsolve({diff(y(x),x)=-1/subs(y=y(x),implicitdiff(pot,y,x)),y(0.125)=par},
             y(x),numeric,parameters=[par],abserr=1e-5):

SL := proc(p)
  ds(':-parameters'=[par=p]);
  display(odeplot(ds,[x,y(x)],x=-0.1..0.35,color=blue));
end proc:

display(CP, seq(SL(y0),y0=-3..3,0.04),
        view=[-0.1..0.35,-0.25..0.25]);

Download Dipole_fields_ac.mw

Is this the kind of thing you're after?

restart

_local(gamma)

with(PDEtools)

with(Physics)

undeclare(prime)

`There is no more prime differentiation variable; all derivatives will be displayed as indexed functions`

NULL

pde := -I*(diff(U(xi), xi))*gamma*k*mu+I*gamma*(diff(U(xi), xi))*sigma*w+(diff(diff(U(xi), xi), xi))*gamma*k*w+U(xi)*gamma*mu*sigma+(2*I)*(diff(U(xi), xi))*k*sigma+2*alpha*U(xi)^3+(diff(diff(U(xi), xi), xi))*k^2-I*(diff(U(xi), xi))*w-U(xi)*sigma^2-U(xi)*mu

-I*(diff(U(xi), xi))*gamma*k*mu+I*(diff(U(xi), xi))*gamma*sigma*w+(diff(diff(U(xi), xi), xi))*gamma*k*w+U(xi)*gamma*mu*sigma+(2*I)*(diff(U(xi), xi))*k*sigma+2*alpha*U(xi)^3+(diff(diff(U(xi), xi), xi))*k^2-I*(diff(U(xi), xi))*w-U(xi)*sigma^2-U(xi)*mu

case1 := [mu = -(4*gamma*k*w+4*k^2-sigma^2)/(gamma*sigma-1), A[0] = 0, A[1] = -RootOf(_Z^2*alpha+gamma*k*w+k^2), B[1] = RootOf(_Z^2*alpha+gamma*k*w+k^2), w = (gamma*k*mu-2*k*sigma)/(gamma*sigma-1)]

G1 := U(xi) = 2*RootOf(_Z^2*alpha+gamma*k*w+k^2)/sinh(2*xi)

`~`[`=`]([mu, w], eval([mu, w], case1)); C1 := solve(%, [mu, w])[]

[mu = -(4*gamma*k*w+4*k^2-sigma^2)/(gamma*sigma-1), w = (gamma*k*mu-2*k*sigma)/(gamma*sigma-1)]

[mu = (4*gamma*k^2*sigma+gamma*sigma^3+4*k^2-sigma^2)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1), w = -k*(4*gamma*k^2+gamma*sigma^2-2*sigma)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)]

newcase1 := [op(C1), op(`~`[`=`]([A[0], A[1], B[1]], eval([A[0], A[1], B[1]], case1)))]

[mu = (4*gamma*k^2*sigma+gamma*sigma^3+4*k^2-sigma^2)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1), w = -k*(4*gamma*k^2+gamma*sigma^2-2*sigma)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1), A[0] = 0, A[1] = -RootOf(_Z^2*alpha+gamma*k*w+k^2), B[1] = RootOf(_Z^2*alpha+gamma*k*w+k^2)]

pde3 := eval(pde, newcase1)

-I*(diff(U(xi), xi))*gamma*k*(4*gamma*k^2*sigma+gamma*sigma^3+4*k^2-sigma^2)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)-I*(diff(U(xi), xi))*gamma*sigma*k*(4*gamma*k^2+gamma*sigma^2-2*sigma)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)-(diff(diff(U(xi), xi), xi))*gamma*k^2*(4*gamma*k^2+gamma*sigma^2-2*sigma)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)+U(xi)*gamma*(4*gamma*k^2*sigma+gamma*sigma^3+4*k^2-sigma^2)*sigma/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)+(2*I)*(diff(U(xi), xi))*k*sigma+2*alpha*U(xi)^3+(diff(diff(U(xi), xi), xi))*k^2+I*(diff(U(xi), xi))*k*(4*gamma*k^2+gamma*sigma^2-2*sigma)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)-U(xi)*sigma^2-U(xi)*(4*gamma*k^2*sigma+gamma*sigma^3+4*k^2-sigma^2)/(4*gamma^2*k^2+gamma^2*sigma^2-2*gamma*sigma+1)

odetest(eval(G1, newcase1), pde3)

0

pde4 := collect(pde3, [U(xi)], simplify)

2*alpha*U(xi)^3-4*k^2*U(xi)/(1+(4*k^2+sigma^2)*gamma^2-2*gamma*sigma)+(diff(diff(U(xi), xi), xi))*k^2/(1+(4*k^2+sigma^2)*gamma^2-2*gamma*sigma)

odetest(eval(G1, newcase1), pde4)

0

Download test_sol_for_PDE1_ac.mw

You have mixed up the order of the arguments. You've used a different order, in two different places.

You have DOE set up with the columns (apparently) being:
    epsilon, A, Br, N, beta, m, lambda0, lambda1

But you constructed your procedure Fop to treat its arguments as if the order were,
    A, Br, N, beta, epsilon, lambda[0], lambda[1], m

I'm guessing that the wrong one is your construction of Fop, because there you just used a lexicographic order, and ignored how you set up the columns of DOE.

So I suppose that you wanted Fop more like this: Answer_not_same_ac.mw

Such a placeholder is not required. And you don't need to substitute into a diff(...) result.

Instead, you can just use D(W). You can use it as D(W)(u(t)) in your DE for dsolve. And you can use it for D(W)(u) in your fieldplot call.

And you also don't need to define W the same way, a second time. Since the original W was defined before the parameters were assigned values then calls to W or D(W) will pick up the latest parameter values assigned.

So your same processes can become more tidy and legible, eg, proteins_ac.mw

If you really want to visualize the latest parameter values in the formula then you can just invoke it to print it, eg.
   D(W)(Un);

If you want you can assign D(W) to some name, to avoid having D repeat effort. Eg,
   dW := D(W);
and then use that. Eg. proteins_acc.mw

You could put all your procedures into a package module, and then LibraryTools:-Save that instead.

See also the relevant section of the Programming Guide.

Here are various ways in which one may leverage the collect command to attain the target form.

restart;

Zin := ((Rsp + (omega*L2 - omega02^2*L2/omega)*I)*(Rpp + (omega*L1 - omega01^2*L1/omega)*I) + 0.01*omega^2*L1*L2)/(Rsp + (omega*L2 - omega02^2*L2/omega)*I);

((Rsp+I*(omega*L2-omega02^2*L2/omega))*(Rpp+I*(omega*L1-omega01^2*L1/omega))+0.1e-1*omega^2*L1*L2)/(Rsp+I*(omega*L2-omega02^2*L2/omega))


Zout := Rpp + (omega*L1 - omega01^2*L1/omega)*I + (0.01*omega^2*L1*L2)/(Rsp + (omega*L2 - omega02^2*L2/omega)*I);

Rpp+I*(omega*L1-omega01^2*L1/omega)+0.1e-1*omega^2*L1*L2/(Rsp+I*(omega*L2-omega02^2*L2/omega))

First, lets assign that denominator to a name, so that we
can more easily manipulate and collect/simplify w.r.t it.

FF:=1/select(type,Zin,anything^(-1));

Rsp+I*(omega*L2-omega02^2*L2/omega)

Let's also veil that 0.01 float, using a placeholder for it. Otherwise various reasonable techniques will get some
subexpression with coefficients of 1. or 1.000..., etc.
(Converting it to rational is not helpful, if you want only that very same float back at the end.)
We can't freeze a float directly, to I'll also wrap with a dummy function.

temp := simplify(subsindets(Zin,float,freeze@__K),{FF=FFF});

((I*L1*omega^2-I*L1*omega01^2+Rpp*omega)*FFF+L1*L2*omega^3*`freeze/R0`)/(omega*FFF)

Going for the target just as you had it, ie. some subexpressions not completely factors w.r.t L1, L2.

Since we cannot collect w.r.t imaginary unit I directly, temporarily replace that too.

subs(I=II,temp):
eval(collect(%,[Rpp,II,omega01],thaw),[II=I,FFF=FF,__K=(x->x)]);

Rpp+I*(omega*L1-omega01^2*L1/omega)+0.1e-1*omega^2*L1*L2/(Rsp+I*(omega*L2-omega02^2*L2/omega))

Alternatively, frontend the collect, so that we may collect w.r.t I.

eval(frontend(collect,[temp,[Rpp,L2,I,omega],thaw],
              [{`+`,`*`,list},{}]),
     [FFF=FF,__K=(x->x)]);

Rpp+I*(omega*L1-omega01^2*L1/omega)+0.1e-1*omega^2*L1*L2/(Rsp+I*(omega*L2-omega02^2*L2/omega))

The choice of variables for which we may collect is not unique.

subs(I=II,temp):
eval(collect(%,[FFF,Rpp,II],thaw),[II=I,FFF=FF,__K=(x->x)]);

Rpp+I*(L1*omega^2-L1*omega01^2)/omega+0.1e-1*omega^2*L1*L2/(Rsp+I*(omega*L2-omega02^2*L2/omega))

These are the kind of irritating 1.000... artefacts that may arise if we
don't veil that float coefficient.

simplify(Zin,{FF=FFF});
eval(collect(subs(I=II,%),[FFF,Rpp,II,omega],thaw),[II=I,FFF=FF]);

0.1000000000e-1*((100.*I)*FFF*L1*omega^2-(100.*I)*FFF*L1*omega01^2+L1*L2*omega^3+100.*FFF*Rpp*omega)/(omega*FFF)

1.000000000*Rpp+I*(1.000000000*omega*L1-1.000000000*omega01^2*L1/omega)+0.1000000000e-1*omega^2*L1*L2/(Rsp+I*(omega*L2-omega02^2*L2/omega))

As I mentioned in my Reply, some of the subexpressions may
be further factored (say, w.r.t L1 or L2).

eval(collect(temp,[FFF,Rpp,L2],simplify@thaw),[FFF=collect(FF,L2),__K=(x->x)]);

Rpp+I*L1*(omega^2-omega01^2)/omega+0.1e-1*omega^2*L1*L2/(I*(omega-omega02^2/omega)*L2+Rsp)

Download collect_I_ex.mw

You can simply pass the explicit option, to get the result in terms of explicit radicals directly from the solve command.

eq1 := y=1/2*(x-5)^2-6:
eq2 := y=3*x-2:

solve([eq1,eq2],{x,y},explicit);

{x = 8+47^(1/2), y = 22+3*47^(1/2)}, {x = 8-47^(1/2), y = 22-3*47^(1/2)}


Download solve_sys_expl.mw

In other words, you don't need to use two different commands to get the roots in radical form.

For a polynomial system involving more than one variable then results involving roots/radicals are not expressed in explicit form by default (even for this low degree).

See also the subsection Controlling the Form of Solutions in the Help page for topic solve,details . (Unfortunately, the difference between a single polynomial in one variable and system is not made entirely clear there, in this respect.)

First, and most importantly, notice that,
   0 < x and x <> 2
evaluates to just,
   0 < x
since <> and = evaluate as if under evalb, with active and.

In this case you are running into the effect of,

evalb( x <> 2 );
             true

So 0 < x and x <> 2 becomes 0 < x and true, which becomes just 0<x . Not what you intended!

This subtlety has caught out many Maple users; you're in good company.

Instead, you can use an inert form such as (captitalized) And .

restart;


Note that the following produces just x>0
So don't pass that to solve !

0 < x and x <> 2

0 < x

d2 := solve(And(0 < x, x <> 2), x);

RealRange(Open(2), infinity), RealRange(Open(0), Open(2))

lprint(d2);

RealRange(Open(2),infinity), RealRange(Open(0),Open(2))

map[2](`::`,x,Or(d2));

Or(x::(RealRange(Open(2), infinity)), x::(RealRange(Open(0), Open(2))))

convert(%, relation);

Or(And(2 < x, x <= infinity), And(0 < x, x < 2))

map[2](`in`,x,Or(d2));

Or(`in`(x, RealRange(Open(2), infinity)), `in`(x, RealRange(Open(0), Open(2))))

convert(%, relation);

Or(And(2 < x, x <= infinity), And(0 < x, x < 2))


Download solve_ineq_1.mw

Now, we've obtained more consistent results. And if you're wondering why the slightly different forms of input produce the different forms of output, well, it's because it's more useful to have the choice. (It's been noted previously, and reported, that documentation of all the input/ouput forms from solve are under-documented.)

I am guessing that you'd like all the real roots to be stored, in the case that there are multiple real roots for a given set of parameter values. If not you can pass the option maxsols=1 to fsolve.

restart;


Here I'll just use the expression-form calling sequence of fsolve,
where the first argument is an expression and the second is of
the form x=range.

Reg_IV := proc(beta, n)
  local alpha, b, c, d, k, `&alpha;L`,
        `&alpha;R`, delta, eqn, x;
  `&alpha;L` := 3+beta-6*beta^(1/2);
  `&alpha;R` := 1-beta; delta := (`&alpha;R`-`&alpha;L`)/n;
  print(`&beta; = `, evalf(beta, 5), `n = `, evalf(n, 5));
  print(`&alpha;L = `, evalf(`&alpha;L`, 5),
        `&alpha;R = `, evalf(`&alpha;R`, 5),
        `&delta; = `, evalf(delta, 5));
  print(``);
  for k from 0 to n+1 do
    alpha := `&alpha;L`+k*delta;
    b := -5+alpha-3*beta;
    c := 8-4*alpha-6*beta+2*beta^2-2*alpha*beta;
    d := -(4*beta+4)*(1-alpha-beta);
    eqn := x^3+b*x^2+c*x+d;
    x[k] := [fsolve(eqn, x=0 .. 2)];
    print(evalf(x[k], 5));
  end do;
  print(``);
  print(evalf(x, 5));
end proc:

Reg_IV(0.2, 4);

`&beta; = `, .2, `n = `, 4.

`&alpha;L = `, .51672, `&alpha;R = `, .8, `&delta; = `, 0.70820e-1

``

[]

[]

[.23706, .71971]

[.10761, .79636]

[0., .85081]

[.89400]

``

x


You could use the operator-form calling sequence of fsolve, but
notice that by default that would only return a single root. You could pass
fsolve the maxsols=3 option, but that's still less efficient that using the
expression-form calling sequence above, which returns all real roots
of the polynomial by default.

Reg_IV := proc(beta, n)
  local alpha, b, c, d, k, `&alpha;L`,
        `&alpha;R`, delta, eqn, x;
  `&alpha;L` := 3+beta-6*beta^(1/2);
  `&alpha;R` := 1-beta; delta := (`&alpha;R`-`&alpha;L`)/n;
  print(`&beta; = `, evalf(beta, 5), `n = `, evalf(n, 5));
  print(`&alpha;L = `, evalf(`&alpha;L`, 5),
        `&alpha;R = `, evalf(`&alpha;R`, 5),
        `&delta; = `, evalf(delta, 5));
  print(``);
  for k from 0 to n+1 do
    alpha := `&alpha;L`+k*delta;
    b := -5+alpha-3*beta;
    c := 8-4*alpha-6*beta+2*beta^2-2*alpha*beta;
    d := -(4*beta+4)*(1-alpha-beta);
    eqn := unapply(x^3+b*x^2+c*x+d, x);
    x[k] := [fsolve(eqn, 0 .. 2, maxsols=3)];
    if hastype(x[k],specfunc(fsolve)) then
      x[k] := [];
    end if;
    print(evalf(x[k], 5));
  end do;
  print(``);
  print(evalf(x, 5));
end proc:

Reg_IV(0.2, 4);

`&beta; = `, .2, `n = `, 4.

`&alpha;L = `, .51672, `&alpha;R = `, .8, `&delta; = `, 0.70820e-1

``

[]

[]

[.23706, .71971]

[.10761, .79636]

[.85081]

[.89400]

``

x

Download fsolve_oper_expr_ex.mw

ps. Some people prefer the alternate name MakeFunction instead of unapply. That's moot if you want all the roots, since using expression-form for fsolve is more efficient in that case.

pps. I put the roots in a list, since in the case of multiple roots I expect you'll find it slightly more straightforward to deal with a stored list rather than deal with stored expression sequences.

I hope you realize that numerically integrating the numerically computed derivative is (numerically) generally a bad idea.

Also, I suppose that you realize such numeric computation is not all necessary here, and that (as you say) you are trying to establish something about the three numeric solvers in play here.

But you have been unclear as to why you think that this methodology shows something significant and what precisely that might be. (Also, why differentiate numerically at all?) There are so many controls in play here (eg. the working precision in each of the three numeric solvers in play, tolerances, etc.) that you blanket/vague goal lacks focus and thus meaning. This is the kind of thing where it's more sensible to start with the numeric requirements, explicitly. Then see if you can attain them. Otherwise (IMO) you risk flailing more with the functionality choices and missing something key.

With all of the 1) numeric pde solver, 2) numeric differentiation outside that pde solver (ugh), and 3) numeric integration then any numeric difficulties are going to be a causality muddle. How would you ever decide which might be some weak link? (especially considering that not all the parts are necessary...)

It's not clear to me what you mean by, "...the global form of the conservation law over time".

Is this the kind of numeric integration you were trying to get at? (I'm not suggesting that this is the plot you're after. I include it merely to go with that integration result at the particular t=0 point.)

restart;

pde := diff(v(x, t), t, t) = diff(v(x, t), x, x):

f := xi -> exp(-xi^2):

a := -10: b := 10: dx := 1/50: t_final := 10:

pds := pdsolve(pde, {v(a, t) = 0, v(b, t) = 0, v(x, 0) = f(x + 5),
                     D[2](v)(x, 0) = -eval(diff(f(x), x), x = x + 5)},
               numeric, range = a .. b, time = t, spacestep = dx):

sol_proc := rhs(pds:-value(output = listprocedure)[3]):

sol := (x, t) -> piecewise(a < x and x < b, sol_proc(x, t), 0):

plot(D[2](sol)(x,0), x=a..b, size=[500,200]);

evalf(Int(D[2](sol)(x,0), x=a..b, digits=10, epsilon=1e-5, method=_d01ajc));

-0.5778633229e-10

Download pde_num_hmm.mw

ps. Here's another syntax for the integration and plot above. You original syntax was not ok, using an fdiff call like an expression alongside the (operator style) a..b for the range of integration.

evalf(Int(x->fdiff(sol_proc(x, t), [t = 0]),
          a .. b, digits=10, epsilon=1e-5, method=_Dexp));
plot(x->fdiff(sol_proc(x, t), [t = 0]), a .. b, size=[500,200]);

Are you perhaps looking for something like the following:

[seq(RootOf(det_num, Omega, index = i), i = 1 .. 3)];
plot(%, omega__v = 0 .. 2, size = [400, 400]);

I'm not 100% sure how your code is supposed to work.

On my machine the following takes about 14sec, compared to the original taking about 24sec.

Formula_II_acK.mw

(It's not easy to work with this code when it's "behind" a Button. But I've put my edits back there because that's how you gave it to us.)

A significant portion of the outstanding time is now taken by the coeftayl calls.

I hazard a guess that some of the following might be possible:
a) Form parts or a variant of `Eq` just once, and then instantiate more quickly when the input Components's values change.
b) Figure out a way to have the coeftayl results be done symbolically, so as to instantiate a template rather than do its heavy lifting for each set of Component values.

I expect that there are further improvements possible. Alas I'm out of time for this, sorry.

I noticed that if I changed parameter N from 0.5 to 1/2 then the solve step seemed to slow down. Hopefully that is all "above board" and not any hint that your current results are actually slightly suspect.

Here I use the formula as in your picture, with the x- and y-components switched. And so a similar plot can attain.

plots:-display(
  plots:-spacecurve([t*cos(t),t*sin(t),2*sqrt(2)/3*t^(3/2)],t=0..Pi,
                    thickness=4,color=black),
  axes=normal,view=[-3..3,-2..4,-2..8], scaling=constrained,
  orientation=[50,70,0]);

You also mentioned 2D plotting, but that could mean several different things and you haven't explained what you are after. Perhaps a projection of that spacecurve, onto the x-y or some other plane?

G := x^5 - 5*x^4 - 35*x^3:

C := mul(x-(a+i*d),i=0..4):

S := solve({seq(coeff(C,x,i)=coeff(G,x,i),i=3..4)});

{a = -5, d = 3}, {a = 7, d = -3}

R := seq(eval(a+i*d,S[1]),i=0..4);

-5, -2, 1, 4, 7

P := expand(eval(C,S[1]));

x^5-5*x^4-35*x^3+125*x^2+194*x-280

Download poly_puzz.mw

The roots are R, and the polynomial is P.

@C_R Notice that your code does not assign the expression to a name, and merely reuse it at the different values of Digits.

Rather, your code explicitly re-forms the expression at the different values of Digits.

The 1e-11 invocation forms the very same float expression at both Digits settings. But the 0.1*10^11 forms different float expressions at those two different values of Digits.

The differing coefficients makes the expressions being passed be to is be different (ie. different address, etc).

That makes the remember table get used for one flavor (where the expression passed is identical) but not the other (where the expression passed is different).

Digits := 10;

10

addressof(0.1*10^11);
dismantle(1e-11);

36893628647194360668


FLOAT(3): .1e-10
   INTPOS(2): 1
   INTNEG(2): -11
 

addressof(0.1*10^11);
dismantle(0.1*10^11);

36893628647194360668


FLOAT(3): .1000000000e11
   INTPOS(2): 1000000000
   INTPOS(2): 1
 

Digits:=30;

30

addressof(1e-11);
dismantle(1e-11);

36893628647194746428


FLOAT(3): .1e-10
   INTPOS(2): 1
   INTNEG(2): -11
 

addressof(0.1*10^11);
dismantle(0.1*10^11);

36893628647194377852


FLOAT(3): 10000000000.0
   INTPOS(2): 100000000000
   INTNEG(2): -1
 

Download flt_ex.mw

On the other hand, if you formed the two expressions just once, up front, then the remembered can interfere (here, consistently).

eval_of_range_in_ln_ac2.mw

So, the cause is that (only) one of those constructions produce identical results at differing Digits.

First 15 16 17 18 19 20 21 Last Page 17 of 336