2

I have working code, but am looking for ways to make it more elegant.

I have a fairly large expression with plenty of repetition and structure. A shortened toy example is

```
expr = (a/(a + b))^4.5 + (b/(a + b))^3.5 +
(a/(a + b))^1.5 + Cosh[a + b] +
Log[a/(a + b)] + Log[b/(a + b)]
```

I have prepared a set of rules that simplifies the expression, for example like this:

```
rules = {
a + b -> sum,
a/sum -> g,
b/sum -> h}
```

In my actual code I use pattern matching, and also create unique symbols for all the matches, see below for an example.

```
Derivative[l_List, i_][δ][xv, ρ] :>
Symbol[StringJoin["$δd", StringJoin[ToString /@ l], "x", ToString[i]]]
```

The simplified expression, and the actual set of replacements is provided by the following function:

```
replaceone[expr_, rule_] := Block[{newtemps, unique},
unique = Union@Cases[expr, rule[[1]], Infinity];
newtemps = Thread[(unique /. rule) -> unique];
Sow[newtemps];
expr /. rule
]
{newekspr, temps} = Reap[Fold[replaceone, expr, rules]]
temps = Association[temps]
```

I can then prepare a function for efficient evaluation of the expression, like this, with a nested Block.

```
exprfun[av_, bv_] :=
Block[{a = av, b = bv},
Block[Evaluate[Keys[temps]], KeyValueMap[Set, temps];
newekspr]]
```

I can `Compile`

this function, although I suspect that the result is that the entire expression is expanded and simplified again.

```
Compile[{a, b}, Evaluate[exprfun[a, b]]]
```

Is this the best way of doing this?

Can I write a higher order function that takes my original expression, and a rules set, simplifies it and provides a optimised, and possibly compiled function?

What is the benefit of a nested With, and `LetL`

, that I have seen elsewhere, compared with this approach?

And

`LetL`

is defined as? – Daniel Lichtblau – 2016-03-10T15:50:10.6801Next time, when using a function obtained from another post on this site, please link to the original post. – J. M.'s ennui – 2016-03-10T16:32:42.390

@J.M. Yes, of course. Thanks for correcting. – Åsmund Hj – 2016-03-10T18:51:28.433

2

Have you tried

– Michael E2 – 2016-03-13T17:07:19.610`Experimental`OptimizeExpression`

on your expression? A few refs: (25136), (31614), (32097), (58985)@MichaelE2 My first attempts on

`Experimental`

OptimizeExpression`failed, but I tried it again on a smaller problem, and now it works. Don't know why. Still, it seems a bit inelegant to let the expression explode in complexity, for then to leave to`

OptimizeExpression` to clean up afterwards. My expression, with an original leafcount of around 150 000 is now calculated in 13 ns, compared to 28ms before compilation. Still, I would really like to use the manual rules as well, as these intermediary results are interesting by their own as well. – Åsmund Hj – 2016-03-13T17:37:16.363Perhaps a small point, but

`rules`

contains typos.`nvec/Total[nvec], {i, nc}]`

and`$[Delta]d`

. – bbgodfrey – 2016-03-14T06:07:13.870@bbgodfrey Thanks. I fixed the first one, but cannot find the second. – Åsmund Hj – 2016-03-14T06:47:25.840

I should have been more explicit.

`$[Delta]d`

should have been`$\[Delta]d`

. Also, a comma was needed between the two rules involving`Derivative`

. I fixed both and also cleaned the format a bit. Please verify that I did not introduce other issues. By the way,`nc`

needs a value. – bbgodfrey – 2016-03-14T14:01:15.307