001/*- 002 ******************************************************************************* 003 * Copyright (c) 2011, 2016 Diamond Light Source Ltd. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Peter Chang - initial API and implementation and/or initial documentation 011 *******************************************************************************/ 012 013package org.eclipse.january.dataset; 014 015 016import java.io.IOException; 017 018import org.apache.commons.math3.random.MersenneTwister; 019import org.apache.commons.math3.random.RandomDataGenerator; 020import org.apache.commons.math3.random.RandomGenerator; 021import org.eclipse.january.IMonitor; 022import org.eclipse.january.io.ILazyLoader; 023 024/** 025 * Class to hold methods to create random datasets 026 * 027 * Emulates numpy.random 028 */ 029public class Random { 030 private final static RandomGenerator generator = new MersenneTwister(); 031 private final static RandomDataGenerator prng = new RandomDataGenerator(generator); 032 033 /** 034 * @param seed 035 */ 036 public static void seed(final int seed) { 037 generator.setSeed(seed); 038 } 039 040 /** 041 * @param seed 042 */ 043 public static void seed(final int[] seed) { 044 generator.setSeed(seed); 045 } 046 047 /** 048 * @param seed 049 */ 050 public static void seed(final long seed) { 051 generator.setSeed(seed); 052 } 053 054 /** 055 * @param shape 056 * @return an array of values sampled from a uniform distribution between 0 (inclusive) and 1 (exclusive) 057 */ 058 public static DoubleDataset rand(final int... shape) { 059 DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, shape); 060 double[] buf = data.getData(); 061 062 for (int i = 0; i < buf.length; i++) { 063 buf[i] = generator.nextDouble(); 064 } 065 066 return data; 067 } 068 069 /** 070 * @param low 071 * @param high 072 * @param shape 073 * @return an array of values sampled from a uniform distribution between low and high (both exclusive) 074 */ 075 public static DoubleDataset rand(double low, double high, final int... shape) { 076 DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, shape); 077 double[] buf = data.getData(); 078 079 for (int i = 0; i < buf.length; i++) { 080 buf[i] = prng.nextUniform(low, high); 081 } 082 083 return data; 084 } 085 086 /** 087 * @param shape 088 * @return an array of values sampled from a Gaussian distribution with mean 0 and variance 1 089 * 090 * (The term Gaussian here is a description of a shape of data taken from the mathematician of the 091 * same name Carl Friedrich Gauss http://en.wikipedia.org/wiki/Carl_Friedrich_Gauss born in 1777.) 092 */ 093 public static DoubleDataset randn(final int... shape) { 094 DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, shape); 095 double[] buf = data.getData(); 096 097 for (int i = 0; i < buf.length; i++) { 098 buf[i] = generator.nextGaussian(); 099 } 100 101 return data; 102 } 103 104 /** 105 * @param mean 106 * @param std standard deviation 107 * @param shape 108 * @return an array of values sampled from a Gaussian distribution with given mean and standard deviation 109 */ 110 public static DoubleDataset randn(double mean, double std, final int... shape) { 111 DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, shape); 112 double[] buf = data.getData(); 113 114 for (int i = 0; i < buf.length; i++) { 115 buf[i] = prng.nextGaussian(mean, std); 116 } 117 118 return data; 119 } 120 121 /** 122 * @param low 123 * @param high 124 * @param shape 125 * @return an array of values sampled from a discrete uniform distribution in range [low, high) 126 */ 127 public static IntegerDataset randint(final int low, final int high, final int[] shape) { 128 return random_integers(low, high-1, shape); 129 } 130 131 /** 132 * @param low 133 * @param high 134 * @param shape 135 * @return an array of values sampled from a discrete uniform distribution in range [low, high] 136 */ 137 public static IntegerDataset random_integers(final int low, final int high, final int[] shape) { 138 IntegerDataset data = DatasetFactory.zeros(IntegerDataset.class, shape); 139 int[] buf = data.getData(); 140 141 if (low == high) { 142 for (int i = 0; i < buf.length; i++) { 143 buf[i] = low; 144 } 145 } else { 146 for (int i = 0; i < buf.length; i++) { 147 buf[i] = prng.nextInt(low, high); 148 } 149 } 150 151 return data; 152 } 153 154 /** 155 * @param beta 156 * @param shape 157 * @return an array of values sampled from an exponential distribution with mean beta 158 */ 159 public static DoubleDataset exponential(final double beta, final int... shape) { 160 DoubleDataset data = DatasetFactory.zeros(DoubleDataset.class, shape); 161 double[] buf = data.getData(); 162 163 for (int i = 0; i < buf.length; i++) { 164 buf[i] = prng.nextExponential(beta); 165 } 166 167 return data; 168 } 169 170 /** 171 * @param lam 172 * @param shape 173 * @return an array of values sampled from an exponential distribution with mean lambda 174 */ 175 public static IntegerDataset poisson(final double lam, final int... shape) { 176 IntegerDataset data = DatasetFactory.zeros(IntegerDataset.class, shape); 177 int[] buf = data.getData(); 178 179 for (int i = 0; i < buf.length; i++) { 180 buf[i] = (int) prng.nextPoisson(lam); 181 } 182 183 return data; 184 } 185 186 /** 187 * @param shape 188 * @return a lazy dataset with uniformly distributed random numbers 189 */ 190 public static ILazyDataset lazyRand(int... shape) { 191 return lazyRand(Dataset.FLOAT64, "random", shape); 192 } 193 194 /** 195 * @param name 196 * @param shape 197 * @return a lazy dataset with uniformly distributed random numbers 198 */ 199 public static ILazyDataset lazyRand(String name, int... shape) { 200 return lazyRand(Dataset.FLOAT64, name, shape); 201 } 202 203 /** 204 * @param dtype 205 * @param name 206 * @param shape 207 * @return a lazy dataset with uniformly distributed random numbers 208 */ 209 public static ILazyDataset lazyRand(int dtype, String name, int... shape) { 210 211 return new LazyDataset(name, dtype, shape, new ILazyLoader() { 212 private static final long serialVersionUID = ILazyLoader.serialVersionUID; 213 214 @Override 215 public boolean isFileReadable() { 216 return true; 217 } 218 219 @Override 220 public IDataset getDataset(IMonitor mon, SliceND slice) throws IOException { 221 return rand(slice.getShape()); 222 } 223 }); 224 } 225}