2

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]
highsciguy
  • 1,700
  • 1
  • 16
  • 23
  • 1
    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. – bill s Feb 14 '14 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. – Szabolcs Feb 14 '14 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}]. – highsciguy Feb 15 '14 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 – Daniel Lichtblau Feb 18 '14 at 21:20

2 Answers2

1

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]:= ...
freddieknets
  • 1,085
  • 8
  • 16
  • If you restrict Cases to level {-1} then you don't need the AtomQ test. Also DeleteDuplicates followed by Sort is equivalent to Union. – Simon Woods Feb 19 '14 at 16:00
0

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 *)
Simon Woods
  • 84,945
  • 8
  • 175
  • 324