Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/builtin/mvnrnd.cs @ 11194

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

#1967: ILNumerics source for experimentation

File size: 14.8 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.Text;
43using ILNumerics;
44using ILNumerics.Exceptions;
45using ILNumerics.Storage;
46using ILNumerics.Misc;
47
48
49
50namespace ILNumerics {
51
52    public partial class ILMath {
53
54        private static ILArrayCache s_mvnrndcache = ILCacheManager.Manager.GetCache();
55
56        /// <summary>
57        /// Choose samples from a multivariate random distribution
58        /// </summary>
59        /// <returns>n random numbers as taken from the multivariate random probability distribution with zero mean and unity covariance</returns>
60        /// <remarks><para>This is an alias for <see cref="M:ILNumerics.ILMath.randn(params int[])"/>. If n was not specified, a single random number is generated.</para>
61        /// <para>The samples are returned as row vector of size 1 x n.</para></remarks>
62        public static ILRetArray<double> mvnrnd(int n = -1) {
63            if (n >= 0)
64                return randn(1,n);
65            return randn(1,1); 
66        }
67
68        /// <summary>
69        /// Choose one sample from a multivariate random distribution
70        /// </summary>
71        /// <returns>Single random number, taken from the multivariate random probability distribution with zero mean and unity covariance</returns>
72        /// <remarks><para>This is an alias for <see cref="M:ILNumerics.ILMath.randn(params int[])"/>. A single (scalar) random number is generated.</para></remarks>
73        public static ILRetArray<double> mvnrnd() {
74            return randn(1, 1);
75        }
76
77
78
79        /// <summary>
80        /// choose samples from a multivariate random distribution 
81        /// </summary>
82        /// <param name="inMu">[optional] centers, size d x n; if d x 1 is given, optional parameter <paramref name="n"/> is used to replicate mu accordingly, if null, the values will be genereated with a center of zero</param>
83        /// <param name="inSigma">[optional] covariance matrix, must be positive definite, size d x d or vector of lenght d, if null (not set), unitiy matrix is expected</param>
84        /// <param name="n">[optional] number of samples to generate, per default (-1) the number of columns of <paramref name="mu"/> defines that number</param>
85        /// <param name="sigmaIsSquaredCov">[optional] if false: safe the effort of finding the square root of <paramref name="sigma"/> parameter; default: true</param>
86        /// <returns>random numbers as taken from the multivariate random probability distribution given by mu and sigma</returns>
87        /// <remarks><para>In order to safe the step of finding the root of sigma, the following options exist:
88        /// <list type="bullet">
89        /// <item>Provide only the diagonal of a (virtual) diagonal matrix to <paramref name="sigma"/>.</item>
90        /// <item>Compute the root manually, give it to sigma and set <paramref name="sigmaIsSquaredCov"/> to false.</item>
91        /// </list></para>
92        /// <para>In case <paramref name="sigmaIsSquaredCov"/> set to 'false' and <paramref name="sigma"/> is given,
93        /// the root is computed via cholesky factorization. The result of the last root finding process is cached and reused for
94        /// subsequent requests with the same set of <paramref name="n"/> and <paramref name="sigma"/> parameters.</para></remarks>
95        public static ILRetArray<double> mvnrnd(ILInArray<double> inMu = null, ILInArray<double> inSigma = null,
96                                                       int n = -1, bool sigmaIsSquaredCov = true) {
97            using (ILScope.Enter(inMu, inSigma)) {
98
99                // early exit, trivial case
100                if (isnullorempty(inMu) && isnullorempty(inSigma)) {
101                    return  /*dummy*/ (randn(1, Math.Max(n, 0)));
102                }
103                ILArray<double> mu = check(inMu, Default: empty< double>());
104                ILArray<double> sigma = check(inSigma, Default: empty<double>());
105
106                // determine output size
107                n = Math.Max(Math.Max(mu.S[1], sigma.S[2]), n);
108                int d = Math.Max(Math.Max(mu.S[0], sigma.S[0]), sigma.S[1]);
109                ILArray<double> ret = empty<double>();
110
111                if (mu.IsEmpty)
112                    mu = zeros<double>(d, 1);
113                if (mu.IsRowVector)
114                    mu = mu.T;
115                if (sigma.IsEmpty)
116                    sigma = ones<double>(d, 1);
117                if (sigma.IsRowVector)
118                    sigma = sigma.T;
119
120                if (mu.IsVector && mu.Length != d) {
121                    throw new ILArgumentException("mu must be empty or have the same dimensionality as sigma");
122                } else if (mu.S[1] > 1 && (mu.S[0] != d || mu.S[1] != n)) {
123                    throw new ILArgumentException("mu must be empty, vector d x 1 or matrix d x n, d = dimensionality of sigma");
124                }
125                ILArray<double> sigmaLoc = sigma;
126                // main
127                if (sigma.IsVector && sigma.Length == d) {
128                    // we dont cach vector sigmas
129                    if (any(sigmaLoc < 0)) {
130                        throw new ILArgumentException("all diagonal elements of sigma must be >= 0");
131                    }
132                    sigmaLoc.a = sqrt(sigmaLoc);
133                    ret.a =  /*dummy*/ (randn(d, n)) * sigmaLoc + mu;
134
135                } else if ((sigma.IsMatrix || sigma.S[2] == n) && sigma.S[0] == d && sigma.S[1] == d) {
136                    if (sigmaIsSquaredCov && !s_mvnrndcache.TryGetArray<double>(sigmaLoc, n, sigma)) {
137                        for (int i = sigmaLoc.S[2]; i --> 0; ) {
138                            sigmaLoc[full, full, i] = chol(sigmaLoc[full, full, i]);
139                        }
140                        s_mvnrndcache.Cache<double>(sigmaLoc, n, sigma);
141                    }
142                    ret.a  = zeros<double>(d,n);
143                    bool sigmaIsMatrix = sigmaLoc.S[2] <= 1;
144                    if (mu.IsVector) {
145                        for (int i = 0; i < n; i++) {
146                            using (ILScope.Enter()) {
147                                if (sigmaIsMatrix)
148                                    ret[full, i] = multiply( /*dummy*/ (randn(1, d)), sigmaLoc).T + mu;
149                                else
150                                    ret[full, i] = multiply( /*dummy*/ (randn(1, d)), sigmaLoc[full, full, i]).T + mu;
151                            }
152                        }
153                    } else {
154                        for (int i = 0; i < n; i++) {
155                            using (ILScope.Enter()) {
156                                if (sigmaIsMatrix)
157                                    ret[full, i] = multiply( /*dummy*/ (randn(1, d)), sigmaLoc).T + mu[full, i];
158                                else
159                                    ret[full, i] = multiply( /*dummy*/ (randn(1, d)), sigmaLoc[full, full, i]).T + mu[full, i];
160
161                            }
162                        }
163                    }
164                } else {
165                    throw new ILArgumentException("invalid size of sigma, check the documentation for valid options");
166                }
167                return ret;
168            }
169        }
170
171#region HYCALPER AUTO GENERATED CODE
172
173
174        /// <summary>
175        /// choose samples from a multivariate random distribution 
176        /// </summary>
177        /// <param name="inMu">[optional] centers, size d x n; if d x 1 is given, optional parameter <paramref name="n"/> is used to replicate mu accordingly, if null, the values will be genereated with a center of zero</param>
178        /// <param name="inSigma">[optional] covariance matrix, must be positive definite, size d x d or vector of lenght d, if null (not set), unitiy matrix is expected</param>
179        /// <param name="n">[optional] number of samples to generate, per default (-1) the number of columns of <paramref name="mu"/> defines that number</param>
180        /// <param name="sigmaIsSquaredCov">[optional] if false: safe the effort of finding the square root of <paramref name="sigma"/> parameter; default: true</param>
181        /// <returns>random numbers as taken from the multivariate random probability distribution given by mu and sigma</returns>
182        /// <remarks><para>In order to safe the step of finding the root of sigma, the following options exist:
183        /// <list type="bullet">
184        /// <item>Provide only the diagonal of a (virtual) diagonal matrix to <paramref name="sigma"/>.</item>
185        /// <item>Compute the root manually, give it to sigma and set <paramref name="sigmaIsSquaredCov"/> to false.</item>
186        /// </list></para>
187        /// <para>In case <paramref name="sigmaIsSquaredCov"/> set to 'false' and <paramref name="sigma"/> is given,
188        /// the root is computed via cholesky factorization. The result of the last root finding process is cached and reused for
189        /// subsequent requests with the same set of <paramref name="n"/> and <paramref name="sigma"/> parameters.</para></remarks>
190        public static ILRetArray<float> mvnrnd(ILInArray<float> inMu = null, ILInArray<float> inSigma = null,
191                                                       int n = -1, bool sigmaIsSquaredCov = true) {
192            using (ILScope.Enter(inMu, inSigma)) {
193
194                // early exit, trivial case
195                if (isnullorempty(inMu) && isnullorempty(inSigma)) {
196                    return  tosingle (randn(1, Math.Max(n, 0)));
197                }
198                ILArray<float> mu = check(inMu, Default: empty< float>());
199                ILArray<float> sigma = check(inSigma, Default: empty<float>());
200
201                // determine output size
202                n = Math.Max(Math.Max(mu.S[1], sigma.S[2]), n);
203                int d = Math.Max(Math.Max(mu.S[0], sigma.S[0]), sigma.S[1]);
204                ILArray<float> ret = empty<float>();
205
206                if (mu.IsEmpty)
207                    mu = zeros<float>(d, 1);
208                if (mu.IsRowVector)
209                    mu = mu.T;
210                if (sigma.IsEmpty)
211                    sigma = ones<float>(d, 1);
212                if (sigma.IsRowVector)
213                    sigma = sigma.T;
214
215                if (mu.IsVector && mu.Length != d) {
216                    throw new ILArgumentException("mu must be empty or have the same dimensionality as sigma");
217                } else if (mu.S[1] > 1 && (mu.S[0] != d || mu.S[1] != n)) {
218                    throw new ILArgumentException("mu must be empty, vector d x 1 or matrix d x n, d = dimensionality of sigma");
219                }
220                ILArray<float> sigmaLoc = sigma;
221                // main
222                if (sigma.IsVector && sigma.Length == d) {
223                    // we dont cach vector sigmas
224                    if (any(sigmaLoc < 0)) {
225                        throw new ILArgumentException("all diagonal elements of sigma must be >= 0");
226                    }
227                    sigmaLoc.a = sqrt(sigmaLoc);
228                    ret.a =  tosingle (randn(d, n)) * sigmaLoc + mu;
229
230                } else if ((sigma.IsMatrix || sigma.S[2] == n) && sigma.S[0] == d && sigma.S[1] == d) {
231                    if (sigmaIsSquaredCov && !s_mvnrndcache.TryGetArray<float>(sigmaLoc, n, sigma)) {
232                        for (int i = sigmaLoc.S[2]; i --> 0; ) {
233                            sigmaLoc[full, full, i] = chol(sigmaLoc[full, full, i]);
234                        }
235                        s_mvnrndcache.Cache<float>(sigmaLoc, n, sigma);
236                    }
237                    ret.a  = zeros<float>(d,n);
238                    bool sigmaIsMatrix = sigmaLoc.S[2] <= 1;
239                    if (mu.IsVector) {
240                        for (int i = 0; i < n; i++) {
241                            using (ILScope.Enter()) {
242                                if (sigmaIsMatrix)
243                                    ret[full, i] = multiply( tosingle (randn(1, d)), sigmaLoc).T + mu;
244                                else
245                                    ret[full, i] = multiply( tosingle (randn(1, d)), sigmaLoc[full, full, i]).T + mu;
246                            }
247                        }
248                    } else {
249                        for (int i = 0; i < n; i++) {
250                            using (ILScope.Enter()) {
251                                if (sigmaIsMatrix)
252                                    ret[full, i] = multiply( tosingle (randn(1, d)), sigmaLoc).T + mu[full, i];
253                                else
254                                    ret[full, i] = multiply( tosingle (randn(1, d)), sigmaLoc[full, full, i]).T + mu[full, i];
255
256                            }
257                        }
258                    }
259                } else {
260                    throw new ILArgumentException("invalid size of sigma, check the documentation for valid options");
261                }
262                return ret;
263            }
264        }
265
266#endregion HYCALPER AUTO GENERATED CODE
267   }
268}
Note: See TracBrowser for help on using the repository browser.