/// /// 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 } }