Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Misc/ILExtensionMethods.cs @ 12732

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

#1967: ILNumerics source for experimentation

File size: 18.6 KB
RevLine 
[9102]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.Linq;
43using System.Runtime.InteropServices;
44using System.Text;
45using System.Numerics;
46using ILNumerics.Storage;
47
48namespace ILNumerics {
49    /// <summary>
50    /// Extension methods for ILNumerics types
51    /// </summary>
52    public static class ILExtensionMethods {
53        /// <summary>
54        /// Convert this complex ILNumerics array to a system array of type System.Numerics.Complex[]
55        /// </summary>
56        /// <param name="A">this ILNumerics array</param>
57        /// <param name="Storage">[option] if given, this system array will be used as storage for the conversion. Defaul: null (a new System.Array is returned)</param>
58        /// <returns>System.Array with the elements of A</returns>
59        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the storage given does not have sufficient length for all elements of the ILNumerics array</exception>
60        /// <remarks><para>The elements of the ILNumerics array will be copied to the System.Array and converted to the System.Numerics.Complex type.</para>
61        /// <para>The System.Array returned will contain all elements of the ILNumerics arrays after conversion - in column major order.</para>
62        /// <example>
63        /// This example demonstrates a common scenario for interchanging System.Numerics.Complex[] with ILNumerics complex arrays. It takes the converion between System.Numerics.Complex and ILNumerics.complex
64        /// into account, as well as the memory management of all storage involved.
65        /// <code>
66        /// ILArray&lt;complex> A = sqrtc(B);
67        /// // interfacing an external library as System.Numerics.Complex[]
68        /// // We dont provide a System.Array as target for the conversion,
69        /// // so it will be fetched from the ILNumerics memory management.
70        /// System.Numerics.Complex[] A_MSComplex = A.ToMSComplex();
71        /// // .. do some work here with A_MSComplex
72        /// // ...
73        /// // The results get converted back to ILNumerics array
74        /// ILArray&lt;complex> Result = A_MSComplex.ToILArray(A.S, true);
75        /// </code>
76        /// <para>For the conversion of the System.Numerics.Complex[] array back to an ILNumerics array, we use the same size (<c>A.S</c>) as before. Here, any size
77        /// would work, as long as it fits into the number of elements of the source System.Array.</para>
78        /// <para>Note that the calls to <c>A.ToMSComplex()</c> and <c>A_MSComplex.ToILArray(A.S, true)</c> will fetch and return all System.Arrays involved into/from the
79        /// ILINumerics memory pool. So if called frequently, no pressure on the GC is produced, what qualifies this scheme for high performance scenarios.</para>
80        /// </example>
81        /// </remarks>
82        /// <seealso cref="ToILArray(Complex[], ILSize, bool )"/>
83        public unsafe static Complex[] ToMSComplex(this ILArray<complex> A, Complex[] Storage = null) {
84            return ToMSComplexHelper(A.Storage, Storage);
85        }
86        /// <summary>
87        /// Convert this complex ILNumerics array to a system array of type System.Numerics.Complex[]
88        /// </summary>
89        /// <param name="A">this ILNumerics array</param>
90        /// <param name="Storage">[option] if given, this system array will be used as storage for the conversion. Defaul: null (a new System.Array is returned)</param>
91        /// <returns>System.Array with the elements of A</returns>
92        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the storage given does not have sufficient length for all elements of the ILNumerics array</exception>
93        /// <remarks><para>The elements of the ILNumerics array will be copied to the System.Array and converted to the System.Numerics.Complex type.</para>
94        /// <para>The System.Array returned will contain all elements of the ILNumerics arrays after conversion - in column major order.</para>
95        /// <example>
96        /// This example demonstrates a common scenario for interchanging System.Numerics.Complex[] with ILNumerics complex arrays. It takes the converion between System.Numerics.Complex and ILNumerics.complex
97        /// into account, as well as the memory management of all storage involved.
98        /// <code>
99        /// ILArray&lt;complex> A = sqrtc(B);
100        /// // interfacing an external library as System.Numerics.Complex[]
101        /// // We dont provide a System.Array as target for the conversion,
102        /// // so it will be fetched from the ILNumerics memory management.
103        /// System.Numerics.Complex[] A_MSComplex = A.ToMSComplex();
104        /// // .. do some work here with A_MSComplex
105        /// // ...
106        /// // The results get converted back to ILNumerics array
107        /// ILArray&lt;complex> Result = A_MSComplex.ToILArray(A.S, true);
108        /// </code>
109        /// <para>For the conversion of the System.Numerics.Complex[] array back to an ILNumerics array, we use the same size (<c>A.S</c>) as before. Here, any size
110        /// would work, as long as it fits into the number of elements of the source System.Array.</para>
111        /// <para>Note that the calls to <c>A.ToMSComplex()</c> and <c>A_MSComplex.ToILArray(A.S, true)</c> will fetch and return all System.Arrays involved into/from the
112        /// ILINumerics memory pool. So if called frequently, no pressure on the GC is produced, what qualifies this scheme for high performance scenarios.</para>
113        /// </example>
114        /// </remarks>
115        /// <seealso cref="ToILArray(Complex[], ILSize, bool )"/>
116        public unsafe static Complex[] ToMSComplex(this ILInArray<complex> A, Complex[] Storage = null) {
117            return ToMSComplexHelper(A.Storage, Storage);
118        }
119        /// <summary>
120        /// Convert this complex ILNumerics array to a system array of type System.Numerics.Complex[]
121        /// </summary>
122        /// <param name="A">this ILNumerics array</param>
123        /// <param name="Storage">[option] if given, this system array will be used as storage for the conversion. Defaul: null (a new System.Array is returned)</param>
124        /// <returns>System.Array with the elements of A</returns>
125        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the storage given does not have sufficient length for all elements of the ILNumerics array</exception>
126        /// <remarks><para>The elements of the ILNumerics array will be copied to the System.Array and converted to the System.Numerics.Complex type.</para>
127        /// <para>The System.Array returned will contain all elements of the ILNumerics arrays after conversion - in column major order.</para>
128        /// <example>
129        /// This example demonstrates a common scenario for interchanging System.Numerics.Complex[] with ILNumerics complex arrays. It takes the converion between System.Numerics.Complex and ILNumerics.complex
130        /// into account, as well as the memory management of all storage involved.
131        /// <code>
132        /// ILArray&lt;complex> A = sqrtc(B);
133        /// // interfacing an external library as System.Numerics.Complex[]
134        /// // We dont provide a System.Array as target for the conversion,
135        /// // so it will be fetched from the ILNumerics memory management.
136        /// System.Numerics.Complex[] A_MSComplex = A.ToMSComplex();
137        /// // .. do some work here with A_MSComplex
138        /// // ...
139        /// // The results get converted back to ILNumerics array
140        /// ILArray&lt;complex> Result = A_MSComplex.ToILArray(A.S, true);
141        /// </code>
142        /// <para>For the conversion of the System.Numerics.Complex[] array back to an ILNumerics array, we use the same size (<c>A.S</c>) as before. Here, any size
143        /// would work, as long as it fits into the number of elements of the source System.Array.</para>
144        /// <para>Note that the calls to <c>A.ToMSComplex()</c> and <c>A_MSComplex.ToILArray(A.S, true)</c> will fetch and return all System.Arrays involved into/from the
145        /// ILINumerics memory pool. So if called frequently, no pressure on the GC is produced, what qualifies this scheme for high performance scenarios.</para>
146        /// </example>
147        /// </remarks>
148        /// <seealso cref="ToILArray(Complex[], ILSize, bool )"/>
149        public unsafe static Complex[] ToMSComplex(this ILOutArray<complex> A, Complex[] Storage = null) {
150            return ToMSComplexHelper(A.Storage, Storage);
151        }
152        /// <summary>
153        /// Convert this complex ILNumerics array to a system array of type System.Numerics.Complex[]
154        /// </summary>
155        /// <param name="A">this ILNumerics array</param>
156        /// <param name="Storage">[option] if given, this system array will be used as storage for the conversion. Defaul: null (a new System.Array is returned)</param>
157        /// <returns>System.Array with the elements of A</returns>
158        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the storage given does not have sufficient length for all elements of the ILNumerics array</exception>
159        /// <remarks><para>The elements of the ILNumerics array will be copied to the System.Array and converted to the System.Numerics.Complex type.</para>
160        /// <para>The System.Array returned will contain all elements of the ILNumerics arrays after conversion - in column major order.</para>
161        /// <example>
162        /// This example demonstrates a common scenario for interchanging System.Numerics.Complex[] with ILNumerics complex arrays. It takes the converion between System.Numerics.Complex and ILNumerics.complex
163        /// into account, as well as the memory management of all storage involved.
164        /// <code>
165        /// ILArray&lt;complex> A = sqrtc(B);
166        /// // interfacing an external library as System.Numerics.Complex[]
167        /// // We dont provide a System.Array as target for the conversion,
168        /// // so it will be fetched from the ILNumerics memory management.
169        /// System.Numerics.Complex[] A_MSComplex = A.ToMSComplex();
170        /// // .. do some work here with A_MSComplex
171        /// // ...
172        /// // The results get converted back to ILNumerics array
173        /// ILArray&lt;complex> Result = A_MSComplex.ToILArray(A.S, true);
174        /// </code>
175        /// <para>For the conversion of the System.Numerics.Complex[] array back to an ILNumerics array, we use the same size (<c>A.S</c>) as before. Here, any size
176        /// would work, as long as it fits into the number of elements of the source System.Array.</para>
177        /// <para>Note that the calls to <c>A.ToMSComplex()</c> and <c>A_MSComplex.ToILArray(A.S, true)</c> will fetch and return all System.Arrays involved into/from the
178        /// ILINumerics memory pool. So if called frequently, no pressure on the GC is produced, what qualifies this scheme for high performance scenarios.</para>
179        /// </example>
180        /// </remarks>
181        /// <seealso cref="ToILArray(Complex[], ILSize, bool )"/>
182        public unsafe static Complex[] ToMSComplex(this ILRetArray<complex> A, Complex[] Storage = null) {
183            try {
184                return ToMSComplexHelper(A.Storage, Storage);
185            } finally {
186                A.Dispose();
187            }
188        }
189
190        unsafe private static Complex[] ToMSComplexHelper(ILDenseStorage<complex> A, Complex[] Storage) {
191            if (object.Equals(A, null) || A.Size.NumberOfElements == 0)
192                return new Complex[0];
193
194            if (!object.Equals(Storage, null) && Storage.Length < A.Size.NumberOfElements)
195                throw new Exceptions.ILArgumentException("The storage array given is too small for the conversion.");
196
197            Complex[] retArr = (object.Equals(Storage, null)) ? ILMath.New<Complex>(A.Size.NumberOfElements) : Storage;
198
199            GCHandle retHandle = GCHandle.Alloc(retArr, GCHandleType.Pinned);
200            GCHandle inHandle = GCHandle.Alloc(A.GetArrayForRead(), GCHandleType.Pinned);
201            complex* retP = (complex*)retHandle.AddrOfPinnedObject();
202            complex* inP = (complex*)inHandle.AddrOfPinnedObject();
203            ILMath.complex2ComplexHelper(inP, retP, A.Size.NumberOfElements);
204            retHandle.Free();
205            inHandle.Free();
206            return retArr;
207        }
208
209        /// <summary>
210        /// Convert this System.Numerics.Complex[] array to an ILNumerics array with ILNumerics.complex elements
211        /// </summary>
212        /// <param name="Storage">the source array, System.Numerics.Complex[]</param>
213        /// <param name="size">[optional] if specified, the size and shape of the ILNumerics array returned. Otherwise, a vector of length Storage.Length will be returned.</param>
214        /// <param name="recycleStorage">[optional] Places the incoming System.Numerics.Complex[] array into the ILNumerics memory pool. Default: false.</param>
215        /// <returns>ILNumerics array of element type ILNumerics.complex</returns>
216        /// <remarks>
217        /// <para>If the <paramref name="size"/> argument was given, it must define an array shape according to the actual length of <paramref name="Storage"/>. Therefore,
218        /// <c>size.NumberOfElements &leq; Storage.Length</c> must be valid.
219        /// </para>
220        /// <para>In a high performance scenario, it is recommended to have the function recycle the incoming storage after use. If <paramref name="recycleStorage"/> is set to <c>true</c>,
221        /// the user is responsible not to reference the incoming array afterwards. The array will be stored into the ILNumerics memory pool and eventually be used for later
222        /// allocation requests (for instance in <see cref="ToMSComplex(ILArray<complex>, Complex[])"/>).</para>
223        /// <example>
224        /// This example demonstrates a common scenario for interchanging System.Numerics.Complex[] with ILNumerics complex arrays. It takes the converion between System.Numerics.Complex and ILNumerics.complex
225        /// into account, as well as the memory management of all storage involved.
226        /// <code>
227        /// ILArray&lt;complex> A = sqrtc(B);
228        /// // interfacing an external library as System.Numerics.Complex[]
229        /// // We dont provide a System.Array as target for the conversion,
230        /// // so it will be fetched from the ILNumerics memory management.
231        /// System.Numerics.Complex[] A_MSComplex = A.ToMSComplex();
232        /// // .. do some work here with A_MSComplex
233        /// // ...
234        /// // The results get converted back to ILNumerics array
235        /// ILArray&lt;complex> Result = A_MSComplex.ToILArray(A.S, true);
236        /// </code>
237        /// <para>For the conversion of the System.Numerics.Complex[] array back to an ILNumerics array, we use the same size (<c>A.S</c>) as before. Here, any size
238        /// would work, as long as it fits into the number of elements of the source System.Array.</para>
239        /// <para>Note that the calls to <c>A.ToMSComplex()</c> and <c>A_MSComplex.ToILArray(A.S, true)</c> will fetch and return all System.Arrays involved into/from the
240        /// ILINumerics memory pool. So if called frequently, no pressure on the GC is produced, what qualifies this scheme for high performance scenarios.</para>
241        /// </example>
242        /// </remarks>
243        /// <exception cref="ILNumerics.Exceptions.ILArgumentException">if the length of the <paramref name="Storage"/> is less than <c>size.NumberOfElements</c></exception>
244        public unsafe static ILRetArray<complex> ToILArray(this Complex[] Storage, ILSize size = null, bool recycleStorage = false) {
245            if (Storage == null || Storage.Length == 0)
246                return ILMath.empty<complex>();
247           
248            ILSize outSize = (size == null) ? ILMath.size(Storage.Length, 1) : size;
249            if (outSize.NumberOfElements > Storage.Length)
250                throw new Exceptions.ILArgumentException("Invalid size definition! The number of elements defined by 'size' must be less or equal to the length of 'Storage'.");
251
252            complex[] retArr = ILMath.New<complex>(outSize.NumberOfElements);
253
254            GCHandle retHandle = GCHandle.Alloc(retArr, GCHandleType.Pinned);
255            GCHandle inHandle = GCHandle.Alloc(Storage, GCHandleType.Pinned);
256            complex* retP = (complex*)retHandle.AddrOfPinnedObject();
257            complex* inP = (complex*)inHandle.AddrOfPinnedObject();
258            ILMath.complex2ComplexHelper(inP, retP, outSize.NumberOfElements);
259            retHandle.Free();
260            inHandle.Free();
261
262            if (recycleStorage) {
263                ILMath.free(Storage);
264            }
265            return ILMath.array<complex>(retArr, outSize);
266        }
267    }
268}
Note: See TracBrowser for help on using the repository browser.