///
/// This file is part of ILNumerics Community Edition.
///
/// ILNumerics Community Edition - high performance computing for applications.
/// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
///
/// ILNumerics Community Edition is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License version 3 as published by
/// the Free Software Foundation.
///
/// ILNumerics Community Edition 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 ILNumerics Community Edition. See the file License.txt in the root
/// of your distribution package. If not, see .
///
/// In addition this software uses the following components and/or licenses:
///
/// =================================================================================
/// The Open Toolkit Library License
///
/// Copyright (c) 2006 - 2009 the Open Toolkit library.
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights to
/// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
/// the Software, and to permit persons to whom the Software is furnished to do
/// so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all
/// copies or substantial portions of the Software.
///
/// =================================================================================
///
using System;
using System.Collections.Generic;
using System.Text;
using ILNumerics.Storage;
using ILNumerics.Misc;
using ILNumerics.Exceptions;
namespace ILNumerics {
public partial class ILMath {
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< double> A, int limit = 0,
ILOutArray C = null, ILOutArray< double> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0, 0) != 0.0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( double* pX = A.GetArrayForRead()) {
double* lastElement = pX + inDim.NumberOfElements;
double* tmpIn = pX;
double* pI = pIndices;
double* pFoundLast = pI + indices.Length;
while (tmpIn < lastElement && pI < pFoundLast) {
if (*tmpIn != 0.0)
*pI++ = (double)(tmpIn - pX);
tmpIn++;
}
foundIdx = (int)(pI - pIndices);
}
}
} else {
// search backwards
unsafe {
fixed (double* pIndices = indices)
fixed ( double* pX = A.GetArrayForRead()) {
double* lastElementX = pX;
double* tmpIn = pX + inDim.NumberOfElements;
double* pI = pIndices + indices.Length;
while (tmpIn > lastElementX && pI > pIndices) {
tmpIn--;
if (*tmpIn != 0.0)
*(--pI) = (double)(tmpIn - pX);
}
foundIdx = (int)(pIndices + indices.Length - pI);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< double>(ILMemoryPool.Pool.New< double>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( double* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
double* pV = pValues;
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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( double* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
#region HYCALPER AUTO GENERATED CODE
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< Int64> A, int limit = 0,
ILOutArray C = null, ILOutArray< Int64> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0) != 0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( Int64* pX = A.GetArrayForRead()) {
Int64* lastElement = pX + inDim.NumberOfElements;
Int64* tmpIn = pX;
double* pI = pIndices;
double* pFoundLast = pI + indices.Length;
while (tmpIn < lastElement && pI < pFoundLast) {
if (*tmpIn != 0)
*pI++ = (double)(tmpIn - pX);
tmpIn++;
}
foundIdx = (int)(pI - pIndices);
}
}
} else {
// search backwards
unsafe {
fixed (double* pIndices = indices)
fixed ( Int64* pX = A.GetArrayForRead()) {
Int64* lastElementX = pX;
Int64* tmpIn = pX + inDim.NumberOfElements;
double* pI = pIndices + indices.Length;
while (tmpIn > lastElementX && pI > pIndices) {
tmpIn--;
if (*tmpIn != 0)
*(--pI) = (double)(tmpIn - pX);
}
foundIdx = (int)(pIndices + indices.Length - pI);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< Int64>(ILMemoryPool.Pool.New< Int64>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( Int64* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
Int64* pV = pValues;
Int64* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( Int64* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< Int32> A, int limit = 0,
ILOutArray C = null, ILOutArray< Int32> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0) != 0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( Int32* pX = A.GetArrayForRead()) {
Int32* lastElement = pX + inDim.NumberOfElements;
Int32* tmpIn = pX;
double* pI = pIndices;
double* pFoundLast = pI + indices.Length;
while (tmpIn < lastElement && pI < pFoundLast) {
if (*tmpIn != 0)
*pI++ = (double)(tmpIn - pX);
tmpIn++;
}
foundIdx = (int)(pI - pIndices);
}
}
} else {
// search backwards
unsafe {
fixed (double* pIndices = indices)
fixed ( Int32* pX = A.GetArrayForRead()) {
Int32* lastElementX = pX;
Int32* tmpIn = pX + inDim.NumberOfElements;
double* pI = pIndices + indices.Length;
while (tmpIn > lastElementX && pI > pIndices) {
tmpIn--;
if (*tmpIn != 0)
*(--pI) = (double)(tmpIn - pX);
}
foundIdx = (int)(pIndices + indices.Length - pI);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< Int32>(ILMemoryPool.Pool.New< Int32>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( Int32* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
Int32* pV = pValues;
Int32* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( Int32* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< float> A, int limit = 0,
ILOutArray C = null, ILOutArray< float> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0) != 0.0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( float* pX = A.GetArrayForRead()) {
float* lastElement = pX + inDim.NumberOfElements;
float* tmpIn = pX;
double* pI = pIndices;
double* pFoundLast = pI + indices.Length;
while (tmpIn < lastElement && pI < pFoundLast) {
if (*tmpIn != 0.0f)
*pI++ = (double)(tmpIn - pX);
tmpIn++;
}
foundIdx = (int)(pI - pIndices);
}
}
} else {
// search backwards
unsafe {
fixed (double* pIndices = indices)
fixed ( float* pX = A.GetArrayForRead()) {
float* lastElementX = pX;
float* tmpIn = pX + inDim.NumberOfElements;
double* pI = pIndices + indices.Length;
while (tmpIn > lastElementX && pI > pIndices) {
tmpIn--;
if (*tmpIn != 0.0f)
*(--pI) = (double)(tmpIn - pX);
}
foundIdx = (int)(pIndices + indices.Length - pI);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< float>(ILMemoryPool.Pool.New< float>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( float* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
float* pV = pValues;
float* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( float* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< fcomplex> A, int limit = 0,
ILOutArray C = null, ILOutArray< fcomplex> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0).real != 0.0 || A.GetValue(0,0).imag != 0.0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( fcomplex* pX = A.GetArrayForRead()) {
fcomplex* lastElement = pX + inDim.NumberOfElements;
fcomplex* 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 ( fcomplex* pX = A.GetArrayForRead()) {
fcomplex* lastElementX = pX;
fcomplex* 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);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< fcomplex>(ILMemoryPool.Pool.New< fcomplex>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( fcomplex* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
fcomplex* pV = pValues;
fcomplex* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( fcomplex* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< complex> A, int limit = 0,
ILOutArray C = null, ILOutArray< complex> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0).real != 0.0 || A.GetValue(0,0).imag != 0.0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( complex* pX = A.GetArrayForRead()) {
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 = A.GetArrayForRead()) {
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);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< complex>(ILMemoryPool.Pool.New< complex>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( complex* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
complex* pV = pValues;
complex* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( complex* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
///
/// Find nonzero elements in A
///
/// Input array
/// [Optional] Number of elements to search for. If this value is 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 (default).
/// [Optional] 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// [Optional] If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInArray< byte> A, int limit = 0,
ILOutArray C = null, ILOutArray< byte> V = null) {
using (ILScope.Enter(A)) {
bool create_row_columns = !Object.Equals(C, null);
bool return_values = !Object.Equals(V, null);
ILArray ret = empty();
ILSize inDim = A.Size;
if (inDim.NumberOfElements == 1) {
#region SCALAR
// scalar -> return copy
if (A.GetValue(0,0) != 0) {
if (create_row_columns) {
C.a = zeros(ILSize.Scalar1_1);
}
if (return_values) {
V.a = A.C;
}
return zeros(1, 1);
} else {
if (create_row_columns) {
C.a = empty(ILSize.Empty00);
}
if (return_values) {
V.a = empty(ILSize.Empty00);
}
return empty(ILSize.Empty00);
}
#endregion SCALAR
}
long nrElements = inDim.NumberOfElements;
if (limit != 0) {
int lim = Math.Abs(limit);
if (lim < nrElements)
nrElements = lim;
}
double[] indices = ILMemoryPool.Pool.New(nrElements); // init return array with most elements for non logical inarray -> shorten afterwards
int foundIdx = 0;
// physical -> pointer arithmetic
if (limit >= 0) {
unsafe {
fixed (double* pIndices = indices)
fixed ( byte* pX = A.GetArrayForRead()) {
byte* lastElement = pX + inDim.NumberOfElements;
byte* tmpIn = pX;
double* pI = pIndices;
double* pFoundLast = pI + indices.Length;
while (tmpIn < lastElement && pI < pFoundLast) {
if (*tmpIn != 0)
*pI++ = (double)(tmpIn - pX);
tmpIn++;
}
foundIdx = (int)(pI - pIndices);
}
}
} else {
// search backwards
unsafe {
fixed (double* pIndices = indices)
fixed ( byte* pX = A.GetArrayForRead()) {
byte* lastElementX = pX;
byte* tmpIn = pX + inDim.NumberOfElements;
double* pI = pIndices + indices.Length;
while (tmpIn > lastElementX && pI > pIndices) {
tmpIn--;
if (*tmpIn != 0)
*(--pI) = (double)(tmpIn - pX);
}
foundIdx = (int)(pIndices + indices.Length - pI);
}
}
}
if (foundIdx == 0) {
return empty();
}
// transform to row / columns; extract values if needed
int leadDimLen = inDim[0];
if (create_row_columns) {
#region RETURN ROWS / COLUMNS /VALUES
C.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
ret.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
if (return_values) {
V.a = new ILRetArray< byte>(ILMemoryPool.Pool.New< byte>(foundIdx), foundIdx, 1);
// copy values, transform to row/columns
unsafe {
fixed (double* pIndices = indices,
pRows = ret.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( byte* pValues = V.GetArrayForWrite(), pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
double* pC = pCols;
byte* pV = pValues;
byte* 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.GetArrayForWrite(), pCols = C.GetArrayForWrite())
fixed ( byte* pInput = A.GetArrayForRead()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + 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.a = new ILRetArray(ILMemoryPool.Pool.New(foundIdx), foundIdx, 1);
unsafe {
fixed (double* pIndices = indices, pRows = ret.GetArrayForWrite()) {
double* pI = (limit >= 0) ?
pIndices : (pIndices + indices.Length - foundIdx);
double* pLastIndex = pI + foundIdx;
double* pR = pRows;
while (pI < pLastIndex) {
*pR++ = *pI++;
}
}
}
} else {
ret.a = new ILRetArray(indices, foundIdx, 1);
}
#endregion RETURN INDICES ONLY
}
return ret;
}
}
#endregion HYCALPER AUTO GENERATED CODE
#region logicals
///
/// Find nonzero elements in A
///
/// Input array
/// Number of elements to search for. If this value is 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 (default).
/// 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 A
/// has more than 2 dimensions, the column indices will go along the 2nd dimension.
/// If not null on entrance, V will hold a copy of the values of nonzero elements returned.
/// Vector containing (sequential) indices of nonzero elements in A. If C was
/// not null, return value will contain row indices of nonzero elements.
/// 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 A. V and C may be null on
/// entrance, indicating their information is not needed. If V is not null (e.g. 'empty()') C must be
/// not null also. Any initial data of V or C will be lost.
public static ILRetArray find(ILInLogical A, int limit,
ILOutArray C, ILOutLogical V) {
using (ILScope.Enter(A)) {
if (isnullorempty(A)) {
if (!isnull(V)) {
V.a = new ILLogical(ILSize.Empty00);
}
return empty();
}
ILArray tmpA = new ILArray(A.Storage);
ILArray tmpV = null;
if (!isnull(V)) {
tmpV = new ILArray(V.Storage);
}
ILArray ret = find(tmpA, limit, C, tmpV);
if (!isnull(tmpV)) {
V.a = new ILLogical(new ILLogicalStorage( tmpV.Storage.GetDataArray(), tmpV.S));
}
return ret;
}
}
#endregion
}
}