samer@4: classdef dmap samer@4: properties (GetAccess=private, SetAccess=immutable) samer@4: cardr_ samer@4: map_rn samer@4: map_ni samer@4: domain_ samer@4: end samer@4: samer@4: methods samer@4: % dmap - Create discretisation map samer@4: % samer@4: % dmap :: samer@4: % N:natural~'range of discretisation function will be 1..N', samer@4: % (real->natural) ~'discretisation function itself', samer@4: % (natural->[[2]]) ~'reverse map, returns upper and lower bin edges' samer@4: % -> dmap. samer@4: % samer@4: % The map consists of a mapping between the integers 1..N and a set samer@4: % of consectutive half-open intervals. The discretisation is performed samer@4: % by mapping a real number to the index of the half-open interval in samer@4: % which it lies. samer@4: % samer@4: % The map be applied using parentheses (function application), eg samer@4: % samer@4: % m = linmap(-2,10,24); samer@4: % i = m(2.45); samer@4: % samer@4: % If the input is outside, the map returns -Inf or Inf. samer@4: % samer@4: % METHODS samer@4: % bins - return some or all of the intervals in the map samer@4: % cardr - number of intervals in a map samer@4: % centres - return the centres of some or all of the intervals samer@4: % domain - return the interval which is union of all the intervals samer@4: % edges - return the set of all the interval endpoints. samer@4: % range - the set 1..N samer@4: % map_clamped - apply map with output clamped to valid range samer@4: % feval - apply map to real numbers samer@4: % samer@4: % dmap also implements subsref, tostring and display samer@4: % samer@4: % linmap, binmap, edgemap - create convenient discretisation maps samer@4: samer@4: function M=dmap(card,mapfn,revmap) samer@4: if nargin==0, M=dmap(1,@floor,@(i)[i-1;i]); % dummy map samer@4: elseif isa(card,'dmap'), M=card samer@4: else samer@4: M.cardr_=card; samer@4: M.map_rn=mapfn; samer@4: M.map_ni=revmap; samer@4: samer@4: intervals=revmap([1 M.cardr_]); samer@4: M.domain_=[intervals(1,1) intervals(2,2)]; samer@4: end samer@4: end samer@4: samer@4: % bins - return bin edges of discretisation map samer@4: % samer@4: % bins :: dmap(N) -> [[2,N]]~'all the bins'. samer@4: % bins :: dmap(N), [[M]->[N]]~'M bin indices'-> [[2,M]]~'selected bins'. samer@4: function X=bins(M,I), samer@4: if nargin<2,I=range(M); end samer@4: X=M.map_ni(I); samer@4: end samer@4: samer@4: % cardr - Cardinality of range (ie size) samer@4: % samer@4: % cardr :: dmap(N) -> N:natural. samer@4: function N=cardr(M), N=M.cardr_; end samer@4: samer@4: % centres - Return centres of discretisation bins samer@4: % samer@4: % centres :: dmap(N) -> [[N]] ~'centres of all bins'. samer@4: % centres :: dmap(N), [[M]->[N]] -> [[M]] ~'centres of selected bins'. samer@4: function X=centres(M,I) samer@4: if nargin<2,I=range(M); end samer@4: X=mean(M.map_ni(I),1); samer@4: end samer@4: samer@4: % tostring - string describing dmap samer@4: % samer@4: % tostring :: dmap(N) -> string. samer@4: function s=tostring(M) samer@4: s=sprintf('dmap::%g--%g->[%d]',M.domain_(1),M.domain_(2),M.cardr_); samer@4: end samer@4: samer@4: % DISPLAY - Display dmap object as string samer@4: function display(c), disp(tostring(c)); end samer@4: samer@4: % domain - return domain of a dmap samer@4: % samer@4: % domain :: dmap(N) -> [[2]] samer@4: function X=domain(M), X=M.domain_; end samer@4: samer@4: % edges - return edges of discretisation map samer@4: % samer@4: % edges :: dmap(N) -> [[N+1]]. samer@4: % edges :: dmap(N) [[M]->[N]-> [[M+1]]. samer@4: function X=edges(M,I), samer@4: if nargin<2,I=range(M); end samer@4: Y=M.map_ni(I); samer@4: X=[Y(1,1) Y(2,:)]; samer@4: end samer@4: samer@4: function I=feval(M,X), I=M.map_rn(X); end samer@4: % if isa(M,'dmap'), I=M.map_rn(X); samer@4: % else I=builtin('feval',M,X); end samer@4: % end samer@4: samer@4: % map_clamped - Apply clamped discretisation map samer@4: % samer@4: % map_clamped :: dmap(N), real -> [N]. samer@4: function I=map_clamped(M,x) samer@4: I=M.map_rn(x); samer@4: I(I==-inf)=1; samer@4: I(I==inf) =M.cardr_; samer@4: end samer@4: samer@4: % range - range of dmap (set of natural numbers) samer@4: % samer@4: % range :: dmap(N) -> 1..N:[[N]->natural]. samer@4: function R=range(M), R=1:M.cardr_; end samer@4: samer@4: % SUBSREF - Subscript referencing for DMAP objects samer@4: % samer@4: % I=MAP(X) - Apply real-to-natural map to all elements of X samer@4: function I=subsref(M,S) samer@4: s=S(1); samer@4: switch s.type samer@4: case '()' samer@4: I=M.map_rn(s.subs{1}); samer@4: end samer@4: end samer@4: end samer@4: end samer@4: