dharr

Dr. David Harrington

8235 Reputation

22 Badges

20 years, 341 days
University of Victoria
Professor or university staff
Victoria, British Columbia, Canada

Social Networks and Content at Maplesoft.com

Maple Application Center
I am a retired professor of chemistry at the University of Victoria, BC, Canada. My research areas are electrochemistry and surface science. I have been a user of Maple since about 1990.

MaplePrimes Activity


These are replies submitted by dharr

@MaPal93 That's a tough question, since a lot depends on what you want to do with the answers. It's always useful to try simplify, evalc, or convert(.., radical) to see if there is a closed form, which can be found for some higher degree polynomials.

Sometimes the complicated closed form solution is harder to work with than a RootOf.

And you can do things with RootOfs that give useful information. As an example consider the first solution with the 6th order polynomial. Plots show that for positive gamma there are solutions with positive Lambda__2 but negative Lambda__3, which may be enough to know that this is not useful to you. But suppose you wanted to know the maximum Gamma value for which it is possible to find a positive Lambda__2. You can differentiate and solve to find this value is Gamma_max = 0.29407, so  for any sigma__v and sigma__d and gamma, their product has to be less than 0.29407 to give a real solution (with a positive Lambda__2 and negative Lambda__3).

Some analysis of this type here.

NondimshortAllEqns.mw

[Edited to correct mistakes as noted below]

@MaPal93 Turns out you can only eliminate 3 of the 13 variables.

difficult_non-dimensionalization.mw

@dharr Here is the plot - the positive one is consistently the first (red) one.

solve(Eqq111, Lambda__2):
allvals:=map(simplify, [allvalues(%)]):
plot(allvals,Gamma=0..3,color=[red,blue,black,magenta]);

Nondimshort.mw

@acer In this case, the question is about non-dimensionalizing a more complicated set of equations. That is certainly not apparent from the title of the thread. I non-dimensionalized the simpler set by inspection as an aside to answering the question about the complexity, but this one will likely require the machinery of Hermite normal forms.

@MaPal93 

  • The only real and positive solution is for lambda_2 = lambda_3, as shown explicitly in Nondimshort.mw. Is this solution the same as ans23[2] and ans32[2] in NondimshortAllEqns.mw (i.e., Lambda_2 = Lambda_3 = beta)?
    Yes, if you look at the definition of beta in the alias, it is the same quartic as before.
  • In Nondimshort.mw you type "Seems to always have one positive root - the curve Jumps at three places (these places can be found with solve(...,parametric).)". How to do so?
    solve(Eqq111, Lambda__2, parametric);
    Moreover, this curve is Lambda_2 as a function of positive Gamma...how to obtain the original lambda_2?
    use the relationship lambda__2 = Lambda__2*sigma__v/sigma__d.
    If I type solve(Eq2redox, lambda__2); map(simplify, [allvalues(%)]); I obtain 4 roots...which one is the positive one?
    You cannot tell from looking at the solution, since it will depend on the values of the parameters. You have a better chance with solve(Eqq111, Lambda__2); map(simplify, [allvalues(%)]); because there is only one parameter Gamma, but even there it is very complicated to analyse. In principle, solve(Eqq111, Lambda__2, parametric,explicit); should give you the different solutions for different ranges of Gamma, but it only gives values at special values of Gamma, presumably because this case is too hard to solve. You can probably plot different solutions for the different ranges of Gamma between the critical values to figure this out.
    Is it unique?
    Descarte's rule of signs says there is one positive root, but which one it is will depend on the value of Gamma.

@Nicole Sharp Here is a worksheet with both your examples in which eval(q, Unit =1) works. Since you didn't provide the actual worksheet, it's hard to further diagnose. Or perhaps I have misunderstood your question?

RemoveUnits.mw

@dharr Here's the full case that I think better answers your question about the apparent asymmetry that arises from the way the equations are solved, but really the answers are not that different.

restart

local gamma;

gamma

# Consider a system of three equations:  

eq1 := sigma__v^2/(lambda__1*(sigma__v^2/(2*lambda__1^2) + (5*sigma__d^2)/4)):

eq2 := (gamma*sigma__v^2 + 2*lambda__3)*sigma__v^2/(((2*gamma*sigma__v^2 + 8*lambda__2)*lambda__3 + 2*gamma*lambda__2*sigma__v^2)*(2*(gamma*sigma__v^2 + 2*lambda__3)^2*sigma__v^2/((2*gamma*sigma__v^2 + 8*lambda__2)*lambda__3 + 2*gamma*lambda__2*sigma__v^2)^2 + lambda__2^2*(gamma*sigma__v^2 + 4*lambda__3)^2*sigma__d^2/((2*gamma*sigma__v^2 + 8*lambda__3)*lambda__2 + 2*gamma*lambda__3*sigma__v^2)^2 + gamma^2*sigma__v^4*lambda__3^2*sigma__d^2/((2*gamma*sigma__v^2 + 8*lambda__2)*lambda__3 + 2*gamma*lambda__2*sigma__v^2)^2 + sigma__d^2)):

eq3 := (gamma*sigma__v^2 + 2*lambda__2)*sigma__v^2/(((2*gamma*sigma__v^2 + 8*lambda__3)*lambda__2 + 2*gamma*lambda__3*sigma__v^2)*(2*(gamma*sigma__v^2 + 2*lambda__2)^2*sigma__v^2/((2*gamma*sigma__v^2 + 8*lambda__3)*lambda__2 + 2*gamma*lambda__3*sigma__v^2)^2 + lambda__3^2*(gamma*sigma__v^2 + 4*lambda__2)^2*sigma__d^2/((2*gamma*sigma__v^2 + 8*lambda__3)*lambda__2 + 2*gamma*lambda__3*sigma__v^2)^2 + gamma^2*sigma__v^4*lambda__2^2*sigma__d^2/((2*gamma*sigma__v^2 + 8*lambda__3)*lambda__2 + 2*gamma*lambda__3*sigma__v^2)^2 + sigma__d^2)):

Eq1, Eq2, Eq3 := eq1 - lambda__1, eq2 - lambda__2, eq3 - lambda__3:

"non-dimensionalize" Eq 1 by hand. New non-dim variable Lambda__1. End up with no parameters in the equation

Lambda__1 = lambda__1*sigma__d/sigma__v;
isolate(%,lambda__1);
Eqq1:=simplify(eval(Eq1,%))*sigma__d/sigma__v;
solve(Eqq1,Lambda__1);

Lambda__1 = lambda__1*sigma__d/sigma__v

lambda__1 = Lambda__1*sigma__v/sigma__d

(-5*Lambda__1^3+2*Lambda__1)/(5*Lambda__1^2+2)

0, (1/5)*10^(1/2), -(1/5)*10^(1/2)

We can find the non-dimensionalization here by a systematic process, but let's guess Lambda__2 and Lambda__3 are  defined similarly to Lambda__1

{Lambda__2 = lambda__2*sigma__d/sigma__v,Lambda__3 = lambda__3*sigma__d/sigma__v};
ss:=solve(%,{lambda__2,lambda__3});
Eqq2:=numer(normal(eval(Eq2,ss),expanded));
Eqq3:=numer(normal(eval(Eq3,ss),expanded));

{Lambda__2 = lambda__2*sigma__d/sigma__v, Lambda__3 = lambda__3*sigma__d/sigma__v}

{lambda__2 = Lambda__2*sigma__v/sigma__d, lambda__3 = Lambda__3*sigma__v/sigma__d}

-(5*gamma^2*Lambda__2^3*sigma__d^2*sigma__v^2+8*gamma^2*Lambda__2^2*Lambda__3*sigma__d^2*sigma__v^2+5*gamma^2*Lambda__2*Lambda__3^2*sigma__d^2*sigma__v^2-2*gamma^2*Lambda__3*sigma__d^2*sigma__v^2+40*gamma*Lambda__2^3*Lambda__3*sigma__d*sigma__v+32*gamma*Lambda__2^2*Lambda__3^2*sigma__d*sigma__v-4*gamma*Lambda__2*Lambda__3*sigma__d*sigma__v-4*gamma*Lambda__3^2*sigma__d*sigma__v+80*Lambda__2^3*Lambda__3^2-8*Lambda__2*Lambda__3^2)*sigma__v

-(5*gamma^2*Lambda__2^2*Lambda__3*sigma__d^2*sigma__v^2+8*gamma^2*Lambda__2*Lambda__3^2*sigma__d^2*sigma__v^2+5*gamma^2*Lambda__3^3*sigma__d^2*sigma__v^2-2*gamma^2*Lambda__2*sigma__d^2*sigma__v^2+32*gamma*Lambda__2^2*Lambda__3^2*sigma__d*sigma__v+40*gamma*Lambda__2*Lambda__3^3*sigma__d*sigma__v-4*gamma*Lambda__2^2*sigma__d*sigma__v-4*gamma*Lambda__2*Lambda__3*sigma__d*sigma__v+80*Lambda__2^2*Lambda__3^3-8*Lambda__2^2*Lambda__3)*sigma__v

We can divide through by sigma__v, which is in every term, and we see that Gamma = gamma*sigma__v*sigma__d

Gamma = gamma*sigma__d*sigma__v;
sg:=isolate(%,gamma);
Eqqq2:=simplify(eval(Eqq2/sigma__v,sg));
Eqqq3:=simplify(eval(Eqq3/sigma__v,sg));

Gamma = gamma*sigma__d*sigma__v

gamma = Gamma/(sigma__d*sigma__v)

(-5*Gamma^2*Lambda__2-32*Gamma*Lambda__2^2-80*Lambda__2^3+4*Gamma+8*Lambda__2)*Lambda__3^2-8*(Gamma*Lambda__2^2+5*Lambda__2^3-(1/4)*Gamma-(1/2)*Lambda__2)*Gamma*Lambda__3-5*Gamma^2*Lambda__2^3

(-5*Gamma^2*Lambda__3-32*Gamma*Lambda__3^2-80*Lambda__3^3+4*Gamma+8*Lambda__3)*Lambda__2^2-8*(Gamma*Lambda__3^2+5*Lambda__3^3-(1/4)*Gamma-(1/2)*Lambda__3)*Gamma*Lambda__2-5*Gamma^2*Lambda__3^3

alias(alpha=RootOf((Gamma^2 + 4)*_Z^2 + 4*Gamma*_Z + Gamma^2),
beta=RootOf(40*_Z^4 + 36*Gamma*_Z^3 + (9*Gamma^2 - 4)*_Z^2 - 4*Gamma*_Z - Gamma^2),
delta=RootOf((200*Gamma^2 + 800)*_Z^6 + 560*Gamma*_Z^5 + (-24*Gamma^2 - 80)*_Z^4 + (-52*Gamma^3 - 64*Gamma)*_Z^3 + 16*Gamma^2*_Z^2 + 24*Gamma^3*_Z + 5*Gamma^4));

alpha, beta, delta

Solve in both orders - we see that we have the Lambda__2=Lambda__3 solution that we saw before. Lambda__2 and Lambda__3 are swapped, i.e. the apparent complexity depends on the solving order

ans23:=SolveTools:-PolynomialSystem({Eqqq2,Eqqq3},[Lambda__2,Lambda__3],engine=triade);

{Lambda__2 = (1/5)*(-900*Gamma^7*delta^4+8400*Gamma^6*delta^5+9*Gamma^8*delta-876*Gamma^7*delta^2-9328*Gamma^6*delta^3+41520*Gamma^5*delta^4-37600*Gamma^4*delta^5+1330*Gamma^7-700*Gamma^6*delta+152*Gamma^5*delta^2+46464*Gamma^4*delta^3-120960*Gamma^3*delta^4-268800*Gamma^2*delta^5-5360*Gamma^5-11088*Gamma^4*delta+14144*Gamma^3*delta^2+20160*Gamma^2*delta^3+12800*Gamma*delta^4+64000*delta^5+800*Gamma^3+2240*Gamma^2*delta-1920*Gamma*delta^2-6400*delta^3)/(Gamma^4*(27*Gamma^4+148*Gamma^2+160)), Lambda__3 = delta}, {Lambda__2 = beta, Lambda__3 = beta}, {Lambda__2 = -(Gamma^2*alpha+4*Gamma+4*alpha)/(Gamma^2+4), Lambda__3 = alpha}, {Lambda__2 = 0, Lambda__3 = 0}

ans32:=SolveTools:-PolynomialSystem({Eqqq2,Eqqq3},[Lambda__3,Lambda__2],engine=triade);

{Lambda__2 = delta, Lambda__3 = (1/5)*(-900*Gamma^7*delta^4+8400*Gamma^6*delta^5+9*Gamma^8*delta-876*Gamma^7*delta^2-9328*Gamma^6*delta^3+41520*Gamma^5*delta^4-37600*Gamma^4*delta^5+1330*Gamma^7-700*Gamma^6*delta+152*Gamma^5*delta^2+46464*Gamma^4*delta^3-120960*Gamma^3*delta^4-268800*Gamma^2*delta^5-5360*Gamma^5-11088*Gamma^4*delta+14144*Gamma^3*delta^2+20160*Gamma^2*delta^3+12800*Gamma*delta^4+64000*delta^5+800*Gamma^3+2240*Gamma^2*delta-1920*Gamma*delta^2-6400*delta^3)/(Gamma^4*(27*Gamma^4+148*Gamma^2+160))}, {Lambda__2 = beta, Lambda__3 = beta}, {Lambda__2 = alpha, Lambda__3 = -(Gamma^2*alpha+4*Gamma+4*alpha)/(Gamma^2+4)}, {Lambda__2 = 0, Lambda__3 = 0}

Consider the third solution where one solution looks simpler than the other. But after taking allvalues  we see that finally the complexity is the same although it didn't look like it. For this third solution the Lambda's are different (complex conjugates) and complex

ans23[3];
map(simplify,[allvalues(%)]);
ans32[3];
map(simplify,[allvalues(%)]);

{Lambda__2 = -(Gamma^2*alpha+4*Gamma+4*alpha)/(Gamma^2+4), Lambda__3 = alpha}

[{Lambda__2 = -(I*Gamma+2)*Gamma/(Gamma^2+4), Lambda__3 = (I*Gamma-2)*Gamma/(Gamma^2+4)}, {Lambda__2 = (I*Gamma-2)*Gamma/(Gamma^2+4), Lambda__3 = -(I*Gamma+2)*Gamma/(Gamma^2+4)}]

{Lambda__2 = alpha, Lambda__3 = -(Gamma^2*alpha+4*Gamma+4*alpha)/(Gamma^2+4)}

[{Lambda__2 = (I*Gamma-2)*Gamma/(Gamma^2+4), Lambda__3 = -(I*Gamma+2)*Gamma/(Gamma^2+4)}, {Lambda__2 = -(I*Gamma+2)*Gamma/(Gamma^2+4), Lambda__3 = (I*Gamma-2)*Gamma/(Gamma^2+4)}]

NULL

Download NondimshortAllEqns.mw

 

@dharr For the case where lambda__2 = lambda__3, there is always a positive root. The same analysis could also be done for the case where the two lambda's are not set equal.

Edit - actually Descartes rule of signs tells us there must be one positive root no matter what the sign of the term with coefficient 4-9*Gamma^2

Nondimshort.mw

 

@MaPal93 

2. In general I understand, but I thought my commands l1-remove(has, l1, I), l2-remove(has, l2, I), and l3-remove(has, l3, I) would return the complex solutions for the respective lambda, if any exist. Since they all return zero, I thought this meant all solutions were real. Am I wrong? 

has(...,I) is not a good test. Firstly, an expression may have some I's that cancel if the expression is simplify using evalc. more importantly, everything depends on the parameters. Sor example sqrt(1-sigma__v) might be real or complex depending on the values of sigma__v even though there are no explicit I's.

 

3. I am not sure I got you. In your example the two specular equations generate specular elements for a solution. Don't look at your av variable but at your ans variable (i.e., implicit form) instead. In particular, look at your third one (with RootOf):

They are not exactly the same, but the RootOf term is the same (a quadratic). In short, the difference is just a sign and the -1. Instead, I get:

Check output 16 of the new script I already attached to see more clearly.

It is not the convolutedness that surprises me, but the fact that lambda_3 is a quartic in _Z, while lambda_2 is made of some weird combination of (actually the same) quartic and with some randomly looking leading coefficients. My question: is this "asymmetry" plausible from two perfectly symmetric equations? In particular, how can the significant difference in the size of the implicit forms for lambda_2 and lambda_3 be explained?

Respone: I'm not sure which file has the relevant eq 16 in; not the last one you posted?. I expect that if you have the quadratic formula of the  quartic formula, it might look different from the quartic formula on the quadratic formula, even if they are actually the same. (I would solve the quadratic first becuase is is easier to see what the right root might be.) To see if they are the same, choose some random values of the parameters and see if they actually evaluate to the same number.

@Nicole Sharp There are definitely problems with the Units package that Maple is working on. In your last two cases though, the Units package just sees a Maple function Quantity() that if specified might return something with units that weren't the same as those of its arguments.

If q is an expression with units and you want to remove them all, just use eval(q, Unit =1) 

@MaPal93 

  1. What am I doing wrong when solving the reduced form system?
    Nothing, the expressions are just too complicated. You substitute the solution of a quartic into a complicated eqn and then that eq is very complicated.
  2. Am I understanding correctly that, in contrast to the provided example in the answer, only real solutions exist here (even if lambda_2 \= lambda_3)?
    I don't think you can tell much about this.
  3. lambda_2 (l2[1]) and lambda_3 (l3[1]) are pretty much nonspecular (i.e., very different in size and form), while in the example provided in the answer the solutions are specular/very similar to each other, am I wrong?
    In my solution, the stepwise equation get more complicated (admittedly only slightly). I think this is general. Of course if you have the same values they potentially can be simplified to the same thing, but once there are radicals, then that is not easy to do. You also don't know that you have picked out the right roots; they might be different.

You are assuming the first value from allvalues is real, but this will depend on your parameters. Only for numeric coefficients is the first RootOf real (if there is a real root).

240124_specular_equations_nonspecular_solutions_dharr.mw

 

Presumably, the reason that f(0.2342493224)  is not changed to f(0.2342)  is because to get 4 place accuracy in the value of the function might require more than 4 place accuracy in its argument.

@acer Thanks. Obvious in highsight, I should have gone straight to seq.

@Nicole Sharp 

I think that getting different results depending in units present or not does seem strange, as does different results for numbers being expressed in different forms (exact or float). These differences seem to be becuase there is different analysis going on behind the scenes. Those can certainly be considered areas for improvement, but I don't think something can be considered a bug unless it returns the wrong answer. A numerical calculation is expected to have a small error. Since Maple works in the complex domain a small imaginary part is no different from a small error in a real answer, which is why the fnormal and simplify/zero postprocessing seems to me to be the correct way to go.

A similar comment applies to "There should be an option in the Maple settings to instruct Maple that all integrations should only give real results and thus Maple can then automatically try alternative integration methods whenever a non-real result is detected." But what you really mean is "if the integrand is always real then the integral should return real", or otherwise you do not allow for integration involving complex quantities. But a small change to the arguments of some functions in the integrand can make them complex, and then you are back to the same problem. The RealDomain package tries to solve this for some functions (but not int), and does not seem to work as well as might be expected.

There is also the possibility of trying different methods to get a real result. But for a really difficult problem, the time taken for this might be quite long, so you would want this only as an option. Many Maple routines do allow you to specify a list of methods or exclude some methods or exclude symbolic preprocessing (which would perhaps help most here). But for integration, the symbolic part can be powerful, say in detecting singularities that might otherwise be missed and that might be degrading accuracy.

@Nicole Sharp To apply fnormal and simplify/zero to the arguments of Quantity, you need a bit of advanced Maple. If q is the expression containing Quantity(..., ...),, then use

subsindets(q, specfunc(Quantity), x -> map(y->simplify(fnormal(y,23),zero), x));

This means every time we see the specific function Quantity, we apply the procedure given, which receives Quantity(a,b). The map over x does it for each of the ops of Quantity, which are the arguments a and b. For each of these, we apply the procedure y->simplify(fnormal(y,23),zero). For your case this yields

subsindets.mw

First 31 32 33 34 35 36 37 Last Page 33 of 85