Domain.m 19.1 KB
Newer Older
1
2
classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
		handle & matlab.mixin.CustomDisplay & matlab.mixin.Copyable
3
4
	%DOMAIN class to describes a range of values on which a function can be defined.
	
5
	properties (SetAccess = protected)
6
7
8
		% The discrete points of the grid for the evaluation of a
		% continuous quantity. For an example, the function f(x) should be
		% considered on the domain x \in X = [0, 1]. Then, a grid can be
9
		% generated by X_grid = linspace(0, 1).
10
		grid (:, 1) double;
11
12
13
		
		% a speaking name for this domain; Should be unique, so that the
		% domain can be identified by the name.
14
		name (1,1) string = "";
15
		
16
17
18
		% number of discretization points == gridLength
		n (1,1) double;		
		
19
20
21
	end
	
	properties (Dependent)
22
23
		lower;		% lower bound of the domain == grid(1)
		upper;		% upper bound of the domain == grid(end)
24
	end
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
25
26
27
28

	properties (Dependent, Hidden)
		ones;
	end
29
30
	
	methods
31
		function obj = Domain(name, grid)
32
			%DOMAIN initialize the domain
33
34
35
			
			arguments
				name string = "";
36
				grid (:,1) double = [];
37
38
			end
			
39
			if nargin >= 1
40
				obj.grid = grid;
41
				obj.name = name;
Jakob Gabriel's avatar
Jakob Gabriel committed
42
				obj.n = length(obj.grid);
43
			end
44
		end % Domain()
45
		
Jakob Gabriel's avatar
Jakob Gabriel committed
46
		function it = get.ones(obj)
47
			it = builtin('ones', size(obj.grid));
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
48
49
		end
		
50
		function lower = get.lower(obj)
51
52
53
			% minimum value of grid = grid(1), since grid must be ascending
			lower = obj.grid(1);
		end % get.lower
54
55
		
		function upper = get.upper(obj)
56
57
58
			% maximum value of grid = grid(end), since grid must be ascending
			upper = obj.grid(end);
		end % get.upper()
59
		
60
61
		function d = quantity.EquidistantDomain(obj)
			d = quantity.Domain(obj.name, obj.grid);
62
63
		end
		
64
65
		function s = string(obj)
			s = obj.name;
66
67
68
		end		
		
		function quan = Discrete(obj)
69
			% DISCRETE casts the domain into a quantity.Discrete with the values of obj.grid.
70
71
72
			arguments
				obj (1, 1) quantity.Domain;
			end
73
			quan = quantity.Discrete(obj.grid, obj, 'name', obj.name);
74
75
76
		end % quantity.Discrete()
		
		function quan = Symbolic(obj)
77
78
			% SYMBOLIC casts the domain into a quantity.Symbolic with the grid name as symbolic
			% value.
79
80
81
			arguments
				obj (1, 1) quantity.Domain;
			end
82
			quan = quantity.Symbolic(sym(obj.name), obj, 'name', obj.name);
83
84
		end % Symbolic()
		
85
86
87
88
89
90
91
92
		function q = Function(obj)
			arguments
				obj (1,1) quantity.Domain;
			end
			
			q = quantity.Function(eval("@(" + obj.name + ")" + obj.name), obj, 'name', obj.name);
		end
		
93
	end
94
		
95
96
	methods (Access = public)
		
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
		function d = split(obj, splittingPoints, optArgs)
			%SPLIT splits the domain into subdomains
			% d = split(OBJ, SPLITTINGPOINTS) splits the domain into the
			% subdomains specified by SPLITTINGPOINTS. To be particular, a
			% domain (0,1) called with the SPLITTINGPOINTS 0.5 will be
			% split into two domains (0,0.5) and (0.5,1). To consider the
			% case if the SPLITTINGPOINTS are not exactly contained in the
			% grid, the closest grid point of OBJ.grid will be chosen as
			% splitting point.
			arguments
				obj
				splittingPoints double;
				optArgs.AbsTol (1,1) double = 1e-3;
				optArgs.warning (1,1) logical = true;
			end
112
			
113
114
			d(1:numel(splittingPoints)+1) = quantity.Domain();
			idx = zeros(numel(splittingPoints)+1,1);
115
116
117
118
			idx(1) = 1;
			
			for k = 1:numel(splittingPoints)
				
119
120
				% Search the grid point closest to the k-th splittingPoint
				[~, idx(k+1)] = min(abs((obj.grid - splittingPoints(k))));
121
				
122
123
124
125
126
127
128
129
				if optArgs.warning
					% verify that the distance of the chosen grid point to the
					% k-th splitting point is within some tolerances:
					delta = abs( obj.grid(idx(k+1)) - splittingPoints(k));
					if delta > optArgs.AbsTol
						warning('DOMAIN:split', ...
							'The deviation of the grid from desired splitting point %d is %d\n', splittingPoints(k), delta);
					end
130
131
				end
				
132
				d(k) = quantity.Domain(obj.name, obj.grid(idx(k):idx(k+1)));
133
134
135
136
137
138
			end
			
			d(k+1) = quantity.Domain(obj.name, obj.grid(idx(k+1):end));
			
		end
		
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
		function [i, logIdx] = contains(obj, d)
			
			logIdx = false(obj.n,1);
			
			if isa(d, 'quantity.Domain')
				d = d.grid;
			end
			
			grd = obj.ndgrid;
			grd = grd{1};
			
			for i = 1:numel(d)
				logIdx = logIdx | grd == d(i);
			end
			
			i = any(logIdx(:));
			
		end
		
158
159
		function isEq = isequal(obj, a)
			% isequal checks if two domains are equal.
160
			
161
			isEq = numel(obj) == numel(a);
162
163
			
			for k = 1:numel(obj)
164
165
				isEq = isEq && all(obj(k).name == a(k).name);
				isEq = isEq && isequal(obj(k).grid, a(k).grid);
166
			end
167
		end % isequal()
168
		
Jakob Gabriel's avatar
Jakob Gabriel committed
169
170
171
172
173
174
175
176
		function d = rename(obj, newName, oldName)
			% RENAME renames the name of the domain OBJ. 
			%
			%	d = rename(obj, newName) replaces all names of obj with the names specified by the
			%	string array newName
			%
			%	d = rename(obj, newName, oldName) replaces the names of obj specified by the string
			%	array oldName with the corresponding elements of the string array newName
177
			
Jakob Gabriel's avatar
Jakob Gabriel committed
178
179
180
181
182
183
184
185
186
187
			arguments
				obj quantity.Domain;
				newName string;
				oldName string = [obj.name];
			end % arguments
			
			assert(numel(newName) == numel(oldName), ...
				"number of new names must be equal to number of old names.");
			d = copy(obj);
			for it = 1 : numel(newName)
188
				d(obj.index(oldName(it))).name = newName{it};
Jakob Gabriel's avatar
Jakob Gabriel committed
189
190
191
			end % for it = 1 : numel(newName)
			assert(misc.isunique([d.name]), "the resulting domain must contain unique names");
		end % rename
192

193
194
195
196
197
198
199
200
201
		function nd = ndims(obj)
			%NDIMS number of dimensions of the domain specified by the
			%object-array.
			nd = size(obj(:), 1);
		end
		
		function n = numGridElements(obj)
			% NUMGRIDLEMENTS returns the number of the elements of the grid
			n = prod([obj.n]);
202
		end % numGridElements()
203
204
205
206
207
208
209
		
		function s = gridLength(obj)
			%GRIDLENGTH number of discretization points for each grid in the
			%object-array.
			s = [obj.n];
		end
		
210
		function d = find(obj, searchName)
211
212
213
214
			% FIND a domain in object-array of quantity.Domain
			%
			%	d = find(OBJ, NAME) returns the domain with the name NAME
			%	of the object-array of quantity.Domain OBJ.
215
216
217
			
			%	d = find(OBJ, NAME1, NAME2, ...) returns the domain array with the
			%	names NAME1 and NAME2 of the object-array of quantity.Domain OBJ.
218
219
			%
			%	d = find(OBJ, DOMAIN) find the domain with the name
220
221
222
223
224
			%	DOMAIN.name in the object-array of quantity.Domain OBJ. It
			%	only looks for the domain name and not the grid.
			%
			%	d = find(OBJ, { NAME or DOMAIN}) the NAME or the DOMAIN to
			%	be found can also be defined by cell-array.
225
226
227
228
229
230
			arguments
				obj quantity.Domain;
			end
			arguments (Repeating)
				searchName string;
			end
231
					
232
			idx = obj.index( searchName );
233
234
235
236
237
238
			
			if idx == 0
				d = [];
			else 
				d = obj( idx );
			end
239
		end
Jakob Gabriel's avatar
Jakob Gabriel committed
240
241
242
243
244
245
246
247
		
		function rest = remove(obj, toBeRemoved)
			% REMOVE removes the domain specified by toBeRemoved from the quantity.Domain array obj.
			%
			%	rest = remove(obj, toBeRemoved) removes the domain specified by toBeRemoved from the 
			%	quantity.Domain array obj. toBeRemoved may be a string or a domain or a array of
			%	those.
			
248
			[~, logicalIdxToBeRemoved] = obj.index(toBeRemoved);
Jakob Gabriel's avatar
Jakob Gabriel committed
249
250
251
252
			
			rest = obj(~logicalIdxToBeRemoved);
		end % remove()
		
Jakob Gabriel's avatar
Jakob Gabriel committed
253
254
255
256
257
258
259
260
261
262
263
264
		function obj = replace(obj, toBeReplaced)
			% REPLACE replaced a domain with another domain.
			%
			%	obj = replace(obj, toBeReplaced) replaces the element of the obj with the same name
			%		as the toBeReplaced domain with the new domain toBeRelaced.
			
			thisIdx = obj.index(toBeReplaced);
			if thisIdx > 0
				obj(thisIdx) = toBeReplaced;
			end
		end % replace()
		
265
		function [idx, log] = index( obj, searchName, position)
266
			%% GRIDINDEX returns the index of the grid
267
			% [idx, log] = index(obj, names) searches in the name
268
269
270
271
272
273
			% properties of obj for the "names" and returns its index as
			% "idx" and its logical index as "log"
			arguments
				obj
				searchName = [obj.name];
				position string = "all";
274
			end
275
			
276
277
			if isa(searchName, 'quantity.Domain')
				searchName = [searchName.name];
278
279
			end
			
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
			objNames = [obj.name];
			
			if isempty(objNames)
				idx = 0;
				log = [];
			else
				searchName = misc.ensureString( searchName );
				
				log = false(size(objNames));
				counter = 1:numel(objNames);
				idx = [];
				for k = 1 : numel(searchName)
					log_ = objNames == searchName(k);
					log = log | log_;
					idx = [idx counter( log_ )];
				end
				if isempty(idx)
					idx = 0;
				end
			end
300
			
301
302
			if position == "first"
				idx = idx(1);
303
			end
304
305
306
307
308
309
		end
		
		function [idx, log] = gridIndex(obj, varargin)
			warning("DEPRICATED: Use quantity.Domain/index instead")
			[idx, log] = obj.index(varargin{:});
		end % index
310
		
311
		function l = ne(obj, obj2)
312
			% ~= Not equal.
313
			l = ~(obj == obj2);
314
		end % ne()
315
				
316
		function [joinedDomain, index] = join(domain1, domain2)
317
318
319
			% JOIN combine two domains
			% [joinedDomain, index] = join(domain1, domain2) combines the domain1 and domain2, such
			% that every gridName only occurs once and that the finer grid of both is used.
320
321
322
323
324
325
326
327
328
329
			arguments
				domain1 quantity.Domain = quantity.Domain.empty
				domain2 quantity.Domain = quantity.Domain.empty
			end
			
			if nargin == 1 && length(domain1) == 1
				joinedDomain = domain1;
				index = 1;
				return;
			end
330
			
331
332
333
334
335
336
			% remove empty domains:
			emptyIdx = arrayfun(@(c) ~isempty(c), domain1);
			domain1 = domain1(emptyIdx);
			emptyIdx = arrayfun(@(c) ~isempty(c), domain2);
			domain2 = domain2(emptyIdx);
						
337
			[joinedGrid, index] = unique([domain1.name, domain2.name], 'stable');
338
			
339
			joinedDomain(1 : numel(joinedGrid)) = quantity.Domain();
340
341
342
343
			
			% check for each grid if it is in the domain of obj1 or obj2 or
			% both
			for i = 1 : numel(joinedGrid)
344
				currentGridName = joinedGrid(i);
345
346
				[index1, logicalIndex1] = domain1.index(currentGridName, "first");
				[index2, logicalIndex2] = domain2.index(currentGridName, "first");
347
								
348
349
350
				% Check if a domain is in both domains:
				%	-> then take the finer one of both
				if any(logicalIndex1) && any(logicalIndex2)
351
352
					tempDomain1 = domain1(index1);
					tempDomain2 = domain2(index2);
353
					
354
355
					assert( numeric.near( tempDomain1.lower, tempDomain2.lower), 'Grids must have same domain for join')
					assert( numeric.near( tempDomain1.upper, tempDomain2.upper), 'Grids must have same domain for join')
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
356

357
358
359
360
361
362
363
					if tempDomain1.gridLength > tempDomain2.gridLength
						joinedDomain(i) = tempDomain1;
					else
						joinedDomain(i) = tempDomain2;
					end
				% If it is not in both, -> just take the normal grid
				elseif any(logicalIndex1)
364
					joinedDomain(i) = domain1(index1(1));
365
				elseif any(logicalIndex2)
366
					joinedDomain(i) = domain2(index2);
367
368
369
				end
				
			end
370
		end % join()
371
		
372
373
374
		function i = isempty(obj)
			i = any(size(obj) == 0);
			i = i || any( cellfun(@isempty, {obj.grid} ) );
375
		end % isempty()
376
377
378
379
380
381
382
383
384
385
		
		function i = isSubDomainOf(obj, d)
			% ISSUBDOMAIN 
			%	i = isSubDomainOf(OBJ, D) checks if the domain OBJ is a
			%	sub-domain of D.
			
			i = obj.lower >= d.lower && ...
				obj.upper <= d.upper;	
		end % isSubDomainOf
		
386
		function matGrid = ndgrid(obj)
387
388
			% NDGRID generate a mesh for this domain
			% matGrid = ndgrid(obj) calles ndgrid for the default grid, if no other grid
389
390
391
392
393
394
395
396
397
398
			% is specified. Empty grid as input returns empty cell as
			% result.
			if isempty(obj)
				matGrid = {};
			else
				grids = {obj.grid};
				[matGrid{1:obj.ndims}] = ndgrid(grids{:});
			end
		end % ndgrid()
		
399
400
401
402
403
404
405
406
407
408
409
410
		function objReal = real(obj)
			% real returns a quantity.Domain objReal whichs grid is only the real
			% part of the possibly complex grid in obj.
			objReal = quantity.Domain(obj.name, real(obj.grid));
		end % real()
		
		function objImag = imag(obj)
			% imag returns a quantity.Domain objImag whichs grid is only the
			% imaginary part of the possibly complex grid in obj.
			objImag = quantity.Domain(obj.name, imag(obj.grid));
		end % imag()
		
411
		function [idx, newDomain] = getPermutationIdx(obj, order)
412
413
			
			if isa(order, 'quantity.Domain')
414
415
416
				names = [order.name];
			elseif iscell(order) || ischar(order) || isstring(order)
				names = misc.ensureString( order );
417
			else
418
				error('the input parameter order must be a array of quantity.Domain objects or a string-array')
419
420
			end
						
421
			idx = cellfun(@(v) obj.index(v), names); % #todo@domainNameString
422
423
424
425
426
427
			
			if isa(order, 'quantity.Domain')
				newDomain = order;
			else			
				newDomain = obj(idx);
			end
428
		end % getPermutationIdx()
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
		
		
		function [newObj, I] = sort(obj, varargin)
			%SORT sorts the grid of the object in a desired order
			% obj = sortGrid(obj) sorts the grid in alphabetical order.
			% obj = sort(obj, 'descend') sorts the grid in descending
			% alphabetical order.
			
			if nargin == 2 && strcmp(varargin{1}, 'descend')
				descend = 1;
			elseif nargin == 1 || strcmp(varargin{1}, 'ascend')
				descend = 0;
			else
				error(['Unknown sorting order' char( varargin{1} )])
			end
			
			% only sort the grids if there is something to sort
			if obj.ndims > 1
447
				gridNames = [obj.name];
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
448
449
450
451
452
453
454
455
456
457
458
459
460
461
				
				% this is the default case for ascending alphabetical
				% order
				[sortedNames, I] = sort(gridNames);
				
				% if descending: flip the order of the entries
				if descend
					sortedNames = flip(sortedNames);
					I = flip(I);
				end
				
				% sort the grid entries
				myGrids = {obj.grid};
				myGrids = myGrids(I);
462
463
				
				newObj(1:length(myGrids)) = quantity.Domain();
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
464
				for k = 1:length(myGrids)
465
					newObj(k) = quantity.Domain(sortedNames{k}, myGrids{k});
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
466
467
468
469
				end
			else
				newObj = obj;
			end
470
471
472
473
474
475
476
		end% sort()
		
		function result = isequidistant(obj, AbsTol)
			% ISEQUIDISTANT(obj) returns true, if the grid is homogenious, i.e. the
			% grid points are equidistant and false else. Also works with
			% quantity.Domain arrays.
			% ISEQUIDISTANT(obj, AbsTol) allows perturbations in the spacing of
477
			% up to the absolute maximum defined by AbsTol. Default: 1e3*eps.
478
479
480
481
482
483
484
485
486
487
488
489
490
			
			arguments
				obj quantity.Domain;
				AbsTol = 1e3*eps;
			end % arguments
			
			result = true(size(obj));
			for it = 1 : numel(result)
				spacing = diff(obj(it).grid);
				if any(diff(obj(it).grid) - mean(spacing) > AbsTol)
					result = false;
				end
			end % for it = 1 : numel(result)
Jakob Gabriel's avatar
Jakob Gabriel committed
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
		end % isequidistant()
		
		function f1 = plot(obj)
			% PLOT create plot of grid points (cross makeing) and slope (dashed).
			% This can be insightful for non-equidistant grids
			arguments
				obj quantity.Domain;
			end
			
			f1 = figure();
			numDomains = numel(obj);
			for it = 1 : numDomains
				subplot(1, numDomains, it);
				equidistantSpacing = diff([obj(it).lower, obj(it).upper]) / (obj(it).n-1);
				plot(linspace(obj(it).lower, obj(it).upper, obj(it).n), obj(it).grid, 'x');
				hold on;
				plot(linspace(obj(it).lower + equidistantSpacing / 2, ...
					obj(it).upper + equidistantSpacing / 2, obj(it).n-1), ...
					diff(obj(it).grid) / equidistantSpacing, '--');
				xlim(obj(it).grid([1, end]));
				xlabel(obj(it).name);
				ylabel(obj(it).name + " (x), " ...
					+ obj(it).name + "_{" + obj(it).name + "} (- -)");
			end % for it = 1 : numDomains
		end % plot()
516
517
				
	end % methods (Public)
518
	
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
519
	methods (Access = protected)
Jakob Gabriel's avatar
Jakob Gabriel committed
520
		
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
		function s = getPropertyGroups(obj)
			% Function to display the correct values
			
			if isempty(obj)
				s = getPropertyGroups@matlab.mixin.CustomDisplay(obj);
				return;
			else
				s = getPropertyGroups@matlab.mixin.CustomDisplay(obj(1));
			end
			
			if numel(obj) ~= 1
				
				grids = {obj.grid};
				
				sizes = cellfun(@(g)size(g), grids, 'UniformOutput', false);							
								
				s.PropertyList.grid = ...
					[sprintf('%ix%i,  ', cell2mat(sizes)) sprintf('\b\b\b')];
				s.PropertyList.name = ...
					[sprintf('%s,  ', obj.name) sprintf('\b\b\b')];
				s.PropertyList.lower = ... 
					[sprintf('%d,  ', obj.lower) sprintf('\b\b\b')];
				s.PropertyList.upper = ... 
					[sprintf('%.3f,  ', obj.upper) sprintf('\b\b\b')];
				s.PropertyList.n = ...
					[sprintf('%i,  ', obj.n) sprintf('\b\b\b')];
			end
		end % getPropertyGroups
Jakob Gabriel's avatar
Jakob Gabriel committed
549
		
550
	end % methods (Access = protected)
Ferdinand Fischer's avatar
tmp    
Ferdinand Fischer committed
551
	
552
	methods (Static)	
553
554
		function d = gridCells2domain(grids, gridNames)
			grids = misc.ensureIsCell(grids);
555
556
557
558
559
			if isempty(gridNames)
				gridNames = {};
			else
				gridNames = misc.ensureIsCell(gridNames);
			end
560
			
561
562
			assert(numel(grids) == numel(gridNames), ...
				"Number of grid vectors is not equal to number of grid names")
563
564
565
566

			d = quantity.Domain.empty();
			
			for k = 1:length(grids)
567
				d = [d quantity.Domain(gridNames{k}, grids{k})];
568
			end
569
		end % gridCells2domain()
570
		
571
572
573
574
575
576
577
578
579
580
581
582
583
584
		function d = defaultDomain(gridSize, name)
			%DEFAULTDOMAIN generate default domain
			% d = defaultDomain() will create a default domain with a grid
			%   from 0 to 1 with 100 points and the default name x_1
			% d = defaultDomain(GRIDSIZE) will create a default domain with
			% a default grid of size specified in GRIDSIZE. The domains
			% will have the default names
			%   x_1, x_2, ...
			% d = defaultDomain(GRIDSIZE, NAME) will create a default
			% domain with a default grid of size specified in GRIDSIZE. The
			% domains will have the names specified in NAME.
			arguments
				gridSize double = 100;
				name string = quantity.Domain.defaultGridNames(gridSize);
585
586
587
			end
			
			% generate a default gird with given sizes
588
			d(1:length(gridSize)) = quantity.Domain();
589
590
591
592
593
594
595
			for k = 1:length(gridSize)
				
				o = ones(1, length(gridSize) + 1); % + 1 is required to deal with one dimensional grids
				o(k) = gridSize(k);
				O = ones(o);
				O(:) = linspace(0, 1, gridSize(k));
				
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
				d(k) = quantity.Domain(name{k}, O);
			end
		end
		
		function g = defaultGrid(varargin)
			%DEFAULTGRID generate default grid for a quantity
			warning('DEPRICATED! Use quantity.Domain.defaultDomain instead.');
			g = quantity.Domain.defaultDomain(varargin{:});
		end
		
		function name = defaultGridNames(gridSize)
			%DEFAULTGRIDNAMES generates default grid names
			% name = defaultGridNames(GRIDSIZE) generates default grid
			% names for a grid of size GRIDSIZE. The default names will be
			% x_1, x_2, ...
			name = cell(1, length(gridSize));
			for k = 1:length(gridSize)
				name{k} = ['x_' num2str(k)];
614
			end
615
		end
616
		
617
		
618
		function [myDomain, unmatched] = parser(varargin)
619
620
621
			%% domain parser
			domainParser = misc.Parser();
			domainParser.addParameter('domain', {}, @(g) isa(g, 'quantity.Domain'));
622
			domainParser.addParameter('gridName', '');
623
624
			domainParser.addParameter('grid', [], @(g) isnumeric(g) || iscell(g));
			domainParser.parse(varargin{:});
625
626
627
			
			if domainParser.isDefault('domain')
				% case: the gridNames and the gridValues are defined:
628
629
630
				%	-> initialize quantity.Domain objects with the
				%	specified values

631
				myGridName = misc.ensureString(domainParser.Results.gridName);
632
633
634
635
636
637
638
639
				myGrid = misc.ensureIsCell(domainParser.Results.grid);

				assert(isequal(numel(myGrid), numel(myGridName)), ...
					'number of grids and gridNames must be equal');

				% initialize the domain objects
				myDomain = quantity.Domain.empty();
				for k = 1:numel(myGrid)
640
					myDomain(k) = quantity.Domain(myGridName(k), myGrid{k});
641
				end
642
			elseif ~domainParser.isDefault('domain')
643
				% case: the domains are specified as domain
644
				% objects.
645
646
647
				myDomain = domainParser.Results.domain;	
			else			
				error('No domain is specified! A domain is obligatory for the initialization of a quantity.')
648
649
			end	
			
650
			assert(misc.isunique([myDomain.name]), ...
651
652
653
				'The names of the domain must be unique');
			
			unmatched = domainParser.UnmatchedNameValuePair;
654
		end % parser()
655
		
656
	end % methods Static
657
end % classdef