random.hpp
Go to the documentation of this file.
1/*!
2 * \brief Defines types for matrix decompositions
3 *
4 * \author O. Krause
5 * \date 2016
6 *
7 *
8 * \par Copyright 1995-2015 Shark Development Team
9 *
10 * <BR><HR>
11 * This file is part of Shark.
12 * <http://image.diku.dk/shark/>
13 *
14 * Shark is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published
16 * by the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Shark is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26 *
27 */
28#ifndef REMORA_RANDOM_HPP
29#define REMORA_RANDOM_HPP
30
31#include "assignment.hpp"
32#include "kernels/random.hpp"
33#include "detail/proxy_optimizers_fwd.hpp"
34
35namespace remora{ namespace detail{
36template<class T, class Rng>
37struct RandomNormal{
38 typedef T value_type;
39 T mean;
40 T variance;
41 Rng* rng;
42
43 template<class E>
44 void generate(E& e, typename E::value_type alpha) const{
45 kernels::generate_normal(e, *rng, mean*alpha, variance*alpha*alpha);
46 }
47};
48
49template<class T, class Rng>
50struct RandomUniform{
51 typedef T value_type;
52 T low;
53 T high;
54 Rng* rng;
55
56 template<class E>
57 void generate(E& e, typename E::value_type alpha) const{
58 kernels::generate_uniform(e, *rng, low * alpha, high * alpha);
59 }
60};
61
62//~ template<class T, class Rng>
63//~ struct RandomDiscrete{
64 //~ typedef T value_type;
65 //~ T low;
66 //~ T high;
67 //~ Rng* rng;
68
69 //~ template<class E>
70 //~ void generate(E& e) const{
71 //~ kernels::generate_discrete(v, *rng, low, high);
72
73 //~ }
74//~ };
75
76}
77
78template<class Distribution, class Device>
79class random_vector: public vector_expression<random_vector<Distribution,Device>, Device>{
80public:
81 typedef typename Distribution::value_type value_type;
82 typedef std::size_t size_type;
83 typedef value_type const_reference;
84 typedef const_reference reference;
85
86 typedef random_vector const_closure_type;
87 typedef const_closure_type closure_type;
88 typedef unknown_storage storage_type;
89 typedef unknown_storage const_storage_type;
90 typedef blockwise<dense_tag> evaluation_category;
91 typedef Device device_type;
92
93 random_vector(
94 Distribution const& distribution,
95 typename device_traits<device_type>::queue_type& queue,
96 std::size_t size,
97 value_type alpha = value_type(1)
98 ):m_distribution(distribution), m_queue(&queue), m_size(size), m_alpha(alpha){};
99
100 size_type size() const {
101 return m_size;
102 }
103 typename device_traits<device_type>::queue_type& queue() const{
104 return *m_queue;
105 }
106
107 Distribution const& dist() const{
108 return m_distribution;
109 }
110
111 value_type alpha() const{
112 return m_alpha;
113 }
114
115 typedef no_iterator iterator;
116 typedef iterator const_iterator;
117
118 //dispatcher to computation kernels
119 template<class VecX>
120 void assign_to(vector_expression<VecX, device_type>& x)const{
121 m_distribution.generate(x(), m_alpha);
122 }
123 template<class VecX>
124 void plus_assign_to(vector_expression<VecX, device_type>& x)const{
125 plus_assign(x,typename vector_temporary<VecX>::type(*this));
126 }
127private:
128 Distribution m_distribution;
129 typename device_traits<device_type>::queue_type* m_queue;
130 std::size_t m_size;
131 value_type m_alpha;
132};
133
134template<class Distribution, class Device>
135class random_matrix: public matrix_expression<random_matrix<Distribution,Device>, Device>{
136public:
137 typedef typename Distribution::value_type value_type;
138 typedef std::size_t size_type;
139 typedef value_type const_reference;
140 typedef const_reference reference;
141
142 typedef random_matrix const_closure_type;
143 typedef const_closure_type closure_type;
144 typedef unknown_storage storage_type;
145 typedef unknown_storage const_storage_type;
146 typedef blockwise<dense_tag> evaluation_category;
147 typedef unknown_orientation orientation;
148 typedef Device device_type;
149
150 random_matrix(
151 Distribution const& distribution,
152 typename device_traits<device_type>::queue_type& queue,
153 std::size_t size1, std::size_t size2,
154 value_type alpha = value_type(1)
155 ):m_distribution(distribution), m_queue(&queue), m_size1(size1), m_size2(size2), m_alpha(alpha){};
156
157 size_type size1() const {
158 return m_size1;
159 }
160 size_type size2() const {
161 return m_size2;
162 }
163 typename device_traits<device_type>::queue_type& queue() const{
164 return *m_queue;
165 }
166
167 Distribution const& dist() const{
168 return m_distribution;
169 }
170
171 value_type alpha() const{
172 return m_alpha;
173 }
174
175 typedef no_iterator major_iterator;
176 typedef no_iterator const_major_iterator;
177
178 //dispatcher to computation kernels
179 template<class MatX>
180 void assign_to(matrix_expression<MatX, device_type>& x)const{
181 m_distribution.generate(x(),m_alpha);
182 }
183 template<class MatX>
184 void plus_assign_to(matrix_expression<MatX, device_type>& x)const{
185 plus_assign(x,typename matrix_temporary<MatX>::type(*this));
186 }
187private:
188 Distribution m_distribution;
189 typename device_traits<device_type>::queue_type* m_queue;
190 std::size_t m_size1;
191 std::size_t m_size2;
192 value_type m_alpha;
193};
194
195namespace detail{
196template<class Distribution, class Device>
197struct vector_scalar_multiply_optimizer<random_vector<Distribution, Device> >{
198 typedef random_vector<Distribution, Device> type;
199 static type create(type const& v, typename type::value_type alpha){
200 return type(v.dist(), v.queue(), v.size(), v.alpha() * alpha);
201 }
202};
203
204template<class Distribution, class Device>
205struct vector_range_optimizer<random_vector<Distribution, Device> >{
206 typedef random_vector<Distribution, Device> type;
207 static type create(type const& v, std::size_t start, std::size_t end){
208 return type(v.dist(), v.queue(), end - start, v.alpha());
209 }
210};
211
212
213template<class Distribution, class Device>
214struct matrix_scalar_multiply_optimizer<random_matrix<Distribution, Device> >{
215 typedef random_matrix<Distribution, Device> type;
216 static type create(type const& m, typename type::value_type alpha){
217 return type(m.dist(), m.queue(), m.size1(), m.size2(), m.alpha() * alpha);
218 }
219};
220
221template<class Distribution, class Device>
222struct matrix_transpose_optimizer<random_matrix<Distribution, Device> >{
223 typedef random_matrix<Distribution, Device> type;
224 static type create(type const& m){
225 return type(m.dist(), m.queue(), m.size2(), m.size1(), m.alpha());
226 }
227};
228
229template<class Distribution, class Device>
230struct matrix_row_optimizer<random_matrix<Distribution, Device> >{
231 typedef random_vector<Distribution, Device> type;
232 static type create(random_matrix<Distribution, Device> const& m){
233 return type(m.dist(), m.queue(), m.size2(), m.alpha());
234 }
235};
236
237template<class Distribution, class Device>
238struct matrix_diagonal_optimizer<random_matrix<Distribution, Device> >{
239 typedef random_vector<Distribution, Device> type;
240 static type create(type const& m){
241 return type(m.dist(), m.queue(), std::min(m.size1(),m.size2()), m.alpha());
242 }
243};
244
245template<class Distribution, class Device>
246struct matrix_range_optimizer<random_matrix<Distribution, Device> >{
247 typedef random_matrix<Distribution, Device> type;
248
249 static type create(type const& m,
250 std::size_t start1, std::size_t end1, std::size_t start2, std::size_t end2
251 ){
252 return type(m.dist(), m.queue(), end1 - start1, end2-start2, m.alpha());
253 }
254};
255
256template<class Distribution, class Device>
257struct matrix_rows_optimizer<random_matrix<Distribution, Device> >{
258 typedef random_matrix<Distribution, Device> type;
259 static type create(type const& m, std::size_t start, std::size_t end
260 ){
261 return type(m.dist(), m.queue(), end - start, m.size2(), m.alpha());
262 }
263};
264
265}
266
267
268//////////////////////////////////////////////////////
269////////Expressions
270//////////////////////////////////////////////////////
271
272
273//solvers for vector rhs
274template<class Device, class T, class Rng>
275random_vector<detail::RandomNormal<T,Rng>, Device> normal(Rng& rng, std::size_t size, T mean, T variance, Device){
276 return {{mean,variance, &rng},device_traits<Device>::default_queue(),size};
277}
278
279template<class Device, class T, class Rng>
280random_matrix<detail::RandomNormal<T,Rng>, Device> normal(Rng& rng, std::size_t size1, std::size_t size2, T mean, T variance, Device){
281 return {{mean,variance, &rng},device_traits<Device>::default_queue(),size1,size2};
282}
283
284template<class Device, class T, class Rng>
285random_vector<detail::RandomUniform<T,Rng>, Device> uniform(Rng& rng, std::size_t size, T low, T high, Device){
286 return {{low,high, &rng},device_traits<Device>::default_queue(),size};
287}
288
289template<class Device, class T, class Rng>
290random_matrix<detail::RandomUniform<T,Rng>, Device> uniform(Rng& rng, std::size_t size1, std::size_t size2, T low, T high, Device){
291 return {{low,high, &rng},device_traits<Device>::default_queue(),size1,size2};
292}
293
294
295}
296#endif