Commit 23e96a74 authored by Ferdinand Fischer's avatar Ferdinand Fischer
Browse files

Minor bug fix and further adaptions to quantity.Domain

parent a622b878
......@@ -135,10 +135,9 @@ function obj = BasicVariable(valueContinuous, varargin)
Di(j) = obj_j.derivatives(k+1);
end
end
Di = reshape(Di, [ 1 size(obj)]);
D(i,:) = Di;
end
D = reshape(D, [numel(K) size(obj)]);
end
%% PROPERTIES
......
......@@ -1365,9 +1365,14 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete < handle & matlab.mi
P = (b.' * a.').';
% this recursion is safe, because isa(b, 'double') is considered in
% the if above.
if isnumeric(P)
return
else
P.setName(['c ', b(1).name]);
return
end
end
if a.isConstant() && ~b.isConstant()
% If the first argument a is constant value, then bad
% things will happen. To avoid this, we calculate
......
......@@ -103,8 +103,6 @@ classdef Function < quantity.Discrete
end
end
% -------------
% --- Mathe ---
%--------------
......
......@@ -25,6 +25,7 @@ classdef Operator < handle & matlab.mixin.Copyable
prsr = misc.Parser();
prsr.addOptional('s', sym('s'));
prsr.addOptional('name', '');
prsr.addOptional('domain', quantity.Domain.empty());
prsr.parse(varargin{:});
s = prsr.Results.s;
......@@ -34,13 +35,13 @@ classdef Operator < handle & matlab.mixin.Copyable
for k = 1 : numel(A)
if isnumeric(A{k})
obj(k).coefficient = ...
quantity.Discrete(A{k}, 'gridName', {}, 'grid', {});
quantity.Discrete(A{k}, 'domain', prsr.Results.domain);
else
obj(k).coefficient = A{k}; %#ok<AGROW>
end
end
elseif isnumeric(A)
obj(1).coefficient = quantity.Discrete(A, 'gridName', {}, 'grid', {});
obj(1).coefficient = quantity.Discrete(A, 'domain', prsr.Results.domain);
end
[obj.s] = deal(s);
......@@ -417,6 +418,12 @@ classdef Operator < handle & matlab.mixin.Copyable
end
function newOperator = subs(obj, varargin)
newOperator = obj.M.subs(varargin{:});
if isnumeric(newOperator)
newOperator = squeeze( num2cell(newOperator, [1 2]) );
newOperator = quantity.Operator(newOperator);
end
end
end
......
......@@ -249,11 +249,9 @@ classdef Symbolic < quantity.Function
obj = objCell{objIdx};
if ~isempty(obj)
myVariable = obj(1).variable;
myGrid = obj(1).grid;
myDomain = obj(1).domain;
else
myVariable = '';
myGrid = {};
myDomain = quantity.Domain.empty();
end
for k = 1:numel(objCell)
......@@ -262,8 +260,7 @@ classdef Symbolic < quantity.Function
o = objCell{k};
elseif isa(objCell{k}, 'double') || isa(objCell{k}, 'sym')
o = quantity.Symbolic( objCell{k}, ...
'variable', myVariable, ...
'grid', myGrid);
'domain', myDomain);
end
objCell{k} = o;
end
......@@ -504,7 +501,7 @@ classdef Symbolic < quantity.Function
obj(it).variable, varNew(s)), varNew(0)==ic);
end
solution = quantity.Symbolic(symbolicSolution, ...
'gridName', {myParser.Results.newGridName, 'ic'}, 'variable', {s, ic}, ...
'gridName', {myParser.Results.newGridName, 'ic'}, ...
'grid', {myParser.Results.variableGrid, myParser.Results.initialValueGrid}, ...
'name', ['solve(', obj(1).name, ')']);
end % solveDVariableEqualQuantity()
......@@ -523,14 +520,14 @@ classdef Symbolic < quantity.Function
function y = sqrt(x)
% quadratic root for scalar and diagonal symbolic quantities
y = quantity.Symbolic(sqrt(x.sym()), ...
'grid', x(1).grid, 'variable', x(1).variable, ...
'domain', x(1).domain, ...
'name', ['sqrt(', x(1).name, ')']);
end % sqrt()
function y = sqrtm(x)
% quadratic root for matrices of symbolic quantities
y = quantity.Symbolic(sqrtm(x.sym()), ...
'grid', x(1).grid, 'variable', x(1).variable, ...
'domain', x(1).domain, ...
'name', ['sqrtm(', x(1).name, ')']);
end % sqrtm()
......@@ -573,7 +570,7 @@ classdef Symbolic < quantity.Function
variableNew{it} = 1-variableOld{it};
end
b = quantity.Symbolic(subs(a.sym, variableOld, variableNew), ...
'grid', a(1).grid, 'variable', a(1).variable, ...
'domain', a(1).domain, ...
'name', ['flip(', a(1).name, ')']);
end % flipGrid()
......@@ -803,7 +800,7 @@ classdef Symbolic < quantity.Function
% with numeric integral bounds. Therefore, this try-catch block
% is needed.
C = quantity.Symbolic(I, ...
'grid', gridI, 'variable', variableI, ...
'grid', gridI, 'gridName', gridNameI, ...
'name', ['int[', obj(1).name, ']']);
catch
C = cumInt(quantity.Discrete(obj), z, a, b);
......
......@@ -128,12 +128,11 @@ classdef TaylorPolynomial < quantity.Discrete
end
function monomials = getMonomials(degree, t, tStar, myLocalGrid, T)
monomials = quantity.Symbolic.zeros([degree, 1], ...
'variable', {t, tStar}, ...
'grid', {myLocalGrid, T}, ...
'domain', quantity.Domain.empty(), ...
'name', 'varphi_k');
for k = 1:degree
monomials(k, 1) = quantity.Symbolic((t-tStar)^(k-1), ...
'variable', {t, tStar}, ...
'gridName', cellfun(@char, {t, tStar}, 'UniformOutput', false), ...
'grid', {myLocalGrid, T}, ...
'name', 'varphi_k');
end
......
......@@ -324,7 +324,8 @@ end
function testDiag2Vec(testCase)
% quantity.Symbolic
syms z
myMatrixSymbolic = quantity.Symbolic([sin(0.5*z*pi)+1, 0; 0, 0.9-z/2]);
do = quantity.Domain('grid', linspace(0,1,3), 'name', 'z');
myMatrixSymbolic = quantity.Symbolic([sin(0.5*z*pi)+1, 0; 0, 0.9-z/2], 'domain', do);
myVectorSymbolic = diag2vec(myMatrixSymbolic);
testCase.verifyEqual(myMatrixSymbolic(1,1).valueContinuous, myVectorSymbolic(1,1).valueContinuous);
testCase.verifyEqual(myMatrixSymbolic(2,2).valueContinuous, myVectorSymbolic(2,1).valueContinuous);
......
......@@ -20,9 +20,9 @@ function testSymbolicEvaluation(tc)
syms z
myGrid = linspace(0, 1, 7);
fS = quantity.Symbolic(z * sinh(z * 1e5) / cosh(z * 1e5), ...
'variable', {z}, 'grid', {myGrid}, 'symbolicEvaluation', true);
'gridName', {'z'}, 'grid', {myGrid}, 'symbolicEvaluation', true);
fF = quantity.Symbolic(z * sinh(z * 1e5) / cosh(z * 1e5), ...
'variable', {z}, 'grid', {myGrid}, 'symbolicEvaluation', false);
'gridName', {'z'}, 'grid', {myGrid}, 'symbolicEvaluation', false);
tc.verifyTrue(any(isnan(fF.on)))
tc.verifyFalse(any(isnan(fS.on)))
......@@ -32,7 +32,7 @@ function testCtranspose(tc)
syms z zeta
qSymbolic = quantity.Symbolic(...
[1+zeta, -zeta; -z, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 'q');
'gridName', {'z', 'zeta'}, 'name', 'q');
qSymbolicCtransp = qSymbolic';
tc.verifyEqual(qSymbolic(1,1).on(), qSymbolicCtransp(1,1).on());
tc.verifyEqual(qSymbolic(2,2).on(), qSymbolicCtransp(2,2).on());
......@@ -40,7 +40,7 @@ tc.verifyEqual(qSymbolic(1,2).on(), qSymbolicCtransp(2,1).on());
tc.verifyEqual(qSymbolic(2,1).on(), qSymbolicCtransp(1,2).on());
qSymbolic2 = quantity.Symbolic(sym('z') * 2i + sym('zeta'), ...
'grid', {linspace(0, 1, 21), linspace(0, 1, 11)}, 'variable', sym({'z', 'zeta'}), 'name', 'im');
'grid', {linspace(0, 1, 21), linspace(0, 1, 11)}, 'gridName', {'z', 'zeta'}, 'name', 'im');
qSymolic2Ctransp = qSymbolic2';
tc.verifyEqual(qSymbolic2.real.on(), qSymolic2Ctransp.real.on());
tc.verifyEqual(qSymbolic2.imag.on(), -qSymolic2Ctransp.imag.on());
......@@ -50,7 +50,7 @@ function testTranspose(tc)
syms z zeta
qSymbolic = quantity.Symbolic(...
[1+z*zeta, -zeta; -z, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 'q');
'gridName', {'z', 'zeta'}, 'name', 'q');
qSymbolicTransp = qSymbolic.';
tc.verifyEqual(qSymbolic(1,1).on(), qSymbolicTransp(1,1).on());
tc.verifyEqual(qSymbolic(2,2).on(), qSymbolicTransp(2,2).on());
......@@ -62,16 +62,16 @@ function testFlipGrid(tc)
syms z zeta
myGrid = linspace(0, 1, 11);
f = quantity.Symbolic([1+z+zeta; 2*zeta+sin(z)] + zeros(2, 1)*z*zeta, ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
% flip zeta
fReference = quantity.Symbolic([1+z+(1-zeta); 2*(1-zeta)+sin(z)] + zeros(2, 1)*z*zeta, ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
fFlipped = f.flipGrid('zeta');
tc.verifyEqual(fReference.on, fFlipped.on, 'AbsTol', 10*eps);
% flip z and zeta
fReference2 = quantity.Symbolic([1+(1-z)+(1-zeta); 2*(1-zeta)+sin(1-z)] + zeros(2, 1)*z*zeta, ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
fFlipped2 = f.flipGrid({'z', 'zeta'});
tc.verifyEqual(fReference2.on, fFlipped2.on, 'AbsTol', 10*eps);
end % testFlipGrid();
......@@ -86,7 +86,7 @@ b = [ s; 2*s];
%% int_0_t a(t,s) * b(s) ds
% compute symbolic version of the volterra integral
integrandSymbolic = quantity.Symbolic(a*b, 'grid', {tGrid, sGrid}, 'variable', {t, s});
integrandSymbolic = quantity.Symbolic(a*b, 'grid', {tGrid, sGrid}, 'gridName', {'t', 's'});
integrandDiscrete = quantity.Discrete(integrandSymbolic);
V = cumInt(integrandSymbolic, 's', tGrid(1), 't');
f = cumInt(integrandDiscrete, 's', sGrid(1), 't');
......@@ -112,7 +112,7 @@ function testScalarPlusMinusQuantity(testCase)
syms z
myGrid = linspace(0, 1, 7);
f = quantity.Symbolic([1; 2] + zeros(2, 1)*z, ...
'variable', {z}, 'grid', {myGrid});
'gridName', {'z'}, 'grid', {myGrid});
testCase.verifyError(@() 1-f-1, '');
testCase.verifyError(@() 1+f+1, '');
end
......@@ -121,7 +121,7 @@ function testNumericVectorPlusMinusQuantity(testCase)
syms z
myGrid = linspace(0, 1, 7);
f = quantity.Symbolic([1+z; 2+sin(z)] + zeros(2, 1)*z, ...
'variable', {z}, 'grid', {myGrid});
'gridName', {'z'}, 'grid', {myGrid});
a = ones(size(f));
testCase.verifyEqual(on(a-f), 1-f.on(), 'RelTol', 10*eps);
testCase.verifyEqual(on(f-a), f.on()-1, 'RelTol', 10*eps);
......@@ -133,11 +133,11 @@ function testDiffWith2Variables(testCase)
syms z zeta
myGrid = linspace(0, 1, 7);
f = quantity.Symbolic([z*zeta, z; zeta, 1], ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
fdz = quantity.Symbolic([zeta, 1; 0, 0], ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
fdzeta = quantity.Symbolic([z, 0; 1, 0], ...
'variable', {z, zeta}, 'grid', {myGrid, myGrid});
'gridName', {'z', 'zeta'}, 'grid', {myGrid, myGrid});
fRefTotal = 0*f.on();
fRefTotal(:,:,1,1) = 1;
......@@ -153,7 +153,7 @@ function testGridName2variable(testCase)
syms z zeta eta e a
myGrid = linspace(0, 1, 7);
obj = quantity.Symbolic([z*zeta, eta*z; e*a, a], ...
'variable', {z zeta eta e a}, ...
'gridName', {'z' 'zeta' 'eta' 'e' 'a'}, ...
'grid', {myGrid, myGrid, myGrid, myGrid, myGrid});
thisGridName = {'eta', 'e', 'z'};
......@@ -172,8 +172,8 @@ end
function testCat(testCase)
syms z zeta
f1 = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'variable', {z}, 'name', 'f1');
f2 = quantity.Symbolic(sin(z), 'grid', {linspace(0, 1, 21)}, 'variable', {z}, 'name', 'f2');
f1 = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'gridName', {'z'}, 'name', 'f1');
f2 = quantity.Symbolic(sin(z), 'grid', {linspace(0, 1, 21)}, 'gridName', {'z'}, 'name', 'f2');
% vertical concatenation
F = [f1; f2];
......@@ -193,7 +193,7 @@ testCase.verifyTrue(F(2,1) == f1);
testCase.verifyTrue(F(2,2) == f2);
% concatenation on different grids
f3 = quantity.Symbolic(cos(z), 'grid', {linspace(0, 1, 13)}, 'variable', {z}, 'name', 'f1');
f3 = quantity.Symbolic(cos(z), 'grid', {linspace(0, 1, 13)}, 'gridName', {'z'}, 'name', 'f1');
F = [f1, f3];
testCase.verifyEqual(F(2).gridSize, f1.gridSize)
......@@ -212,19 +212,19 @@ end
function testExp(testCase)
% 1 spatial variable
syms z zeta
s1d = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'variable', {z}, 'name', 's1d');
s1d = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'gridName', {'z'}, 'name', 's1d');
testCase.verifyEqual(s1d.exp.on(), exp(s1d.on()));
% diagonal matrix
s2dDiag = quantity.Symbolic([1+z*zeta, 0; 0, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 's2dDiag');
'gridName', {'z', 'zeta'}, 'name', 's2dDiag');
testCase.verifyEqual(s2dDiag.exp.on(), exp(s2dDiag.on()));
end
function testExpm(testCase)
syms z zeta
mat2d = quantity.Symbolic(ones(2, 2) + [1+z*zeta, 3*zeta; 2+5*z+zeta, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 's2d');
'gridName', {'z', 'zeta'}, 'name', 's2d');
mat2dMat = mat2d.on();
mat2dExpm = 0 * mat2d.on();
for zIdx = 1 : 21
......@@ -276,7 +276,7 @@ function testOn(testCase)
syms z zeta
gridZ = linspace(0, 1, 40);
gridZeta = linspace(0, 1, 21);
A = quantity.Symbolic(2+[z, z^2, z+zeta; -sin(zeta), z*zeta, 1], 'variable', {z, zeta}, ...
A = quantity.Symbolic(2+[z, z^2, z+zeta; -sin(zeta), z*zeta, 1], 'gridName', {'z', 'zeta'}, ...
'grid', {gridZ, gridZeta}, 'name', 'A');
%%
......@@ -309,17 +309,17 @@ end
function testSqrt(testCase)
% 1 spatial variable
syms z zeta
s1d = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'variable', {z}, 'name', 's1d');
s1d = quantity.Symbolic(1+z*z, 'grid', {linspace(0, 1, 21)}, 'gridName', {'z'}, 'name', 's1d');
testCase.verifyEqual(s1d.sqrt.on(), sqrt(s1d.on()));
% 2 spatial variables
s2d = quantity.Symbolic(1+z*zeta, 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 's2d');
'gridName', {'z', 'zeta'}, 'name', 's2d');
testCase.verifyEqual(s2d.sqrt.on(), sqrt(s2d.on()));
% diagonal matrix
s2dDiag = quantity.Symbolic([1+z*zeta, 0; 0, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 's2dDiag');
'gridName', {'z', 'zeta'}, 'name', 's2dDiag');
testCase.verifyEqual(s2dDiag.sqrt.on(), sqrt(s2dDiag.on()));
end
......@@ -327,7 +327,7 @@ end
function testSqrtm(testCase)
syms z zeta
mat2d = quantity.Symbolic(ones(2, 2) + [1+z*zeta, 3*zeta; 2+5*z+zeta, z^2], 'grid', {linspace(0, 1, 21), linspace(0, 1, 41)},...
'variable', {z, zeta}, 'name', 's2d');
'gridName', {'z', 'zeta'}, 'name', 's2d');
mat2dMat = mat2d.on();
mat2dSqrtm = 0 * mat2d.on();
for zIdx = 1 : 21
......@@ -346,7 +346,7 @@ function testInv(testCase)
syms z
zGrid = linspace(0, 1, 21);
v = quantity.Symbolic(1+z*z, ...
'grid', {zGrid}, 'variable', {z}, 'name', 's1d');
'grid', {zGrid}, 'gridName', {'z'}, 'name', 's1d');
vInvReference = 1 ./ (1 + zGrid.^2);
vInv = v.inv();
......@@ -379,7 +379,10 @@ end
function testCast2Quantity(testCase)
syms z t
x = quantity.Symbolic(sin(z * t * pi), 'grid', {linspace(0, 1).', linspace(0, 2, 200)});
d = [quantity.Domain('grid', linspace(0, 1, 5), 'name', 'z'), ...
quantity.Domain('grid', linspace(0, 2, 2), 'name', 't')];
x = quantity.Symbolic(sin(z * t * pi), 'domain', d);
X = quantity.Discrete(x);
......@@ -388,7 +391,9 @@ end
function testMrdivide(testCase)
syms z t
x = quantity.Symbolic(sin(z * t * pi), 'grid', {linspace(0, 1).', linspace(0, 2, 200)});
d = [quantity.Domain('grid', linspace(0, 1, 5), 'name', 'z'), ...
quantity.Domain('grid', linspace(0, 2, 2), 'name', 't')];
x = quantity.Symbolic(sin(z * t * pi), 'domain', d);
o = x / x;
verifyTrue(testCase, misc.alln(o.on == 1));
......@@ -402,7 +407,9 @@ end
function testMTimesConstants(testCase)
syms z t
x = quantity.Symbolic(sin(z * t * pi), 'grid', {linspace(0, 1).', linspace(0, 2, 200)});
d = [quantity.Domain('grid', linspace(0, 1, 5), 'name', 'z'), ...
quantity.Domain('grid', linspace(0, 2, 2), 'name', 't')];
x = quantity.Symbolic(sin(z * t * pi), 'domain', d);
% test multiplicaiton iwth a constant scalar
x5 = x * 5;
......@@ -500,7 +507,7 @@ end
function testInit(testCase)
z = linspace(0,1).';
t = linspace(0,1,101);
t = linspace(0,1,3);
syms x y
......@@ -631,10 +638,10 @@ syms z;
f1 = (sin(z .* pi) );
f2 = z;
f3 = (cos(z .* pi) );
zz = linspace(0, 1, 42).';
d = quantity.Domain('grid', linspace(0, 1, 3).', 'name', 'z');
f = quantity.Symbolic([f1, f2; 0, f3], ...
'grid', {zz});
'domain', d);
fDisc = quantity.Discrete(f);
values = f.on();
......@@ -650,11 +657,11 @@ end
function testConstantValues(testCase)
%%
syms z
q = quantity.Symbolic(magic(7), 'grid', {linspace(0, 1)'}, 'gridName', 'z');
q = quantity.Symbolic(magic(3), 'grid', {linspace(0, 1, 4)'}, 'gridName', 'z');
%%
magic7 = magic(7);
magic700 = zeros(100, 7, 7);
magic7 = magic(3);
magic700 = zeros(4, 3, 3);
for k = 1:q.gridSize()
magic700(k, :,:) = magic7;
end
......@@ -663,7 +670,7 @@ end
testCase.verifyEqual(magic700, q.on());
testCase.verifyTrue(q.isConstant());
p = quantity.Symbolic([0 0 0 0 z], 'grid', linspace(0,1)', 'variable', z);
p = quantity.Symbolic([0 0 0 0 z], 'grid', linspace(0, 1, 4)', 'gridName', 'z');
testCase.verifyFalse(p.isConstant());
end
......@@ -689,7 +696,7 @@ syms Z;
f1 = (sin(Z .* pi) );
f2 = Z;
f3 = (cos(Z .* pi) );
z = quantity.Domain('grid', linspace(0, 1, 42), 'name', 'Z');
z = quantity.Domain('grid', linspace(0, 1, 4), 'name', 'Z');
R1 = quantity.Symbolic([f1, f2; 0, f3], ...
'domain', z);
......@@ -732,7 +739,7 @@ syms Z;
f1 = (sin(Z .* pi) );
f2 = Z;
f3 = (cos(Z .* pi) );
z = linspace(0, 1, 42).';
z = linspace(0, 1, 4).';
zDomain = quantity.Domain('grid', z, 'name', 'Z');
f = quantity.Symbolic([f1, f2; 0, f3], ...
'domain', zDomain);
......@@ -796,7 +803,8 @@ testCase.verifyEqual(Fyx.sym(), fOfyx.sym());
%%
syms z zeta
assume(z>0 & z<1); assume(zeta>0 & zeta<1);
F = quantity.Symbolic(zeros(1), 'grid', {linspace(0,1), linspace(0,1)}, 'gridName', {'z', 'zeta'});
F = quantity.Symbolic(zeros(1), 'grid', ...
{linspace(0, 1, 3), linspace(0, 1, 3)}, 'gridName', {'z', 'zeta'});
Feta = F.subs('z', 'eta');
testCase.verifyEqual(Feta(1).gridName, {'eta', 'zeta'});
......
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