# Testing for arbitrary algebraic expression in given variable

I want to test, for example with MatchQ, if the argument of a function is an arbitrary expression in a single or several variables whose names can be assumed to be known. Except of these variables the expression should contain only numeric values. An approach would be to generate a list of unknowns in an expression and to compare this list to a given one. But I do not know either how to create that list for an arbitrary expression. By expression I mean a mathematical expression here.

Edit

Exampe:

(1-Exp[I*(x-5.6)*23.4])*Log[Abs[x-4.3]]/(1.7+3.2*I-x^2)


should be matched if I require it to be an expression in x and

(1-Exp[I*(x-y)*23.4])*Log[Abs[x-4.3]]/(1.7+3.2*I-x^2)


should not be matched in this case. Note that this does not mean that you can assume that the expression contains only these functions and rationals.

My function

func[expr_?...,var]:=Module[{},...]


should evaluate only if the expression is e.g. of the first kind

func[(1-Exp[I*(x-5.6)*23.4])*Log[Abs[x-4.3]]/(1.7+3.2*I-x^2),x]

• Can you give a concrete example of what kinds of expressions you have and what kinds of results you expect to see? If possible, please include any Mathematica code you have for these expressions. Feb 14, 2014 at 21:14
• I don't understand the question. Are you trying to test whether the expression is only a function of a certain variable? Union@Cases[Level[expr, {-1}], x_ /; Not@NumericQ[x]] this should extract the variables. It gives {x} for the first expression and {x,y} for the second. Feb 14, 2014 at 21:19
• Yes, what I need seems to be something like Sort[Union@Cases[Level[expr, {-1}], x_ /; Not@NumericQ[x]]] == Sort[{var, var1}]. Feb 15, 2014 at 11:48
• You may be looking for a way to extract the variables from an expression. Some approaches may be found here and also here Feb 18, 2014 at 21:20

Is this what you want?

ClearAll@ExactVarsQ;
ExactVarsQ[func_, vars__] := MatchQ[
Sort@DeleteDuplicates@Cases[func, x_ /; (AtomQ[x] && ! NumericQ[x]), {0, Infinity}],
Sort@DeleteDuplicates@{vars}
]

test1 = (1 - Exp[I*(x - 5.6)*23.4])*Log[Abs[x - 4.3]]/(1.7 + 3.2*I - x^2)
test2 = (1 - Exp[I*(x - y)*23.4])*Log[Abs[x - 4.3]]/(1.7 + 3.2*I - x^2)

ExactVarsQ[test1, x]           (* True *)
ExactVarsQ[test2, x]           (* False *)
ExactVarsQ[test2, x, y]        (* True *)


EDIT

For completeness, to use it in your function definition (to make sure it only evaluates when the latter is satisfied), you would write

func[expr_,vars__]/;ExactVarsQ[expr,vars]:= ...

• If you restrict Cases to level {-1} then you don't need the AtomQ test. Also DeleteDuplicates followed by Sort is equivalent to Union. Feb 19, 2014 at 16:00

I would write it like this, which I find quite readable:

onlyvarsQ[expr_, vars__] := Cases[expr, Except[_?NumericQ | vars], {-1}] == {}


e.g.

expr = (1 - Exp[I*(x - 5.6)*23.4])*Log[Abs[x - 4.3]]/(1.7 + 3.2*I - x^2);
onlyvarsQ[expr, x]
(* True *)
onlyvarsQ[y + expr, x]
(* False *)