The module "relativeind" of the Mastrave modelling library
Copyright and license notice of the function relativeind
Copyright © 2008,2009,2010,2011 Daniele de Rigo
The file relativeind.m is part of Mastrave.
Mastrave is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Mastrave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Mastrave. If not, see http://www.gnu.org/licenses/.
Function declaration
[ subelems , subinds , nsubs ] = relativeind( elems , relinds , order = 'unordered' , mode = '[]' , func = @( x ) x )
Description
Utility function to enable indexing multiple numeric vectors with shared indices expressing the relative position of the desired elements from 0 (begin of each vector) to 1 (end of each vector). Vector sizes may be heterogeneous.
The function extracts from a vector of numbers or from a cell-array of numeric vectors elems a corresponding vector or cell-array subelems whose elements are those of elems having their size reduced to preserve only subelements in the interval relinds . relinds is an interval from 0 to 1 indicating the desired starting and ending relative position of the subelements to be preserved. Within relinds interval, 0 means the first subelement (and 1 means the last subelement) of each element of elems . The relative positions refer to each element of elems after it has been sorted according to the passed order (if omitted, order is 'unordered' meaning that each element of elems preserves its original order).
The mode with which interval endpoints are processed depends upon the passed mode (if omitted, its default value is '[]'). The returned vector or cell-array subinds has the same size of subelems and lists the position of each subelement of subelems with respect to the elements of values . nsubs is returned as a vector of non-negative integers, showing per each element of subelems the number of returned subelements.
The returned subelems values can be processed by passing as func input argument a function handle to a function which can be either unary or binary. Valid unary functions are expected to take a vector as input and to return another vector with the same size of the input one. Valid binary functions are expeted to take as inputs two vectors having the same size and to return another vector with the same size of the inputs.
All computations done within the utiliy are fully vectorized, avoiding any explicit interpreted loop.
Input arguments
elems ::cellnumeric:: Vector of numbers or cell-array of numeric vectors from which subels is to be extraced. relinds ::probability,(scalar|interval,row_vector):: Reative indices belonging to [0,1] expressing the relative position of the desired elements of elems from 0 (begin of each vector) to 1 (end of each vector). order ::string:: Sorting mode with which each element of elems has to to be ordered. (Default value: 'unoredered' ). Valid orders are: order │ meaning ───────────────┼─────────────────────────────────────── 'none' │ Leave the elements of elems 'unordered' │ unordered. (Default) ───────────────┼─────────────────────────────────────── 'ascend' │ Sort the elements of elems in │ ascending order. ───────────────┼─────────────────────────────────────── 'descend' │ Sort the elements of elems in │ descending order. mode ::string:: Mode with which endpoints of the interval relinds are processed with respect to the nearest corresponding value positions of each elems element. (Default value: '[]' ). Valid modes are: mode │ meaning ────────┼────────────────────────────────────────────── '[]' │ Include all subelements of each elems │ element elems {i}(j) if their position j │ lie inside relinds or if j is equal to │ floor( relinds (1)*numel( elems (i) ) ) │ or │ ceil( relinds (2)*numel( elems (i) ) ) │ This is the default value of mode . ────────┼────────────────────────────────────────────── '[)' │ Include all subelements of each elems '[[' │ element elems {i}(j) if their position j │ lie inside relinds or if j is equal to │ ceil( relinds (2)*numel( elems (i) ) ) ────────┼────────────────────────────────────────────── '(]' │ Include all subelements of each elems ']]' │ element elems {i}(j) if their position j │ lie inside relinds or if j is equal to │ floor( relinds (1)*numel( elems (i) ) ) ────────┼────────────────────────────────────────────── '][' │ Include those subelements of each elems ')(' │ element elems {i}(j) whose position j lie │ inside relinds . func ::function_handle|cell:: Function handle which is applied to the elements of elems selected by relinds to compute each value of subel . The function can be either unary or binary. Valid unary functions are expected to take a vector as input and to return another vector with the same size of the input one. Valid binary functions are expected to take as inputs two vectors having the same size and to return another vector with the same size of the inputs. Binary functions must be passed as first element of a cell-array. The cell-array must be composed by a couple { function , method } whose second element must be a string. If omitted, the default value of func is the identity function @(x) x . Valid methods are: method │ meaning ──────────┼──────────────────────────────────────────── 'self' │ Pass as first and second arguments of │ the binary function the same values, both │ indexed by relinds . ──────────┼──────────────────────────────────────────── 'fold' │ Pass as first argument of the binary │ function the values indexed by relinds , │ and as second argument the corresponding │ values s.t. within each element of elems │ the distance between the i-th index │ referred by relinds and the index 1 │ is equal to the distance between the │ second argument i-th index and the last │ index of the element.
Example of usage
% Basic usage: isolated relative indices ci = 1:10 [ sci, idx, ni ] = relativeind( ci , 0 ) [ sci, idx, ni ] = relativeind( ci , 0.5 ) [ sci, idx, ni ] = relativeind( ci , 1 ) % Managing a cell-array of numeric vectors ci = { 10:10:100 , 1:100 }; [ sci, idx, ni ] = relativeind( ci , 0 ) [ sci, idx, ni ] = relativeind( ci , 0.5 ) [ sci, idx, ni ] = relativeind( ci , 1 ) % Intervals of relative indices: exact matching [ sci, idx, ni ] = relativeind( ci , [ 0.4 0.5 ] ) % Dealing with interval endpoints [ sci, idx, ni ] = relativeind( ci , 0.41 ) [ sci, idx, ni ] = relativeind( ci , [ 0.41 0.51 ] ) % Including all nearest subelements [ sci, idx, ni ] = relativeind( ci , 0.41 , 'none' , '[]' ) [ sci, idx, ni ] = relativeind( ci , [ 0.41 0.51 ] , 'none' , '[]' ) % Including lower nearest subelements [ sci, idx, ni ] = relativeind( ci , 0.41 , 'none' , '[)' ) [ sci, idx, ni ] = relativeind( ci , [ 0.41 0.51 ] , 'none' , '[)' ) % Including upper nearest subelements [ sci, idx, ni ] = relativeind( ci , 0.41 , 'none' , '(]' ) [ sci, idx, ni ] = relativeind( ci , [ 0.41 0.51 ] , 'none' , '(]' ) % Including only exactly matching subelements [ sci, idx, ni ] = relativeind( ci , 0.41 , 'none' , '()' ) [ sci, idx, ni ] = relativeind( ci , [ 0.41 0.51 ] , 'none' , '()' ) % Sorting elements ci = ceil( rand(1,10)*100 ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'unordered' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'ascend' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'descend' ) ci = { ceil( rand(1,10)*10 ) , ceil( rand(1,10)*20 ) } [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'unordered' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'ascend' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'descend' ) % Managing empty elements ni = [0 5 0 0 1 3 2 0] ci = mat2cell( ceil(rand(1,sum(ni))*100) , 1 , ni ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'unordered' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'ascend' ) [ sci, idx, ni ] = relativeind( ci , [ 0 0.5 ] , 'descend' ) [ sci, idx, ni ] = relativeind( ci , [ 0.5 1 ] ) [ sci, idx, ni ] = relativeind( ci , 0 ) [ sci, idx, ni ] = relativeind( ci , 0.5 ) [ sci, idx, ni ] = relativeind( ci , 1 ) % Passing a function to transform output values ci = { 1:9 , [20 50 30 40 10] } % unary function f = @(x) x.*x int = [ 0 1 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f ) int = [ 0.4 0.9 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f ) % binary function: method 'self' f = @(x,y) x.*y f2 = { f , 'self' } int = [ 0 1 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f2 ) int = [ 0.4 0.9 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f2 ) % binary function: method 'fold' f = @(x,y) x.*y f2 = { f , 'fold' } int = [ 0 1 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f2 ) int = [ 0.4 0.9 ] [ sci, idx, ni ] = relativeind( ci , int , 'unordered' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'ascend' , '[]' , f2 ) [ sci, idx, ni ] = relativeind( ci , int , 'descend' , '[]' , f2 ) % Efficiency ni = floor( rand( 1 , 100000 ) * 20 ); ci = mat2cell( rand( 1 , sum(ni) ) , 1 , ni ); tic; ci1 = relativeind( ci , [.1 .8] ); toc tic; ci2 = cell( 1 , numel(ci) ); for i=1:numel(ci) n = numel( ci{i} ); id = max( 1 , floor(.1*n) ):min( ceil(.8*n) , n ); ci2{i} = ci{i}(id); end; toc % check to ensure ci1 and ci2 are equal assert( isequal( [ci1{:}] , [ci2{:}] ) ) assert(isequal( ... cellfun( 'prodofsize', ci1 ) , cellfun( 'prodofsize', ci2 ) ... ));
See also: mat2groups Keywords: cell array, indexing Version: 0.7.6
Support
The Mastrave modelling library is committed to provide reusable and general - but also robust and scalable - modules for research modellers dealing with computational science. You can help the Mastrave project by providing feedbacks on unexpected behaviours of this module. Despite all efforts, all of us - either developers or users - (should) know that errors are unavoidable. However, the free software paradigm successfully highlights that scientific knowledge freedom also implies an impressive opportunity for collectively evolve the tools and ideas upon which our daily work is based. Reporting a problem that you found using Mastrave may help the developer team to find a possible bug. Please, be aware that Mastrave is entirely based on voluntary efforts: in order for your help to be as effective as possible, please read carefully the section on reporting problems. Thank you for your collaboration.