From 19caf494686c97d1b4ba9c7b0b4aa521d865f0bd Mon Sep 17 00:00:00 2001
From: Jakob Gabriel <jakob.gabriel@fau.de>
Date: Thu, 6 Jun 2019 18:33:03 +0200
Subject: [PATCH] quantity.Discrete: - fixed infinite loop in mtimes()

quantity.Discrete & .Symbolic:
- renamed variables in isConstant() to improve readability
---
 +quantity/Discrete.m | 26 ++++++++++++++++----------
 +quantity/Symbolic.m |  8 ++++----
 2 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/+quantity/Discrete.m b/+quantity/Discrete.m
index 875b948..1ade316 100644
--- a/+quantity/Discrete.m
+++ b/+quantity/Discrete.m
@@ -159,10 +159,10 @@ classdef  (InferiorClasses = {?quantity.Symbolic, ?quantity.Operator}) Discrete
 		%---------------------------
 		% --- getter and setters ---
  		%---------------------------
-		function i = isConstant(obj)
+		function itIs = isConstant(obj)
 			% the quantity is interpreted as constant if it has no grid or
 			% it has a grid that is only one point.
-			i = isempty(obj.gridSize) || prod(obj.gridSize) == 1;
+			itIs = isempty(obj.gridSize) || prod(obj.gridSize) == 1;
 		end
 		function doNotCopy = get.doNotCopy(obj)
 			doNotCopy = obj.doNotCopyPropertiesName();
@@ -1143,9 +1143,11 @@ classdef  (InferiorClasses = {?quantity.Symbolic, ?quantity.Operator}) Discrete
 			
 			if isa(a, 'double')
 				P = (b' * a')';
+				% this recursion is safe, because isa(b, 'double') is considered in
+				% the if above.
 				return
 			end
-			if a.isConstant == 1 && b.isConstant == false
+			if a.isConstant() && ~b.isConstant()
 				% If the first argument a is constant value, then bad
 				% things will happen. To avoid this, we calculate
 				%	a * b = (b' * a')'
@@ -1154,7 +1156,7 @@ classdef  (InferiorClasses = {?quantity.Symbolic, ?quantity.Operator}) Discrete
 				P = (b' * a')';
 				return
 			end
-			if all(size(b) == 1) % b is a scalar value				
+			if numel(b) == 1 % b is a scalar value				
 				for k = 1:numel(a)
 					P(k) = innerMTimes(a(k), b);				
 				end
@@ -1162,15 +1164,19 @@ classdef  (InferiorClasses = {?quantity.Symbolic, ?quantity.Operator}) Discrete
 				return
 			end
 			
-			if all(size(a) == 1)
-				% TODO test the case a is double and b is scalar and vice
-				% versa
-				P = (b' * a')';
-					return
+			if numel(a) == 1
+				% in the previous version this was implemented recursivley with 
+				% P = (b' * a')'; but this was an ininite loop for numel(a) == 1 
+				% and b.isConstant()
+				for k = 1:numel(b)
+					P(k) = innerMTimes(a, b(k));				
 				end
+				P = reshape(P, size(b));
+				return
+			end
 
 			P = innerMTimes(a, b);			
-			end
+		end
 		
 		function P = innerMTimes(a, b)
 			assert(size(a, 2) == size(b, 1), ['For multiplication the ', ...
diff --git a/+quantity/Symbolic.m b/+quantity/Symbolic.m
index 354eb7a..9f9930a 100644
--- a/+quantity/Symbolic.m
+++ b/+quantity/Symbolic.m
@@ -93,11 +93,11 @@ classdef Symbolic < quantity.Function
 			end
 		end
 				
-		function i = isConstant(obj)
-			i = true;
+		function itIs = isConstant(obj)
+			itIs = true;
 			for k = 1:numel(obj)
-				i = i && isempty(symvar(obj(k).sym));
-				if ~i 
+				itIs = itIs && isempty(symvar(obj(k).sym));
+				if ~itIs 
 					break
 				end
 			end
-- 
GitLab