From 78f2a2708006a02302bb1dd3a9e30c1ad7eff27e Mon Sep 17 00:00:00 2001 From: latot Date: Thu, 1 Sep 2016 20:35:12 -0300 Subject: [PATCH 1/4] add diff2 --- inst/@sym/diff2.m | 163 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 inst/@sym/diff2.m diff --git a/inst/@sym/diff2.m b/inst/@sym/diff2.m new file mode 100644 index 000000000..33618dfb4 --- /dev/null +++ b/inst/@sym/diff2.m @@ -0,0 +1,163 @@ +%% Copyright (C) 2014-2016 Colin B. Macdonald +%% +%% This file is part of OctSymPy. +%% +%% OctSymPy is free software; you can redistribute it and/or modify +%% it under the terms of the GNU General Public License as published +%% by the Free Software Foundation; either version 3 of the License, +%% or (at your option) any later version. +%% +%% This software is distributed in the hope that it will be useful, +%% but WITHOUT ANY WARRANTY; without even the implied warranty +%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +%% the GNU General Public License for more details. +%% +%% You should have received a copy of the GNU General Public +%% License along with this software; see the file COPYING. +%% If not, see . + +%% -*- texinfo -*- +%% @documentencoding UTF-8 +%% @defmethod @@sym diff (@var{f}) +%% @defmethodx @@sym diff (@var{f}, @var{x}) +%% @defmethodx @@sym diff (@var{f}, @var{x}, @dots{}) +%% @defmethodx @@sym diff (@var{f}, @dots{}) +%% Symbolic differentiation. +%% +%% Examples: +%% @example +%% @group +%% syms x +%% f = sin (cos (x)); +%% diff (f) +%% @result{} (sym) -sin(x)⋅cos(cos(x)) +%% diff (f, x) +%% @result{} (sym) -sin(x)⋅cos(cos(x)) +%% simplify (diff (f, x, x)) +%% @result{} (sym) +%% 2 +%% - sin (x)⋅sin(cos(x)) - cos(x)⋅cos(cos(x)) +%% @end group +%% @end example +%% +%% Partial differentiation: +%% @example +%% @group +%% syms x y +%% f = cos(2*x + 3*y); +%% diff(f, x, y, x) +%% @result{} (sym) 12⋅sin(2⋅x + 3⋅y) +%% diff(f, x, 2, y, 3) +%% @result{} (sym) -108⋅sin(2⋅x + 3⋅y) +%% @end group +%% @end example +%% +%% Other examples: +%% @example +%% @group +%% diff(sym(1)) +%% @result{} (sym) 0 +%% @end group +%% @end example +%% +%% @seealso{@@sym/int} +%% @end defmethod + + +function z = diff(f, varargin) + + cmd = { 'f = _ins[0]' + 'args = _ins[1:]' + 'd = list(f.free_symbols)' + 'if len(d) == 0:' + ' return sympy.S(0),' + 'if len(args) == 0:' + ' if len(d) > 1:' + ' return ("NO_DEV_VAR"),' + 'else:' + ' if args[0].is_integer:' + ' if len(d) > 1:' + ' return ("NO_DEV_VAR"),' + ' d = d*args[0]' + ' else:' + ' d = [args[0]]' + ' for i in xrange(1, len(args)):' + ' if args[i].is_integer:' + ' if args[i] >= 1:' + ' d = d + [d[-1]]*(args[i]-1)' + ' else:' + ' d = d + [args[i]]' + 'return f.diff(*d),' }; + + varargin = sym(varargin); + z = python_cmd (cmd, sym(f), varargin{:}); + + if strcmp(z, 'NO_DEV_VAR') + error('Please set a derive var, actually we do not support autodetect vars to chain rule'); + end + +end + + +%!shared x,y,z +%! syms x y z + +%!test +%! % basic +%! assert(logical( diff(sin(x)) - cos(x) == 0 )) +%! assert(logical( diff(sin(x),x) - cos(x) == 0 )) +%! assert(logical( diff(sin(x),x,x) + sin(x) == 0 )) + +%!test +%! % these fail when doubles are not converted to sym +%! assert(logical( diff(sin(x),x,2) + sin(x) == 0 )) +%! assert(logical( diff(sym(1),x) == 0 )) +%! assert(logical( diff(1,x) == 0 )) +%! assert(logical( diff(pi,x) == 0 )) + +%!test +%! % symbolic diff of const (w/o variable) fails in sympy, but we work around +%! assert (isequal (diff(sym(1)), sym(0))) + +%!test +%! % nth symbolic diff of const +%! assert (isequal (diff(sym(1), 2), sym(0))) +%! assert (isequal (diff(sym(1), sym(1)), sym(0))) + +%!test +%! % octave's vector difference still works +%! assert(isempty(diff(1))) +%! assert((diff([2 6]) == 4)) + +%!test +%! % other forms +%! f = sin(x); +%! g = diff(f,x,2); +%! assert (isequal (diff(f,2), g)) +%! assert (isequal (diff(f,sym(2)), g)) +%! assert (isequal (diff(f,sym(2),x), diff(g))) +%! g = diff(f,x); +%! assert (isequal (diff(f), g)) +%! assert (isequal (diff(f,1), g)) +%! assert (isequal (diff(f,1,x), diff(g))) + +%!test +%! % matrix +%! A = [x sin(x); x*y 10]; +%! B = [1 cos(x); y 0]; +%! assert(isequal(diff(A,x),B)) + +%!error +%! % bug: use symvar +%! a = x*y; +%! b = diff(a); + +%!test +%! % bug: symvar should be used on the matrix, not comp-by-comp +%! a = [x y x*x]; +%! b = diff(a, x); +%! assert (~isequal (b(2), 1)) +%! assert (isequal (b, [1 0 2*x])) +%! b = diff(a, x, 1); +%! assert (~isequal (b(2), 1)) +%! assert (isequal (b, [1 0 2*x])) From e7a4dc3e5fbf3766ce1f8e22ee6ed927727e3dae Mon Sep 17 00:00:00 2001 From: latot Date: Thu, 1 Sep 2016 21:03:32 -0300 Subject: [PATCH 2/4] update tests --- inst/@sym/diff2.m | 61 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/inst/@sym/diff2.m b/inst/@sym/diff2.m index 33618dfb4..a36630f3c 100644 --- a/inst/@sym/diff2.m +++ b/inst/@sym/diff2.m @@ -29,11 +29,11 @@ %% @group %% syms x %% f = sin (cos (x)); -%% diff (f) +%% diff2 (f) %% @result{} (sym) -sin(x)⋅cos(cos(x)) -%% diff (f, x) +%% diff2 (f, x) %% @result{} (sym) -sin(x)⋅cos(cos(x)) -%% simplify (diff (f, x, x)) +%% simplify (diff2 (f, x, x)) %% @result{} (sym) %% 2 %% - sin (x)⋅sin(cos(x)) - cos(x)⋅cos(cos(x)) @@ -45,9 +45,9 @@ %% @group %% syms x y %% f = cos(2*x + 3*y); -%% diff(f, x, y, x) +%% diff2(f, x, y, x) %% @result{} (sym) 12⋅sin(2⋅x + 3⋅y) -%% diff(f, x, 2, y, 3) +%% diff2(f, x, 2, y, 3) %% @result{} (sym) -108⋅sin(2⋅x + 3⋅y) %% @end group %% @end example @@ -55,7 +55,7 @@ %% Other examples: %% @example %% @group -%% diff(sym(1)) +%% diff2(sym(1)) %% @result{} (sym) 0 %% @end group %% @end example @@ -104,60 +104,59 @@ %!test %! % basic -%! assert(logical( diff(sin(x)) - cos(x) == 0 )) -%! assert(logical( diff(sin(x),x) - cos(x) == 0 )) -%! assert(logical( diff(sin(x),x,x) + sin(x) == 0 )) +%! assert(logical( diff2(sin(x)) - cos(x) == 0 )) +%! assert(logical( diff2(sin(x),x) - cos(x) == 0 )) +%! assert(logical( diff2(sin(x),x,x) + sin(x) == 0 )) %!test %! % these fail when doubles are not converted to sym -%! assert(logical( diff(sin(x),x,2) + sin(x) == 0 )) -%! assert(logical( diff(sym(1),x) == 0 )) -%! assert(logical( diff(1,x) == 0 )) -%! assert(logical( diff(pi,x) == 0 )) +%! assert(logical( diff2(sin(x),x,2) + sin(x) == 0 )) +%! assert(logical( diff2(sym(1),x) == 0 )) +%! assert(logical( diff2(1,x) == 0 )) +%! assert(logical( diff2(pi,x) == 0 )) %!test %! % symbolic diff of const (w/o variable) fails in sympy, but we work around -%! assert (isequal (diff(sym(1)), sym(0))) +%! assert (isequal (diff2(sym(1)), sym(0))) %!test %! % nth symbolic diff of const -%! assert (isequal (diff(sym(1), 2), sym(0))) -%! assert (isequal (diff(sym(1), sym(1)), sym(0))) +%! assert (isequal (diff2(sym(1), 2), sym(0))) +%! assert (isequal (diff2(sym(1), sym(1)), sym(0))) %!test %! % octave's vector difference still works -%! assert(isempty(diff(1))) -%! assert((diff([2 6]) == 4)) +%! assert(isempty(diff2(1))) +%! assert((diff2([2 6]) == 4)) %!test %! % other forms %! f = sin(x); -%! g = diff(f,x,2); -%! assert (isequal (diff(f,2), g)) -%! assert (isequal (diff(f,sym(2)), g)) -%! assert (isequal (diff(f,sym(2),x), diff(g))) -%! g = diff(f,x); -%! assert (isequal (diff(f), g)) -%! assert (isequal (diff(f,1), g)) -%! assert (isequal (diff(f,1,x), diff(g))) +%! g = diff2(f,x,2); +%! assert (isequal (diff2(f,2), g)) +%! assert (isequal (diff2(f,sym(2)), g)) +%! assert (isequal (diff2(f,sym(2),x), diff2(g))) +%! g = diff2(f,x); +%! assert (isequal (diff2(f), g)) +%! assert (isequal (diff2(f,1), g)) +%! assert (isequal (diff2(f,1,x), diff2(g))) %!test %! % matrix %! A = [x sin(x); x*y 10]; %! B = [1 cos(x); y 0]; -%! assert(isequal(diff(A,x),B)) +%! assert(isequal(diff2(A,x),B)) %!error -%! % bug: use symvar %! a = x*y; -%! b = diff(a); +%! b = diff2(a); %!test %! % bug: symvar should be used on the matrix, not comp-by-comp %! a = [x y x*x]; -%! b = diff(a, x); +%! b = diff2(a, x); %! assert (~isequal (b(2), 1)) %! assert (isequal (b, [1 0 2*x])) -%! b = diff(a, x, 1); +%! b = diff2(a, x, 1); %! assert (~isequal (b(2), 1)) %! assert (isequal (b, [1 0 2*x])) From b87e976cacfbabef987cd37a3576a40b1b88e0f9 Mon Sep 17 00:00:00 2001 From: latot Date: Thu, 1 Sep 2016 21:21:33 -0300 Subject: [PATCH 3/4] little fix --- inst/@sym/diff2.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/@sym/diff2.m b/inst/@sym/diff2.m index a36630f3c..e8544b6ee 100644 --- a/inst/@sym/diff2.m +++ b/inst/@sym/diff2.m @@ -64,7 +64,7 @@ %% @end defmethod -function z = diff(f, varargin) +function z = diff2(f, varargin) cmd = { 'f = _ins[0]' 'args = _ins[1:]' From a3c15fd5bdfbf1d2b8bc7a16d96b7c4764252a6b Mon Sep 17 00:00:00 2001 From: latot Date: Sat, 3 Sep 2016 22:58:36 -0300 Subject: [PATCH 4/4] lets sympy handle some vars --- inst/@sym/diff2.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inst/@sym/diff2.m b/inst/@sym/diff2.m index e8544b6ee..2f9c35435 100644 --- a/inst/@sym/diff2.m +++ b/inst/@sym/diff2.m @@ -18,10 +18,10 @@ %% -*- texinfo -*- %% @documentencoding UTF-8 -%% @defmethod @@sym diff (@var{f}) -%% @defmethodx @@sym diff (@var{f}, @var{x}) -%% @defmethodx @@sym diff (@var{f}, @var{x}, @dots{}) -%% @defmethodx @@sym diff (@var{f}, @dots{}) +%% @defmethod @@sym diff2 (@var{f}) +%% @defmethodx @@sym diff2 (@var{f}, @var{x}) +%% @defmethodx @@sym diff2 (@var{f}, @var{x}, @dots{}) +%% @defmethodx @@sym diff2 (@var{f}, @dots{}) %% Symbolic differentiation. %% %% Examples: @@ -73,7 +73,7 @@ ' return sympy.S(0),' 'if len(args) == 0:' ' if len(d) > 1:' - ' return ("NO_DEV_VAR"),' + ' d = []' 'else:' ' if args[0].is_integer:' ' if len(d) > 1:'