Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Array/ILRetLogical.cs @ 12547

Last change on this file since 12547 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 39.4 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.IO;
43using ILNumerics;
44using ILNumerics.Misc;
45using ILNumerics.Exceptions;
46using ILNumerics.Storage;
47using ILNumerics.Native;
48using System.Text;
49
50namespace ILNumerics {
51    /// <summary>
52    /// Boolean array for high performance relational operations on arbitrary arrays
53    /// </summary>
54    /// <remarks>
55    /// Logical arrays store true/false conditions as elements. Each element consumes
56    /// one byte. Logical arrays are the output parameter of all relational comparisons.</remarks>
57    [Serializable]
58    public sealed class ILRetLogical : ILBaseLogical {
59
60        private static readonly bool s_isTempArray = true;
61
62        #region properties
63        /// <summary>
64        /// Number of 'true' elements in this array
65        /// </summary>
66        /// <remarks>This value caches the number of 'true' elements in this logical array.
67        /// It may be used for information purposes but is actually needed internally for performance
68        /// reasons.</remarks>
69        public override long NumberNonZero {
70            get {
71                using (ILScope.Enter(this))
72                    return Storage.NumberNonZero;
73            }
74            internal set {
75                Storage.NumberNonZero = value;
76            }
77        }
78        /// <summary>
79        /// Shift the dimensions of this array by one (transpose for matrix)
80        /// </summary>
81        public new ILRetLogical T {
82            get {
83                using (ILScope.Enter(this))
84                    return new ILRetLogical((ILLogicalStorage)Storage.ShiftDimensions(1), NumberNonZero);
85            }
86        }
87        /// <summary>
88        /// Create clone of this array
89        /// </summary>
90        public new ILRetLogical C {
91            get {
92                return this;
93            }
94        }
95        /// <summary>
96        /// Size descriptor shortcut
97        /// </summary>
98        public override ILSize S {
99            get {
100                using (ILScope.Enter(this))
101                    return Storage.Size;
102            }
103        }
104        /// <summary>
105        /// Size descriptor
106        /// </summary>
107        public override ILSize Size {
108            get {
109                using (ILScope.Enter(this))
110                    return Storage.Size;
111            }
112        }
113        /// <summary>
114        /// Test if this array instance is a column vector (e.g. n x 1)
115        /// </summary>
116        public override bool IsColumnVector {
117            get {
118                using (ILScope.Enter(this))
119                    return Size[1] == 1 && Size.NumberOfDimensions == 2; ;
120            }
121        }
122        /// <summary>
123        /// Test if this array instance is a row vector (e.g. 1 x n)
124        /// </summary>
125        public override bool IsRowVector {
126            get {
127                using (ILScope.Enter(this))
128                    return Size[0] == 1 && Size.NumberOfDimensions == 2;
129            }
130        }
131        /// <summary>
132        /// Determine if this array has complex elements.
133        /// </summary>
134        /// <remarks><para>Calling this member will dispose this instance afterwards (for temporary arrays).</para></remarks>
135        public override bool IsComplex {
136            get {
137                using (ILScope.Enter(this))
138                    return false;
139            }
140        }
141        /// <summary>
142        /// Test if this instance is an empty array (number of elements stored = 0)
143        /// </summary>
144        public override bool IsEmpty {
145            get {
146                using (ILScope.Enter(this))
147                    return Size.NumberOfElements == 0;
148            }
149        }
150        /// <summary>
151        /// Test if this instance is a matrix
152        /// </summary>
153        /// <remarks>In order for an array to be a matrix the number of <b>non singleton</b>
154        /// dimensions must equal 2. This attribute is readonly.</remarks>
155        public override bool IsMatrix {
156            get {
157                using (ILScope.Enter(this))
158                    return Size.NumberOfDimensions == 2;
159            }
160        }
161        /// <summary>
162        /// Determine if this array holds numeric values.
163        /// </summary>
164        /// <remarks>An ILArray is numeric as long as its elements are one of the
165        /// following types:
166        /// <list type="table">
167        /// <listheader>
168        ///     <term>inner type</term>
169        /// </listheader>
170        /// <item>
171        ///     <term>System.double</term>
172        ///     <description>floating point, real, 8 bytes </description>
173        /// </item>
174        /// <item>
175        ///     <term>System.float</term>
176        ///     <description>floating point real, 4 bytes</description>
177        /// </item>
178        /// <item>
179        ///     <term>ILNumerics.complex</term>
180        ///     <description>floating point complex, 16 bytes</description>
181        /// </item>
182        /// <item>
183        ///     <term>ILNumerics.fcomplex</term>
184        ///     <description>floating point complex, 8 bytes</description>
185        /// </item>
186        /// <item>
187        ///     <term>System.char</term>
188        ///     <description>integer, real, 1 byte</description>
189        /// </item>
190        /// <item>
191        ///     <term>System.byte</term>
192        ///     <description>integer, real, 1 byte</description>
193        /// </item>
194        /// <item>
195        ///     <term>System.Int16</term>
196        ///     <description>integer, real, 2 byte</description>
197        /// </item>
198        /// <item>
199        ///     <term>System.Int32</term>
200        ///     <description>integer, real, 4 byte</description>
201        /// </item>
202        /// <item>
203        ///     <term>System.Int64</term>
204        ///     <description>integer, real, 8 byte</description>
205        /// </item>
206        /// <item>
207        ///     <term>System.UInt16</term>
208        ///     <description>unsigned integer, real, 2 byte</description>
209        /// </item>
210        /// <item>
211        ///     <term>System.UInt32</term>
212        ///     <description>unsigned integer, real, 4 byte</description>
213        /// </item>
214        /// <item>
215        ///     <term>System.UInt64</term>
216        ///     <description>unsigned integer, real, 8 byte</description>
217        /// </item>
218        /// </list>
219        /// <para>Calling this member will dispose this instance afterwards (for temporary arrays).</para>
220        /// </remarks>
221        public override bool IsNumeric {
222            get {
223                using (ILScope.Enter(this))
224                    return true;
225            }
226        }
227        /// <summary>
228        /// Test if this instance is a scalar
229        /// </summary>
230        /// <remarks>This attribute is readonly. It returns: Size.NumberOfElements == 1.</remarks>
231        public override bool IsScalar {
232            get {
233                using (ILScope.Enter(this))
234                    return Size.NumberOfElements == 1;
235            }
236        }
237        /// <summary>
238        /// Test if this array is a vector
239        /// </summary>
240        /// <remarks>In order for an array to be a vector the number of <b>non singleton</b>
241        /// dimensions must equal 1. Keep in mind that all ILArrays have at least 2 dimensions. Therefore
242        /// it is not sufficient to test for the number of dimensions, but to take the number of
243        /// <b>non singleton</b> dimensions into account. This attribute is readonly.</remarks>
244        public override bool IsVector {
245            get {
246                using (ILScope.Enter(this))
247                    return (Size[0] == 1 || Size[1] == 1) && Size.NumberOfDimensions == 2;
248            }
249        }
250        /// <summary>
251        /// Length of the longest dimension of this instance
252        /// </summary>
253        /// <remarks>This property is readonly.
254        /// <para>Calling this member will dispose this instance afterwards (for temporary arrays).</para></remarks>
255        public override int Length {
256            get {
257                using (ILScope.Enter(this))
258                    return base.Length;
259            }
260        }
261        /// <summary>
262        /// Gets the name of this array (readonly)
263        /// </summary>
264        public new String Name {
265            get {
266                using (ILScope.Enter(this))
267                    return m_name;
268            }
269        }
270        #endregion
271
272        #region constructors
273        internal ILRetLogical(ILDenseStorage<byte> A)
274            : base(new ILLogicalStorage(A.GetDataArray(), A.Size), s_isTempArray) {
275        }
276        /// <summary>
277        /// Constructor creating ILRetLogical from dense storage
278        /// </summary>
279        /// <param name="A">input array, the storage given will directly be used for
280        /// storage of the new logical array</param>
281        internal ILRetLogical(ILLogicalStorage A)
282            : base(A, s_isTempArray) {
283        }
284        /// <summary>
285        /// create temporary logical from predefined storage
286        /// </summary>
287        /// <param name="A">the storage will directly be used as storage of the new logical array</param>
288        /// <param name="numberNonZero">number of nonzero elements in A. Must be positive or 0.</param>
289        /// <remarks> Providing this parameter prevents the constructor from having to count the
290        /// 'true' elements in A.</remarks>
291        internal ILRetLogical(ILLogicalStorage A, long numberNonZero)
292            : base(A, s_isTempArray) {
293            if (numberNonZero < 0)
294                throw new ILNumerics.Exceptions.ILArgumentException("invalid number of non-zero-elements given!");
295            NumberNonZero = numberNonZero;
296        }
297        /// <summary>
298        /// create temporary logical array of specified size
299        /// </summary>
300        /// <param name="size">
301        /// variable length int array specifying the number and size of dimensions to
302        /// be created.
303        /// </param>
304        /// <remarks>
305        /// The size parameter may not be null or an empty array. An exception will be
306        /// thrown in this case. The dimensions will be trimmed before processing
307        /// (removing trailing non singleton dimensions).
308        /// Depending on the requested size a logical temporary array of the specified size
309        /// will be created. </remarks>
310        internal ILRetLogical(ILSize size)
311            : base(new ILLogicalStorage(size), s_isTempArray) {
312        }
313        /// <summary>
314        /// Constructor - create ILRetLogical of specified size
315        /// from data array
316        /// </summary>
317        /// <param name="size">
318        /// Variable length int array specifying the number and size of dimensions to
319        /// be created.
320        /// </param>
321        /// <param name="data">byte array matching the size of the dimensions
322        /// specified. The data will directly be used as storage! No copy will be made!</param>
323        /// <remarks>
324        /// The size parameter may not be null or an empty array! An Exception will be
325        /// thrown in this case. The dimensions will be trimmed before processing
326        /// (removing trailing non singleton dimensions).
327        /// Depending on the requested size an ILRetLogical of the specified size
328        /// will be created. The type of storage will be <code>byte</code>.
329        /// </remarks>
330        public ILRetLogical(byte[] data, params int[] size)
331            : base(new ILLogicalStorage(data, new ILSize(size)), s_isTempArray) {
332        }
333        /// <summary>
334        /// Constructor creating ILRetLogical, provide predefined storage
335        /// </summary>
336        /// <param name="data">Predefined storage elements. The array will directly be used
337        /// as underlying storage. No copy will be made! </param>
338        /// <param name="size">Size descriptor</param>
339        public ILRetLogical(byte[] data, ILSize size)
340            : base(new ILLogicalStorage(data, size), s_isTempArray) {
341        }
342        /// <summary>
343        /// Constructor creating ILRetLogical, predefined storage (fast version)
344        /// </summary>
345        /// <param name="data">Predefined storage elements. The array will directly be used
346        /// as underlying storage. No copy will be made! </param>
347        /// <param name="size">Size descriptor</param>
348        /// <param name="nonZeroCount">Number of nonzero elements in <paramref name="data"/>.
349        /// Providing this parameter prevents from counting the 'true' elements (again). </param>
350        public ILRetLogical(byte[] data, ILSize size, long nonZeroCount)
351            : base(new ILLogicalStorage(data, size), s_isTempArray) {
352            if (nonZeroCount < 0)
353                throw new ILNumerics.Exceptions.ILArgumentException("invalid number of non-zero-elements given!");
354            NumberNonZero = nonZeroCount;
355        }
356        #endregion
357
358        #region public functions
359        /// <summary>
360        /// Clone of this array
361        /// </summary>
362        /// <remarks><para>
363        /// Clones of all arrays in ILNumerics are done in a very fast, lazy way. This means,
364        /// at the time the clone is made, no relevant memory is copied. Elements of both arrays rather point to the same
365        /// underlying System.Array. A reference counting mechanism ensures the detaching of thoses arrays
366        /// on write access.</para>
367        /// <para>The clone returned will be of the same type as this instance.</para></remarks>
368        internal override ILBaseArray Clone() {
369            return this;
370        }
371        /// <summary>
372        /// Concatenate this array
373        /// </summary>
374        /// <param name="A">N-dimensional array. Except for dimensions <paramref name="dim"/>
375        /// the dimensions of A must match the dimensions of this storage</param>
376        /// <param name="dim">Index of dimension to concatenate arrays along.
377        /// If dim is larger than the number of dimensions of any of the arrays,
378        /// its value will be used in modulus the number of dimensions.</param>
379        /// <returns>New array having the size
380        /// of both input arrays layed behind each other along the dim's-dimension</returns>
381        public new ILRetLogical Concat(ILInLogical A, int dim) {
382            using (ILScope.Enter(this,A))
383                return new ILRetLogical((ILLogicalStorage)Storage.Concat(A.Storage, dim));
384        }
385        /// <summary>
386        /// Compare elements and shape of this array with another array
387        /// </summary>
388        /// <param name="A">Other array</param>
389        /// <returns>true if shape and element values of both arrays match, false otherwise</returns>
390        /// <remarks><para>Calling this member will dispose this instance afterwards (for temporary arrays.</para></remarks>
391        public override bool Equals(object A) {
392            using (ILScope.Enter(this))
393                return base.Equals(A);
394        }
395        /// <summary>
396        /// Copy values of all elements into System.Array.
397        /// </summary>
398        /// <param name="outArray">[Output] System.Array, holding all element values of this ILDenseStorage.</param>
399        /// <remarks>The System.Array may be predefined. If its length is sufficient, it will be used and
400        /// its leading elements will be overwritten when function returns. If 'outArray' is null or has too few elements,
401        /// it will be recreated from the ILNumerics memory pool.</remarks>
402        public new void ExportValues(ref byte[] outArray) {
403            using (ILScope.Enter(this))
404                Storage.ExportValues(ref outArray);
405        }
406        /// <summary>
407        /// Enumerator returning elements as ElementType
408        /// </summary>
409        /// <returns>Enumerator</returns>
410        /// <remarks>This method enables the use of ILNumerics arrays in foreach loops.
411        /// <para>The iterator is returned, if arrays are directly used in foreach statements. The iterator
412        /// is compatible with ILNumerics memory management.</para></remarks>
413        /// <example><code>ILDenseStorage&lt;T&gt; A = ILMath.rand(5,4,6);
414        /// foreach (double element in A) {
415        /// // all elements are scalar double values
416        /// String.Format("Element: {0} ",element);
417        /// // Note: 'element' cannot be used to alter the collection!
418        /// }
419        /// </code></example>
420        public override IEnumerator<byte> GetEnumerator() {
421            using (ILScope.Enter(this)) {
422                byte[] values = GetArrayForRead();
423                int len = Size.NumberOfElements;
424                for (int i = 0; i < len; i++)
425                    yield return values[i];
426            }
427        }
428        /// <summary>
429        /// Generate a hash code based on the current arrays values
430        /// </summary>
431        /// <returns>Hash code</returns>
432        /// <remarks>The hashcode is generated by taking the values currently stored in the array into account.
433        /// Therefore, the function must iterate over all elements in the array - which makes it somehow a costly
434        /// operation. Take this into account, if you consider using large arrays in collections like dictionaries
435        /// or hashtables, which make great use of hash codes.
436        /// <para>Calling this member will dispose this instance afterwards (for temporary arrays).</para></remarks>
437        public override int GetHashCode() {
438            using (ILScope.Enter(this))
439                return base.GetHashCode();
440        }
441        /// <summary>
442        /// Get minimum and maximum value of all elements - if any
443        /// </summary>
444        /// <param name="min">[Output] Minimum value</param>
445        /// <param name="max">[Output] Maximum value</param>
446        /// <returns>true if the limits exists and could be computed, false otherwise</returns>
447        /// <remarks>Empty arrays will return false. In this case the output parameter will be: default(ElementType).
448        /// <para>Calling this member will dispose this instance afterwards (for temporary arrays).</para></remarks>
449        public override bool GetLimits(out byte min, out byte max) {
450            using (ILScope.Enter(this))
451                return base.GetLimits(out min, out max);
452        }
453        /// <summary>
454        /// Get single element from this array
455        /// </summary>
456        /// <param name="idx">Indices, location of element</param>
457        /// <returns>The requested element</returns>
458        public override byte GetValue(params int[] idx) {
459            using (ILScope.Enter(this))
460                return base.GetValue(idx);
461        }
462        /// <summary>
463        /// Create reshaped copy of this logical array
464        /// </summary>
465        /// <param name="size">New dimensions of the array</param>
466        /// <returns>Reshaped copy of this array</returns>
467        /// <remarks><para>The current instance will not be changed! A new array is created, having
468        /// the elements of this array and a shape as determined by <paramref name="size"/>.</para>
469        /// </remarks>
470        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">If the number of elements in
471        /// <paramref name="size"/> do not match the number of elements in this array.</exception>
472        public new ILRetLogical Reshape(ILSize size) {
473            using (ILScope.Enter(this)) {
474                ILLogical ret = C;
475                ret.Storage.Reshape(size);
476                return ret;
477            }
478        }
479        /// <summary>
480        /// Create replication of this array
481        /// </summary>
482        /// <param name="dims">Dimensions specifier. If the number of elements in <paramref name="dims"/> is
483        /// less than the number of dimensions in this array, the trailing dimensions will
484        /// be set to 1 (singleton dimensions). On the other hand, if the number specified
485        /// is larger then the number of dimension stored inside the storge the resulting
486        /// storage will get its number of dimensions extended accordingly. </param>
487        /// <returns>Array being created out of multiple replications of this array along
488        /// arbitrary dimensions according to <paramref name="dims"/></returns>
489        public new ILRetLogical Repmat(params int[] dims) {
490            using (ILScope.Enter(this))
491            return new ILRetLogical((ILLogicalStorage)Storage.Repmat(dims));
492        }
493        /// <summary>
494        ///  Serialize this ILArray into a binary stream.
495        /// </summary>
496        /// <param name="outStream">System.IO.Stream to receive the byte stream
497        /// for this ILBaseArray</param>
498        /// <returns>True on success, false on error.</returns>
499        /// <remarks><para>Calling this member will dispose this instance afterwards (for temporary arrays).</para>
500        /// </remarks>
501        public override bool Serialize(Stream outStream) {
502            using (ILScope.Enter(this))
503                return base.Serialize(outStream);
504        }
505        /// <summary>
506        /// Create logical array from this logical and shift dimensions
507        /// </summary>
508        /// <param name="shift">Number of dimensions to shift</param>
509        /// <returns>Shifted version of this array</returns>
510        /// <remarks><para>The shift is done 'to the left':</para>
511        /// <example><code>ILArray&lt;double> A = zeros(2,4);
512        /// ILArray&lt;double> B = A.Shifted(1);
513        /// // B is now: &lt;double> [4,2]
514        ///
515        /// ILArray&lt;double> C = zeros(2,4,3);
516        /// ILArray&lt;double> D = C.Shifted(1);
517        /// // D is now: &lt;double> [4,3,2]
518        /// </code></example>
519        /// <para>The dimensions are shifted circulary to the left. This
520        /// can be imagined as removing the first dimensions from the beginning of the list of
521        /// dimensions and "append" them to the end in a ringbuffer style.</para>
522        /// <para>For dimension shifts of '1', you may consider using the
523        /// <see cref="ILNumerics.ILDenseArray{ElementType}.T"/> property for readability.</para>
524        /// <para><paramref name="shift"/> must be positive. It is taken modulus the number of dimensions.</para>
525        /// <seealso cref="ILNumerics.ILDenseArray{ElementType}.T"/></remarks>
526        public new ILRetLogical Shifted(int shift) {
527            using (ILScope.Enter(this))
528                return new ILRetLogical((ILLogicalStorage)Storage.ShiftDimensions(shift));
529        }
530        /// <summary>
531        /// Subarray from this array
532        /// </summary>
533        /// <param name="range">Arrays specifying the ranges to create subarray from</param>
534        /// <returns>Subarray as specified</returns>
535        public new ILRetLogical Subarray(params ILBaseArray[] range) {
536            using (ILScope.Enter(this))
537            using (ILScope.Enter(range))
538                return new ILRetLogical((ILLogicalStorage)Storage.Subarray(range));
539        }
540        /// <summary>
541        /// Send values of this instance to stream.
542        /// </summary>
543        /// <param name="stream">Stream to write the values into.</param>
544        /// <param name="format">Format string to be used for output. See <see cref="System.String.Format(string,object)"/> for a specification
545        /// of valid formating expressions. This flag is only used, when 'method' is set to 'Serial'.</param>
546        /// <param name="method">A constant out of <see cref="ILArrayStreamSerializationFlags"/>. Specifies the way in which
547        /// the values will be serialized.</param>
548        /// <remarks><para>If the 'Formatted' method is used, any occurences of the NewLine character(s)
549        /// will be replaced from the format string before applying to the elements. This is done to
550        /// prevent the format from breaking the 'page' style of the output.</para>
551        /// <para>If 'method' is set to 'Matlab', the array will be written as Matfile version 5.0. No compression will be used. The internal 'Name' property will be used as the
552        /// array name for writing. This array instance will be the only array in the .mat file. If you want to write several arrays bundled into one mat file, use the MatFile class to
553        /// create a collection of arrays and write the MatFile to stream.</para></remarks>
554        public override void ToStream(Stream stream, string format, ILArrayStreamSerializationFlags method) {
555            using (ILScope.Enter(this))
556                try {
557                    int len;
558                    switch (method) {
559                        case ILArrayStreamSerializationFlags.Serial:
560                            len = Size.NumberOfElements;
561                            using (TextWriter tw = new StreamWriter(stream)) {
562                                for (int i = 0; i < len; i++) {
563                                    tw.Write(format, GetValue(i));
564                                }
565                            }
566                            break;
567                        case ILArrayStreamSerializationFlags.Formatted:
568                            format = format.Replace(Environment.NewLine, "");
569                            ILDenseStorage<byte> temp = this.Storage.ShiftDimensions(1);
570                            //len = Dimensions.NumberOfElements / Dimensions[1];
571                            using (TextWriter tw = new StreamWriter(stream)) {
572                                tw.Write(temp.ValuesToString(0));
573                            }
574                            break;
575                        case ILArrayStreamSerializationFlags.Matlab:
576                            ILMatFile mf = new ILMatFile(new ILBaseArray[1] { this });
577                            mf.Write(stream);
578                            break;
579                    }
580                } catch (Exception e) {
581                    throw new ILException("ToStream: Could not serialize to stream.", e);
582                }
583        }
584        #endregion
585
586        #region index access + mutability
587        /// <summary>
588        /// Subarray access (readonly)
589        /// </summary>
590        /// <param name="range">Range specification</param>
591        /// <returns>Logical array with the elements specified by range</returns>
592        /// <remarks>Query access: for N-dimensional arrays trailing dimensions will be choosen to be 0. Therefore you
593        /// may ommit those trailing dimensions in range.
594        /// <para>The indexer may be used for querying any elements
595        /// in this array. <c>range</c> may contains index specifications for one ... to any
596        /// dimension. The array returned will have the size specified by range.</para>
597        /// </remarks>
598        public ILRetLogical this[params ILBaseArray[] range] {
599            get {
600                using (ILScope.Enter(this))
601                using (ILScope.Enter(range))
602                    return new ILRetLogical((ILLogicalStorage)Storage.Subarray(range));
603            }
604        }
605        #endregion
606
607        #region operator overloading
608        #region constructional operators
609        /// <summary>
610        /// Implicitly cast one dimensional System.Array to ILNumerics array (vector)
611        /// </summary>
612        /// <param name="A">1-dimensional system array, arbitrary type</param>
613        /// <returns>ILNumerics array of same element type as elements of A.
614        /// Row vector. If A is null: empty array.</returns>
615        /// <remarks>The System.Array A will directly be used for the new ILNumerics array!
616        /// No copy will be done! Make sure, not to reference A after this conversion!</remarks>
617        public static implicit operator ILRetLogical(byte[] A) {
618            if (A == null) {
619                return new ILRetLogical(ILSize.Empty00);
620            }
621            return new ILRetLogical(A, 1, A.Length);
622        }
623        /// <summary>
624        /// Implicitly convert n-dim. System.Array to ILNumerics array
625        /// </summary>
626        /// <param name="A">Arbitrarily sized System.Array</param>
627        /// <returns>If A is null: empty array. Else: new ILNumerics array of the same size as A</returns>
628        /// <remarks>The resulting ILArray will reflect all dimensions of
629        /// A. Elements of A will get copied to elements of output array (shallow copy).</remarks>
630        /// <exception cref="ILNumerics.Exceptions.ILCastException">If type of input does not match
631        /// ElementType</exception>
632        public static implicit operator ILRetLogical(Array A) {
633            if (A == null || A.Length == 0) {
634                return new ILLogical(ILSize.Empty00);
635            }
636            if (A.GetType().GetElementType() != typeof(byte))
637                throw new ILCastException("inner type of System.Array must match");
638            int[] dims = new int[A.Rank];
639            byte[] retArr = ILMemoryPool.Pool.New<byte>(A.Length);
640            int posArr = 0;
641            for (int i = 0; i < dims.Length; i++) {
642                dims[i] = A.GetLength(dims.Length - i - 1);
643            }
644            foreach (byte item in A)
645                retArr[posArr++] = item;
646            return new ILRetLogical(retArr, dims);
647        }
648        /// <summary>
649        /// Implicitly cast two dimensional System.Array to ILNumerics array
650        /// </summary>
651        /// <param name="A">2D System.Array</param>
652        /// <returns>If A is null: empty array. ILNumerics array of same size and type as A otherwise.</returns>
653        public static implicit operator ILRetLogical(byte[,] A) {
654            if (A == null || A.Length == 0) {
655                return new ILRetLogical(ILSize.Empty00);
656            }
657            int[] dims = new int[2];
658            byte[] retArr = ILMemoryPool.Pool.New<byte>(A.Length);
659            int posArr = 0;
660            for (int i = 0; i < 2; i++) {
661                dims[i] = A.GetLength(dims.Length - i - 1);
662            }
663            foreach (byte item in A)
664                retArr[posArr++] = item;
665            return new ILRetLogical(retArr, dims);
666        }
667        /// <summary>
668        /// Implicitly cast three dimensional System.Array to ILNumerics array
669        /// </summary>
670        /// <param name="A">3D System.Array</param>
671        /// <returns>If A is null: empty array. ILNumerics array of same size and type as A otherwise.</returns>
672        public static implicit operator ILRetLogical(byte[, ,] A) {
673            if (A == null || A.Length == 0) {
674                return new ILRetLogical(ILSize.Empty00);
675            }
676            int[] dims = new int[3];
677            byte[] retArr = ILMemoryPool.Pool.New<byte>(A.Length);
678            int posArr = 0;
679            for (int i = 0; i < 3; i++) {
680                dims[i] = A.GetLength(dims.Length - i - 1);
681            }
682            foreach (byte item in A)
683                retArr[posArr++] = item;
684            return new ILRetLogical(retArr, dims);
685        }
686
687        /// <summary>
688        /// Implicitly convert boolean System.Byte to scalar logical array
689        /// </summary>
690        /// <param name="val">System.Byte</param>
691        /// <returns>Scalar logical array with value of val.</returns>
692        public static implicit operator ILRetLogical(bool val) {
693            ILRetLogical ret = new ILRetLogical(new byte[1] { val ? (byte)1 : (byte)0 }, 1, 1);
694            return ret;
695        }
696        /// <summary>
697        /// Implicitly convert logical array to System.Boolean
698        /// </summary>
699        /// <param name="A">Logical array</param>
700        /// <returns>true if elements of A are non-zero, false otherwise
701        /// </returns>
702        /// <remarks>If A is null or empty, the function returns false. Otherwise returns true,
703        /// if all elements of A are non-zero and returns false, if A contains zero elements.
704        /// <para>The behavior depends on the setting of the ILSettings.LogicalArrayToBoolConversion switch.
705        /// Per default, only scalar arrays are allowed to be converted implicitely. This can be changed
706        /// to implicitely convert non-scalar arrays by using ILMath.any on the array.</para>
707        /// <seealso cref="ILNumerics.Settings.LogicalArrayToBoolConversion"/>
708        /// <seealso cref="ILNumerics.ILMath.any(ILInArray{double}, int)"/>
709        /// </remarks>
710        public static implicit operator bool(ILRetLogical A) {
711            using (ILScope.Enter(A)) {
712                // this operator is implicit for convenience reasons:
713                // if(tmp[0]!=-10.0) { ... is only possible this way
714                if (object.Equals(A, null) || A.IsEmpty)
715                    return false;
716                if (A.IsScalar)
717                    return A.GetValue(0, 0) == 1;
718                if (Settings.LogicalArrayToBoolConversion == LogicalConversionMode.ImplicitAllAll)
719                    return ILMath.allall(A).GetValue(0) == 1;
720                //else if (Settings.ILSettings.LogicalArrayToBoolConversion == LogicalConversionMode.NonScalarThrowsException)
721                throw new ILArgumentException("Nonscalar logical to bool conversion. See ILSettings.LogicalArrayToBoolConversion");
722            }
723        }
724        /// <summary>
725        /// Implicitly convert integer scalar to logical array of size 1x1 (scalar).
726        /// </summary>
727        /// <param name="val">Scalar value</param>
728        /// <returns>New logical array of size 1x1 holding the only element of type Byte
729        /// with value of val.</returns>
730        public static implicit operator ILRetLogical(int val) {
731            ILRetLogical ret = new ILRetLogical(new Byte[1] {
732                                 val != 0 ? (byte)1:(byte)0 }, 1, 1);
733            return ret;
734        }
735        #endregion
736
737        #region conversional operators
738        /// <summary>
739        /// Convert logical to temporary logical array
740        /// </summary>
741        /// <param name="a">Original logical array</param>
742        /// <returns>Temporary logical array</returns>
743        public static implicit operator ILRetLogical(ILLogical a) {
744            if (object.Equals(a,null))
745                return null;
746            return a.C;
747        }
748        /// <summary>
749        /// Convert logical input parameter type array to temporary logical array
750        /// </summary>
751        /// <param name="a">Logical input parameter type</param>
752        /// <returns>Temporary logical array</returns>
753        public static implicit operator ILRetLogical(ILInLogical a) {
754            if (object.Equals(a, null))
755                return null;
756            return a.C;
757        }
758        /// <summary>
759        /// Convert logical output parameter type array to temporary logical array
760        /// </summary>
761        /// <param name="a">Logical output parameter type</param>
762        /// <returns>Temporary logical array</returns>
763        public static implicit operator ILRetLogical(ILOutLogical a) {
764            if (object.Equals(a, null))
765                return null;
766            return a.C;
767        }
768        /// <summary>
769        /// Implicitly cast to ILArray&lt;byte&gt;
770        /// </summary>
771        /// <param name="a">A ILRetLogical</param>
772        /// <returns>ILArray&lt;byte&gt;</returns>
773        public static implicit operator ILArray<byte>(ILRetLogical a) {
774            if (object.Equals(a, null))
775                return null;
776            ILArray<byte> ret = new ILArray<byte>(a.GiveStorageAwayOrClone());
777            ILScope.Context.RegisterArray(ret);
778            return ret;
779        }
780        /// <summary>
781        /// Implicitly cast from ILArray&lt;byte&gt;
782        /// </summary>
783        /// <param name="a">An ILArray&lt;byte&gt;</param>
784        /// <returns>logical return array</returns>
785        public static implicit operator ILRetLogical(ILArray<byte> a) {
786            if (object.Equals(a,null))
787                return null;
788            return new ILRetLogical(new ILLogicalStorage(
789                a.Storage.GetDataArray(),a.Size));
790        }
791        /// <summary>
792        /// Implicitly cast from ILInArray&lt;byte&gt;
793        /// </summary>
794        /// <param name="a">An ILInArray&lt;byte&gt;</param>
795        /// <returns>logical return array</returns>
796        public static implicit operator ILInArray<byte>(ILRetLogical a) {
797            if (object.Equals(a,null))
798                return null;
799            ILArray<byte> ret = new ILArray<byte>(a.GiveStorageAwayOrClone());
800            if (Settings.AllowInArrayAssignments)
801                ILScope.Context.RegisterArray(ret);
802            return ret;
803        }
804        /// <summary>
805        /// Implicitly cast from ILInArray&lt;byte&gt;
806        /// </summary>
807        /// <param name="a">An ILInArray&lt;byte&gt;</param>
808        /// <returns>logical return array</returns>
809        public static implicit operator ILRetLogical(ILInArray<byte> a) {
810            if (object.Equals(a, null))
811                return null;
812            return new ILRetLogical(new ILLogicalStorage(
813                a.Storage.GetDataArray(), a.Size));
814        }
815        #endregion
816
817        #region operational operators
818        /// <summary>
819        /// Invert values of array elements
820        /// </summary>
821        /// <param name="in1">Input array</param>
822        /// <returns>New logical array, inverted element values</returns>
823        public static ILRetLogical operator !(ILRetLogical in1) {
824            if (object.Equals(in1,null))
825                throw new ILArgumentException("operator -(): parameter must not be null!");
826            return (in1 != (byte)1);
827        }
828        #endregion
829        #endregion
830
831    }
832}
Note: See TracBrowser for help on using the repository browser.