Commit 93abf2de authored by Jakob Gabriel's avatar Jakob Gabriel
Browse files

quantity.Discrete & Symbolic: new methods sum, prod and det

quantity.Domain: new methods real and imag
parent 7c08c155
......@@ -1444,11 +1444,31 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end
function s = sum(obj, dim)
% sum Sum of elements
% s = sum(X) is the sum of all elements of the array X.
% s = sum(X, DIM) is the sum along the dimensions specified by DIM.
arguments
obj;
dim = 1:ndims(obj);
end % arguments
s = quantity.Discrete(sum(obj.on(), obj.nargin + dim), ...
'domain', obj(1).domain, ...
'name', "sum(" + obj(1).name + ")");
end % sum()
function P = prod(obj, dim)
% prod Product of elements
% P = prod(X) is the product of all elements of the vector X.
% P = prod(X, DIM) is the product along the dimensions specified by DIM.
arguments
obj;
dim = 1:ndims(obj);
end % arguments
P = quantity.Discrete(prod(obj.on(), obj(1).nargin + dim), ...
'domain', obj(1).domain, ...
'name', "prod(" + obj(1).name + ")");
end % prod()
function y = sqrt(x)
% quadratic root for scalar and diagonal quantities
y = quantity.Discrete(sqrt(x.on()), ...
......@@ -2131,6 +2151,31 @@ classdef (InferiorClasses = {?quantity.Symbolic}) Discrete ...
end
end % abs()
function d = det(obj)
% det(X) returns the the determinant of the squre matrix X
if isempty(obj)
d = quantity.Discrete.empty(1);
elseif numel(obj) == 1
d = copy(obj);
elseif ismatrix(obj) && (size(obj, 1) == size(obj, 2))
if size(obj, 1) == 2
d = obj(1, 1) * obj(2, 2) - obj(2, 1) * obj(1, 2);
elseif size(obj, 1) == 3
d = prod(obj(logical([1, 0, 0; 0, 1, 0; 0, 0, 1]))) ...
+ prod(obj(logical([0, 1, 0; 0, 0, 1; 1, 0, 0]))) ...
+ prod(obj(logical([0, 0, 1; 1, 0, 0; 0, 1, 0]))) ...
- prod(obj(logical([0, 0, 1; 0, 1, 0; 1, 0, 0]))) ...
- prod(obj(logical([1, 0, 0; 0, 0, 1; 0, 1, 0]))) ...
- prod(obj(logical([0, 1, 0; 1, 0, 0; 0, 0, 1])));
else
error("only implemented for 2x2 matrices yet");
% maybe a more sophisticated implementation would be nice.
end
else
error("det is only defined for quadratic matrices");
end
end % det()
function y = real(obj)
% real() returns the real part of the obj.
y = quantity.Discrete(real(obj.on()), ...
......
......@@ -248,6 +248,18 @@ classdef (InferiorClasses = {?quantity.EquidistantDomain}) Domain < ...
end
end % ndgrid()
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()
function [idx, newDomain] = getPermutationIdx(obj, order)
if isa(order, 'quantity.Domain')
......
......@@ -516,6 +516,55 @@ classdef Symbolic < quantity.Function
warning('not tested')
end % adj()
function s = sum(obj, dim)
% sum Sum of elements
% s = sum(X) is the sum of all elements of the array X.
% s = sum(X, DIM) is the sum along the dimensions specified by DIM.
arguments
obj;
dim = 1:ndims(obj);
end % arguments
if ndims(obj) <= 2
s = quantity.Symbolic(sum(obj.sym(), dim), ...
'domain', obj(1).domain, ...
'name', "sum(" + obj(1).name + ")");
else
% todo: sym/sum only supports matrices and vectors, but not ndims > 2
% a nicer implementation should be possible anyways.
s = sum(quantity.Discrete(obj), dim);
end
end % sum()
function P = prod(obj, dim)
% prod Product of elements
% P = prod(X) is the product of all elements of the vector X.
% P = prod(X, DIM) is the product along the dimensions specified by DIM.
arguments
obj;
dim = 1:ndims(obj);
end % arguments
if ndims(obj) <= 2
P = quantity.Symbolic(prod(obj.sym(), dim), ...
'domain', obj(1).domain, ...
'name', "prod(" + obj(1).name + ")");
else
% todo: sym/prod only supports matrices and vectors, but not ndims > 2
% a nicer implementation should be possible anyways.
P = prod(quantity.Discrete(obj), dim);
end
end % prod()
function d = det(obj)
% det(X) returns the the determinant of the squre matrix X
if isempty(obj)
d = quantity.Discrete.empty(1);
else
d = quantity.Symbolic(det(obj.sym()), ...
'domain', obj(1).domain, ...
'name', "det(" + obj(1).name + ")");
end
end % det()
function y = sqrt(x)
% quadratic root for scalar and diagonal symbolic quantities
y = quantity.Symbolic(sqrt(x.sym()), ...
......
......@@ -4,7 +4,6 @@ function [tests] = testDiscrete()
tests = functiontests(localfunctions);
end
function setupOnce(testCase)
syms z zeta t sy
testCase.TestData.sym.z = z;
......@@ -13,6 +12,38 @@ testCase.TestData.sym.t = t;
testCase.TestData.sym.sy = sy;
end
function testDet(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
zDiscrete = quantity.Discrete(z.grid, 'domain', z);
myMatrix2x2 = [1, 2; 3, 4] * (1 + 0 * zDiscrete);
myMatrix3x3 = [1, 2, 3; 2, 3, 4; 3, 4, 5] * (1 + 0 * zDiscrete);
tc.verifyEqual(zDiscrete.det.on(), zDiscrete.on(), 'AbsTol', 10*eps);
tc.verifyEqual(myMatrix2x2.det.at(0.5), det(myMatrix2x2.at(0.5)), 'AbsTol', 10*eps);
tc.verifyEqual(myMatrix3x3.det.at(0.5), det(myMatrix3x3.at(0.5)), 'AbsTol', 10*eps);
end % testDet()
function testSum(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
myOnes = quantity.Discrete(ones(11, 3, 4), 'domain', z);
tc.verifyEqual(on(sum(myOnes)), 3*4*ones(11, 1), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, 2)), 4*ones(11, 3), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, 1)), 3*ones(11, 1, 4), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, [1, 2])), 3*4*ones(11, 1), 'AbsTol', 10*eps);
myTwos3D = quantity.Discrete(2*ones(11, 2, 3, 4), 'domain', z);
tc.verifyEqual(on(sum(myTwos3D)), 2*3*4*ones(11, 1)*2, 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myTwos3D, 2)), 3*ones(11, 2, 1, 4)*2, 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myTwos3D, [1, 3])), 2*4*ones(11, 1, 3)*2, 'AbsTol', 10*eps);
end % testSum()
function testProd(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
myTwos3D = quantity.Discrete(2*ones(11, 2, 3, 4), 'domain', z);
tc.verifyEqual(on(prod(myTwos3D)), 2^(2*3*4)*ones(11, 1), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos3D, 2)), 2^3*ones(11, 2, 1, 4), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos3D, [1, 3])), 2^(2*4)*ones(11, 1, 3), 'AbsTol', 10*eps);
end % testProd()
function testIsdiag(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
......
......@@ -4,6 +4,44 @@ function [tests ] = testSymbolic()
tests = functiontests(localfunctions());
end
function testDet(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
zSymbolic = quantity.Symbolic(sym("z"), 'domain', z);
myMatrix2x2 = [1, 2; 3, 4] * (1 + 0 * zSymbolic);
myMatrix3x3 = [1, 2, 3; 2, 3, 4; 3, 4, 5] * (1 + 0 * zSymbolic);
tc.verifyEqual(zSymbolic.det.on(), zSymbolic.on(), 'AbsTol', 10*eps);
tc.verifyEqual(myMatrix2x2.det.at(0.5), det(myMatrix2x2.at(0.5)), 'AbsTol', 10*eps);
tc.verifyEqual(myMatrix3x3.det.at(0.5), det(myMatrix3x3.at(0.5)), 'AbsTol', 10*eps);
end % testDet()
function testSum(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
myOnes = ones(3, 4) * (1 + 0*quantity.Symbolic(sym("z"), 'domain', z));
tc.verifyEqual(on(sum(myOnes)), 3*4*ones(11, 1), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, 2)), 4*ones(11, 3), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, 1)), 3*ones(11, 1, 4), 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myOnes, [1, 2])), 3*4*ones(11, 1), 'AbsTol', 10*eps);
myTwos3D = ones(2, 3, 4) * 2 * (1 + 0*quantity.Symbolic(sym("z"), 'domain', z));
tc.verifyEqual(on(sum(myTwos3D)), 2*3*4*ones(11, 1)*2, 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myTwos3D, 2)), 3*ones(11, 2, 1, 4)*2, 'AbsTol', 10*eps);
tc.verifyEqual(on(sum(myTwos3D, [1, 3])), 2*4*ones(11, 1, 3)*2, 'AbsTol', 10*eps);
end % testSum()
function testProd(tc)
z = quantity.Domain("z", linspace(0, 1, 11));
myTwos = 2 * ones(3, 4) * (1 + 0*quantity.Symbolic(sym("z"), 'domain', z));
tc.verifyEqual(on(prod(myTwos)), 2^(3*4)*ones(11, 1), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos, 2)), 2^4*ones(11, 3), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos, 1)), 2^3*ones(11, 1, 4), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos, [1, 2])), 2^(3*4)*ones(11, 1), 'AbsTol', 10*eps);
myTwos3D = quantity.Symbolic(2*(1+0*sym("z")) * ones(2, 3, 4), 'domain', z);
tc.verifyEqual(on(prod(myTwos3D)), 2^(2*3*4)*ones(11, 1), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos3D, 2)), 2^3*ones(11, 2, 1, 4), 'AbsTol', 10*eps);
tc.verifyEqual(on(prod(myTwos3D, [1, 3])), 2^(2*4)*ones(11, 1, 3), 'AbsTol', 10*eps);
end % testProd()
function testVec2Diag(testCase)
% quantity.Symbolic
syms z
......
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