Formatting Expression to Standard Forms in Maxima

Viewed 81

I'm a newbie to Maxima and I'm finding the tool very useful. One of the more common use-cases for me is the validation of expressions given in academic texts. Take this as an example: enter image description here

This is a transfer function written in a pretty standard format. Notice how the squared term in the denominator appears by itself. Fair enough.

So, I go about building this expression in pieces and my expectation is to compare results at the end. It helps then if the expressions are displayed using a common format. So, I'm trying to get my result to have the same normalized format as the expression in the book.

In this case, I do the following:

(%i10)  F(s):=(1+s*tau_2)/(1+s*(tau_1+tau_2));

(%o10)  F(s):=(1+s*tau_2)/(1+s*(tau_1+tau_2))

(%i13)  H(s):=(K_0*K_d*F(s))/(s+((K_0*K_d*F(s)/N)));

(%o13)  H(s):=(K_0*K_d*F(s))/(s+(K_0*K_d*F(s))/N)

(%i81)  H_1(s):=ratsimp(H(s),s);

(%o81)  H_1(s):=ratsimp(H(s),s)

(%i82)  H_1(s);

(%o82)  (K_0*K_d*N*s*tau_2+K_0*K_d*N)/(s^2*(N*tau_2+N*tau_1)+s*(K_0*K_d*tau_2+N)+K_0*K_d)

enter image description here

Which is very close. But, I've tried a few different ways of dividing across the expression by N*(tau_1 + tau_2) to leave s^2 without a coefficient and none worked. Is there an easy way to solve this?

UPDATE: Some options I've tried:

 -->    divthru(e,d):=map(lambda([u], multthru(u,d)),e); /* map applies function f() to each subpart of expr*/

(%o164) divthru(e,d):=map(lambda([u],multthru(u,d)),e)
 -->    divthru(H_1(s), 1/(N*tau_2+N*tau_1));

(%o165) (K_0*K_d*N*s*tau_2+K_0*K_d*N)/(s^2*(N*tau_2+N*tau_1)+s*(K_0*K_d*tau_2+N)+K_0*K_d)

(%i35)  matchdeclare([A,B,C,D],all);

(%o35)  done

(%i26)  defmatch(isDefPoly, A/(s^2*B+s*C+D), x);

(%o26)  isDefPoly

(%i27)  isDefPoly(H_1(s),s);

(%o27)  [A=K_0*K_d*N*s*tau_2+K_0*K_d*N,D=K_0*K_d,B=N*tau_2+N*tau_1,C=K_0*K_d*tau_2+N,x=s]

(%i36)  tellsimpafter(A/(s^2*B+s*C+D), (A/B)/(s^2+(s*C)/B+D/B));

(%o36)  [\*rule1,simptimes]
2 Answers

ratsimp tries to put expressions in a standardized format which makes further operations more straightforward, and it is difficult to convince it to rearrange terms in some other way. For example, for an expression like (a + b/c)/(d + e/f), ratsimp will try to rearrange it to something which is one sum of terms over another set of terms.

I think there are some add-on functions which rearrange terms in different ways, but I'm not sure there is anything to achieve the form you have shown.

One thing that will help in a small way. My advice is to write subscripted variables as x[k] instead of x_k. That can help the TeX formatting code recognize the variable name, e.g. tau, and format it as a Greek letter. Also, you can enter Unicode characters (from any language, multibyte characters included) as variable names.

I worked on it some more and maybe there are some ideas here which can help. Here is a function to divide above and below. I'll apply it to Hs as shown in the problem statement.

(%i1) divabovebelow (e, r) := (multthru (1/e, num(r)))/(multthru (1/e, denom(r))) $

(%i2) Hs: (K_0*K_d*N*s*tau_2+K_0*K_d*N)/(s^2*(N*tau_2+N*tau_1)+s*(K_0*K_d*tau_2+N)+K_0*K_d);
                   K_0 K_d N s tau_2 + K_0 K_d N
(%o2) --------------------------------------------------------
       2
      s  (N tau_2 + N tau_1) + s (K_0 K_d tau_2 + N) + K_0 K_d
(%i3) divabovebelow (N*tau_2 + N*tau_1, Hs);
             K_0 K_d N s tau_2       K_0 K_d N
             ----------------- + -----------------
             N tau_2 + N tau_1   N tau_2 + N tau_1
(%o3)    ----------------------------------------------
         s (K_0 K_d tau_2 + N)        K_0 K_d         2
         --------------------- + ----------------- + s
           N tau_2 + N tau_1     N tau_2 + N tau_1

Here are a couple more functions that could be helpful. polynomial_in rearranges terms to kind of isolate one variable from the others. nicer_rational tries to make a rational function look nicer, via polynomial_in.

(%i4) Hs1: ratsimp (Hs);
                  K_0 K_d N s tau_2 + K_0 K_d N
(%o4) -----------------------------------------------------
          2                         2
      (N s  + K_0 K_d s) tau_2 + N s  tau_1 + N s + K_0 K_d
(%i5) polynomial_in (var, e) := apply ("+", makelist (var^k * ratcoef (e, var, k), k, 0, hipow (e, var))) $

(%i6) nicer_rational (var, e) := (polynomial_in (var, num(e)))/(polynomial_in (var, denom(e))) $

(%i7) nicer_rational (s, Hs1);
                   K_0 K_d N s tau_2 + K_0 K_d N
(%o7) --------------------------------------------------------
       2
      s  (N tau_2 + N tau_1) + s (K_0 K_d tau_2 + N) + K_0 K_d

These yield the same eventual result as ratsimp above, but maybe they make more sense since they are devised for the kind of expressions you're working with.

I was thinking about some additional functions to get closer to the textbook form, but it's a little fragile, since Maxima wants to reorganize expressions into its standard form, so for better or worse, one can get either a nice display, or an expression for working with. Hope this helps anyway.

Related