acer

32313 Reputation

29 Badges

19 years, 316 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@dojodr You are the one who asked for the symbolic solution, so only you know what you wanted to do with it.

Here are some alternatives:

restart;

eq := A=P*(1+r/n)^(n*t);

A = P*(1+r/n)^(n*t)

# First way: plug in values for r and t,
# and then call `solve`.

eval(eq, [r=0.05,t=8]);
solve(%,n);

A = P*(1+0.5e-1/n)^(8*n)

-.2500000000*ln(A/P)/(2.*LambertW(-2.500000000*ln(A/P)/(A/P)^(5/2))+5.*ln(A/P))

# more general form
ans:=combine(simplify(evalindets(solve(eq,n,allsolutions),
                                 suffixed(_Z),u->0)));

-r*ln(A/P)/(LambertW(-ln(A/P)*(A/P)^(-1/(r*t))/(r*t))*r*t+ln(A/P))

# Plug in same values as before, and
# get same result (in a different way).

eval(ans, [r=0.05,t=8]);

-0.5e-1*ln(A/P)/(.40*LambertW(-2.500000000*ln(A/P)/(A/P)^2.500000000)+ln(A/P))

# Plug in numeric values for all parameters,
# and compute as floating-point with `evalf`.

evalf(eval(ans, [P=5,A=10,r=0.05,t=8]));

-0.7086797315e-1

# Alternatively, plug same values for parameters
# into the original equation, and then solve
# numerically with `fsolve`.

eval((rhs-lhs)(eq), [P=5,A=10,r=0.05,t=8]);
fsolve(%);

5*(1+0.5e-1/n)^(8*n)-10

-0.7086797317e-1

 

Download solve_ex2b.mw

As demonstrated above, you could numerically solve (fsolve) for n if all the other parameters are substituted with numeric values.

Or you could plug such numeric values for the parameters into the more symbolic solution ans.

So you might not actually need the symbolic form ans. (You asked about such a solution, which is why I showed how one such might be obtained programmatically. Only you know why you requested it.)

If you do want to deal with that symbolic solution then you cannot simply "disregard" the LambertW or another part of the symbolic expression that you might not fully understand or enjoy.

The command LambertW is a special function that expresses a solution to a special kind of equation. You probably are familiar with other special functions that express other mathematical relationships, eg. sin(x), cos(x). But because some others are so familiar you may overlook/forget that they're made-up names that act as stand-ins for the more complicated mathematical relationships.

@Rouben Rostamian  One could tweak this kind of thing,

H := E->subsindets(E, `*`,
                   u->foldl((ee,v)->frontend(combine,[ee],
                                             [{`+`,`*`,
                                               specfunc(identical(v),
                                                        {sin,cos})},{}]),
                            u, `union`(op~(indets(u,specfunc({sin,cos}))))[])):

 

4*sin(x)*cos(x)*sin(y)*cos(y);
H( % );
simplify(expand(% - %%));

4*sin(x)*cos(x)*sin(y)*cos(y)

sin(2*x)*sin(2*y)

0

3*sin(z)*cos(z);
H( % );
simplify(expand(% - %%));

3*sin(z)*cos(z)

(3/2)*sin(2*z)

0

sqrt(7*exp(1)*sin(z+p)*cos(z+p)*sin(x)^2*cos(x)^2*(2*cos(y)^2-1));
H( % );
simplify(expand(% - %%));

7^(1/2)*(exp(1)*sin(z+p)*cos(z+p)*sin(x)^2*cos(x)^2*(2*cos(y)^2-1))^(1/2)

7^(1/2)*(-(1/16)*exp(1)*cos(2*y)*(cos(4*x)-1)*sin(2*z+2*p))^(1/2)

0

Download trig_comb_sep.mw

There are interesting examples where a shortest (simplest) form can be attained by applying combine after repeatedly and selectively freezing only some of the trig terms. (Somewhere I have a variant of a "crusher" appliable-module which -- expensively -- tries combinations of such things, in a search for a shortest form.)

@mmcdara Increased memory use can be a consequence of running multiple computations in parallel. It's not necessarily a consequence only of using multiple kernels in parallel.

Even when you run multiple threads in parallel (in the same kernel) they might each get some local allocation. It depends on the nature of the computation. I just happen more often to use Threads for numeric Array computations that can often each be done "in-place" on specific portions of a preassigned hardware rtable container. So usually I don't happen to see additional memory consumption according to the number of threads. But that's just due to the kinds of computations I more often do.

I don't think that I can act in-place when using Grid, and I've also noticed a marked slowdown if a passed rtable if "too big". But sure, often there is a natural give-and-take between speed and memory consumption.

It's hard to make general statements: much of all this is problem specific.

@mmcdara The Grid package uses distinct instances of the Maple kernel (engine) for each node, with no cross-pollution of memory or assignments. Thus the issue of thread safety of the code is ameliorated.

The Threads package uses the same instance of the Maple kernel (engine) for all threads. So any code which relies (even indirectly, via whatever Library commands it calls) on global state is potentially thread-unsafe. And thread-unsafety cascades. So, for example, any Thread-ed code that calls symbolic-definite int is thread-unsafe because limit is thread-unsafe.

Many (if not most) important Library commands for symbolic computation are thread-unsafe. The situation is better for kernel builtin commands, but those are a minority.

Hence I typically use Threads only for purely numeric code that I can also run under evalhf or Compile. That is to say, code the calls few (if any) commands for symbolic computation.

@rlopez Thanks, Robert.

with(VectorCalculus): SetCoordinates('cartesian'[x,y]):

 

TangentLine(7*x^2-7*y^2-12.0*x+9.0*y+2.25-2*x*y=0,
            <0.504244923, 0.3781836925>);

-5.696938463*x+1.852714152+2.696938459*y = 0

isolate(%,y);

y = 2.112372436*x-.6869693841

Download hyp_tangVC.mw

@Mariusz Iwaniuk Ingenious.

Paraphrasing, and using Maple 2021.2,

restart;

kernelopts(version);

`Maple 2021.2, X86 64 LINUX, Nov 23 2021, Build ID 1576349`

H:=int((x*(1-x)*(-epsilon*I+p^2)+m^2)^((d-4)/2), x=0..1);

int((x*(1-x)*(-I*epsilon+p^2)+m^2)^((1/2)*d-2), x = 0 .. 1)

ans:=eval(evalindets(simplify(map(convert, subs(-epsilon*I+p^2=A,H),
                                  Sum, expansionvariable=A)),
                     specfunc(Sum), s->sum(op(s),formal)),
          A=-epsilon*I+p^2) assuming m>0;

m^(d-4)*hypergeom([1, -(1/2)*d+2], [3/2], -(1/4)*(-I*epsilon+p^2)/m^2)

eval(ans,[epsilon=1/100,d=3,m=1,p=1]);
evalf(%);
simplify(%%);
evalf(%);

hypergeom([1/2, 1], [3/2], -1/4+(1/400)*I)

.9272944444+0.6364749769e-3*I

20*arctan((1/20)*(100-I)^(1/2))/(100-I)^(1/2)

.9272944444+0.6364749776e-3*I

evalf(eval(Int((x*(1-x)*(-epsilon*I+p^2)+m^2)^((d-4)/2), x=0..1),
           [epsilon=1/100,d=3,m=1,p=1]));

.9272944444+0.6364749769e-3*I

integral_ac.mw

Since the OP seems to have used Maple 18 (in which Sum doesn't take formal as an option),

restart;

kernelopts(version);

`Maple 18.02, X86 64 LINUX, Oct 20 2014, Build ID 991181`

H:=int((x*(1-x)*(-epsilon*I+p^2)+m^2)^((d-4)/2), x=0..1);

int((x*(1-x)*(-I*epsilon+p^2)+m^2)^((1/2)*d-2), x = 0 .. 1)

ans:=eval(value(simplify(map(convert,
                             subs(-epsilon*I+p^2=A,H),
                             Sum,expansionvariable=A))),
          A=-epsilon*I+p^2) assuming m>0;

m^(d-4)*hypergeom([1, -(1/2)*d+2], [3/2], -(1/4)*(-I*epsilon+p^2)/m^2)

evalf(eval(ans,[epsilon=1/100,d=3,m=1,p=1]));

.9272944444+0.6364749769e-3*I

evalf(eval(Int((x*(1-x)*(-epsilon*I+p^2)+m^2)^((d-4)/2), x=0..1),
           [epsilon=1/100,d=3,m=1,p=1]));

.9272944444+0.6364749769e-3*I

Download integral_ac_1802.mw

@C_R For your following example I wan't sure whether you wanted to 1) turn either expression into the other, or 2) show that they are equivalent. All under an assumption, of course.

Here's both, under the wider assumption r>=-1.

restart;

ee1 := -sqrt(r^2-1)/(r-1);

-(r^2-1)^(1/2)/(r-1)

ee2 := -sqrt(r+1)/sqrt(r-1);

-(r+1)^(1/2)/(r-1)^(1/2)

The following turns ee1 into ee2 under the assumption r>=-1.

conds:=map(u->`if`(`assuming`([is(u>=0)],[r>=-1]),freeze(u)>0,NULL),
           [indets(factor(ee1),`+`)[]]): thaw(conds);
new:=subsindets(factor(ee1),`+`,freeze):
thaw(`assuming`([simplify(new)],conds));

[0 < r+1]

-(r+1)^(1/2)/(r-1)^(1/2)

The following turns ee2 into ee1 under the assumption r>=-1.

simplify(rationalize(combine(ee2))) assuming r>=-1;

-(r^2-1)^(1/2)/(r-1)

simplify(combine(ee2-ee1)) assuming r>1;

0

simplify(combine(ee2-ee1)) assuming r>=1;

0

simplify(combine(ee2-ee1)) assuming r>-1;

0

plot([Re,Im](ee2-ee1),r=-2..2,
     thickness=3,style=[point,line],color=[red,blue],
     symbol=solidcircle,symbolsize=15,
     adaptive=false,numpoints=40, size=[600,100]);

Download some_simp_ex.mw 

On the chance the you were actually trying to make ee1 turn into ee2, here's a more ad hoc and step-by-step explanation of what I did above. I say "ad hoc" because it contains assumptions placed manually on r+1 and r-1, whereas in the above worksheet I tried to make it more programmatic, deriving those assumptions on terms r+1 and r-1 (multiplicands in the factored radical) from assumptions like r>=-1 or r>=1 say. A wholly ad hoc solution to a problem like this no better than merely writing out the desired form by hand.

The idea is that simplify can pull out factors from the radical (under suitable assumptions). But collapse of the factored form back to r^2-1 gets in the way. So an approach is to replace factors by their frozen names, and place the corresponding assumptions of positivity on such (if appropriate). Making that replacement more automatic and less ad hoc is icing.

restart;

ee1 := -sqrt(r^2-1)/(r-1);

-(r^2-1)^(1/2)/(r-1)

ee2 := -sqrt(r+1)/sqrt(r-1);

-(r+1)^(1/2)/(r-1)^(1/2)

factor(ee1);
temp := subs(r+1=freeze(r+1),%);
# next step uses r>=-1, implicitly
simplify(temp) assuming freeze(r+1)>=0;
thaw(%);
# note:
simplify(numer(temp)) assuming freeze(r+1)>=0;

-((r-1)*(r+1))^(1/2)/(r-1)

-((r-1)*`freeze/R0`)^(1/2)/(r-1)

-`freeze/R0`^(1/2)/(r-1)^(1/2)

-(r+1)^(1/2)/(r-1)^(1/2)

-`freeze/R0`^(1/2)*(r-1)^(1/2)

factor(ee1);
temp := subs([r+1=freeze(r+1),r-1=freeze(r-1)],%);
# next step uses r>=-1 and r>=1 implicitly
simplify(temp) assuming freeze(r+1)>=0, freeze(r-1)>=0;
thaw(%);
# note:
simplify(numer(temp)) assuming freeze(r+1)>=0, freeze(r-1)>=0;

-((r-1)*(r+1))^(1/2)/(r-1)

-(`freeze/R1`*`freeze/R0`)^(1/2)/`freeze/R1`

-`freeze/R0`^(1/2)/`freeze/R1`^(1/2)

-(r+1)^(1/2)/(r-1)^(1/2)

-`freeze/R1`^(1/2)*`freeze/R0`^(1/2)

Download some_simp_ex_notes.mw

@C_R You may use any of the following.

restart

expr := Ei(sqrt(r+1)*sqrt(1/(r-1))) = Ei(-sqrt(r^2-1)/(r-1))

Ei((r+1)^(1/2)*(1/(r-1))^(1/2)) = Ei(-(r^2-1)^(1/2)/(r-1))

`assuming`([is(combine(expr))], [0 < r and r < 1])

true

`assuming`([is(combine(expr))], [0 < r, r < 1])

true

`assuming`([(`@`(is, combine))(expr)], [0 < r and r < 1])

true

`assuming`([(`@`(is, combine))(expr)], [0 < r, r < 1])

true

`assuming`([is(combine(expr))], [And(0 < r, r < 1)])

true

``

Download Simplify_exp_with_roots_02_ac.mw

I prefer not to use the 2D Input that looks like,
   0<r<1
because it gets parsed as  0<r and r<1   and I prefer to avoid lowercase and here.

sidebar: I have seen instances where calling is((rhs-lhs)(eqn)=0) does better than is(eqn) for eqn some equation. That step may not always have been done automatically (at least historically), and simplification-to-zero is sometimes easier than reduction to a pair of forms accepted as equivalent.

Duplicates threads about this code will be flagged as such (and may be deleted).

If you have additional problems with correcting the code then you could describe those here, in Reply/Comments, instead of adding wholly separate and unconnected additional discussion threads.

@Ronan It looks as if you might have accidentally saved your own packages to that DirectSearch.mla file at some time in the past.

One way that could happen is if you used `savelib`, and it was writable and first in `libname`. 

This is one reason why I prefer to store to .mla files only by using LibraryTools:-Save (not savelib) and specifiy the library file destination explicitly.

You may wish to (remove and) reinstall a clean instance of DirectSearch v.2.

@tomleslie I could get around that abs error by a slight adjustment to Carl's code (but without having to raise Digits or set UseHardwareFloats=false, etc).

Eg,

restart:
ABS:= (a,b,c)-> [a-b*c <= k*c, a-b*c >= -k*c]:
(L,M,U):= seq([cat](x, __, 1..3), x= [l,m,u]):
Cons:= 
    (op@ABS)~(
        map(op@index, [L,M,U], [1,1,2]),
        [.67, 2.5, 1.5, 1, 3, 2, 1.5, 3.5, 2.5],
        map(op@index, [U,M,L], [2,3,3])
    )[],
    add(L) + 4*add(M) + add(U) = 6,
    (L <=~ M)[], (M <=~ U)[]
:
Sol:= Optimization:-NLPSolve(k, {Cons}, assume= nonnegative)[2]:
evalf[5](Sol);

    [k = 0.23607, l__1 = 0.40747, l__2 = 0.31246, l__3 = 0.16437, 

     m__1 = 0.45430, m__2 = 0.36753, m__3 = 0.16437, u__1 = 0.54121, 

     u__2 = 0.44972, u__3 = 0.17998]

@C_R You might be interested to know that there are some common terms for some of these things.

Your examples may be considered as functional programming (in Maple). Good examples are scarce in the Help pages, eg. 1, 2. Basically, Maple allows for a quite useful functional syntax.

Sometimes elements of this are called functional operators but that's a slight misnomer here since functional programming can cover a broader flavour of procedure than just an operator -- in Maple's technical sense.)

I too am a fan of using an anonymous procedure (or some concoction from a functional algebra) when I want to make convenient multiple references to the same thing, from within a single statement.

Depending on who you're talking to, you might hear some comparison of such anonymous procedure use in Maple with pure functions in Mma.

@C_R You're welcome. Here it is again, and below a slightly more involved alternative, for your information:

[Int(1/sqrt(x), x), 'int(1/sqrt(x), x)', 'sin(1.2)', 'cos((1/6)*Pi)']

[Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)]

 

The original approach:
((proc (x::uneval) options operator, arrow; x end proc) = value)([Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)])

[Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)] = [2*x^(1/2), 2*x^(1/2), .9320390860, (1/2)*3^(1/2)]

 

We could alternatively have applied the identity  x->x
along with value@eval (which calls value after calling eval).

Both sides of the equation get applied to the result of
1-level evaluation of the reference.
((proc (x) options operator, arrow; x end proc) = `@`(value, eval))(eval([Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)], 1))

[Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)] = [2*x^(1/2), 2*x^(1/2), .9320390860, (1/2)*3^(1/2)]

 

Notes on how the alternative works:

The reference, with full evaluation:
[Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)]

[Int(1/x^(1/2), x), 2*x^(1/2), .9320390860, (1/2)*3^(1/2)]

The reference, but with 1-level evaluation:
eval([Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)], 1)

[Int(1/x^(1/2), x), int(1/sqrt(x), x), sin(1.2), cos((1/6)*Pi)]

NULL

Download expr_equals_evalexpr_acc.mw

@tomleslie My Maple 2021.2 and Maple 2021.1 for Linux both have this command result,

interface(typesetting);

              standard

Curiously, the GUI's menubar's Tools->Options/Display shows "Extended" for the "Typesetting level" item.

I have previously noted that, and found it a weirdly confusing state of affairs in Maple 2021, and supposed that it was an intentional change (whose ramifications I don't really grok). I have not changed the GUI's setting away from default, on installation. And I launch Maple without any initialization file.

Anyway... if I manually make the call,

   interface(typesetting=extended):

then I can reproduce the undesired rendering that you showed. But by default I get it as I showed it.

@mmcdara Suppose that one has a preassigned list of strings L of length m*n (not all entries the same, say).

Then there are a variety of other ways in which one could construct m-by-n Matrix without having to manually enter the columns or rows (ie. as individual lists). And one could place the entries column-wise or row-wise, without having to transpose.

For amusement, here are some examples. (Not an exhaustive collection...)

restart;
interface(rtablesize=100):
with(ListTools,LengthSplit):
(m,n):=4,6;
L:=[$"a".."z"][1..m*n];
Matrix([LengthSplit(L,2)]);
Matrix([LengthSplit(L,m)]);
ArrayTools:-Reshape(Vector(L),[m,n]);
Matrix([seq(L[(i-1)*m+1..i*m],i=1..iquo(nops(L),m))]);
Matrix([seq(L[[seq((i-1)*m+j,i=1..iquo(nops(L),m))]],j=1..m)]);

The OP has also mentioned,
   Matrix(m, n, (i, j)-> L[j+n*(i-1)])
for one of the flavours laying down entries row-wise, ie. like my,
   Matrix([LengthSplit(L,n)])
Both are easy, and fine. (I sometimes have an internal resistance to using a user-defined procedure which might get called many times, if I can get by with seq and indexing. That's just me. It doesn't matter here, and it avoids production of collectible garbage sublists.)

First 112 113 114 115 116 117 118 Last Page 114 of 591