Commit 046fb87c authored by Ferdinand Fischer's avatar Ferdinand Fischer
Browse files

Simplification of some functions

closes #49
parent 7abc7930
......@@ -552,6 +552,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end
function [referenceGrid, referenceGridName] = getFinestGrid(a, varargin)
warning("DEPRICATED: Use quantity.Domain/join instead")
% find the finest grid of all input quantities by comparing
% gridSize for each iteratively.
......@@ -575,7 +576,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end
assert(numel(referenceGridName) == numel(varargin{it}(1).gridName), ...
['For getFinestGrid, the gridName of all objects must be equal', ...
'. Maybe gridJoin() does what you want?']);
'. Maybe join() does what you want?']);
for jt = 1 : numel(referenceGridName)
comparisonGridSize = varargin{it}(1).domain.find(referenceGridName{jt}).n;
comparisonGrid = varargin{it}.gridOf(referenceGridName{jt});
......@@ -799,9 +800,9 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% quantity.Discrete object. This is considered to give
% the basic values for the initialization of new
% quantity.Discrete values
isAquantityDiscrete = cellfun(@(o) isa(o, 'quantity.Discrete'), objCell);
isAQuantityDiscrete = cellfun(@(o) isa(o, 'quantity.Discrete'), objCell);
isEmpty = cellfun(@(o) isempty(o), objCell);
objIdx = find(isAquantityDiscrete & (~isEmpty), 1);
objIdx = find(isAQuantityDiscrete & (~isEmpty), 1);
if all(isEmpty)
% if there are only empty entries, nothing can be
......@@ -817,11 +818,16 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
c = quantity.Discrete.empty(S);
return
else
% the first object, that is not empty is considered to be the new obj instance.
obj = objCell{objIdx};
end
for k = 1:numel(objCell(~isEmpty))
% TODO: is here a bug? if k goes from 1:numel(...) this does not exclude that
% objCell{k}is not empty, or? Example: objCell = {o, o, [], o}, where o is some
% object not empty. Then numel(objCell(~isEmpty)) will return 3, but objCell{3}
% is empty ...
if isa(objCell{k}, 'quantity.Discrete')
o = objCell{k};
else
......@@ -847,11 +853,17 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
objCell{it} = objCell{it}.sortDomain();
end
[fineGrid, fineGridName] = getFinestGrid(objCell{~isEmpty});
for it = 1 : (numel(varargin) + 1) % +1 because the first entry is a
% change the grid to the finest
objCell{it} = objCell{it}.changeGrid(fineGrid, fineGridName);
% find the finest domain:
newDomain = obj(1).domain;
for it = 1: (numel(varargin) + 1)
newDomain = newDomain.join(objCell{it}(1).domain);
end
% change the domain to the newDomain
for it = 1 : (numel(varargin) + 1)
objCell{it} = objCell{it}.changeDomain(newDomain);
end
assertSameGrid(objCell{:});
argin = [{dim}, objCell(:)'];
c = builtin('cat', argin{:});
......@@ -1456,65 +1468,47 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
'name', "flip(" + a(1).name + ")");
end % flipGrid()
function newObj = changeGrid(obj, gridNew, gridNameNew)
% CHANGEGRID change the grid of the quantity.
% newObj = CHANGEGRID(obj, gridNew, gridNameNew)
% change the grid of the obj quantity. The order of grid and
% gridName in the obj properties remains unchanged, only the
% data points are exchanged.
%
% newObj = CHANGEGRID(obj, domain) changes the domain of the
% object specified by the name of DOMAIN into the
% corresponding domain from DOMAIN.
%
% example:
% q.changeGrid( linspace(0,1)', 't')
% will change the grid with the name 't' to the new grid
% linspace(0,1)'
function newObj = changeDomain(obj, domain)
% CHANGEDOMAIN change the grid of the quantity.
% newObj = CHANGEDOMAIN(obj, NEWDOMAIN) changes the domain of the
% object specified by the name of NEWDOMAIN into NEWDOMAIN.
% create a copy of the object, because the change of the domain does not allow to reuse
% the handle.
newObj = obj.copy();
if isempty(obj)
newObj = obj.copy();
% if the object is empty, we are ready here.
return;
end
if isa(gridNew, 'quantity.Domain')
assert(nargin == 2, "quantity:Discrete:changeGrid", "If a domain is specified in the first argument, the gridNameNew argument can not be set")
gridNameNew = [gridNew.name];
gridNew = {gridNew.grid};
else
gridNameNew = misc.ensureString(gridNameNew);
gridNew = misc.ensureIsCell(gridNew);
for it = 1:numel(gridNew)
assert( isnumeric( [gridNew{it}] ), "The gridNew parameter must be a cell array of numeric arrays." )
end
end
if obj(1).isNumber()
newDomain(1:length( gridNew )) = quantity.Domain();
for it = 1 : length(gridNew)
newDomain(it) = ...
quantity.Domain(gridNameNew(it), gridNew{it});
end
newDomain = domain;
else
gridIndexNew = obj(1).domain.gridIndex(gridNameNew);
% find the domains to be replaced:
gridIndexNew = obj(1).domain.gridIndex([domain.name]);
% initialization of the newDomain array as quantity.Domain
% array. This is required in order to handle also
% quantity.EquidistantDomains:
newDomain(1:obj(1).nargin) = quantity.Domain();
newDomain(:) = obj(1).domain;
for it = 1 : length(gridIndexNew)
newDomain(gridIndexNew(it)) = ...
quantity.Domain(gridNameNew(it), gridNew{it});
for it = 1 : length( gridIndexNew )
newDomain(gridIndexNew(it)) = domain(it);
end
assert(isequal([newDomain.name], obj(1).gridName), ...
'rearranging grids failed');
end
newObj = obj.copy();
[newObj.domain] = deal(newDomain);
for it = 1 : numel(obj)
newObj(it).valueDiscrete = obj(it).on(newDomain);
if obj(1).domain.isequal(newDomain)
% if the new domain is the same as the old one; the copy of the object can be
% returned and do not do a recalculation of the values.
return
else
[newObj.domain] = deal(newDomain);
for it = 1 : numel(obj)
newObj(it).valueDiscrete = obj(it).on(newDomain);
end
end
end % changeGrid()
......@@ -1835,11 +1829,11 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% The joined domain of quantity A and B is a mixture from both
% domains. If the domains have the same name, it must be
% checked if they have the same discretization. This is done by
% the function "gridJoin". It returns the finer grid.
% the function "join". It returns the finer grid.
% If the domain names do not coincide, they are just
% appended. At first, the domains of qunatity A, then the
% domains of quantity B.
joinedDomain = [ gridJoin(domainA(idx.A.common), domainB(idx.B.common)), ...
joinedDomain = [ join(domainA(idx.A.common), domainB(idx.B.common)), ...
domainA(~idx.A.common), domainB(~idx.B.common) ];
%% generate the new grids
......
......@@ -297,9 +297,9 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
end % ne()
function [joinedDomain, index] = join(domain1, domain2)
%% gridJoin combines the grid and gridName of two objects (obj1,
% obj2), such that every gridName only occurs once and that the
% finer grid of both is used.
% 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.
arguments
domain1 quantity.Domain = quantity.Domain.empty
domain2 quantity.Domain = quantity.Domain.empty
......@@ -334,8 +334,8 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
tempDomain1 = domain1(index1);
tempDomain2 = domain2(index2);
assert( numeric.near( tempDomain1.lower, tempDomain2.lower), 'Grids must have same domain for gridJoin')
assert( numeric.near( tempDomain1.upper, tempDomain2.upper), 'Grids must have same domain for gridJoin')
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')
if tempDomain1.gridLength > tempDomain2.gridLength
joinedDomain(i) = tempDomain1;
......@@ -353,6 +353,7 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
end % join()
function [joinedDomain, index] = gridJoin(obj1, obj2)
warning("DEPRICATED: Use quantity.Domain/join instead.")
[joinedDomain, index] = obj1.join(obj2);
end % gridJoin()
......@@ -373,7 +374,8 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
end % isSubDomainOf
function matGrid = ndgrid(obj)
% ndgrid calles ndgrid for the default grid, if no other grid
% NDGRID generate a mesh for this domain
% matGrid = ndgrid(obj) calles ndgrid for the default grid, if no other grid
% is specified. Empty grid as input returns empty cell as
% result.
if isempty(obj)
......
......@@ -265,9 +265,13 @@ classdef Symbolic < quantity.Function
gridName2Replace = misc.ensureString(gridName2Replace);
if nargin == 3 && isa(values, 'quantity.Domain')
% replacement of the grid AND the gridName
% 1) replace the grid
solution = obj.changeGrid( {values.grid}, gridName2Replace );
% replacement of domains:
% 1) replace the domain
assert( numel(gridName2Replace) == numel(values) );
for it = 1:numel(gridName2Replace)
newDomain(it) = values(it).rename(gridName2Replace(it));
end
solution = obj.changeDomain( newDomain );
% 2) replace the name
solution = solution.subs( gridName2Replace, {values.name} );
return
......@@ -584,7 +588,7 @@ classdef Symbolic < quantity.Function
parameters.name = A(1).name + " " + B(1).name;
parameters = misc.struct2namevaluepair(parameters);
C = quantity.Symbolic(A.sym() * B.sym(), gridJoin(A(1).domain, B(1).domain), ...
C = quantity.Symbolic(A.sym() * B.sym(), join(A(1).domain, B(1).domain), ...
parameters{:});
end % mtimes()
......@@ -619,7 +623,7 @@ classdef Symbolic < quantity.Function
parameters.name = a(1).name + "+" + b(1).name;
parameters = misc.struct2namevaluepair(parameters);
C = quantity.Symbolic(a.sym() + b.sym(), gridJoin(a(1).domain, b(1).domain), ...
C = quantity.Symbolic(a.sym() + b.sym(), join(a(1).domain, b(1).domain), ...
parameters{:});
end % plus()
......
......@@ -20,6 +20,14 @@ classdef BasicVariable < handle
function obj = BasicVariable(fun, derivatives)
obj.fun = fun;
obj.derivatives = derivatives;
% do the pre-initialization, because if it is done implicit, some strange bug causes the
% functions to be evaluated more often.
obj.fun.on();
for i = 1:numel(derivatives)
obj.derivatives{i}.on();
end
end
function h = get.highestDerivative(obj)
h = numel(obj(1).derivatives);
......@@ -166,13 +174,13 @@ classdef BasicVariable < handle
end
% restore the result as signals.BasicVariable
for k = 1:numel(b)
for k = 1: (size(a,1) * size(b,2))
for l = 2:size(tmp,1)
derivs_{l-1} = tmp(l,k);
end
c(k) = signals.BasicVariable( tmp(1,k), derivs_);
end
c = reshape(c, size(b));
c = reshape(c, [size(a,1), size(b,2)]);
end
end % methods (Access = public)
......
......@@ -1650,29 +1650,33 @@ z = quantity.Domain("z", linspace(0, 1, 21).');
t = quantity.Domain("t", linspace(0, 1, 31));
quan = quantity.Discrete({sin(z.grid * t.grid.' * pi); cos(z.grid * t.grid.' * pi)}, [z, t]);
gridSampled = {linspace(0, 1, 11), linspace(0, 1, 21)};
quanCopy = copy(quan);
%
quanSampled = quanCopy.changeDomain( [z, t] );
testCase.verifyEqual(quanSampled.on(), quan.on())
% test the change of two grids:
quanSampled = quanCopy.changeGrid(gridSampled, {'z', 't'});
z2 = quantity.Domain("z", linspace(0, 1, 11));
t2 = quantity.Domain("t", linspace(0, 1, 12));
gridSampled = {z2.grid, t2.grid};
quanSampled = quanCopy.changeDomain( [z2, t2] );
testCase.verifyEqual(quanSampled.on(), quan.on(gridSampled))
% test the change of only one grid:
newZ = linspace(0,1,5);
qNewZ = quanCopy.changeGrid( newZ, 'z');
testCase.verifyEqual(qNewZ.on(), quan.on({newZ, t.grid}));
newZ = quantity.Domain("z", linspace(0,1,5));
qNewZ = quanCopy.changeDomain( newZ );
testCase.verifyEqual(qNewZ.on(), quan.on([newZ t]));
% test the change of grids in wrong order
quanCopy2 = copy(quan);
quanSampled2 = quanCopy2.changeGrid(gridSampled, {'t', 'z'});
testCase.verifyEqual(quanSampled2.on(), permute(quan.on(gridSampled, {'t', 'z'}), [2, 1, 3]));
quanSampled2 = quan.changeDomain([t z]);
testCase.verifyEqual(quanSampled2.on(), quan.on());
% test the change of a quantity.EquidistantDomain with a quantity.Domain
e = quantity.EquidistantDomain( 'z', 0, 1);
d = quantity.Domain('z', linspace(0,1, 3));
E = quantity.Discrete( sin(e.grid), e);
E_ = E.changeGrid(d);
E_ = E.changeDomain(d);
testCase.verifyEqual(E_.on(), E.on(d))
end
......
......@@ -159,6 +159,12 @@ tc.verifyEqual( dd, d );
tc.verifyEqual( ee, e );
tc.verifyNotEqual( e, d );
d1 = quantity.Domain('d', 1:3);
d2 = quantity.Domain('d', 1:3);
d3 = quantity.Domain('d', 2:4);
tc.verifyEqual(d1, d2);
tc.verifyNotEqual(d1, d3);
end
function testDomainInit(tc)
......@@ -264,10 +270,10 @@ c = Pt;
% c = quantity.Discrete(ones(numel(t), 2, 2), ...
% 'size', [2 2], 'grid', {t}, 'gridName', {'p'});
joinedDomainAB = sort( gridJoin(a, b) );
joinedDomainCC = sort( gridJoin(c, c) );
joinedDomainBC = sort( gridJoin(b, c) );
joinedDomain = sort( gridJoin(Z, [Z, T]) );
joinedDomainAB = sort( join(a, b) );
joinedDomainCC = sort( join(c, c) );
joinedDomainBC = sort( join(b, c) );
joinedDomain = sort( join(Z, [Z, T]) );
tc.verifyEqual([joinedDomainAB.name], ["p", "s", "t", "z"]);
tc.verifyEqual({joinedDomainAB.grid}, {s(:), s(:), t(:), z(:)});
......
......@@ -46,11 +46,11 @@ function testSubs(testCase)
f = quantity.Discrete((1:5)', quantity.EquidistantDomain("t", 0, 1, "stepNumber", 5));
testCase.verifyEqual( f.subs("t", 1), f.on(1))
testCase.verifyEqual( f.changeGrid(quantity.Domain("t", linspace(0,1))).on(), linspace(1,5)', 'AbsTol', 1e-15);
testCase.verifyEqual( f.changeDomain(quantity.Domain("t", linspace(0,1))).on(), linspace(1,5)', 'AbsTol', 1e-15);
f = quantity.Symbolic(sym("t"), quantity.EquidistantDomain("t", 0, 1, "stepNumber", 5));
testCase.verifyEqual( f.subs("t", 1), f.on(1))
testCase.verifyEqual( f.changeGrid(quantity.Domain("t", linspace(0,1))).on(), linspace(0,1)', 'AbsTol', 1e-15);
testCase.verifyEqual( f.changeDomain(quantity.Domain("t", linspace(0,1))).on(), linspace(0,1)', 'AbsTol', 1e-15);
end
\ No newline at end of file
......@@ -17,7 +17,7 @@ tc.verifyEqual(C1.on([z, zeta]), C2.on([z, zeta]));
end
function testChangeGrid(tc)
function testChangeDomain(tc)
z = quantity.Domain("z", 0:5);
t = quantity.Domain("t", 0:4);
......@@ -27,8 +27,12 @@ b = a.sortDomain();
tc.verifyEqual( a.on([z,t]), b.on([z,t]));
c = a.changeGrid( linspace(0,5), "z");
%d = a.changeGrid( [t, z], {linspace(0,1), linspace(0,1)});
z2 = quantity.Domain("z", 2:7);
c = a.changeDomain( z2 );
grid = ndgrid([z2, t]);
f = c.valueContinuous;
tc.verifyEqual(c.on(), f(grid{1}, grid{2}))
end
......
......@@ -62,7 +62,7 @@ tc.verifyEqual(C1.on([z, zeta]), C2.on([z, zeta]));
e = zeta.Symbolic + 0*z.Symbolic;
e = e.sortDomain();
f = e.changeGrid({z.grid z.grid}, ["z", "zeta"]);
f = e.changeDomain([z z.rename("zeta")]);
% TODO: fix this error! See issue #41
......
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