Commit 4be50ea7 authored by Jakob Gabriel's avatar Jakob Gabriel
Browse files

cast quantity.Domain to Discrete or Symbolic

parent 64be2d84
......@@ -100,7 +100,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% the case if all values are empty. This is required for
% the initialization of quantity.Function and
% quantity.Symbolic objects
assert( misc.alln( cellfun(@isempty, valueOriginal ) ) || ...
assert( all( cellfun(@isempty, valueOriginal ), 'all' ) || ...
numGridElements(myDomain) == numel(valueOriginal{1}), ...
'grids do not fit to valueOriginal');
......@@ -236,6 +236,9 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% end
[obj.name] = deal(newName);
end % setName()
end
methods (Access = public)
......@@ -294,7 +297,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
function obj_hat = compose(obj, g, optionalArgs)
% COMPOSE compose two functions
% OBJ_hat = compose(obj, G, varargin) composes the function
% OBJ_hat = compose(obj, G, varargin) composes the function f
% defined by OBJ with the function given by G. In particular,
% f_hat(z,t) = f( z, g(z,t) )
% if f(t) = obj, g is G and f_hat is OBJ_hat.
......@@ -400,7 +403,7 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
'size', size(obj), ...
'domain', tmpDomain.join);
end
end % compose()
function value = on(obj, myDomain, gridNames)
% ON evaluation of the quantity on a certain domain.
......@@ -850,7 +853,6 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
assert(numel(obj(1).gridName) == 1);
assert(isequal(size(obj), [1, 1]));
inverse = quantity.Discrete(repmat(obj(1).grid{obj(1).domain.gridIndex(gridName)}(:), [1, size(obj)]), ...
'size', size(obj), ...
'domain', quantity.Domain([obj(1).name], obj.on()), ...
'name', gridName);
end % invert()
......@@ -1410,8 +1412,8 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
for it = 1 : numel(obj)
newObj(it).valueDiscrete = obj(it).on(newDomain);
end
end
end
end % changeGrid()
end % methods (Access = public)
%% math
methods (Access = public)
......@@ -1557,11 +1559,23 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end
end
function P = mpower(a, p)
% a^p implemented by multiplication
assert(p==floor(p) && p > 0);
P = a;
for k = 1:(p-1)
P = P * a;
% Matrix power a^p is matrix or scalar a to the power p.
if p == 0
P = setName(eye(size(a) + 0*a), "I");
elseif p < 0
if numel(a) > 1
warning("mpower(a, p) implements a^p. " ...
+ "For matrices a with negative exponent p, inv(a^(-p)) is returned. " ...
+ "This represents a division from left, " ...
+ "maybe division from right is needed in your case!")
end % this warning is not important in the scalar case.
P = inv(mpower(a, -p));
else % p > 0
assert(p==floor(p), "power p must be integer");
P = a;
for k = 1:(p-1)
P = P * a;
end
end
end % mpower()
function s = num2str(obj)
......@@ -1756,10 +1770,27 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
% exp() is the exponential function using obj as the exponent.
y = quantity.Discrete(exp(obj.on()), ...
'domain', obj(1).domain, ...
'name', "exp(" + obj(1).name + ")", ...
'size', size(obj));
'name', "exp(" + obj(1).name + ")");
end % exp()
function y = log(obj)
% log Natural logarithm.
% log(X) is the natural logarithm of the elements of X.
% Complex results are produced if X is not positive.
y = quantity.Discrete(log(obj.on()), ...
'domain', obj(1).domain, ...
'name', "log(" + obj(1).name + ")");
end % log()
function y = log10(obj)
% log10 Common (base 10) logarithm.
% log10(X) is the base 10 logarithm of the elements of X.
% Complex results are produced if X is not positive.
y = quantity.Discrete(log10(obj.on()), ...
'domain', obj(1).domain, ...
'name', "log10(" + obj(1).name + ")");
end % log()
function xNorm = l2norm(obj, integralGridName, optArg)
% calculates the l2 norm, for instance
% xNorm = sqrt(int_0^1 x.' * x dz).
......
......@@ -63,9 +63,30 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
function s = string(obj)
s = obj.name;
end
end
function quan = Discrete(obj)
% Discrete casts the domain into a quantity.Discrete of with the values
% obj.grid.
arguments
obj (1, 1) quantity.Domain;
end
%assert(numel(obj) == 1, 'only defined for scalar domains');
%quan = quantity.Discrete(obj.grid, 'domain', obj, 'name', obj.name);
quan = quantity.Discrete(obj.grid, 'domain', obj, 'name', obj.name);
end % quantity.Discrete()
function quan = Symbolic(obj)
% Discrete casts the domain into a quantity.Discrete of with the values
% obj.grid.
arguments
obj (1, 1) quantity.Domain;
end
quan = quantity.Symbolic(sym(obj.name), 'domain', obj, 'name', obj.name);
end % Symbolic()
end
methods (Access = public)
function d = split(obj, splittingPoints, optArgs)
......
......@@ -79,7 +79,7 @@ classdef Function < quantity.Discrete
Q = quantity.Discrete(obj.on(), ...
'domain', myParser.Results.domain, ...
'name', myParser.Results.name);
end
end % quantity.Discrete()
%-----------------------------
% --- overloaded functions ---
......
......@@ -18,7 +18,17 @@ tc.TestData.d = d;
end
function testParser(testCase)
function testDiscrete(tc)
tc.verifyEqual(tc.TestData.a.grid, on(tc.TestData.a.Discrete()));
tc.verifyClass(tc.TestData.a.Discrete, "quantity.Discrete");
end
function testSymbolic(tc)
tc.verifyEqual(tc.TestData.a.grid, on(tc.TestData.a.Symbolic()));
tc.verifyClass(tc.TestData.a.Symbolic, "quantity.Symbolic");
end
function testParser(tc)
%profile on
d = quantity.Domain.parser('blub', 1, 'grid', 1:3, 'gridName', 'test');
......@@ -29,46 +39,46 @@ b = quantity.Domain.parser('blabla', 0, 'domain', a, 'blub', 'a');
%profile viewer
testCase.verifyEqual(d, a);
testCase.verifyEqual(b, a);
tc.verifyEqual(d, a);
tc.verifyEqual(b, a);
end
function testSplit(testCase)
function testSplit(tc)
a = quantity.Domain('a', -5:15 );
b = a.split([-1, 0, 4]);
testCase.verifyEqual(b(1).grid', -5:-1)
testCase.verifyEqual(b(2).grid', -1:0)
testCase.verifyEqual(b(3).grid', 0:4)
testCase.verifyEqual(b(4).grid', 4:15)
tc.verifyEqual(b(1).grid', -5:-1)
tc.verifyEqual(b(2).grid', -1:0)
tc.verifyEqual(b(3).grid', 0:4)
tc.verifyEqual(b(4).grid', 4:15)
testCase.verifyWarning(@() a.split([0.1, 2.6]), 'DOMAIN:split')
testCase.verifyWarningFree(@() a.split([0.1, 2.6], 'AbsTol', 0.4), 'DOMAIN:split')
tc.verifyWarning(@() a.split([0.1, 2.6]), 'DOMAIN:split')
tc.verifyWarningFree(@() a.split([0.1, 2.6], 'AbsTol', 0.4), 'DOMAIN:split')
c = a.split([0.1, 2.6], 'warning', false);
testCase.verifyEqual(c(1).grid', -5:0)
testCase.verifyEqual(c(2).grid', 0:3)
testCase.verifyEqual(c(3).grid', 3:15)
tc.verifyEqual(c(1).grid', -5:0)
tc.verifyEqual(c(2).grid', 0:3)
tc.verifyEqual(c(3).grid', 3:15)
end
function testContains(testCase)
function testContains(tc)
a = quantity.Domain('a', 0:10);
b = quantity.Domain('b', 3:5);
testCase.verifyTrue( a.contains(b) )
testCase.verifyTrue( a.contains(1) )
testCase.verifyFalse( a.contains(11) )
testCase.verifyFalse( a.contains(1.5) )
tc.verifyTrue( a.contains(b) )
tc.verifyTrue( a.contains(1) )
tc.verifyFalse( a.contains(11) )
tc.verifyFalse( a.contains(1.5) )
A = [quantity.Domain('a1', 0:10), quantity.Domain('a2', 0:10)];
testCase.verifyTrue( A.contains(5) )
tc.verifyTrue( A.contains(5) )
end
......
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