Skip to content

Commit 86acfb3

Browse files
Alex VongAlex Vong
Alex Vong
authored and
Alex Vong
committed
@sym/iztrans: Add new function.
WIP: Almost done. Still Need to add help text, doctest and bist. INDEX and NEWS need to be adjusted accordingly. Not ready for merge yet. * inst/@sym/iztrans.m: New file.
1 parent c187ce8 commit 86acfb3

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

inst/@sym/iztrans.m

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
%% Copyright (C) 2022 Alex Vong
2+
%%
3+
%% This file is part of OctSymPy.
4+
%%
5+
%% OctSymPy is free software; you can redistribute it and/or modify
6+
%% it under the terms of the GNU General Public License as published
7+
%% by the Free Software Foundation; either version 3 of the License,
8+
%% or (at your option) any later version.
9+
%%
10+
%% This software is distributed in the hope that it will be useful,
11+
%% but WITHOUT ANY WARRANTY; without even the implied warranty
12+
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13+
%% the GNU General Public License for more details.
14+
%%
15+
%% You should have received a copy of the GNU General Public
16+
%% License along with this software; see the file COPYING.
17+
%% If not, see <https://www.gnu.org/licenses/>.
18+
19+
%% -*- texinfo -*-
20+
%% @documentencoding UTF-8
21+
%% @defmethod @@sym iztrans (@var{F}, @var{z}, @var{n})
22+
%% @defmethodx @@sym iztrans (@var{F})
23+
%% @defmethodx @@sym iztrans (@var{F}, @var{n})
24+
%% FIXME: add help text and doctest
25+
%%
26+
%% @seealso{@@sym/ztrans}
27+
%% @end defmethod
28+
29+
%% Author: Alex Vong
30+
%% Keywords: symbolic
31+
32+
function x = iztrans (varargin)
33+
if (nargin > 3 || nargin == 0)
34+
print_usage ();
35+
end
36+
37+
%% ensure all inputs are sym
38+
if ~all (cellfun (@(x) isa (x, 'sym'), varargin))
39+
inputs = cellfun (@sym, varargin, 'UniformOutput', false);
40+
x = iztrans (inputs{:});
41+
return
42+
end
43+
44+
%% recursively call iztrans for non-scalar inputs
45+
if ~all (cellfun (@isscalar, varargin))
46+
inputs = cellfun (@(x) num2cell (x), varargin, 'UniformOutput', false);
47+
x = sym (cellfun (@iztrans, inputs{:}, 'UniformOutput', false));
48+
return
49+
end
50+
51+
F = sym (varargin{1});
52+
F_vars = findsymbols (F);
53+
find_var_from_F = @(v) F_vars (cellfun (@(x) strcmp (char (x), v), F_vars));
54+
55+
%% select var z
56+
if (nargin == 3)
57+
z = sym (varargin{2});
58+
else
59+
zs = find_var_from_F ('z');
60+
assert (numel (zs) <= 1, 'ztrans: there is more than one "z" symbol: check symvar (F) and sympy (F)');
61+
if (~isempty (zs))
62+
z = zs{:}; % use var z from F
63+
elseif (~isempty (F_vars))
64+
z = symvar (F, 1); % select var from F using symfun
65+
else
66+
z = sym ('z'); % use freshly generated var z, FIXME: any assumptions?
67+
end
68+
end
69+
70+
%% select var n
71+
if (nargin == 3)
72+
n = sym (varargin{3});
73+
elseif (nargin == 2)
74+
n = sym (varargin{2});
75+
else
76+
ns = find_var_from_F ('n');
77+
if (isempty (ns)) % use var n if F is a not function of n
78+
n = sym ('n');
79+
else % use var k if F is a function of n
80+
n = sym ('k');
81+
end
82+
end
83+
84+
cmd = {'from sympy.series.formal import compute_fps'
85+
'def unevaluated_iztrans(F, z, n):'
86+
' R = Symbol("R", positive=True, real=True)'
87+
' theta = Symbol("theta", real=True)'
88+
' F_polar = F.subs(z, R * exp(I * theta))'
89+
' xn = Limit(R**n * Integral(F_polar * exp(I * n * theta),'
90+
' (theta, -pi, pi)),'
91+
' R, +oo) / (2 * pi)'
92+
' return xn'
93+
'def poly_to_lin_comb_of_kron_delta(p):'
94+
' return sum([ak * KroneckerDelta(n - k, 0)'
95+
' for ((k,), ak) in p.all_terms()])'
96+
'(F, z, n) = _ins'
97+
'F_of_1_over_z = F.subs(z, 1 / z)'
98+
'if expand(F_of_1_over_z).is_polynomial(z):'
99+
' return poly_to_lin_comb_of_kron_delta(F_of_1_over_z.as_poly(z))'
100+
'try:'
101+
' (ak, _, ind) = compute_fps(F_of_1_over_z, z)'
102+
'except TypeError:'
103+
' return unevaluated_iztrans(F, z, n)'
104+
'(k,) = ak.variables'
105+
'assert ak.start.is_integer and ak.start >= 0 and ak.stop == +oo'
106+
'if expand(ind).is_polynomial(z):'
107+
' an = Piecewise((ak.formula.subs(k, n), n >= ak.start), (0, True))'
108+
' bn = poly_to_lin_comb_of_kron_delta(ind.as_poly(z))'
109+
' xn = piecewise_fold(an) + bn'
110+
' return xn'
111+
'else:'
112+
' return unevaluated_iztrans(F, z, n)'};
113+
x = pycall_sympy__ (cmd, F, z, n);
114+
end
115+
116+
%% FIXME: add bist

0 commit comments

Comments
 (0)