context: //////////////////////////////////////////////////////////////////
  //                                                              //
  //  This is an auto - manipulated source file.                  //
  //  Edits inside regions of HYCALPER AUTO GENERATED CODE        //
  //  will be lost and overwritten on the next build!             //
  //                                                              //
  //////////////////////////////////////////////////////////////////
  #region LGPL License
  /*    
      This file is part of ILNumerics.Net Core Module.
  
      ILNumerics.Net Core Module is free software: you can redistribute it 
      and/or modify it under the terms of the GNU Lesser General Public 
      License as published by the Free Software Foundation, either version 3
      of the License, or (at your option) any later version.
  
      ILNumerics.Net Core Module 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 Lesser General Public License for more details.
  
      You should have received a copy of the GNU Lesser General Public License
      along with ILNumerics.Net Core Module.  
      If not, see <http://www.gnu.org/licenses/>.
  */
  #endregion
  
  using System;
  using System.Collections.Generic;
  using System.Text;
  using ILNumerics.Storage;
  using ILNumerics.Misc;
  using ILNumerics.Exceptions;
  /*!HC:TYPELIST:
  <hycalper>
  <type>
      <source locate="after">
          inArr1
      </source>
      <destination>byte</destination>
      <destination>complex</destination>
  </type>
  <type>
      <source locate="after">
          inCls1
      </source>
      <destination><![CDATA[ILArray<byte>]]></destination>
      <destination><![CDATA[ILArray<complex>]]></destination>
  </type>
  <type>
      <source locate="nextline">
          HCnullValue
      </source>
      <destination>if (X.GetValue(0,0) != 0)</destination>
      <destination>if (X.GetValue(0,0).real != 0.0 || X.GetValue(0,0).imag != 0.0)</destination>
  </type>
  <type>
      <source locate="nextline">
          HCcompare0
      </source>
      <destination>if (*tmpIn != 0)</destination>
      <destination>if ((*tmpIn).real != 0.0 || (*tmpIn).imag != 0.0)</destination>
  </type>
  <type>
      <source locate="nextline">
          HCreferenceComp
      </source>
      <destination>if (*(pInArr + idxOffset.Map(i)) != 0.0)</destination>
      <destination>if ((*tmpIn).real != 0.0 || (*tmpIn).imag != 0.0)</destination>
  </type>
  <type>
      <source locate="nextline">
          locicalAbbrev
      </source>
      <destination>if (X is ILLogicalArray) nrElements = ((ILLogicalArray)X).NumberTrues;</destination>
      <destination></destination>
  </type></hycalper>
   */
  
  namespace ILNumerics.Untyped {
      /// <summary>
      /// general math class. This is in an experimental state! 
      /// </summary>
      public partial class ILMath {
          #region untyped object handler interface
          /// <summary>
          /// 
          /// </summary>
          /// <param name="outValue">Array of BaseArray of output parameter. outValue must be 
          /// at least of lenght 1, at most of length 3. The meanings are: 
          /// <list type="bullet">
          /// <item>One parameter: the sequential indices of all nonzero elements of X are returned.</item>
          /// <item>Two parameter: The first BaseArray returned in 'outValue' will hold the row indices of 
          /// nonzero elements of X, the second BaseArray will hold the column indices of those nonzero elements.</item>
          /// <item>If Length of outValue is 3, the rows and columns of nonzero elements are returned as the 
          /// first and second BaseArray elements. The third array will hold a (shallow) copy of those 
          /// nonzero elements found.</item>
          /// </list>
          /// </param>
          /// <param name="X">Array of input parameter. This must be at least 1 BaseArray holding 
          /// the input array for evaluation. If this array has length of 2, the second element must 
          /// be a scalar array of type <![CDATA[ILArray<double> or ILArray<int> or ILArray<float> or ILArray<byte>]]> 
          /// specifying the integer number of values to be returned. If this value is smaller 0, Find will 
          /// return that number of nonzero elements of X from the end of X.</param>
          /// <remarks>In order to specify the mode of Find, the length of the arrays 'outValue' and 
          /// 'X' will be recognized only. Any initial values of elements in 'outValue' will 
          /// be destroyed. The elements of X will not be altered.</remarks>
          public static void Find(ILBaseArray [] outValue, params ILBaseArray [] X) {
              if (outValue.Length > 3)
                  throw new ILException ( "Find: Too many out parameters specified." );
              if (outValue.Length < 1)
                  throw new ILException ( "Find: Too less out parameters specified." );
              if (X.Length < 1)
                  throw new ILException ( "Find: Input array must be specified." );
              if (X.Length > 2)
                  throw new ILException ( "Find: Too many parameters specified. At most 2 parameters allowed." );
              int limit = 0;
              if (X.Length == 2) {
                  if (!X[1].IsScalar)
                      throw new ILArgumentSizeException ( "Find: the 'limit' parameter must be integer and scalar!" );
                  if (X [1] is ILArray<double>)
                      limit = (int) ( (ILArray<double>) X [1] ).GetValue(0);
                  else if (X [1] is ILArray<float>)
                      limit = (int) ( (ILArray<float>) X [1] ).GetValue(0);
                  else if (X [1] is ILArray<int>)
                      limit = ( (ILArray<int>) X[1]).GetValue(0);
                  else if (X [1] is ILArray<Int32>)
                      limit = (int) ( (ILArray<Int32>) X [1] ).GetValue(0);
                  else if (X [1] is ILArray<Int64>)
                      limit = (int) ( (ILArray<Int64>) X [1] ).GetValue(0);
                  else if (X [1] is ILArray<byte>)
                      limit = (int) ( (ILArray<byte>) X [1] ).GetValue(0);
                  else if (X [1] is ILArray<char>)
                      limit = (int) ( (ILArray<char>) X [1] ).GetValue(0);
                  else
                      throw new ILArgumentTypeException ( "Find: Limit parameter must be of any signed numeric type and must not be complex." );
              }  
              ILArray<double> C = null; 
              if (outValue.Length > 1) C = ILArray<double>.empty(0,0); 
              if (false) {
              #region HYCALPER LOOPSTART UNTYPED 
              } else if (X[0] is /*!HC:inCls1*/ ILArray<double> )  {
                  /*!HC:inCls1*/ ILArray<double> V = null; 
                  if (outValue.Length == 3)
                      V = /*!HC:inCls1*/ ILArray<double> .empty(0,0);
                  outValue[0] = ILNumerics.BuiltInFunctions.ILMath.find ( (/*!HC:inCls1*/ ILArray<double> ) X [0], limit, ref C, ref V);
                  if (outValue.Length > 1) 
                      outValue[1] = C; 
                  if (outValue.Length == 3)
                      outValue[2] = V; 
                  return; 
              #endregion HYCALPER LOOPEND UNTYPED
  #region HYCALPER AUTO GENERATED CODE
  // DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
              } else if (X[0] is  ILArray<complex> )  {
                  ILArray<complex> V = null; 
                  if (outValue.Length == 3)
                      V =  ILArray<complex> .empty(0,0);
                  outValue[0] = ILNumerics.BuiltInFunctions.ILMath.find ( ( ILArray<complex> ) X [0], limit, ref C, ref V);
                  if (outValue.Length > 1) 
                      outValue[1] = C; 
                  if (outValue.Length == 3)
                      outValue[2] = V; 
                  return; 
              } else if (X[0] is  ILArray<byte> )  {
                  ILArray<byte> V = null; 
                  if (outValue.Length == 3)
                      V =  ILArray<byte> .empty(0,0);
                  outValue[0] = ILNumerics.BuiltInFunctions.ILMath.find ( ( ILArray<byte> ) X [0], limit, ref C, ref V);
                  if (outValue.Length > 1) 
                      outValue[1] = C; 
                  if (outValue.Length == 3)
                      outValue[2] = V; 
                  return; 
  
  #endregion HYCALPER AUTO GENERATED CODE
  
              } else {
                  throw new ILException ( "Function 'Find' is not defined for Arrays of Type "
                      + X [0].GetType ().ToString () );
              }
          }
          #endregion untyped object handler interface
      }
  }
  
  namespace ILNumerics.BuiltInFunctions {
  	public partial class ILMath {
          #region HYCALPER LOOPSTART FIND(X)
          /// <summary>
          /// Find nonzero elements of X
          /// </summary>
          /// <param name="X">N-dimensional double array</param>
          /// <returns>vector with sequential indices of X elements 
          /// having a value not equal to 0.0. 
          /// </returns>
          public static ILArray<double> find(/*!HC:inCls1*/ ILArray<double> X) {
              ILArray<double> R = null; 
              /*!HC:inCls1*/ ILArray<double> V = null;
              return find(X,0,ref R,ref V);
          }
          #endregion HYCALPER LOOPEND FIND(X)
  #region HYCALPER AUTO GENERATED CODE
  // DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
          /// <summary>
          /// Find nonzero elements of X
          /// </summary>
          /// <param name="X">N-dimensional double array</param>
          /// <returns>vector with sequential indices of X elements 
          /// having a value not equal to 0.0. 
          /// </returns>
          public static ILArray<double> find( ILArray<complex> X) {
              ILArray<double> R = null; 
              ILArray<complex> V = null;
              return find(X,0,ref R,ref V);
          }
          /// <summary>
          /// Find nonzero elements of X
          /// </summary>
          /// <param name="X">N-dimensional double array</param>
          /// <returns>vector with sequential indices of X elements 
          /// having a value not equal to 0.0. 
          /// </returns>
          public static ILArray<double> find( ILArray<byte> X) {
              ILArray<double> R = null; 
              ILArray<byte> V = null;
              return find(X,0,ref R,ref V);
          }
  
  #endregion HYCALPER AUTO GENERATED CODE
  
          #region HYCALPER LOOPSTART FIND(X,limit)
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          public static ILArray<double> find(/*!HC:inCls1*/ ILArray<double> X, int limit) {
              ILArray<double> C = null; 
              /*!HC:inCls1*/ ILArray<double> V = null;
              return find(X,limit,ref C,ref V);
          }
          #endregion HYCALPER LOOPEND FIND(X,limit)
  #region HYCALPER AUTO GENERATED CODE
  // DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          public static ILArray<double> find( ILArray<complex> X, int limit) {
              ILArray<double> C = null; 
              ILArray<complex> V = null;
              return find(X,limit,ref C,ref V);
          }
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          public static ILArray<double> find( ILArray<byte> X, int limit) {
              ILArray<double> C = null; 
              ILArray<byte> V = null;
              return find(X,limit,ref C,ref V);
          }
  
  #endregion HYCALPER AUTO GENERATED CODE
  
          #region HYCALPER LOOPSTART FIND(X,limit,C)
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          /// <param name="C">If not null, the function will return the row indices of nonzero elements 
          /// as main return value. C will therefore hold the column indices of those elements. If X
          /// has more than 2 dimensions, the column indices will go along the 2nd dimension.</param>
          public static ILArray<double> find(/*!HC:inCls1*/ ILArray<double> X, int limit, ref ILArray<double> C) {
              /*!HC:inCls1*/ ILArray<double> V = null; 
              return find(X, limit, ref C, ref V);
          }
          #endregion HYCALPER LOOPEND FIND(X,limit,C)
  #region HYCALPER AUTO GENERATED CODE
  // DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          /// <param name="C">If not null, the function will return the row indices of nonzero elements 
          /// as main return value. C will therefore hold the column indices of those elements. If X
          /// has more than 2 dimensions, the column indices will go along the 2nd dimension.</param>
          public static ILArray<double> find( ILArray<complex> X, int limit, ref ILArray<double> C) {
              ILArray<complex> V = null; 
              return find(X, limit, ref C, ref V);
          }
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          /// <param name="C">If not null, the function will return the row indices of nonzero elements 
          /// as main return value. C will therefore hold the column indices of those elements. If X
          /// has more than 2 dimensions, the column indices will go along the 2nd dimension.</param>
          public static ILArray<double> find( ILArray<byte> X, int limit, ref ILArray<double> C) {
              ILArray<byte> V = null; 
              return find(X, limit, ref C, ref V);
          }
  
  #endregion HYCALPER AUTO GENERATED CODE
  
          #region HYCALPER LOOPSTART FIND(X,limit,C,V)
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          /// <param name="C">If not null, the function will return the row indices of nonzero elements 
          /// as main return value. C will therefore hold the column indices of those elements. If X
          /// has more than 2 dimensions, the column indices will go along the 2nd dimension.</param>
          /// <param name="V">if not null on entrance, V will hold a copy of the values of nonzero elements returned.</param>
          /// <returns>Vector containing (sequential) indices of nonzero elements in X. If C was 
          /// not null, return value will contain row indices of nonzero elements. </returns>
          /// <remarks>The return type of the index vectors is always 'double'. The return type 
          /// of the element vector 'V' depends on the type of input array X. V and C may be null on 
          /// entrance, indicating their information is not needed. If V is not null (f.e. 'empty()') C must be 
          /// not null also. Any initial data of V or C will be lost.</remarks>
          public static ILArray<double> find(/*!HC:inCls1*/ ILArray<double> X, int limit,
                        ref ILArray<double> C, ref /*!HC:inCls1*/ ILArray<double> V) {
              double[] retArray;
              bool create_row_columns = !Object.Equals(C, null);
              bool return_values = !Object.Equals(V, null); 
              ILArray<double> ret = null;
              ILDimension inDim = X.Dimensions;
              if (inDim.NumberOfElements == 1) {
                  #region SCALAR
                  // scalar -> return copy
                  /*!HC:HCnullValue*/
                  if (X.GetValue(0, 0) != 0.0) 
                  {
                      retArray = new double[1] { 0 };
                      if (create_row_columns) {
                          C = new ILArray<double>(0.0); 
                      }
                      if (return_values) {
                          V = new /*!HC:inCls1*/ ILArray<double> (new /*!HC:inArr1*/ double [1]{X.GetValue(0, 0)}); 
                      }
                      return new ILArray<double>(retArray, 1, 1);
                  } else {
                      if (create_row_columns) {
                          C = ILArray<double>.empty(0,0);
                      }
                      if (return_values) {
                          V = /*!HC:inCls1*/ ILArray<double> .empty(0,0);
                      }
                      return ILArray<double>.empty(0,0);
                  }
                  #endregion SCALAR
              }
              double[] indices;
              int nrElements = inDim.NumberOfElements;
              /*!HC:locicalAbbrev*/
  
              if (limit != 0) {
                  int lim = Math.Abs ( limit );
                  if (lim < nrElements)
                      nrElements = lim;
              }
              indices = ILMemoryPool.Pool.New<double>(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards 
              int foundIdx = 0;
  
              #region physical
              // physical -> pointer arithmetic
              if (limit >= 0) {
                  unsafe {
                      fixed (double* pIndices = indices)
                      fixed (/*!HC:inArr1*/ double * pX = X.m_data) {
                          /*!HC:inArr1*/ double * lastElement = pX + inDim.NumberOfElements;
                          /*!HC:inArr1*/ double * tmpIn = pX;
                          double* pI = pIndices;
                          double* pFoundLast = pI + indices.Length;
                          while (tmpIn < lastElement && pI < pFoundLast) {
                              /*!HC:HCcompare0*/
                              if (*tmpIn != 0.0)
                                  *pI++ = (double) ( tmpIn - pX );
                              tmpIn++;
                          }
                          foundIdx = (int) ( pI - pIndices );
                      }
                  }
              } else {
                  // search backwards 
                  unsafe {
                      fixed (double* pIndices = indices)
                      fixed (/*!HC:inArr1*/ double * pX = X.m_data) {
                          /*!HC:inArr1*/ double * lastElementX = pX; 
                          /*!HC:inArr1*/ double * tmpIn = pX + inDim.NumberOfElements;
                          double* pI = pIndices + indices.Length;
                          while (tmpIn > lastElementX && pI > pIndices) {
                              tmpIn--;
                              /*!HC:HCcompare0*/
                              if (*tmpIn != 0.0)
                                  *(--pI) = (double) ( tmpIn - pX );
                          }
                          foundIdx = (int) ( pIndices + indices.Length - pI );
                      }
                  }
              }
              #endregion
  
              if (foundIdx == 0) {
                  // return empty array
                  return ILArray<double>.empty(0,0);
              }
              // transform to row / columns; extract values if needed
              int leadDimLen = inDim[0]; 
              if (create_row_columns) {
                  #region RETURN ROWS / COLUMNS /VALUES
                  C = new ILArray<double> ( ILMemoryPool.Pool.New<double>(foundIdx), foundIdx, 1 );
                  ret = new ILArray<double> ( ILMemoryPool.Pool.New<double>(foundIdx), foundIdx, 1 );
                  if (return_values) {
                      V = new /*!HC:inCls1*/ ILArray<double> ( ILMemoryPool.Pool.New< /*!HC:inArr1*/ double >(foundIdx), foundIdx, 1 );
                      // copy values, transform to row/columns
                      unsafe {
                          fixed (double* pIndices = indices,
                                 pRows = ret.m_data, pCols = C.m_data)
                          fixed (/*!HC:inArr1*/ double * pValues = V.m_data, pInput = X.m_data) {
                              double* pI = (limit >= 0) ? 
                                      pIndices : (pIndices + indices.Length - foundIdx);
                              double* pLastIndex = pIndices + foundIdx;
                              double* pR = pRows;
                              double* pC = pCols;
                              /*!HC:inArr1*/ double * pV = pValues;
                              /*!HC:inArr1*/ double * pX = pInput;
  
                              while (pI < pLastIndex) {
                                  *pR++ = *( pI ) % leadDimLen;
                                  *pC++ = (int) *( pI ) / leadDimLen;
                                  *pV++ = *( pInput + (int) *pI++ );
                              }
  
                          }
                      }
                  } else {
                      // just return row / columns 
                      unsafe {
                          fixed (double* pIndices = indices,
                                 pRows = ret.m_data, pCols = C.m_data)
                          fixed (/*!HC:inArr1*/ double * pInput = X.m_data) {
                              double* pI = (limit >= 0) ? 
                                      pIndices : (pIndices + indices.Length - foundIdx);
                              double* pLastIndex = pIndices + foundIdx;
                              double* pR = pRows;
                              double* pC = pCols;
                              while (pI < pLastIndex) {
                                  *pR++ = *(pI) % leadDimLen; 
                                  *pC++ = (int)(*(pI++) / leadDimLen); 
                              }
                          }
                      }
                  }
                  #endregion RETURN ROWS / COLUMNS 
              } else {
                  #region RETURN INDICES ONLY 
                  if (foundIdx != indices.Length) {
                      ret = new ILArray<double> ( ILMemoryPool.Pool.New<double>(foundIdx), foundIdx, 1 );
                      unsafe {
                          fixed (double* pIndices = indices, pRows = ret.m_data){
                              double* pI = (limit >= 0) ? 
                                      pIndices : (pIndices + indices.Length - foundIdx);
                              double* pLastIndex = pIndices + foundIdx;
                              double* pR = pRows;
                              while (pI < pLastIndex) {
                                  *pR++ = *pI++;
                              }
                          }
                      }
                  } else {
                      ret = new ILArray<double> (indices, foundIdx, 1);
                  }
                  #endregion RETURN INDICES ONLY
              }
              return ret; 
          }
          #endregion HYCALPER LOOPEND FIND(X,limit,C,V)
  #region HYCALPER AUTO GENERATED CODE
  // DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! 
          /// <summary>
          /// Find nonzero elements in X
          /// </summary>
          /// <param name="X">input array to be evaluated</param>
          /// <param name="limit">number of elements to search for. If this value is <![CDATA[< 0]]> the function 
          /// will return at most 'limit' nonzero elements from the end of the array ordered by ascending index.
          /// Set to 0 to search full array.</param>
          /// <param name="C">If not null, the function will return the row indices of nonzero elements 
          /// as main return value. C will therefore hold the column indices of those elements. If X
          /// has more than 2 dimensions, the column indices will go along the 2nd dimension.</param>
          /// <param name="V">if not null on entrance, V will hold a copy of the values of nonzero elements returned.</param>
          /// <returns>Vector containing (sequential) indices of nonzero elements in X. If C was 
          /// not null, return value will contain row indices of nonzero elements. </returns>
          /// <remarks>The return type of the index vectors is always 'double'. The return type 
          /// of the element vector 'V' depends on the type of input array X. V and C may be null on 
          /// entrance, indicating their information is not needed. If V is not null (f.e. 'empty()') C must be 
          /// not null also. Any initial data of V or C will be lost.</remarks>
          public static ILArray<double> find( ILArray<complex> X, int limit,
                        ref ILArray<double> C, ref  ILArray<complex> V) {
              double[] retArray;
              bool create_row_columns = !Object.Equals(C, null);
              bool return_values = !Object.Equals(V, null); 
              ILArray<double> ret = null;
              ILDimension inDim = X.Dimensions;
              if (inDim.NumberOfElements == 1) {
                  #region SCALAR
                  // scalar -> return copy
                  if (X.GetValue(0,0).real != 0.0 || X.GetValue(0,0).imag != 0.0)
                  {
                      retArray = new double[1] { 0 };
                      if (create_row_columns) {
                          C = new ILArray<double>(0.0); 
                      }
                      if (return_values) {
                          V = new  ILArray<complex> (new  complex [1]{X.GetValue(0, 0)}); 
                      }
                      return new ILArray<double>(retArray, 1, 1);
                  } else {
                      if (create_row_columns) {
                          C = ILArray<double>.empty(0,0);
                      }
                      if (return_values) {
                          V =  ILArray<complex> .empty(0,0);
                      }
                      return ILArray<double>.empty(0,0);
                  }
                  #endregion SCALAR
              }
              double[] indices;
              int nrElements = inDim.NumberOfElements;
              
              if (limit != 0) {
                  int lim = Math.Abs ( limit );
                  if (lim < nrElements)
                      nrElements = lim;
              }
              indices = ILMemoryPool.Pool.New<double>(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards 
              int foundIdx = 0;
  
              #region physical
              // physical -> pointer arithmetic
              if (limit >= 0) {
                  unsafe {
                      fixed (double* pIndices = indices)
                      fixed ( complex * pX = X.m_data) {
                          complex * lastElement = pX + inDim.NumberOfElements;
                          complex * tmpIn = pX;
                          double* pI = pIndices;
                          double* pFoundLast = pI + indices.Length;
                          while (tmpIn < lastElement && pI < pFoundLast) {
                              if ((*tmpIn).real != 0.0 || (*tmpIn).imag != 0.0)
                                  *pI++ = (double) ( tmpIn - pX );
                              tmpIn++;
                          }
                          foundIdx = (int) ( pI - pIndices );
                      }
                  }
              } else {
                  // search backwards 
                  unsafe {
                      fixed (double* pIndices = indices)
                      fixed ( complex * pX = X.m_data) {
                          complex * lastElementX = pX; 
                          complex * tmpIn = pX + inDim.NumberOfElements;
                          double* pI = pIndices + indices.Length;
                          while (tmpIn > lastElementX && pI > pIndices) {
                              tmpIn--;
                              if ((*tmpIn).real != 0.0 || (*tmpIn).imag != 0.0)
                                  *(--pI) = (double) ( tmpIn - pX );
                          }
                          foundIdx = (int) ( pIndices + indices.Length - pI );
                      }
                  }
              }
              #endregion
  
              if (foundIdx == 0) {
                  // return empty array
                  return ILArray<double>.empty(0,0);
              }
              // transform to row / columns; extract values if needed
              int leadDimLen = inDim[0]; 
              if (create_row_columns) {
                  #region RETURN ROWS / COLUMNS /VALUES
                  C = new ILArray<double> ( ILMemoryPool.Pool.New<double>(foundIdx), foundIdx, 1 );
                  ret = new ILArray<double> ( ILMemoryPool.Pool.New<double>(foundIdx), foundIdx, 1 );
                  if (return_values) {
                      V = new  ILArray<complex> ( ILMemoryPool.Pool.New<  complex >(foundIdx), foundIdx, 1 );
                      // copy values, transform to row/columns
                      unsafe {
                          fixed (double* pIndices = indices,
                                 pRows = ret.m_data, pCols = C.m_data)
                          fixed ( complex * pValues = V.m_data, pInput = X.m_data) {
                              double* pI = (limit >= 0) ? 
                                      pIndices : (pIndices + indices.Length - foundIdx);
                              double* pLastIndex = pIndices + foundIdx;
                              double* pR = pRows;
  
gt:                             double* pC = pCols;