Skip to content

Commit 78f2a27

Browse files
committed
add diff2
1 parent 6980d29 commit 78f2a27

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

inst/@sym/diff2.m

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
%% Copyright (C) 2014-2016 Colin B. Macdonald
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 <http://www.gnu.org/licenses/>.
18+
19+
%% -*- texinfo -*-
20+
%% @documentencoding UTF-8
21+
%% @defmethod @@sym diff (@var{f})
22+
%% @defmethodx @@sym diff (@var{f}, @var{x})
23+
%% @defmethodx @@sym diff (@var{f}, @var{x}, @dots{})
24+
%% @defmethodx @@sym diff (@var{f}, @dots{})
25+
%% Symbolic differentiation.
26+
%%
27+
%% Examples:
28+
%% @example
29+
%% @group
30+
%% syms x
31+
%% f = sin (cos (x));
32+
%% diff (f)
33+
%% @result{} (sym) -sin(x)⋅cos(cos(x))
34+
%% diff (f, x)
35+
%% @result{} (sym) -sin(x)⋅cos(cos(x))
36+
%% simplify (diff (f, x, x))
37+
%% @result{} (sym)
38+
%% 2
39+
%% - sin (x)⋅sin(cos(x)) - cos(x)⋅cos(cos(x))
40+
%% @end group
41+
%% @end example
42+
%%
43+
%% Partial differentiation:
44+
%% @example
45+
%% @group
46+
%% syms x y
47+
%% f = cos(2*x + 3*y);
48+
%% diff(f, x, y, x)
49+
%% @result{} (sym) 12⋅sin(2⋅x + 3⋅y)
50+
%% diff(f, x, 2, y, 3)
51+
%% @result{} (sym) -108⋅sin(2⋅x + 3⋅y)
52+
%% @end group
53+
%% @end example
54+
%%
55+
%% Other examples:
56+
%% @example
57+
%% @group
58+
%% diff(sym(1))
59+
%% @result{} (sym) 0
60+
%% @end group
61+
%% @end example
62+
%%
63+
%% @seealso{@@sym/int}
64+
%% @end defmethod
65+
66+
67+
function z = diff(f, varargin)
68+
69+
cmd = { 'f = _ins[0]'
70+
'args = _ins[1:]'
71+
'd = list(f.free_symbols)'
72+
'if len(d) == 0:'
73+
' return sympy.S(0),'
74+
'if len(args) == 0:'
75+
' if len(d) > 1:'
76+
' return ("NO_DEV_VAR"),'
77+
'else:'
78+
' if args[0].is_integer:'
79+
' if len(d) > 1:'
80+
' return ("NO_DEV_VAR"),'
81+
' d = d*args[0]'
82+
' else:'
83+
' d = [args[0]]'
84+
' for i in xrange(1, len(args)):'
85+
' if args[i].is_integer:'
86+
' if args[i] >= 1:'
87+
' d = d + [d[-1]]*(args[i]-1)'
88+
' else:'
89+
' d = d + [args[i]]'
90+
'return f.diff(*d),' };
91+
92+
varargin = sym(varargin);
93+
z = python_cmd (cmd, sym(f), varargin{:});
94+
95+
if strcmp(z, 'NO_DEV_VAR')
96+
error('Please set a derive var, actually we do not support autodetect vars to chain rule');
97+
end
98+
99+
end
100+
101+
102+
%!shared x,y,z
103+
%! syms x y z
104+
105+
%!test
106+
%! % basic
107+
%! assert(logical( diff(sin(x)) - cos(x) == 0 ))
108+
%! assert(logical( diff(sin(x),x) - cos(x) == 0 ))
109+
%! assert(logical( diff(sin(x),x,x) + sin(x) == 0 ))
110+
111+
%!test
112+
%! % these fail when doubles are not converted to sym
113+
%! assert(logical( diff(sin(x),x,2) + sin(x) == 0 ))
114+
%! assert(logical( diff(sym(1),x) == 0 ))
115+
%! assert(logical( diff(1,x) == 0 ))
116+
%! assert(logical( diff(pi,x) == 0 ))
117+
118+
%!test
119+
%! % symbolic diff of const (w/o variable) fails in sympy, but we work around
120+
%! assert (isequal (diff(sym(1)), sym(0)))
121+
122+
%!test
123+
%! % nth symbolic diff of const
124+
%! assert (isequal (diff(sym(1), 2), sym(0)))
125+
%! assert (isequal (diff(sym(1), sym(1)), sym(0)))
126+
127+
%!test
128+
%! % octave's vector difference still works
129+
%! assert(isempty(diff(1)))
130+
%! assert((diff([2 6]) == 4))
131+
132+
%!test
133+
%! % other forms
134+
%! f = sin(x);
135+
%! g = diff(f,x,2);
136+
%! assert (isequal (diff(f,2), g))
137+
%! assert (isequal (diff(f,sym(2)), g))
138+
%! assert (isequal (diff(f,sym(2),x), diff(g)))
139+
%! g = diff(f,x);
140+
%! assert (isequal (diff(f), g))
141+
%! assert (isequal (diff(f,1), g))
142+
%! assert (isequal (diff(f,1,x), diff(g)))
143+
144+
%!test
145+
%! % matrix
146+
%! A = [x sin(x); x*y 10];
147+
%! B = [1 cos(x); y 0];
148+
%! assert(isequal(diff(A,x),B))
149+
150+
%!error
151+
%! % bug: use symvar
152+
%! a = x*y;
153+
%! b = diff(a);
154+
155+
%!test
156+
%! % bug: symvar should be used on the matrix, not comp-by-comp
157+
%! a = [x y x*x];
158+
%! b = diff(a, x);
159+
%! assert (~isequal (b(2), 1))
160+
%! assert (isequal (b, [1 0 2*x]))
161+
%! b = diff(a, x, 1);
162+
%! assert (~isequal (b(2), 1))
163+
%! assert (isequal (b, [1 0 2*x]))

0 commit comments

Comments
 (0)