See http://www.maplesoft.com/applications/view.aspx?SID=1533&view=html&L=G
use select. For example
>restart; >my_list:=[1,3.4,3+I,5]; >select(x->evalb(Im(x)=0),my_list); [1, 3.4, 5]
restart; m:=Matrix( [[1.3,2,3],[3,4,4] ]); matrixTestQ := proc(m::Matrix) local r,c,i,j; (r,c):=LinearAlgebra[Dimensions](m); for i from 1 to r do for j from 1 to c do if( not evalb( whattype(m[i,j]) = integer) ) then return(false); end if; end do; end do; return true; end proc; >matrixTestQ(m); false
I am sure there is a better way than the above. Need to find out.
Given
Find terms that are sqrt. Use indets
restart; expr_with_radical:= 3+x+sqrt(b^2-4*a*c)+sin(y)+x^3*sqrt(39)+sqrt(cos(x));| indets(expr_with_radical, algebraic^fraction)
\( \{ \sqrt {39}, \sqrt {-4 a c +b^{2}}, \sqrt {\cos }x \} \)
Alternative is to use type radical
restart; expr_with_radical:= 3+x+sqrt(b^2-4*a*c)+sin(y)+x^3*sqrt(39)+sqrt(cos(x));| indets(expr_with_radical, radical)
\( \{ \sqrt {39}, \sqrt {-4 a c +b^{2}}, \sqrt {\cos }x \} \)
I wanted to simplify an expression which could have csgn()
in it, and find all the
arguments.
One way is
restart; expr:=(1+csgn(a)*a)/(3*csgn(b)*b): expr:=subsindets(expr,'specfunc( anything, csgn )',f->1);
Given sol:=1/2*2^(1/2)*csgn(x)*x*csgn(y);
how to find all symbols inside csgn which
will be \(x,y\) in this case?
restart; sol:=1/2*2^(1/2)*csgn(x)*x*csgn(y); indets(sol,'specfunc( anything, csgn )'); vars:=subsindets(%,'specfunc( anything, csgn )',f->op(f))
Gives {x, y}
Now if we want to simplify the above solution by assuming that all variables inside vars
are
positive, how to do that?
restart; sol:=1/2*2^(1/2)*csgn(x)*x*csgn(y); indets(sol,'specfunc( anything, csgn )'); vars:=subsindets(%,'specfunc( anything, csgn )',f->op(f)); simplify(sol) assuming op(map2(`<`,0,vars))
Gives \(\frac {\sqrt {2}\, x}{2}\). Notice in the above the use of op(map2(`<`,0,vars))
, this will generate the
sequence 0 < x, 0 < y
automatically. op
is needed otherwise the result will be
{0 < x, 0 < y}
which will give syntax error when passed to assuming
Ofcourse, it would have been also possible to just write
simplify(sol) assuming positive;
And get the same result. But sometimes we might want to specify which variables are to be assumed positive and not all of them at once in the expression.
I wanted to replace |expr|
by (expr)
One way is
restart; expr:=u(x) = _C1*exp(-3*x^(1/3)*sqrt(c))*(3*x^(1/3)*sqrt(c) + 1) + _C2*exp(3*x^(1/3)*sqrt(c))*abs(-1 + 3*x^(1/3)*sqrt(c));
expr:=subsindets(expr,'specfunc( anything, abs )',f->op(f));
For an example, How to find list of all \(\ln \) functions in this expression?
restart; expr:=ln(abs(x+1))+2*x*ln(x)+sin(x); tmp := indets(expr,'specfunc(anything,ln)'); # tmp := {ln(x), ln(abs(x + 1))}
To pick only \(\ln \) functions which has \(abs\) inside them anywhere, replace the above with
restart; expr:=ln(abs(x+1))+2*x*ln(x)+sin(x); lis:=indets(expr,'specfunc(anything,ln)'); select(Z->has(Z,abs),lis) # tmp := {ln(abs(x + 1))}
Or, better alternative to the above is
restart; expr:=ln(abs(x+1))+2*x*ln(x)+sin(x); indets(expr,'specfunc( satisfies(u->has(u,abs)) ,ln )'); # tmp := {ln(abs(x + 1))}
Given
How to remove the absolute, the ones only inside each \(\ln \) in the above expression?
restart; expr:=sin(x)+ln(abs(x))+ln(x+abs(y)/sqrt(abs(x+3)))+ln(x^3)+cos(abs(x)); expr:=evalindets(expr,'specfunc(ln)',f->evalindets(f,'specfunc(abs)',f->op(1,f))) # sin(x) + ln(x) + ln(x + y/sqrt(x + 3)) + ln(x^3) + cos(abs(x))
Given
How to find all arguments of signum
and simplify the above by assuming they are all
positive?
restart; expr:=-(ln((b + sqrt(b^2 + y(x)^2)*signum(b))*b/y(x)) + ln(2))*signum(b)/b = _C1 + (-ln(a) + ln(x) - ln(a + sqrt(a^2 + x^2)*signum(a)) - ln(2))/abs(a); lis:=indets(expr,'specfunc(anything,signum)'); assum:=convert(map(x->op(1,x)>0,lis),list); simplify(expr,assume=assum);
Given
How to replace all signum
by 1?
restart; expr:=-(ln((b + sqrt(b^2 + y(x)^2)*signum(b))*b/y(x)) + ln(2))*signum(b)/b = _C1 + (-ln(a) + ln(x) - ln(a + sqrt(a^2 + x^2)*signum(a)) - ln(2))/abs(a); evalindets(expr, 'specfunc(anything,signum)', f -> 1);
Given expression \(3 \sin \left (x \right )+t +3 f \left (x , t\right ) t +g \left (x , t\right )\) find if it contains function \(f()\).
Use indets
with specfunc(f)
restart; expr := 3*sin(x)+t+3*f(x,t)*t+g(x,t); res := indets(expr, specfunc(f)); if numelems(res)<>0 then print("Found f(x,t)"); else print("could not find f(x,t)"); fi;
"Found f(x,t)"
Given expression \(3 \sin \left (x \right )+t +3 f \left (x , t\right ) t +g \left (x , t\right )\) find all functions, if any, in the expression.
Use indets
with function
restart; expr := 3*sin(x)+t+3*f(x,t)*t+g(x,t); res := indets(expr,function); if numelems(res)<>0 then print("Found these functions",res); else print("could not find any function)"); fi;
"Found these functions", f(x, t), g(x, t), sin(x)
Given expression \(3 \sin \left (x \right )+t +3 f \left (x , t\right ) t +g \left (x , t\right )\) find all functions, if any, in the expression but exclude the math functions such as \(\sin \) in the above.
restart; expr := 3*sin(x)+t+3*f(x,t)*t+g(x,t); res := indets(expr, And( function, Not(typefunc(mathfunc)))); if numelems(res)<>0 then print("Found these functions",res); else print("could not find any function)"); fi;
"Found these functions", f(x, t), g(x, t)
use op
restart; op(1..,f(x,t)) x, t
Note that op(0,f(x,t))
finds the function name.
restart; expr := 3*sin(z)+t+3*f(z,t,y)*t+g(x,t); res := indets(expr, patfunc(identical(z), anything)); if numelems(res)<>0 then print("Found these functions",res); else print("could not find any function)"); fi;
gives
"Found these functions", f(z, t, y), sin(z)
expr := 3*sin(z)+t+3*f(z,t,y)*t+g(x,t); res := indets(expr, patfunc(anything, identical(t), anything)); if numelems(res)<>0 then print("Found these functions",res); else print("could not find any function)"); fi;
gives
"Found these functions", f(z, t, y), g(x, t)
Given expression such as \(3+(1+x)\sin x\) or \(3+(1+x)\sin ^2 x\) use select to find any polynomial * sin^n
subexpressions.
restart; mytype_1 := ''`*`'( {polynom(And(algebraic, satisfies(u -> not has(u, I))),x), Or( 'specfunc(sin)'^integer, 'specfunc(sin)') } )'; select(type, 3+(1+x)*sin(x),mytype_1); select(type, 3+(1+x)*sin(x)^2,mytype_1);
Gives
(1 + x) sin(x) 2 (1 + x) sin(x)
restart; my_type:=''`*`'( { Or('specfunc'(sin),'specfunc'(sin)^Or(integer,rational)), Or('specfunc'(cos),'specfunc'(cos)^Or(integer,rational))})'; type(sin(x)^2*cos(x)^3,my_type); type(sin(x)^2*cos(x),my_type); type(sin(x)*cos(x),my_type); type(cos(x)*sin(x)^(1/2),my_type); true true true true
I could not find a way to avoid writing Or('specfunc'(sin),'specfunc'(sin)^Or(integer,rational)
in order to match both \(\sin x\) and \(\sin ^2 x\). For these things, I find Mathematica patterns more flexiable.
The above can be done as follows in Mathematica
ClearAll[x,n,m,any] patt=any_.*Sin[_]^n_. * Cos[_]^m_. MatchQ[Sin[x]^2*Cos[2*x]^3,patt] MatchQ[Sin[x]^2*Cos[x],patt] MatchQ[Sin[x]*Cos[x],patt] MatchQ[Cos[x]*Sin[x],patt] True True True True
In Mathematica n_.
says basically to match \(\sin x\) or \(\sin ^2 x\) since the dot says to match zero or
more. So no need to duplicate things as I did above in Maple. There might be a
way to do the same in Maple using structured type, but I could not find it. In
General, I find patterns in Mathematica more flexible and easier to use for this sort
of thing. Maple has patmatch
command, but not as easy to use as Patterns in
Mathematica.
use indets
with type 'indexed'
expr:=16*a[3]+6*a[1]; terms:=indets(expr,'indexed'); terms := {a[1], a[3]} #to find maximum index, then do map(x->op(x),terms) {1, 3}
Given say \(\frac {d^{2}}{d x^{2}}y \left (x \right )+n \left (\frac {d}{d x}y \left (x \right )\right )+3 = \sin \left (x \right )\) how to find all variables and functions in it, not including math functions such as \(\sin x\)?
So the result should be \(n,x,y(x)\).
ode:=diff(y(x),x$2)+n*diff(y(x),x)+3=sin(x); vars:=indets(ode, Or( And(symbol,Not(constant)), And(function,Not(typefunc(mathfunc)) ) )) #gives # vars := {n, x, diff(y(x), x), diff(y(x), x, x), y(x)}
I still need to work on excluding derivatives from the search.
I had case where I needed to check if something is integer or not. The problem is that the result had a symbol \(n\) in it. I need a way to tell Maple that to check if the result can be an integer given that \(n\) is also an integer.
Using type
does not work, since can’t use assumptions. One way is to use coulditbe
as
follows
restart; expr:=n-1+2*m; vars:=indets(expr,And(symbol,Not(constant))); coulditbe(expr,integer) assuming op(map(Z->Z::integer,vars)) # true
In the above indets(expr,And(symbol,Not(constant)))
picks all variables in the
expression, and assuming op(map(Z->Z::integer,vars))
makes assumption that each is
integer.
Use
restart; expr:=4*Pi+sin(x); indets(expr,And(name,constant)) {Pi}
Given an expression such as
Find all \(y'(x)\) for any power that show up, so the result should be
Use indets
with type identical(diff(y(x),x))^anything
is used. But must use the flat
option to work correctly.
restart; expr:= y(x)*diff(y(x),x)^(1/3)+sin(x)*diff(y(x),x)^3 + z*diff(y(x),x)*ln(y(x)*diff(y(x),x)^2) +diff(y(x),x)^(1/2) + x/diff(y(x),x)^7; t1:=identical(diff(y(x),x))^anything; t2:=identical(diff(y(x),x)); indets[flat](expr, 'Or'( t1, t2 ));
gives
{diff(y(x), x)^(1/3), 1/diff(y(x), x)^7, diff(y(x), x)^2, diff(y(x), x)^3, diff(y(x), x), sqrt(diff(y(x), x))}
Without using flat
it will given wrong result. For example
restart; expr:=diff(y(x),x)^2; t1:=identical(diff(y(x),x))^anything; t2:=identical(diff(y(x),x)); indets(expr, 'Or'( t1, t2 ));
Gives
{diff(y(x), x)^2, diff(y(x), x)}
You see, it has extra diff(y(x), x)
showing up. Adding flat
it gives
restart; expr:=diff(y(x),x)^2; t1:=identical(diff(y(x),x))^anything; t2:=identical(diff(y(x),x)); indets[flat](expr, 'Or'( t1, t2 ));
Now it gives
{diff(y(x), x)^2}
Which is the correct result.
To go from \(\ln (A B)\) to \(\ln A + \ln B\) need to use simplify
with ln
option but add assumptions that one of the
terms is positive. Else it will not do it
restart; simplify(ln(A*B),ln); # no change simplify(ln(A*B),ln) assuming A>0; # ln(A) + ln(B) simplify(ln(A*B),ln) assuming B>0; # ln(A) + ln(B)
To go from \(\ln ( \frac {A}{B})\) to \(\ln A - \ln B\) need to use simplify
with ln
option but add assumptions that
\(B>0\).
restart; simplify(ln(A/B),ln); # no change simplify(ln(A/B),ln) assuming A>0; # ln(A) + ln(1/B) simplify(ln(A/B),ln) assuming B>0; # do this: -ln(B) + ln(A)
To go from \(\ln A + \ln B\) to \(\ln (A B)\) need to use combine
with assumptions that either \(A\) or \(B\) is positive, else it will
not do it.
restart; combine( ln(A) + ln(B),ln); # no change combine( ln(A) + ln(B),ln) assuming A>0; # ln(A*B) combine( ln(A) + ln(B),ln) assuming B>0 # ln(A*B)
To go from \(\ln A - \ln B\) to \(\ln \frac {A}{B} \) need to use combine
with assumptions that either \(B\) is positive.
restart; combine( ln(A) - ln(B),ln); #no change combine( ln(A) - ln(B),ln) assuming A>0; # -ln(B/A) combine( ln(A) - ln(B),ln) assuming B>0 # use this ln(A/B)
Given list such as [1,2,3,4,5,x,y,8,9,Pi]
find position of elements that are not numeric.
In this case the answer should be [6,7,10]
restart; lis:=[1,2,3,4,5,x,y,8,9,Pi]; lis2:=select(x->not(type(x,numeric)),lis); map(x->ListTools:-Search(x,lis),lis2) [6,7,10]
I could not find a way to do it using one command like with Mathematica. The first
command above uses select
to first find non numeric entries. The second command
ListTools:-Search
then find the index/position.
Maple’s ListTools:-Search
should really have a version that allows one to select the
element directly. Something like this
lis:=[1,2,3,4,5,x,y,8,9,Pi]; ListTools:-Search(x->not(type(x,'numeric')),lis,all)
I needed to do this as I was translating Maple code to Sagemath. Where sagemath supports \(\arctan \) with only one argument.
Given an expression such as
Convert it to
evalindets(expr,'specfunc(arctan)',f->`if`(nops(f)=2,arctan(op(1,f)/op(2,f)),f))
Given an expression such as \(a+\sin (x) + \pi + y+ f(r) \) how to find all symbols in it, which will be \(a,x,y,r\)?
One way
expr:=a+sin(x) + Pi + y+ f(r); indets(expr,And(symbol,Not(constant)));
Another is
expr:=a+sin(x) + Pi + y+ f(r); indets(expr,assignable(name));
Both give {a, r, x, y}
This question came up in https://mathematica.stackexchange.com/questions/274535/replacing-only-variables-in-specific-locations-with-replace-all
where the user wanted to I would like to replace R0 with r, but only in the arguments of functions.
The input they had is line = R0*f[R0,x] + R0^2*42*D[g[R0,x],x]
In Maple, this can be done as follows, which I think is a easier thanks to Maple’s strong type system.
line := R0*f(R0,x) + R0^2*42*diff(g(R0,x),x); evalindets(line, 'patfunc(identical(R0),anything)', Z-> subsop(1 = r, Z ));
Which gives
Given an expression which contains some different functions each with different number of arguments. Suppose we want to change only the last argument of each function if the last argument is \(x\), and change it to say \(x^2\).
how to do that?
Hence given R0*f(R0,x)+42*R0^2*D[2](g)(R0,x)+h(x,y,z,r,x)
we want to change it to
R0*f(R0,x^2)+42*R0^2*D[2](g)(R0,x^2)+h(x,y,z,r,x^2)
.
expr:= R0*f(R0,x) + R0^2*42*diff(g(R0,x),x)+ h(x,y,z,r,x); evalindets(expr, 'patfunc[reverse](anything,identical(x))', Z-> subsop(-1 = x^2, Z ));
Note the use of subsop(-1 = x^2, Z )
where \(-1\) means the last entry in the argument of the
function. This is basically same as last example, but uses patfunc[reverse]
instead of just
patfunc
This is the same example as the above, but now we want to remove the last argument instead of changing it.
Hence, given an expression which contains some different functions each with different number of arguments. Suppose we want to remove only the last argument of each function if the last argument is \(x\).
how to do that?
Hence given R0*f(R0,x)+h(x,y,z,r,x)
we want to change it to R0*f(R0)+h(x,y,z,r)
.
expr:=R0*f(R0,x)+h(x,y,z,r,x) evalindets(expr, 'patfunc[reverse](anything,identical(x))', Z-> subsop(-1 = NULL, Z ));
Be careful using the above on expression that has diff(f(y,x),x)
as this will give 0,
because we basically removed the variable of the differentiation.
Given \(3 \,{\mathrm e}^{x}+\sin \left (a \,{\mathrm e}^{x}\right ) f\left ({\mathrm e}^{5 x}\right )\) how to find all terms with pattern anything*exp
? If we do this
expr:=3*exp(x)+sin(a*exp(x))*f(exp(5*x)); indets(expr,`&*`(anything,'specfunc(exp)')); # {a*exp(x), 3*exp(x)}
We see it did not find exp(5*x)
this is because there is nothing multiplying the exp
function. To find this we add Or
like this to count for both cases
expr:=3*exp(x)+sin(a*exp(x))*f(exp(5*x)); indets[flat](expr,Or( `&*`(anything,'specfunc(exp)'), 'specfunc(exp)' )) # {a*exp(x), 3*exp(x), exp(5*x)}
The flat
option is needed, as without it this will be the result
expr:=3*exp(x)+sin(a*exp(x))*f(exp(5*x)); indets(expr,Or( `&*`(anything,'specfunc(exp)'), 'specfunc(exp)' )) # {a*exp(x), 3*exp(x), exp(x), exp(5*x)}
Given an inert Sum such as
How to obtain the body of the sum, the index variable, the lower starting value and the upper limit?
r:=Sum(a[n - 1]*x^(n - 1), n = 2 .. infinity); op(0,r) #head Sum op(1,r) #body a[n - 1] x^(n - 1) op(2,r) # sum specs n = 2 .. infinity lhs(op(2,r)) #name of summation index n rhs(op(2,r)) # lower..upper limits 2 .. infinity op(1,rhs(op(2,r))) #lower limit 2 op(2,rhs(op(2,r))) #upper limit infinity
Given a 1D container, such as vector or list, called \(A\), how to find if this sequence is inside another sequence say \(B\) and the indecies in \(B\) where the sequence \(A\) is located?
Use ArrayTool
in version 2023
A:=[1,3,5]; B:=[1,3,4,5]; status,indices_list := ArrayTools:-IsSubsequence( A, B ,'output' = ['check','indices'],'match'='exact'); if status then print("Sequence ",A," Was found in ",B," At indices ",indices_list); else print("Sequence ",A," Was not found in ",B); fi;
The above gives
"Sequence ", [1, 3, 5], " Was found in ", [1, 3, 4, 5], " At indices ", [1, 2, 4]
If \(A\) was not sequence inside \(B\), then status
will be false otherwise.
Use membertype
restart; expr:=cos(x)+x+9+sin(x)*(x^2+4); membertype( polynom(anything,x), expr,'loc' ); true loc; 2
The above says there is a polynomial in \(x\) inside the expression at op(2,expr)
notice that \(x^2+4\) is
not a polynomial since the expression will expand and \(\sin x\) will be multiplied by it causing
it not to become polynomial. So only \(9+x\) is the polynomial. The location is where
the memeber starts at. Notice that Maple sorts polynomial from lower to higher
powers.
restart; expr:=cos(x)+x+9+sin(x)*(x^2+4); membertype( integer, expr,'loc' ); true loc; 3
The above says that there is an integer (which is \(9\) in this example) inside the expression at
op(3,expr)
I had case where I wanted to substitute _F=(y-x^2)/x
in an expression obtained which is
x*diff(F1, x) + 2*y*diff(F1, y)
Using eval does not work
restart; eval(x*diff(F1, x) + 2*y*diff(F1, y),F1=(y-x^2)/x); 0
Also using delayed does not work
restart; eval('x*diff(F1, x) + 2*y*diff(F1, y)',F1=(y-x^2)/x); value(%) 0
ALso using subs does not work
restart; subs(F1=(y-x^2)/x,x*diff(F1, x) + 2*y*diff(F1, y)) 0
However, delayed with subs finally worked
restart; subs(F1=(y-x^2)/x,'x*diff(F1, x) + 2*y*diff(F1, y)'); value(%) x*(-2 - (-x^2 + y)/x^2) + 2*y/x
So the rule is, if you want to replace a function inside diff, use subs and not eval, and make
sure to delay evaluation of the expression and then use value()
to obtain the final
result.
These are examples how to match expression types
expr is product a*b
which is matched using
type(a*b,`&*`(anything,anything)) true
The above can also be written using infix notation
type(a*b, anything &* anything) true
However, the above only match product of two terms. To match 3*a*b
use
type(3*a*b,`*`) true
expr is division a/b
which is matched using same as `*`
type(a/b,`&*`(anything,anything)) true
Match type of a*f(x)
, which is anything times a function that takes one argument
\(x\).
type(a*f(x),`&*`(anything,patfunc(identical(x),anything))) true
Using patfunc
is better than using function
type(a*f(x,y),`&*`(anything,function(identical(x)))) true
Because patfunc
matches on \(f(x,y,z,\dots )\) and not just function which takes only one
argument \(f(x)\). But if you know your function takes only one argument, then use
function
To match 3*y/x
. This was tricky. Had to use
expr:=3*y/x; type(expr, `&*`(anything,identical(y),`^`(identical(x),-1))) or type(expr, `&*`(identical(y),`^`(identical(x),-1))) true
I used or
to account for possible expr:=y/x
, i.e. missing constant at front. Note
that
expr:=3*y/x; type(3*y/x, `&*`(anything,identical(y/x))) false
Does not match, since 3*y/x
is actually 3*y
times 1/x
internally.
Match on f(b* y/x)
type(f(3*y/x),function(`&*`(anything,identical(y),`^`(identical(x),-1)))) true
Match on f(b* y/x)
or f(y/x)
expr:=f(3*y/x); type(expr, function(`&*`(anything,identical(y),`^`(identical(x),-1)))) or type(expr, function(`&*`(identical(y),`^`(identical(x),-1)))) true
Again, had to use or to account for missing constant multipler.
Match on a*f(b* y/x)
expr:=a*f(3*y/x); type(expr, `&*`(anything,patfunc(`&*`(anything,identical(y),`^`(identical(x),-1))))) true
Match against 9+3 y/x
expr:=9+3*y/x; selector:=`&+`(anything,`&*`(anything,identical(y),`^`(identical(x),-1))): type(expr, selector); true select(type,[expr],selector); [9 + 3*y/x]
Notice in the above, when using select
we need to put the expression inside a list, as
select looks at each operand, This way the whole expression is taken as one.
If we just used select(type,expr,selector);
it would not have found
it.
To use patmatch
the command becomes
patmatch(expr, a::anything+b::anything*y/x,'la'); la [a = 9, b = 3]
The nice thing about patmatch is that it allowed one to assign variable to parts of the expression automatically.
Match against 9+f(3 y/x)
where now \(f\) is function. Using patmatch
. I could not do this
in one command, as all my attempts failed:
expr:=3+4*x*f(3*y/x); body_of_function:=C::anything*y/x; patmatch(expr,A::anything+B::anything*F::function(C::anything*y/x),'la'); patmatch(expr,A::anything+B::anything*F::patfunc(C::anything*y/x),'la'); Error, (in PatternMatching:-AlgStruct:-Match) testing against an invalid type Error, (in type/patfunc) testing against an invalid type
So I had to do it in two steps. First match on the function as whole, then use that to
match on f(3*y/x)
in second stage, like this
expr:=3+4*x*f(3*y/x); patmatch(expr,A::anything+B::anything*F::function(anything),'la'); la; [A = 3, B = 4*x, F = f(3*y/x)]
And now
assign(la); A:='A'; patmatch (op(1,F),A::anything*y/x,'la'); la [A = 3]
Overall, I find Mathematica’s pattern matching constructs much simpler and more intutive to use and easier to learn as there are many examples and tutorials. For example, the last example above in Mathematica could be done as follows
expr=9+(4*x)*f[3*y/x]; Cases[{expr},any0_.+ any1_.*any2_[any3_.*y/x]:>{any0,any1,any2,any3}] {{9, 4 x, f, 3}}
Maple’s help pages are not good at all and provide little or no examples to learn from compared to Mathematica’s excellent help pages. For any serious pattern matching tasks, I would use Mathematica. Maple has a better debugger and hence easier to debug the code because of this. So it is a tradeff between these two systems.
I was trying to match on anyfunction that has \(x\) inside its arguments. It turned out that
matching \(f(a x)\) vs. \(f(a+x)\) needed to have the identical(x)
being placed first when it is a sum and last
when it is a product. Very strange. Just be aware of this
indets(f(a+x),function(`&+`(anything,identical(x)))); #failed {}
But
indets(f(a+x),function(`&+`(identical(x),anything))); {f(x + a)}
While with product, it is the other way around
indets(f(a*x),function(`&*`(anything,identical(x)))); {f(a*x)}
But now this fail
indets(f(a*x),function(`&*`(identical(x),anything))); #fail {}
I have not yet figure how to tell it that the order does not matter. Maple 2023.1
A better way than the above, if I want to find any function that takes in \(x\) or \(y\) as arguments is
to use patfunc
like this
indets(f(a*x+b+y),patfunc(anything,`Or`({identical(x),identical(y)}))); {f(a*b + y)} indets(f(b+y),patfunc(anything,`Or`({identical(x),identical(y)}))); {f(b + y)} indets(exp(a*x),patfunc(anything,`Or`({identical(x),identical(y)}))); {exp(a*x)} indets(exp(a+x),patfunc(anything,`Or`({identical(x),identical(y)}))); {exp(x + a)}