From f5b9d15beb020ed96553ea42c0a17ccca35eae64 Mon Sep 17 00:00:00 2001
From: Ferdinand Fischer <ferdinand.fischer@fau.de>
Date: Mon, 30 Mar 2020 17:13:45 +0200
Subject: [PATCH] quantity.Discrete/zeros will return an empty array if the
 requested size for zeros contains 0 as size. quantity.Discrete/compose works
 on quantities defined on quantity.EquidistantDomain

---
 +quantity/Discrete.m                | 31 +++++++++++++++++++----------
 +quantity/Domain.m                  |  3 ++-
 +quantity/EquidistantDomain.m       | 27 ++++++++++++++++---------
 +unittests/+quantity/testDiscrete.m | 16 ++++++++++++++-
 +unittests/+quantity/testDomain.m   |  1 -
 5 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/+quantity/Discrete.m b/+quantity/Discrete.m
index b30b347..40356a5 100644
--- a/+quantity/Discrete.m
+++ b/+quantity/Discrete.m
@@ -327,14 +327,21 @@ classdef  (InferiorClasses = {?quantity.Symbolic}) Discrete ...
 			% newValues will be reshaped into the form
 			%	f(z, t, zeta)
 			newValues = reshape( newValues, [tmpDomain.gridLength, 1] );
-			% now the common domains, i.e., zeta = z must be merged:
-			%	for this, find the index of the common domain in list of
-			%	temporary combined domain
-			% Before, do a cast to quantity.Domain in order to handle also
-			% quantity.EquidistantDomain objects.
-			intersectDomain = intersect( ...
-				quantity.Domain( originalDomain( ~logOfDomain ) ), ...
-				quantity.Domain( g(1).domain ) );
+			
+			if ~logOfDomain == 0
+				intersectDomain = [];
+			else
+				% now the common domains, i.e., zeta = z must be merged:
+				% For this, use intersect to find the common domains. The
+				% comparison is applied to the domain names. This is
+				% required, because intersect only works with objects of
+				% the same type. If one of the domains is an
+				% quantity.EquidistantDomain, the direct call of intersect
+				% on the domains will lead to an error.
+				intersectDomain = intersect( ...
+					[originalDomain( ~logOfDomain ).name], ...
+					[g(1).domain.name] );
+			end
 			
 			if ~isempty(intersectDomain)
 				
@@ -2236,8 +2243,12 @@ classdef  (InferiorClasses = {?quantity.Symbolic}) Discrete ...
 					domain, myParser.Results.gridName);
 			end
 			
-			O = zeros([domain.gridLength, valueSize(:)']);
-			P = quantity.Discrete(O, 'size', valueSize, 'domain', domain, varargin{:});
+			if any( valueSize == 0)
+				P = quantity.Discrete.empty(valueSize);
+			else
+				O = zeros([domain.gridLength, valueSize(:)']);
+				P = quantity.Discrete(O, 'size', valueSize, 'domain', domain, varargin{:});
+			end
 		end
 		
 		function q = value2cell(value, gridSize, valueSize)
diff --git a/+quantity/Domain.m b/+quantity/Domain.m
index 70ac7a6..ebf5ca4 100644
--- a/+quantity/Domain.m
+++ b/+quantity/Domain.m
@@ -329,7 +329,8 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
 				end
 			end % for it = 1 : numel(result)
 		end % ishomogenious
-	end % methods
+				
+	end % methods (Public)
 	
 	methods (Access = protected)
 		
diff --git a/+quantity/EquidistantDomain.m b/+quantity/EquidistantDomain.m
index 1b492d3..6cac171 100644
--- a/+quantity/EquidistantDomain.m
+++ b/+quantity/EquidistantDomain.m
@@ -3,7 +3,7 @@ classdef EquidistantDomain < quantity.Domain
 	%definition of a function. The discretization points are equally
 	%distributed over the domain.
 	
-	properties (Access = protected)
+	properties (SetAccess = protected)
 		stepSize;
 	end
 	
@@ -33,18 +33,18 @@ classdef EquidistantDomain < quantity.Domain
 				name = '',
 				lower = [],
 				upper = [],
-				optArgs.stepNumber = [];
-				optArgs.stepSize = [];
+				optArgs.stepNumber double {mustBeInteger};
+				optArgs.stepSize double {mustBePositive};
 				optArgs.exactBoundary = quantity.DomainBoundary.lower;
 			end
 			
 			if nargin > 1
 				
-				if  ~isempty(optArgs.stepSize) && ~isempty(optArgs.stepNumber)
+				if  isfield(optArgs, 'stepSize') && isfield(optArgs, 'stepNumber')
 					warning('If both, stepSize and stepNumber is set; steSize is chosen and stepNumber is neglected!')
 				end
 				
-				if ~isempty(optArgs.stepSize)
+				if isfield(optArgs, 'stepSize')
 					if optArgs.exactBoundary == quantity.DomainBoundary.lower
 						grid = lower : optArgs.stepSize : upper;
 					elseif optArgs.exactBoundary == quantity.DomainBoundary.upper
@@ -55,17 +55,26 @@ classdef EquidistantDomain < quantity.Domain
 							grid = [grid grid(end) + optArgs.stepSize];
 						end
 					end
-				elseif ~isempty(optArgs.stepNumber)
-					grid = linspace(lower, upper, optArgs.stepNumber);
+					
+					stepSize = optArgs.stepSize;
+					
 				else
-					grid = linspace(lower, upper);
+					
+					if isfield(optArgs, 'stepNumber')
+						grid = linspace(lower, upper, optArgs.stepNumber);
+					else
+						grid = linspace(lower, upper);
+					end
+					
+					stepSize = grid(2) - grid(1);
+					
 				end
 			else
 				grid = [];
 			end
 			
 			obj@quantity.Domain(name, grid);
-			obj.stepSize = optArgs.stepSize;
+			obj.stepSize = stepSize;
 		end
 		
 		function d = quantity.Domain(obj)
diff --git a/+unittests/+quantity/testDiscrete.m b/+unittests/+quantity/testDiscrete.m
index 5d5e065..f4540ef 100644
--- a/+unittests/+quantity/testDiscrete.m
+++ b/+unittests/+quantity/testDiscrete.m
@@ -105,6 +105,15 @@ Mog = M.compose(g, 'domain', tau);
 MoG(1:2, 1:2) = FoG;
 
 testCase.verifyEqual( MoG.on, MoG.on, 'AbsTol', 5e-16)
+
+% verify the case if one of the domains is a quantity.EquidistantDomain
+z = quantity.EquidistantDomain("z", 0, 1, 'stepNumber', 11);
+tau = quantity.EquidistantDomain("tau", 0, 2, 'stepNumber', 31);
+f = quantity.Discrete( z.grid + tau.grid', 'domain', [z, tau]);
+
+fog = f.compose(g, 'domain', tau);
+testCase.verifyEqual( fog.on, FoG.on, 'AbsTol', 5e-16)
+
 end
 
 function testCastDiscrete2Function(testCase)
@@ -1296,11 +1305,16 @@ testCase.verifyEqual(referenceResult, permute(ax2.on(), [1, 3, 2]), 'AbsTol', 1e
 end
 
 function testZeros(testCase)
+
 z = quantity.Discrete.zeros([2, 7, 8], {linspace(0,10)', linspace(0, 23, 11)}, 'gridName', {'a', 'b'});
 O = zeros(100, 11, 2, 7, 8);
-
 testCase.verifyEqual(z.on(), O);
 
+% test the creation of empty zeros:
+e = quantity.Discrete.zeros([3, 0], quantity.Domain.defaultGrid(10));
+
+testCase.verifyEmpty( e );
+
 end
 
 function testChangeGrid(testCase)
diff --git a/+unittests/+quantity/testDomain.m b/+unittests/+quantity/testDomain.m
index b8e9ca9..2729557 100644
--- a/+unittests/+quantity/testDomain.m
+++ b/+unittests/+quantity/testDomain.m
@@ -18,7 +18,6 @@ tc.TestData.d = d;
 
 end
 
-
 function testIsequidistant(tc)
 tc.verifyTrue(tc.TestData.a.isequidistant);
 tc.verifyTrue(all(isequidistant(tc.TestData.d)));
-- 
GitLab