///
/// 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 ILNumerics;
using ILNumerics.Misc;
using ILNumerics.Exceptions;
using ILNumerics.Storage;
using ILNumerics.Native;
using System.Text;
namespace ILNumerics {
///
/// Boolean array for high performance relational operations on arbitrary arrays
///
///
/// Logical arrays are derived from ]]>. It consumes
/// 1 byte per element and is the output parameter of all relational comparisons
/// as well as the input parameter for all functions consuming ]]>.
/// The difference between ]]> and an ILLogical is, the ILLogical
/// storing a integer value with the number of nonzero elements as additional information.
/// Therefore functions like 'find' are able to determine the lenght of output array to
/// be created omitting the need of multiple walks through the array. Therefore ILLogicalArrays
/// consume (a little) more time while construction but are much more performand on functions like
/// 'find'.
///
[Serializable]
public class ILBaseLogical : ILDenseArray {
#region properties
///
/// Number of 'true' elements in this array
///
/// This value caches the number of 'true' elements in this logical array.
/// It may be used for information purposes but is actually needed internally for performance
/// reasons.
public virtual long NumberNonZero {
get {
return Storage.NumberNonZero;
}
internal set {
Storage.NumberNonZero = value;
}
}
///
/// Shift the dimensions of this array by one (transpose for matrix)
///
public new ILRetLogical T {
get {
return new ILRetLogical((ILLogicalStorage)Storage.ShiftDimensions(1), NumberNonZero);
}
}
internal new ILLogicalStorage Storage {
get {
return (m_storage as ILLogicalStorage);
}
}
///
/// Create clone of this array
///
public new ILRetLogical C {
get {
return new ILRetLogical((ILLogicalStorage)base.Clone().Storage, NumberNonZero);
}
}
#endregion
#region constructors
///
/// Constructor creating ILLogical from dense storage
///
/// Input array, the storage of this ILArray will directly be used for
/// storage of the new ILLogical
/// Indicate whether the result is supposed to be a temporary array (true) or persistent (false)
internal ILBaseLogical(ILDenseStorage A, bool isTempArray)
: base(A,isTempArray) {
NumberNonZero = sumElements();
}
#endregion
#region helper functions
///
/// Sum all elements of this storage.
///
/// Number of non zero elements
protected int sumElements() {
int ret = 0;
int nrElements = Storage.Size.NumberOfElements;
// physical storage
unsafe {
fixed (byte* pInArray = GetArrayForRead()) {
byte* pCurData = pInArray;
byte* pLastElement = pInArray + nrElements;
while (pCurData < pLastElement)
ret += *pCurData++;
}
}
return ret;
}
#endregion
#region public functions
///
/// Concatenate this array
///
/// N-dimensional array. Except for dimensions
/// the dimensions of A must match the dimensions of this storage
/// Index of dimension to concatenate arrays along.
/// If dim is larger than the number of dimensions of any of the arrays,
/// its value will be used in modulus the number of dimensions.
/// New array having the size
/// of both input arrays layed behind each other along the dim's-dimension
public ILRetLogical Concat(ILInLogical A, int dim) {
using (ILScope.Enter(A))
return new ILRetLogical ((ILLogicalStorage)Storage.Concat(A.Storage, dim));
}
///
/// Create reshaped copy of this logical array
///
/// New dimensions of the array
/// Reshaped copy of this array
/// The current instance will not be changed! A new array is created, having
/// the elements of this array and a shape as determined by .
///
/// If the number of elements in
/// do not match the number of elements in this array.
public new ILRetLogical Reshape(ILSize size) {
using (ILScope.Enter()) {
ILLogical ret = C;
ret.Storage.Reshape(size);
return ret;
}
}
///
/// Create reshaped copy of this logical array
///
/// New dimensions of the array
/// Reshaped copy of the array
/// The current instance will not be changed! A new array is created, having
/// the elements of this array and a shape as determined by .
///
/// If the number of elements in
/// do not match the number of elements in this array.
public new ILRetLogical Reshape(params int[] size) {
return Reshape(new ILSize(size));
}
///
/// Create replication of this array
///
/// Dimensions specifier. If the number of elements in is
/// less than the number of dimensions in this array, the trailing dimensions will
/// be set to 1 (singleton dimensions). On the other hand, if the number specified
/// is larger then the number of dimension stored inside the storge the resulting
/// storage will get its number of dimensions extended accordingly.
/// array being created out of multiple replications of this array along
/// arbitrary dimensions according to
public new ILRetLogical Repmat(params int[] dims) {
return new ILRetLogical((ILLogicalStorage)Storage.Repmat(dims));
}
///
/// Create logical array from this logical and shift dimensions
///
/// Number of dimensions to shift
/// Shifted version of this array
/// The shift is done 'to the left':
/// ILArray<double> A = zeros(2,4);
/// ILArray<double> B = A.Shifted(1);
/// // B is now: <double> [4,2]
///
/// ILArray<double> C = zeros(2,4,3);
/// ILArray<double> D = C.Shifted(1);
/// // D is now: <double> [4,3,2]
///
/// The dimensions are shifted circulary to the left. This
/// can be imagined as removing the first dimensions from the beginning of the list of
/// dimensions and "append" them to the end in a ringbuffer style.
/// For dimension shifts of '1', you may consider using the
/// property for readability.
/// must be positive. It is taken modulus the number of dimensions.
///
public new ILRetLogical Shifted(int shift) {
return new ILRetLogical((ILLogicalStorage)Storage.ShiftDimensions(shift));
}
///
/// Subarray from this array
///
/// Arrays specifying the ranges to create subarray from
/// Subarray as specified
public new ILRetLogical Subarray(params ILBaseArray[] range) {
using (ILScope.Enter(range))
return new ILRetLogical((ILLogicalStorage)Storage.Subarray(range));
}
///
/// Short summary of this logical array
///
/// Type and size information
public override string ShortInfo() {
string ret = "Logical ";
if (object.Equals(m_storage,null))
return ret + " (disposed)";
if (Storage.Size.NumberOfElements == 1)
ret += Storage.GetValue(0);
else
ret += Storage.Size.ToString();
return ret.ToString();
}
#endregion
#region depricated
///
/// [deprecated] create empty ILLogical
///
/// empty ILLogical.
[Obsolete()]
public static ILRetLogical empty(ILSize dim) {
return new ILRetLogical(new byte[0],dim);
}
#endregion
}
}