Commit 7765fb90 authored by Jakob Gabriel's avatar Jakob Gabriel
Browse files

quantity.Discrete.compose: some clean-up & readability

parent 945d1cb4
...@@ -251,18 +251,18 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -251,18 +251,18 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
h = misc.hash(data); h = misc.hash(data);
end % hash() end % hash()
function d = compositionDomain(obj, domainName) function thisDomain = compositionDomain(obj, domainName)
% compositionDomain is a helper function for compose.
assert(isscalar(obj)); arguments
obj (1, 1) quantity.Discrete;
d = obj.on(); domainName (1, 1) string;
end
% the evaluation of obj.on( compositionDomain ) is done by: dDiscrete = obj.on();
d_size = size(d);
% vectorization of the n-d-grid: compositionDomain % vectorization of the n-d-grid: compositionDomain
d = quantity.Domain(domainName, d(:)); thisDomain = quantity.Domain(domainName, dDiscrete(:));
end end % compositionDomain
function obj_hat = compose(obj, g, optionalArgs) function obj_hat = compose(obj, g, optionalArgs)
% COMPOSE compose two functions % COMPOSE compose two functions
...@@ -272,41 +272,35 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -272,41 +272,35 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% if f(t) = obj, g is G and f_hat is OBJ_hat. % if f(t) = obj, g is G and f_hat is OBJ_hat.
arguments arguments
obj obj
g quantity.Discrete; g (1, 1) quantity.Discrete;
optionalArgs.domain quantity.Domain = obj(1).domain; optionalArgs.domain (1, 1) quantity.Domain = obj(1).domain(1);
end end
myCompositionDomain = optionalArgs.domain;
originalDomain = obj(1).domain;
% quick workaround to apply to marix valued quantities % quick workaround to apply to marix valued quantities
if numel(obj) > 1 if numel(obj) > 1
obj_hat = copy(obj);
optArgs = misc.struct2namevaluepair( optionalArgs ); optArgs = misc.struct2namevaluepair( optionalArgs );
for k = 1:numel(obj) for k = 1:numel(obj)
obj_hat(k) = compose(obj(k), g, optArgs{:}); obj_hat(k) = compose(obj(k), g, optArgs{:});
end end
obj_hat = reshape(obj_hat, size(obj));
return return
end end
assert( length( myCompositionDomain ) == 1 ); myCompositionDomain = optionalArgs.domain;
originalDomain = obj(1).domain;
[idx, logOfDomain] = originalDomain.index(myCompositionDomain); [idx, logOfDomain] = originalDomain.index(myCompositionDomain);
assert( isequal( originalDomain(idx), myCompositionDomain ), ...
'Composition of functions: The domains for the composition must be equal. A grid join is not implemented yet.');
assert( any( logOfDomain ) )
% get the composition domain: % get the composition domain:
% For the argument y of a function f(y) which should be % For the argument y of a function f(y), which should be
% composed by y = g(z,t) a new dommain will be created on the % composed by y = g(z,t), a new domain is created by evaluating g(z,t).
% basis of evaluation of g(z,t). composeOnDomain = g.compositionDomain(myCompositionDomain.name);
composeOnDomain = ...
g.compositionDomain(myCompositionDomain.name); % check if the composition domain is in the range of definition of obj.domain.
if ~composeOnDomain.isSubDomainOf( originalDomain(idx) )
% check if the composition domain is in the range of definition
% of obj.
if ~composeOnDomain.isSubDomainOf( myCompositionDomain )
warning('quantity:Discrete:compose', .... warning('quantity:Discrete:compose', ....
'The composition domain is not a subset of obj.domain! The missing values will be extrapolated.'); "The composition domain is not a subset of obj.domain, i.e. the values of g " ...
end + "exceed the grid of obj.domain. Missing values will be extrapolated.");
end
% evaluation on the new grid: % evaluation on the new grid:
% the order of the domains is important. At first, the % the order of the domains is important. At first, the
...@@ -317,9 +311,8 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -317,9 +311,8 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% g(z,t) % g(z,t)
% #TODO: optimize the memory consumption of this function. % #TODO: optimize the memory consumption of this function.
% 1) only consider the unqiue grid points in evaluationDomain % 1) only consider the unique grid points in evaluationDomain
% 2) do the conversion of the evaluationDomain directly to % 2) do the conversion of the evaluationDomain directly to the target domain.
% the target domain.
evaluationDomain = [originalDomain( ~logOfDomain ), composeOnDomain ]; evaluationDomain = [originalDomain( ~logOfDomain ), composeOnDomain ];
newValues = obj.on( evaluationDomain ); newValues = obj.on( evaluationDomain );
...@@ -328,7 +321,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -328,7 +321,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% dimension is any domain but the composition domain and the % dimension is any domain but the composition domain and the
% last dimension is the composition domain % last dimension is the composition domain
sizeOldDomain = prod( [originalDomain( ~logOfDomain ).n] ); sizeOldDomain = prod( [originalDomain( ~logOfDomain ).n] );
sizeComposeDomain = composeOnDomain.gridLength; sizeComposeDomain = composeOnDomain.n;
newValues = reshape(newValues, [sizeOldDomain, sizeComposeDomain]); newValues = reshape(newValues, [sizeOldDomain, sizeComposeDomain]);
%rearrange the computed values, to have the same dimension %rearrange the computed values, to have the same dimension
...@@ -356,9 +349,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -356,9 +349,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end end
if ~isempty(intersectDomain) if ~isempty(intersectDomain)
idx = tmpDomain.index( intersectDomain ); idx = tmpDomain.index( intersectDomain );
% take the diagonal values of the common domain, i.e., z = zeta % take the diagonal values of the common domain, i.e., z = zeta
% use the diag_nd function because it seems to be faster % use the diag_nd function because it seems to be faster
% then the diagNd function, although the values must be % then the diagNd function, although the values must be
...@@ -368,7 +359,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ... ...@@ -368,7 +359,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% *) build a new valueDiscrete on the correct grid. % *) build a new valueDiscrete on the correct grid.
obj_hat = quantity.Discrete( newValues, tmpDomain.join, ... obj_hat = quantity.Discrete( newValues, tmpDomain.join, ...
'name', obj.name + " ° " + g.name); "name", obj.name + " ° " + g.name);
end % compose() end % compose()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment