I'm using GNU Octave with Symbolic (SymPy) and I want all s^2
should have scalar 1
.
% Load packet
pkg load symbolic
% Symbolic
syms Vin Vout dVout ddVout R C Rf R1
A = 1 + Rf/R1;
eq = Vin == Vout/A + R*C*1/A*dVout + R*(C*1/A*dVout + C*((1/A*dVout + R*C*1/A*ddVout)- dVout));
% More symbolic
syms U s Y
eq2 = subs(eq, {Vin, Vout, dVout, ddVout}, {U, Y, Y*s, Y*s^2});
eq3 = expand(eq2);
% Transfer function G = Y/U
G = simplify(solve(eq3, Y)/U)
Output:
G = (sym)
R1 + Rf
----------------------------------------
2 2 2
C *R *R1*s + 2*C*R*R1*s - C*R*Rf*s + R1
If you run that code above, you will get a transfer function G
of second order. But it's not on the second order standard form.
The standard form requries that s^2
have a scalar one. Then I can compute the rest of greek letters.
Question:
Is it possible in GNU Octave Symbolic (SymPy) to tell that s^2
should have scalar 1?
With symbolic computations there are many ways to achieve the same simplification. Having said that, I'm not familiar with Octave. Looking at the symbolic package documentation it appears that it lacks many many Sympy's function that are exposed on Python. However, by looking at the package source code, it is relatively quick to implement them. So, we are going to implement a couple of them:
pkg load symbolic
function y = collect(expr, t)
% Collects common powers of a term in an expression.
cmd = 'return sp.collect(*_ins),';
y = pycall_sympy__ (cmd, expr, t);
end
function [num, den] = fraction(expr)
% Returns a pair with expression’s numerator and denominator.
cmd = 'return sp.fraction(*_ins),';
y = pycall_sympy__ (cmd, expr);
num = y{1,1}
den = y{1,2}
end
Now we can apply them to our use case:
% retrieve the numerator and denominator of G
[num, den] = fraction(G)
% num = (sym) R₁ + Rf
% den = (sym)
%
% 2 2 2
% C ⋅R ⋅R₁⋅s + 2⋅C⋅R⋅R₁⋅s - C⋅R⋅Rf⋅s + R₁
% Let's modify the denominator
den_mod = collect(expand(den / (C^2 * R^2 * R1)), s)
% In the previous command:
% 1. we divide "den" by (C^2 * R^2 * R1)
% 2. we expand the expression so that the division gets executed term by term.
% At this points, the term containing "s^2" will have a coefficient of 1.
% 3. we collect the terms having a common "s".
% Output:
% den_mod = (sym)
%
% 2 ⎛ 2 Rf ⎞ 1
% s + s⋅⎜─── - ──────⎟ + ─────
% ⎝C⋅R C⋅R⋅R₁⎠ 2 2
% C ⋅R
%
% Now we simply reconstruct G. Since we divided "den" by (C^2 * R^2 * R1)
% we also have to divide "num" by the same amount
G_mod = num / (C^2 * R^2 * R1) / den_mod
% G_mod = (sym)
%
% R₁ + Rf
% ────────────────────────────────────────
% 2 2 ⎛ 2 ⎛ 2 Rf ⎞ 1 ⎞
% C ⋅R ⋅R₁⋅ ⎜s + s⋅⎜─── - ──────⎟ + ─────⎟
% ⎜ ⎝C⋅R C⋅R⋅R₁⎠ 2 2⎟
% ⎝ C ⋅R ⎠