# Re: generate all possible math expr of one term

*From*: "joswig@xxxxxxxxxxxxxxxxxxxxxxx" <joswig@xxxxxxxxxxxxxxxxxxxxxxx>*Date*: Thu, 15 May 2008 03:51:54 -0700 (PDT)

On 15 Mai, 01:49, "xah...@xxxxxxxxx" <xah...@xxxxxxxxx> wrote:

Here's a example of Expressiveness of a Language.

The following is Mathematica code that generates all possible

equations of one term involving trig function. (tweak the funList and

nesting level to define what “all possible” means. if nesting level is

2, it takes about 20 minutes and returns a list of 2876 terms on a

2004 personal computer.

<< DiscreteMath`Combinatorica`

funList = {Sin, Tan, Power[#, -1] &};

Nest[Module[{li = #},

(Union[#, SameTest -> (Module[{arg1 = #1, arg2 = #2},

If[(*both expression contains both x and y*)

And @@ (((((StringMatchQ[#, "*x*"] &&

StringMatchQ[#, "*y*"]) &)@

ToString@#) &) /@ {arg1, arg2})

, SameQ[arg1, arg2 /. {x -> y, y -> x}],

SameQ[arg1, arg2]]

] &)] &)@

Union@Flatten@(Table[(Times @@ # &) /@ KSubsets[#, i], {i, 1,

2}] &)@Flatten@{li, Outer[#1@#2 &, funList, li]}

] &, {x, y}, 1];

Select[%, (StringMatchQ[ToString@#, "*x*"] &&

StringMatchQ[ToString@#, "*y*"]) &]

The problem is this: generate a list of all possible math expressions

using the following combination and rules:

• the math expression involves both x and y. (must have both present)

• you can use any of the 6 trig functions (you must, since the goal is

to create all possibilities)

• The binary operations you can use are multiply, divide. (no addition

or substraction, since that can make the result 2 terms)

• a sub-expression (such as x or y) can be replaced by a more

complicated one. (i.e. you can nest)

For example, these are first few items from the above code:

{1/(x^2*y^2), 1/(x*y^2), x/y^2, 1/(x*y), x/y, x^2/y, x*y, x^2*y,

x^2*y^2, Cos[x]/y^2, Cos[x]/y, Cos[x]/(x*y), (x*Cos[x])/y, y*Cos[x],

(y*Cos[x])/x, x*y*Cos[x], y^2*Cos[x], Cos[x]*Cos[y], Cot[x]/y^2,

Cot[x]/(x*y^2)}

For a gallery of selection plots of these equations, see

http://xahlee.org/MathGraphicsGallery_dir/dense/dense1.html

The above i wrote in 2002. If there are requests, i'll translate the

above code into emacs lisp. The result lisp expression should match

Mathematica's, token for token. (the code make a lot use of nested

lambda and or apply and or map) If you are interested, you could

translate the above into lisp too, it's not difficult (though the

number of lines will increase maybe 10 fold. And if Common Lisp

doesn't have combinatorics library providing KSubsets, and also since

CL doesn't have Outer, so the above in CL might be few hundred lines).

(see here for a example of how to:http://xahlee.org/UnixResource_dir/writ/notations.html

)

PS as a after-thought, i decided to post this to perl, python, and

java too. This will take about the same number of lines in perl as in

Common Lisp. Probably llightly more in Python due to syntax. In Java,

it will be one million lines.

Gratuitous poem of the day:

in the climb to geekdom,

you have few rungs to catch,

before you see my ass.

—Xah Lee, 2005

Xah

x...@xxxxxxxxxx

∑http://xahlee.org/

☄

The thing is stuff like that is relatively in Lisp. Let's see your

Emacs Lisp version!

In Common Lisp you get the benefit of nicer code.

To give a hint:

(defun example ()

(pprint

(cross-product '(* +)

(cons 'x (cross-product '(sin cos tan /) '(x)))

(cons 'y (cross-product '(sin cos tan /) '(y))))))

CL-USER 33 > (time (example))

Timing the evaluation of (EXAMPLE)

((+ X Y)

(+ X (/ Y))

(+ X (TAN Y))

(+ X (COS Y))

(+ X (SIN Y))

(+ (/ X) Y)

(+ (/ X) (/ Y))

(+ (/ X) (TAN Y))

(+ (/ X) (COS Y))

(+ (/ X) (SIN Y))

(+ (TAN X) Y)

(+ (TAN X) (/ Y))

(+ (TAN X) (TAN Y))

(+ (TAN X) (COS Y))

(+ (TAN X) (SIN Y))

(+ (COS X) Y)

(+ (COS X) (/ Y))

(+ (COS X) (TAN Y))

(+ (COS X) (COS Y))

(+ (COS X) (SIN Y))

(+ (SIN X) Y)

(+ (SIN X) (/ Y))

(+ (SIN X) (TAN Y))

(+ (SIN X) (COS Y))

(+ (SIN X) (SIN Y))

(* X Y)

(* X (/ Y))

(* X (TAN Y))

(* X (COS Y))

(* X (SIN Y))

(* (/ X) Y)

(* (/ X) (/ Y))

(* (/ X) (TAN Y))

(* (/ X) (COS Y))

(* (/ X) (SIN Y))

(* (TAN X) Y)

(* (TAN X) (/ Y))

(* (TAN X) (TAN Y))

(* (TAN X) (COS Y))

(* (TAN X) (SIN Y))

(* (COS X) Y)

(* (COS X) (/ Y))

(* (COS X) (TAN Y))

(* (COS X) (COS Y))

(* (COS X) (SIN Y))

(* (SIN X) Y)

(* (SIN X) (/ Y))

(* (SIN X) (TAN Y))

(* (SIN X) (COS Y))

(* (SIN X) (SIN Y)))

User time = 0.002

That should be easy to extend to get a solution for your problem.

Then you map a simplifier over the result. (mapcar 'simplify result)

and you get a nice list of simplified forms.

With some added recursion you can change the depth of the term

generation.

.

**Follow-Ups**:**Re: generate all possible math expr of one term***From:*Jon Harrop

**Re: generate all possible math expr of one term***From:*Rainer Joswig

- Prev by Date:
**Re: Lisp on an FPGA** - Next by Date:
**Re: Reading random bits of clhs** - Previous by thread:
**Lisp and Symbolic Integration** - Next by thread:
**Re: generate all possible math expr of one term** - Index(es):