The module "relativeind" of the Mastrave modelling library

 

Daniele de Rigo

 


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.

Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Daniele de Rigo

This page is licensed under a Creative Commons Attribution-NoDerivs 3.0 Italy License.

This document is also part of the book:
de Rigo, D. (2012). Semantic Array Programming with Mastrave - Introduction to Semantic Computational Modelling. http://mastrave.org/doc/MTV-1.012-1


Valid XHTML 1.0 Transitional