28#ifndef REMORA_RANDOM_HPP
29#define REMORA_RANDOM_HPP
33#include "detail/proxy_optimizers_fwd.hpp"
35namespace remora{
namespace detail{
36template<
class T,
class Rng>
44 void generate(E& e,
typename E::value_type alpha)
const{
45 kernels::generate_normal(e, *rng, mean*alpha, variance*alpha*alpha);
49template<
class T,
class Rng>
57 void generate(E& e,
typename E::value_type alpha)
const{
58 kernels::generate_uniform(e, *rng, low * alpha, high * alpha);
78template<
class Distribution,
class Device>
79class random_vector:
public vector_expression<random_vector<Distribution,Device>, Device>{
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;
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;
94 Distribution
const& distribution,
95 typename device_traits<device_type>::queue_type& queue,
97 value_type alpha = value_type(1)
98 ):m_distribution(distribution), m_queue(&queue), m_size(size), m_alpha(alpha){};
100 size_type size()
const {
103 typename device_traits<device_type>::queue_type& queue()
const{
107 Distribution
const& dist()
const{
108 return m_distribution;
111 value_type alpha()
const{
115 typedef no_iterator iterator;
116 typedef iterator const_iterator;
120 void assign_to(vector_expression<VecX, device_type>& x)
const{
121 m_distribution.generate(x(), m_alpha);
124 void plus_assign_to(vector_expression<VecX, device_type>& x)
const{
125 plus_assign(x,
typename vector_temporary<VecX>::type(*
this));
128 Distribution m_distribution;
129 typename device_traits<device_type>::queue_type* m_queue;
134template<
class Distribution,
class Device>
135class random_matrix:
public matrix_expression<random_matrix<Distribution,Device>, Device>{
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;
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;
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){};
157 size_type size1()
const {
160 size_type size2()
const {
163 typename device_traits<device_type>::queue_type& queue()
const{
167 Distribution
const& dist()
const{
168 return m_distribution;
171 value_type alpha()
const{
175 typedef no_iterator major_iterator;
176 typedef no_iterator const_major_iterator;
180 void assign_to(matrix_expression<MatX, device_type>& x)
const{
181 m_distribution.generate(x(),m_alpha);
184 void plus_assign_to(matrix_expression<MatX, device_type>& x)
const{
185 plus_assign(x,
typename matrix_temporary<MatX>::type(*
this));
188 Distribution m_distribution;
189 typename device_traits<device_type>::queue_type* m_queue;
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);
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());
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);
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());
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());
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());
245template<
class Distribution,
class Device>
246struct matrix_range_optimizer<random_matrix<Distribution, Device> >{
247 typedef random_matrix<Distribution, Device> type;
249 static type create(type
const& m,
250 std::size_t start1, std::size_t end1, std::size_t start2, std::size_t end2
252 return type(m.dist(), m.queue(), end1 - start1, end2-start2, m.alpha());
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
261 return type(m.dist(), m.queue(), end - start, m.size2(), m.alpha());
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};
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};
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};
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};