Carl Love

Carl Love

27599 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

I've found it useful to have a verifcation constructor &under just like the longstanding type constructor &under.

restart:

interface(prompt= ""):

#We model a verification constructor on this type constructor:
showstat(`type/&under`);


`type/&under` := proc(expr, theType, f)
   1   type(f(expr,_rest),theType)
end proc
 

VerifyTools:-AddVerification(
    #I'm using Maple < 2024 symbol=procedure syntax rather than Maple 2024
    #(symbol,procedure) syntax:
    `&under`= ((a,b,v::verification,f)-> verify(f(a,_rest), f(b,_rest), v))
);
#And just because I think it's ridiculous to spell out "less_than" in any
#computer code...:
VerifyTools:-AddVerification(`<`= ((a,b)-> verify(a,b,less_than)))
;

#So Austin's examples become these, reducing the need for ad hoc
#verifications such as length_not_increased:
verify(x+1/x, (x^2+1)/x, `<` &under length);

true

verify((x^2+1)/x, x+1/x, `<` &under length);

false

#Next we model the syntax e::t  =>  type(e,t) for verifications. It's not
#allowed to overload `::`, nor is `&::` allowed as an infix operator, so
#I'll settle for `&:`:
`&:`:= verify
:

#Now the examples can be written thus:
(x+1/x, (x^2+1)/x) &: (`<` &under length);

true

((x^2+1)/x, x+1/x) &: (`<` &under length);

false

 

Download VerifyUnder.mw

Could the kernel be modified so that when (a,b)::v is used in a boolean context, verify(a,b,v) would be invoked?

@Oliver Munk To check or set your Autosave status, go to Tools ==> Options from the main menu.

To load a Backup file, go to Files ==> Restore Backup.

@Exiu The best first step towards understanding a Maple data structure is to look at it with lprint, and this is often all that's needed to understand it.

lprint(f);
Sum((1/2-1/2*_alpha)/(x-_alpha),_alpha = RootOf(_Z^2+1))+Sum(1/4*_alpha/(x-
_alpha),_alpha = RootOf(_Z^2+2))

From this we see that Sum is a function (in the Maple sense), the 2nd argument of each function contains the RootOf, and the 1st argument contains the expression whose numertaor and denominator you want..

`&<`:= curry:
[op&<[2,2], [numer, denom] @ op&<1]~(indets(f, specfunc(Sum)));

 
{[RootOf(_Z^2+1), [-1+_alpha, -2*x+2*_alpha]], [RootOf(_Z^2+2), [-_alpha, -4*x+4*_alpha]]}

The command allvalues can be used to make RootOfs explicit, when it's possible to do that. Thus allvalues(f) returns the same thing as @vv 's convert(f, radical).
 

 

@mmcdara I don't know if this is true in the Maple 2015 that you use, but it has been true at least for several years: Unit is exactly the same command as Units:-Unit, regardless of whether the Units package is loaded. This just saves some typing; there's no problem with spelling out Units-Unit if you wish. I can't find documentation for this, but it can be confirmed by

restart:
eval(Unit);

               
proc () Units:-Unit(args) end proc

@DJJerome1976 

plots:-polarplot(
    4, thickness= 3, 
    coordinateview= [0..6, 0..2*Pi], axis[2]= [tickmarks= [8, subticks= 2]]
);

@Thomas Richard The help page (?Student,NumericalAnalysis,MatrixDecomposition) phrase "... using the Crout factorization algorithm for tridiagonal matrices" is poorly worded and hence a bit misleading. The Crout algorithm itself is not restricted to tridiagonal matrices; rather, the help page is trying to say that this command's implementation of that algorithm is limited to tridiagonal matrices. See the subsection "LU Crout decomposition" of the Wikipedia page "LU decomposition".

With a tiny additional step, you can convert your LDU decomposition to a Crout: Set L:= L.D. However, by using transposes as shown in my Answer, the slight extra computation of factoring the from can be avoided.

@nm For some reason that I don't understand, the assumption that the argument of ln is positive isn't enough. If you also assume _C1 < 0, it'll work.

odetest will also work for an explicit separable solution by using the right assumptions. I'm just pointing this out because it's true, not because I think the separable solution is better. I understand why the d'Alembert solution is better.

restart:

ode:= y(x) = x + 3*ln(diff(y(x), x)):

It's not necessary to use an initial condition for this. I just do it to ensure that the constant of integration

is the same in my two solutions. However, note that my initial condition is completely arbitrary.

ic:= y(x0)=y0:

ivp:= {ode, ic}:

Solution by dsolve(..., [separable]) and verification with odetest:

sol1:= dsolve(ivp, [separable]);

y(x) = -3*ln(-exp(-(1/3)*x0)+exp(-(1/3)*y0)+exp(-(1/3)*x))

assmp:= sol-> ((x,x0,y0)::~real, op(indets(sol, specfunc(ln))[]) >~ 0):

odetest(sol1, ivp) assuming assmp(sol1);

{0}

"By-hand" solution via Calc II separable technique:

eq1:= expand(eval(solve(ode, diff(y(x),x)), y(x)= y));

exp((1/3)*y)*exp(-(1/3)*x)

(ys,xs):= selectremove(has, eq1, y);
solgen:= solve(int(1/ys, y) = int(xs, x) + C, y);

exp((1/3)*y), exp(-(1/3)*x)

3*ln(-3/(-3*exp(-(1/3)*x)+C))

sol2:= (simplify@eval)(
    y(x) = solgen,
    solve({rhs(ic) = eval(solgen, x= op(lhs(ic)))}, C)
);

y(x) = 3*ln(1/(-exp(-(1/3)*x0)+exp(-(1/3)*y0)+exp(-(1/3)*x)))

odetest(sol2, ivp) assuming assmp(sol2);

{0}

Verify equivalence of solutions:

simplify(rhs(sol1-sol2)) assuming assmp(sol2), assmp(sol1);

0

 

Download DsolveSeparable.mw

@Andiguys Yes, you can include any number of inequalities in the first argument to solve. Using them has no effect on the number-of-equations-versus-number-of-variables issue. (You can't use inequalities with eliminate.) For example,

sol:= solve({tau = `&tau;opt`, lambda = `&lambda;opt`, Rem > Rom}, {w, Clm});

(`&tau;opt` is the correct way to write tauopt in 1D input (Maple Notation); I incorrectly put tauopt in the Answer above. This comment doesn't matter if you're using 2D Input, which seems to be the case.)

This type of solution (see ?solve,parametric and ?SolveTools,Parametric) very often takes a long time. The solution is returned as a piecewise structure that is often too wide to be easily read. In that case, it helps to use lprint:

lprint(sol);

The returned form will be 

piecewise(condtion[1], [solution[1]], ..., condition[n], [solution[n]], [otherwise_solution]),

where each condition is an inequality, an equation, or several such in disjunctive normal form, i.e., 

Or(And(ineq[1][1], ..., ineq[1][k[1]]), ..., And(ineq[n][1], ..., ineq[n][k[n]])),

and otherwise_solution is the solution (often empty) if all the conditions are false. Note that each solution is presented as a list, even if it's a singleton. Thus, the kth condition can be extracted via op(2*k-1, sol) and its corresponding solution via op(2*k, sol)[]. The otherwise_solution can be extracted via op(-1, sol)[].

There is an asymmetry between your procedures and above that I find odd. I'd like you to check whether it's correct. In B, the term b2*(s2+h) occurs in in both factors of the denominator, and the similar term b1*(s1+v) also occurs once. In A, there are three distinct such terms: b1*(s1+h)b2*(s2+v), and b1*(s1+v). So, are those correct?

I confirm that I frequently encounter this bug in all Maple versions starting with Maple 2021, using either Windows 10 or Windows 11. This is not a rare bug for me. It happens roughly 30% - 50% of the time that I try to use a context menu.

@C_R The use of ? like an alphabetic letter in symbols is described in the very first sentence of help page ?nameI tend to use it as the last letter of the name of a procedure (including type checks) that returns true or false.

@zenterix You are correct: The 2nd argument to simplify will only be interpreted as side relations if it is a set or a list.

 

@C_R My guess is that FileTools hasn't kept up with file system changes made for Windows 11. The problem is that there are secret system "files" that are listed in directories, yet they don't "exist" by whatever criterion is used to determine existence. I don't know if this is new to Windows 11.

Anyway, the problem is easy to work around: We only check files and directories for which both FileTools:-Exists and FileTools:-IsReadable return true. Here's some code for it:

AllFiles:= module()
uses FT= FileTools;
local
    Q, dirs, DirsRead, files, Selected, Files, CurDir, time0, time1,   
    Readable?:= f-> FT:-Exists(f) and FT:-IsReadable(f), 
    Report:= proc(RepIntv)
        Files+= nops~([files, Selected]);
        if (time1:= time[real]()) - time0 > RepIntv then
            time0:= time1;
            printf(
                "Current dir: %s\n"
                "Dirs checked: %-7d  Dirs stacked: %-7d  "
                "Files checked: %-7d  Files selected: %-7d\n\n",
                CurDir, DirsRead, numelems(Q), Files[]
            )
        fi
    end proc,
    ModuleApply:= proc(base::string:= "", ext::string:= "mw", {RepIntv::nonnegint:= 15})
    local Wanted?:= f-> FT:-Extension(f) = ext;
        Q:= DEQueue(base);
        Files:= [0,0];
        time0:= time[real]();
        [
            for DirsRead do
                (dirs, files):= selectremove(
                    FT:-IsDirectory, 
                    select(Readable?, FT:-ListDirectory((CurDir:= back(Q)), 'absolute'))
                );
                Selected:= select(Wanted?, files);
                pop_back(Q);  Q,= dirs[];
                if RepIntv <> 0 then Report(RepIntv) fi;              
                Selected[]
            until empty(Q)
        ]
    end proc
;
end module
:

F:= AllFiles():

Current dir: C:\\Windows\WinSxS\Temp\InFlight\50b12bd18ca6da016e0700007868d418\wow64_microsoft-windows-s..ity-netlogon-netapi_31bf3856ad364e35_10.0.22621.3085_none_bda3256405ca58e6
Dirs checked: 23640    Dirs stacked: 12102    Files checked: 11452    Files selected: 0      

Current dir: C:\\Windows\WinSxS\Manifests
Dirs checked: 50587    Dirs stacked: 10235    Files checked: 31094    Files selected: 0      

... many lines omitted ...

It takes about an hour for it to work through the 100,000+ "existing" and "readable" directories on my computer.

Can someone please check whether this code works on Linux and/or Apple?

All of the actual work can be done by the following code; everything else above is just to display the status updates:

AllFiles:= proc(base::string:= "", ext::string:= "mw")
uses FT= FileTools;
local
    Q:= DEQueue(base), dirs, files, 
    Readable?:= f-> FT:-Exists(f) and FT:-IsReadable(f),
    Wanted?:= f-> FT:-Extension(f) = ext
;
    [
        do
            (dirs, files):= selectremove(
                FT:-IsDirectory, 
                select(Readable?, FT:-ListDirectory(pop_back(Q), 'absolute'))
             );
             Q,= dirs[];
             select(Wanted?, files)[]
         until empty(Q)
    ]
end proc
:

 

I think that it would be easy to automate this by using FileTools:-ListDirectory to find all "*.mw" files on one's computer and then using eBookTools:-CreatePDF to make PDFs from them.

First 8 9 10 11 12 13 14 Last Page 10 of 703