interpolant.m 4.95 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
classdef interpolant
% Class interpolant: This class intends to fix the nasty error of
% griddedInterpolant: "Interpolation requires at least two sample points
%						in each dimension."
% This is done by implementing a griddedInterpolant with squeezed values
% and by accessing values by a new evaluate function. With varargin
% settings can be passed to the griddedInterpolant, for instance, the type
% of interpolation (linear, quadratic, ...) or extrapolation can be allowed
% or forbidden. For details see griddedInterpolant documentation.
%
%% Examples (griddedInterpolant would not work)
% % Example 1: interpolation
% testData = rand(5,1,3);
% testInterpolant = numeric.interpolant({1:5, 1, 1:3}, testData);
% test_2p5_1_1 = testInterpolant.evaluate(2.5, 1, 1);
%
% % Example 2: sampling data
% testData = rand(5,1,3);
% testInterpolant = numeric.interpolant({1:5, 1, 1:3}, testData);
% testDataHigherResolution = testInterpolant.evaluate(1:.5:5, 1, 1:3);
% dps.hyperbolic.plot.matrix_3D(testData);
% dps.hyperbolic.plot.matrix_3D(testDataHigherResolution);

	properties (SetAccess = public)
		reducedGriddedInterpolant {mustBe.griddedInterpolant};
	end
	properties (SetAccess = private)
		reducedDimension (1,:);		% vector of indices that are 
									% used in reducedGriddedInterpolant
		permutationVector (1,:);	% vector of sequence of dimensions
									% used to permute reduced value back to
									% original size
	end
	
	methods
		%% Constructor
		function obj = interpolant(gridOriginal, valueOriginal, varargin)
% INPUT PARAMETERS:
%	CELL-ARRAY		 gridOriginal : grid vectors of valueOriginal in a cell array
%	ARRAY			valueOriginal : sample data
%	VARARGIN			 varargin : optional parameters for
%									griddedInterpolant, e.g. extrapolation
%									or type of interpolation. See
%									documentation of griddedInterpolant.

			sizeOriginal = misc.sizeOf(valueOriginal);
			valueSqueezed = squeeze(valueOriginal);
			if isscalar(valueSqueezed)
				sizeSqueezed = 1;
			else
				sizeSqueezed = size(valueSqueezed);
				sizeSqueezed = sizeSqueezed(sizeSqueezed>1);
			end
			obj.reducedDimension = zeros(1, numel(sizeSqueezed));
			obj.permutationVector = zeros(1, numel(sizeOriginal));
			jt = 1;
			numberOfDeletedDimensions = numel(sizeOriginal) - numel(sizeSqueezed);
			for it=1:numel(sizeOriginal)
				if sizeOriginal(it) == sizeSqueezed(jt)
					obj.reducedDimension(jt) = it;
					obj.permutationVector(it) = jt;
					jt = jt+1;
				else
					obj.permutationVector(it) = numel(sizeOriginal)-numberOfDeletedDimensions+1;
					numberOfDeletedDimensions = numberOfDeletedDimensions - 1;
				end
			end
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
			if numel(sizeOriginal) == 1 && sizeOriginal == 1
				% consider scalar case
				if sizeOriginal == 1
					gridSqueezed = [0, 1];
					valueSqueezed = [valueSqueezed, valueSqueezed];
					obj.permutationVector = [1, 2];
				end
			else
				if numel(sizeOriginal) == 1
					% consider vector case
					obj.permutationVector = ones(1,2);
					obj.permutationVector = obj.permutationVector ...
								+ (sizeOriginal ~= size(valueOriginal));
				end
				gridSqueezed = gridOriginal(obj.reducedDimension);
				for it = 1 : numel(gridSqueezed)
					if issorted(gridSqueezed{it}, 'descend')
						gridSqueezed{it} = flip(gridSqueezed{it});
						valueSqueezed = flip(valueSqueezed, it);
					end
88
89
90
91
92
93
				end
			end
			obj.reducedGriddedInterpolant = griddedInterpolant(gridSqueezed, valueSqueezed, varargin{:});
		end
		
		function value = evaluate(obj, varargin)
94
95
96
97
98
99
100
101
102
			% Example:
			%	test_2p5_1_1 = testInterpolant.evaluate(2.5, 1:5, 1)
			%
			% INPUT PARAMETERS:
			%		 obj : interpolant object VARARGIN
			%	varargin : sample points for which the values are
			%			   interpolated. Expected to be a list of arrays
			% OUTPUT:
			%	   value : values at the points specified by varargin
103
104
105
106
			% evaluate is used to get the value of the data at certain
			% points specified by varargin. It is assumed that
			%	numel(varargin) == ndims(valueOriginal)
			reducedGrid = varargin(obj.reducedDimension);
107
108
			interpolant = obj.reducedGriddedInterpolant(reducedGrid);
			value = permute(interpolant, obj.permutationVector);
109
110
		end
		
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
		function value = eval(obj, varargin)
		% a new version of evaluate that allows to use the syntax of the griddedInterpolant.
		% That is, when the arguments are passed in braces, e.g.
		%   value = myInterpolant.eval({z,z})
		% then the vectors z,z define a grid on which the interpolant is evaluated. (same as
		% evaluate!)
		%
		% when the arguments are passed as a list, e.g.
		%   value = myInterpolant.eval(z,z)
		% then the vectors (of same length) define a list of pairwise coordinates, which are
		% evaluated.
			if iscell(varargin{1}) % passed as cellArray
				temp = varargin{1};
				reducedGrid = temp(obj.reducedDimension);
				value = permute(obj.reducedGriddedInterpolant(reducedGrid), obj.permutationVector);
			else % passed as list
				reducedGrid = varargin(obj.reducedDimension);
				value = permute(obj.reducedGriddedInterpolant(reducedGrid{:}), obj.permutationVector);
			end
		end
		
132
133
134
	end
end