acer

33425 Reputation

29 Badges

20 years, 347 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@Mac Dude The issue of whether the sqrts' values are real or imaginary (under assumptions, or whatever) is not a part of what's going on in this example.

There's no combining of sqrts, either with other radicals or wrt to cancellation other factorizable expressions. That's why the symbolic option of either simplify or combine is not the key bit of missing magic here. The sign of what's inside the radical, or branch cut stuff, is just not the difficulty here.

That's why the target rearrangement is tricky to obtain even after one replaces all those multiplicands (including radicals) in the denominators by mere names. See my followups above; that's why I showed them. The issues exist even for expressions that essentially can be represented as one polynomial (of rational coefficients) over another.

And assumptions are directly unrelated here, in consequence.

Rather, your example's issues mostly boil down to just a few things, such as,
1) simplify(...,size) tries to be fast, and so doesn't attempt all possible rearrangements such as those doable via collect (or via other arithmetic operator rearrangements, etc).
2) collect won't collect wrt all things; it can baulk on radicals, reciprocals of radicals, other reciprocals, and so on.


I've been on this ride several times before, over decades. Many years ago I wrote myself a super-compressor utility, that speculatively tried all manner of arithmetic and term-wise rearrangements and factoring and collecting and what have you. And it could make a deep nesting of such command calls. Quite often it beat simplify(...,size), since it didn't have to be fast. (I also wrote it to spit back the sequence of command steps that could reproduce the result.) It's important to remember that getting a completely optimal result can be relatively quite expensive.

Note too that your target form is not optimal in terms of expression "size". It's just quite good. You may get various suggested Answers (some ok, some not ok). But if you're shooting for a specific target form (that might not be optimally "small") then you may need to characterize it's form and nature -- else how could one reliably program for it...

ps. Please understand that the code nm posted is pretty severely flawed. It got your particular example ok, but it also produces completely wrong and invalid results for a large swath of other examples -- some of which are not too far from the form of your example.

I remembered that I'd deliberately used C rather than 1/C for the substitutions above.

But it's also interesting to substitute for 1/C, similarly to how the radicals (power negative 1/2) are treated above.

And we can also notice some variants due to different ordering and simplifier of the collect call.

nb. I have previously noted, elsewhere, that simplify(..,size) doesn't try all (or maybe even any) possible collect choices, speculatively. It's a generally expensive thing to do, blanketing the choices. (I have a crusher that tries them, but in general it's not fast.)

restart;

kernelopts(version);

`Maple 2015.2, X86 64 LINUX, Dec 20 2015, Build ID 1097895`

H := ee->[MmaTranslator:-Mma:-LeafCount(ee),`simplify/size/size`(ee),length(ee)]:

 

vec:=Vector(3, {(1) = 0, (2) = x*z/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-z*ell__1/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-x*z/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))-z*ell__2/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2)), (3) = -s*x/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))+s*ell__1/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))+s*x/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))+s*ell__2/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))}):

H(vec[2]);

[128, 417, 387]

L := [(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(-1/2)=A,(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(-1/2)=B,1/(s^2+z^2)=C];

[1/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2) = A, 1/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2) = B, 1/(s^2+z^2) = C]

foo := subs(L,vec[2]);

-A*C*ell__1*z+A*C*x*z-B*C*ell__2*z-B*C*x*z

collect(foo,[A,B,C],simplify);
eval(%, (rhs=lhs)~(L));
H(%);

(-ell__1*z+x*z)*C*A+(-ell__2*z-x*z)*C*B

(-ell__1*z+x*z)/((s^2+z^2)*(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2))+(-ell__2*z-x*z)/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))

[76, 247, 239]

collect(foo,[A,B,C],factor);
eval(%, (rhs=lhs)~(L));
H(%);

-z*(ell__1-x)*C*A-z*(ell__2+x)*C*B

-z*(ell__1-x)/((s^2+z^2)*(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2))-z*(ell__2+x)/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))

[71, 226, 215]

collect(foo,[C,A,B],factor);
eval(%, (rhs=lhs)~(L));
H(%);

(-z*(ell__1-x)*A-z*(ell__2+x)*B)*C

(-z*(ell__1-x)/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)-z*(ell__2+x)/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))/(s^2+z^2)

[63, 206, 199]

simplify(foo,size);
eval(%, (rhs=lhs)~(L));
H(%);

((x-ell__1)*A-B*(ell__2+x))*C*z

((x-ell__1)/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)-(ell__2+x)/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))*z/(s^2+z^2)

[61, 196, 195]

Download Maple_example_ac3.mw

@nm I see at least five programming problems with that my_simplify procedure.

Alas I don't have time to describe them all. I'll just show that for several kinds of expressions it produces results that are not mathematically the same (or even close) to the original.

restart;

 

my_simplify:=proc(Y)

   map(X->ListTools[Categorize]((t1, t2) -> evalb(denom(t1) = denom(t2)),convert(X,list)), [Y]);

   add(map(X->simplify(add(op(X))),%))

end proc:

 

G:=proc(u, T::anything:=simplify) local P,Q;

           Q:=remove(type,[ifelse(denom(u)::`*`,op(denom(u)),denom(u))],constant);

           P:=( s->s=freeze(s) )~(Q);

           thaw(collect(eval(numer(u),P)/eval(denom(u),P),rhs~(P),T));

end proc:

 

L := [-x/y, -1/3, sqrt(x+y), 1/x+1/y, (s^2+1)/(s*sqrt(p+q)) + (s+t)/sqrt(p+q),
      x*z/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-z*ell__1/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-x*z/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))-z*ell__2/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))];

[-x/y, -1/3, (x+y)^(1/2), 1/x+1/y, (s^2+1)/(s*(p+q)^(1/2))+(s+t)/(p+q)^(1/2), x*z/((ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))-z*ell__1/((ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))-x*z/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))-z*ell__2/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))]

 

my_simplify~(L);

[-2+x+y, 2, 3+x+y, -2+x+y, (s^3*(p+q)^(1/2)+s*(p+q)^(1/2)+(p+q)^(1/2)+s)/(s*(p+q)^(1/2))+(s*(p+q)^(1/2)+t*(p+q)^(1/2)+1)/(p+q)^(1/2), -z*(ell__1-x)/((ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))-z*(ell__2+x)/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))]

The results are not all equivalent to the originals.
They're mostly mathematically invalid. It gets the last one ok,
but not even the second to last which is a sum with radicals in the
denominators.


simplify(L-%);

[-(x*y+y^2+x-2*y)/y, -7/3, -3-x-y+(x+y)^(1/2), -(x^2*y+x*y^2-2*x*y-x-y)/(x*y), -(s^3*(p+q)^(1/2)+(p+q)^(1/2)*s^2+(p+q)^(1/2)*s*t+s*(p+q)^(1/2)-2*s^2-s*t+(p+q)^(1/2)+2*s-1)/(s*(p+q)^(1/2)), 0]

 

G~(L,expand);

[-x/y, -1/3, (x+y)^(1/2), 1/x+1/y, 2*s/(p+q)^(1/2)+t/(p+q)^(1/2)+1/((p+q)^(1/2)*s), (-ell__2*z-x*z)/((ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))+(-ell__1*z+x*z)/((s^2+z^2)*(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2))]

The results are equivalent to the originals (even if not always optionally small -- but then, neither is the OP's target).
They're mathematically valid.

simplify(L-%);

[0, 0, 0, 0, 0, 0]

Download maple_sol_acc.mw

I'll try to explain my line of attack.

restart;

kernelopts(version);

`Maple 2015.2, X86 64 LINUX, Dec 20 2015, Build ID 1097895`


A variety of metrics (decent, ok, and dubious)

H := ee->[MmaTranslator:-Mma:-LeafCount(ee),`simplify/size/size`(ee),length(ee)]:

 

vec:=Vector(3, {(1) = 0, (2) = x*z/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-z*ell__1/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))-x*z/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))-z*ell__2/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2)), (3) = -s*x/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))+s*ell__1/(sqrt(ell__1^2-2*ell__1*x+s^2+x^2+z^2)*(s^2+z^2))+s*x/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))+s*ell__2/((s^2+z^2)*sqrt(ell__2^2+2*ell__2*x+s^2+x^2+z^2))}):


Let's look at just vec[2]

expr := vec[2];

x*z/((ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))-z*ell__1/((ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)*(s^2+z^2))-x*z/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))-z*ell__2/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))

H(expr);

[128, 417, 387]


I'm going to replace all the terms (multiplicands) in the denominator, which happens to be a product.
I'll enter these manually, but I can also easily get them from the denominator using `op`.

L := [(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(-1/2)=A,(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(-1/2)=B,s^2+z^2=C];

[1/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2) = A, 1/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2) = B, s^2+z^2 = C]

foo := subs(L,vec[2]);

x*z*A/C-z*ell__1*A/C-x*z*B/C-z*ell__2*B/C


This seems to be a key part, to collect. (I don't see how you could get to this next result
directly via the `simplify` command. And you can't easiliy collect on the radicals (though
there might be a clever way using `frontend`.) Hence the substitutions.

nb. If I collect wrt [A,B,C] then the `z` gets distributed across the other factor (sum) in
the numerators due to automatic simplification.

goo := collect(foo,[A,B],simplify);

-z*(ell__1-x)*A/C-z*(ell__2+x)*B/C

eval(goo, (rhs=lhs)~(L));

-z*(ell__1-x)/((s^2+z^2)*(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2))-z*(ell__2+x)/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))

H(%);

[71, 226, 215]

hoo := simplify(goo,size);

z*((x-ell__1)*A-(ell__2+x)*B)/C


This is "smaller" than the OP's target expression (by all three metrics, as it happens...).

eval(hoo, (rhs=lhs)~(L));

z*((x-ell__1)/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2)-(ell__2+x)/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))/(s^2+z^2)

H(%);

[61, 196, 195]


Similarly, but targeting only the radicals (since I happen to know they
are multiplicands of the denominator).

P:=(u->u=freeze(u))~(indets(vec[2],radical));

{1/(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2) = `freeze/R0`, 1/(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2) = `freeze/R1`}

thaw(collect(eval(vec[2],P),rhs~(P),simplify));

-z*(ell__1-x)/((s^2+z^2)*(ell__1^2-2*ell__1*x+s^2+x^2+z^2)^(1/2))-z*(ell__2+x)/((s^2+z^2)*(ell__2^2+2*ell__2*x+s^2+x^2+z^2)^(1/2))

 

 

Download Maple_example_ac2.mw

An initialization file can go inside special locations under the folder in which Maple itself is installed.

It can also go inside some special location under a user's personal config files on the OS (the location of which varies by OS).

It is explained in a Help page, the online version of which is here. (That Maplesoft Online Help site might be having certificate issues at present, requiring http rather than safer https access at the momment. The page is also available in Maple own Help browser, under the Help Topic worksheet,reference,initialization  )

ps. some of the replies above show some misconceptions in this (and other) regards.

@Ronan I only suggested that you might not have to add to libname.

And that indeed was your question: "I need to add a library path name to get an old style package .lib to run. Currently a have to manually add the path. How do I solve this?"

I didn't suggest that you do something new/different wrt savelibname. You might need to revise your assignment to it, accordingly (or possibly not assign to it at all, perhaps).

It's quite possible that something inside that eClifford archve package does something with savelibname. If that were the case then I likely wouldn't be able to change what it does.

So you might have to ensure that it were (now) assigned to match the new location that ended with /lib .

It's even possible that something in the package does something crazy and near-unworkable. I wouldn't know what it does, how it was built, what it's internals do (maybe something old-fashioned and no longer necessary such as call readlib), etc.

ps. I don't know why you had savelibname assigned, at all, and you haven't explained why.  Was it part of some magic just to get this eClifford package to run, earlier? Or was it something you do for your own package development? If the latter then I strongly advise not assigning and using savelibname (it's a horrid concept). Instead, I'd just use LibraryTool commands and sane, explicit reference to target archive files.

@C_R Your approach does not account for the fact that the result only needs to agree up to a piecewise constant.

For real x, see the last call in my earlier Reply, where it differs by Pi*I/2.

For method=risch, you can see something where it differs by not just a constant but by a piecewise constant (even for real x).

int(D(tanh)(x),x,method=derivativedivides, method=risch);

   -2/(exp(2*x)+1)

plot(% - tanh(x), x=-7..7, adaptive=false, numpoints=400, style=point);

That's why vv differentiated, before his check. (That's a usual check, since the additive constant disappears.)

@Kitonum Yes, style=surface is a usual way to beautify the implicitplot3d result. Vote up.

Since it's a mere plane, is it not the case that adding the option grid=[2,2,2] for the implicitplot3d call makes it faster to compute and with a much smaller size structure.

@dharr For the range under discussion, could one easily and programmatically get to, say,
    (25*x*y + 5)^(1/5) = (x - y)^(1/4)
or,
    25*x*y + 5 = (x - y)^(5/4)

I mean, we could divide sol2 through by 7, etc.

@Rouben Rostamian  

restart;

ode := diff(y(x), x) = (4*y(x)^2 + x*y(x) + 1)/(4*x^2 + x*y(x) + 1):

ics := y(4/5) = -1/5:

sol:=dsolve([ode,ics], y(x), 'implicit'):

sol:=simplify(eval(sol,y(x)=y)) assuming x>0, 5*x*y>-1;

(7/5)*ln(5*x*y+1)-(7/4)*ln(x-y)+(7/5)*ln(5) = 0

eval(lhs(sol),[x=4/5,y=-1/5]);

0

rngs := x=0..8, y=-1..0.1:
plots:-display(plots:-implicitplot(sol,rngs,color=red,gridrefine=5),
               plots:-implicitplot(5*x*y>-1,rngs,filled,transparency=0.5),
               size=[500,300], gridlines);

Download test_AF2_nm_ac.mw

@nm You simplified under the assumption that y is positive, and have a plot with only y<0.

[edit] The Answer has since changed.

So, how does your simplifying assumption of `positive` relate to the OP's IC  y(4/5)=-1/5 ?

I can almost never get the interrupt button to work using the new GUI ribbon (any version up to Maple 2026.1).

I'm on Ubuntu 24.04 LTS (which is supported).

It doesn't seem to make a difference whether it's trying to interrupt a kernel/Library or GUI output printing.

I don't know why such an important piece of functionality is unfixed.

@Alfred_F 

I used inert Int because I don't want lowercase (active) int to waste time trying to compute the symbolic integral (and failing, only then reverting to numeric quadrature) for each different value used for the `a` parameter. Maple's plotting calls evalf on the Int calls, as a mechnism for directly inducing numeric integration.

I used epsilon=some_float as an error-estimate tolerance for the numeric integration, because at fast double precision evalf(Int(...)) might not always attain a converged numeric integration result (for all `a`). I wanted something quickly. (I suspect it did better than that tolerance, for some `a` ranges. For plotting I usually can't see finer than about 10^-5 discrepancies.)

I used those unapply calls to turn the integrands from expressions into operators. That preempts evalf(Int(...)) from spending time figuring out potential discontinuities or places it might break the integration range into pieces. (It sees the operators more like black-boxes, that it can't properly do symbolic analysis against.) Again, I wanted something quickly.

I used method=_Dexp because 1) I saw it seemed to work, and pretty quickly, and 2) if I'm doing numeric integration for the purpose of comparison I'd like to know method's being used without getting a flood of userinfo messages.

And I passed adaptive = false, numpoints = 200 to the plot command because I wanted an even spread of `a` values (but not too many).

ps. There are sometimes some ways to get GUI zoom to be able to recompute & redraw (here, at finer range of `a` values, say). But I didn't expand on that because I don't find it a programmatically useful approach. Also, it seems impractical for those slow plot calls in your code.

@C_R You're now written,

"Maple AI could not provide an explanation why the call to assign declares the passed names as local names although the arguments of the assign call assign(params) are exactly the same that lead to gobals in my attempts."

But Carl's Answer's method assigns to the names a,b,c,d from the outer scope, and not to any new locals a,b,c,d of the procedure my_assign.

It's clear from your quote that you continue to think the opposite of what is actually happening with respect to globals/locals/etc names a,b,c,d in Carl's Answer's example involving his procedures my_assign.

You've ascribed to special-evaluation technique something about variable-names (local/global/declaration/ect) that did not happen. The reason you didn't understand it is not because you don't understand the evaluation details; it's because something you think happened never actually happened.

That's why I then wrote, in my Reply in that Answer thread, "But that makes it confusing to me since you discussed Carl's Answer's  my_assign procedure, without mentioning that it assigns to the global names." Now I understand why you didn't respond to that sentence. It's because it's claim wasn't understood.

The only local in Carl's Answer's procedure my_assign is the name check (which is used merely to store a not-fully-evaluated  list containing equations involving the names from a higher scope).

Look, in your original Question it was not clear that you were trying to avoid assignment to the globals names. Instead, it looked as if you might be trying to figure out how to successfully pass in a list involving global a,b,c,d more than once, and assign to them as well as then update their assigned values. In that context Carl's code my_assign makes sense; it let's you do that. And the example in his Answer demonstrates exactly that.

Only after that did you explain (in a few Replies) that what you really wanted to do was assign to locals a,b,c,d inside in procedure. So Carl then wrote a second wrapping procedure Foo with its own explictly declared b,c,d and have that Foo pass in a list involving those explicitly declared locals to his my_assign. But note that his Foo never got passed in a list from the outer top-level, so it doesn't handle was appears (to me) to be your actual use-case involivng a passed list from elsewhere. The locals in Foo are explicitly declared there(!), and the list is constructed there. There's no hidden "rule" at work. and no magic construction of new locals on-the-fly, etc.

Note that the list of equations in Carl's Foo example there contains the locals b,c and the global d. And the list is created inside Foo, not passed in.

Only then, with new knowledge that you didn't want to affect globals, while still passing in the equations b=..,etc from the higher level, Carl wrote a third routine foo that accepted four separate keyword parameters for each of a,b,c,d.

@Ronan It's not clear to me with what you're agreeing, sorry.

Note that in my Answer I gave code that accepted a set of any number (including zero) or both 3-element lists and 3-element column Vectors.

But it seems now that you're saying that there must be exactly one (and only one) of each type. So here is code for that.

I use a list to contain the two. But see also the proc example.

restart;

TypeTools:-AddType(_L3DP,{[[algebraic$3],'Vector[column](3,algebraic)'],
                           ['Vector[column](3,algebraic)',[algebraic$3]]});


Strictly two elements. Either order is accepted. One of each: a 3-element list, and a 3-element Vector.

type([[7,8,9],<1,2,3>],_L3DP);

true

type([<1,2,3>,[7,8,9]],_L3DP);

true

type([[a,b,c],[7,8,9],<1,2,3>],_L3DP);

false

type([[a,b,c],[7,8,9]],_L3DP);

false


Usage example:

F := proc( L::_L3DP ) local S:={L[]};
    return S[1], S[2];
end proc:

 

F( [<1,2,3>,[7,8,9]] );

[7, 8, 9], Vector(3, {(1) = 1, (2) = 2, (3) = 3})

F( [[7,8,9],<1,2,3>] );

[7, 8, 9], Vector(3, {(1) = 1, (2) = 2, (3) = 3})

Download Ronan_TT2.mw

1 2 3 4 5 6 7 Last Page 1 of 612