11
$\begingroup$

I want some help here. I want to define a function called Lg[z] that has the property that Lg[a/b] is always converted automatically to the form Lg[a] - Lg[b] , when a and b are polynomials of some variable say t.

I tried many things nothing works. I don't want to replace one by one by hand as it takes too long.

$\endgroup$

1 Answer 1

14
$\begingroup$

This could be a start, but it performs the transformation irrespective of whether a and b are polynomials in t or not.

ClearAll[Lg];
Lg[HoldPattern[Times[a__]]] := Plus @@ Lg /@ {a};
Lg[HoldPattern[Power[a_, p_]]] := p  Lg[a];

Here a few usage examples:

Lg[a b]
Lg[a/ b]
Lg[a^p]
Lg[Sum[t^k, {k, 0, 3}]/ Sum[k t^k, {k, 0, 3}]]

Lg[a] + Lg[b]

Lg[a] - Lg[b]

p Lg[a]

Lg[1 + t + t^2 + t^3] - Lg[t + 2 t^2 + 3 t^3]

One could make the patterns more restrictive with PolynomialQ, but maybe this already suffices for your task?

$\endgroup$
6
  • $\begingroup$ what's the advantage of using a HoldPattern? $\endgroup$
    – Roman
    Dec 26, 2019 at 12:11
  • 6
    $\begingroup$ @Roman: the pattern Times[a__] evaluates to a__ during the assignment in SetDelayed, so if you don't use HoldPattern, you won't get the correct downvalues. $\endgroup$ Dec 26, 2019 at 12:15
  • 1
    $\begingroup$ I see, thanks! A bit simpler would be Lg[a_*b_] = Lg[a] + Lg[b] and Lg[a_^p_] = p*Lg[a]. $\endgroup$
    – Roman
    Dec 26, 2019 at 12:34
  • 6
    $\begingroup$ @Roman - Henrik's approach is more efficient for more complicated arguments. Compare timings for Lg[a b c d e f g h i j k l m n o p q r s t u v w x y z] $\endgroup$
    – Bob Hanlon
    Dec 26, 2019 at 13:13
  • $\begingroup$ @BobHanlon yes Henrik's is much faster because mine relies on recursion. Cheers! $\endgroup$
    – Roman
    Dec 26, 2019 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.