More cleanup. Remove files that are not strictly required.
This commit is contained in:
@ -7,7 +7,6 @@ SET(MATH_SRCS
|
||||
Plane.h Plane.cpp
|
||||
Box.h
|
||||
Color.h
|
||||
Random.h Random.cpp
|
||||
Half.h Half.cpp
|
||||
Fitting.h Fitting.cpp)
|
||||
|
||||
|
@ -1,135 +0,0 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#include <nvmath/Montecarlo.h>
|
||||
|
||||
using namespace nv;
|
||||
|
||||
|
||||
void SampleDistribution::redistribute(Method method/*=Method_NRook*/, Distribution dist/*=Distribution_Cosine*/)
|
||||
{
|
||||
switch(method)
|
||||
{
|
||||
case Method_Random:
|
||||
redistributeRandom(dist);
|
||||
break;
|
||||
case Method_Stratified:
|
||||
redistributeStratified(dist);
|
||||
break;
|
||||
case Method_NRook:
|
||||
redistributeNRook(dist);
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void SampleDistribution::redistributeRandom(const Distribution dist)
|
||||
{
|
||||
const uint sampleCount = m_sampleArray.count();
|
||||
|
||||
// This is the worst method possible!
|
||||
for(uint i = 0; i < sampleCount; i++)
|
||||
{
|
||||
float x = m_rand.getFloat();
|
||||
float y = m_rand.getFloat();
|
||||
|
||||
setSample(i, dist, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SampleDistribution::redistributeStratified(const Distribution dist)
|
||||
{
|
||||
const uint sampleCount = m_sampleArray.count();
|
||||
const uint sqrtSampleCount = uint(sqrtf(float(sampleCount)));
|
||||
|
||||
nvDebugCheck(sqrtSampleCount*sqrtSampleCount == sampleCount); // Must use exact powers!
|
||||
|
||||
// Create a uniform distribution of points on the hemisphere with low variance.
|
||||
for(uint v = 0, i = 0; v < sqrtSampleCount; v++) {
|
||||
for(uint u = 0; u < sqrtSampleCount; u++, i++) {
|
||||
float x = (u + m_rand.getFloat()) / float(sqrtSampleCount);
|
||||
float y = (v + m_rand.getFloat()) / float(sqrtSampleCount);
|
||||
|
||||
setSample(i, dist, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Multi-Stage N-rooks Sampling Method.
|
||||
* See: http://www.acm.org/jgt/papers/WangSung9/9
|
||||
*/
|
||||
void SampleDistribution::multiStageNRooks(const int size, int* cells)
|
||||
{
|
||||
if (size == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int size1 = size >> 1;
|
||||
int size2 = size >> 1;
|
||||
|
||||
if (size & 1) {
|
||||
if (m_rand.getFloat() > 0.5) {
|
||||
size1++;
|
||||
}
|
||||
else {
|
||||
size2++;
|
||||
}
|
||||
}
|
||||
|
||||
int* upper_cells = new int[size1];
|
||||
int* lower_cells = new int[size2];
|
||||
|
||||
int i, j;
|
||||
for(i = 0, j = 0; i < size - 1; i += 2, j++) {
|
||||
if (m_rand.get() & 1) {
|
||||
upper_cells[j] = cells[i];
|
||||
lower_cells[j] = cells[i + 1];
|
||||
}
|
||||
else {
|
||||
upper_cells[j] = cells[i + 1];
|
||||
lower_cells[j] = cells[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (size1 != size2) {
|
||||
if (size1 > size2) {
|
||||
upper_cells[j] = cells[i];
|
||||
}
|
||||
else {
|
||||
lower_cells[j] = cells[i];
|
||||
}
|
||||
}
|
||||
|
||||
multiStageNRooks(size1, upper_cells);
|
||||
memcpy(cells, upper_cells, size1 * sizeof(int));
|
||||
delete [] upper_cells;
|
||||
|
||||
multiStageNRooks(size2, lower_cells);
|
||||
memcpy(cells + size1, lower_cells, size2 * sizeof(int));
|
||||
delete [] lower_cells;
|
||||
}
|
||||
|
||||
|
||||
void SampleDistribution::redistributeNRook(const Distribution dist)
|
||||
{
|
||||
const uint sampleCount = m_sampleArray.count();
|
||||
|
||||
// Generate nrook cells
|
||||
int * cells = new int[sampleCount];
|
||||
for(uint32 i = 0; i < sampleCount; i++)
|
||||
{
|
||||
cells[i] = i;
|
||||
}
|
||||
multiStageNRooks(sampleCount, cells);
|
||||
|
||||
for(uint i = 0; i < sampleCount; i++)
|
||||
{
|
||||
float x = (i + m_rand.getFloat()) / sampleCount;
|
||||
float y = (cells[i] + m_rand.getFloat()) / sampleCount;
|
||||
|
||||
setSample(i, dist, x, y);
|
||||
}
|
||||
|
||||
delete [] cells;
|
||||
}
|
||||
|
@ -1,103 +0,0 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#ifndef NV_MATH_MONTECARLO_H
|
||||
#define NV_MATH_MONTECARLO_H
|
||||
|
||||
#include <nvmath/Vector.h>
|
||||
#include <nvmath/Random.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
/// A random sample distribution.
|
||||
class SampleDistribution
|
||||
{
|
||||
public:
|
||||
|
||||
// Sampling method.
|
||||
enum Method {
|
||||
Method_Random,
|
||||
Method_Stratified,
|
||||
Method_NRook
|
||||
};
|
||||
|
||||
// Distribution functions.
|
||||
enum Distribution {
|
||||
Distribution_UniformSphere,
|
||||
Distribution_UniformHemisphere,
|
||||
Distribution_CosineHemisphere
|
||||
};
|
||||
|
||||
/// Constructor.
|
||||
SampleDistribution(uint num)
|
||||
{
|
||||
m_sampleArray.resize(num);
|
||||
}
|
||||
|
||||
uint count() const { return m_sampleArray.count(); }
|
||||
|
||||
void redistribute(Method method=Method_NRook, Distribution dist=Distribution_CosineHemisphere);
|
||||
|
||||
/// Get parametric coordinates of the sample.
|
||||
Vector2 sample(int i) const { return m_sampleArray[i].uv; }
|
||||
|
||||
/// Get sample direction.
|
||||
Vector3 sampleDir(int i) const { return m_sampleArray[i].dir; }
|
||||
|
||||
/// Get number of samples.
|
||||
uint sampleCount() const { return m_sampleArray.count(); }
|
||||
|
||||
private:
|
||||
|
||||
void redistributeRandom(const Distribution dist);
|
||||
void redistributeStratified(const Distribution dist);
|
||||
void multiStageNRooks(const int size, int* cells);
|
||||
void redistributeNRook(const Distribution dist);
|
||||
|
||||
|
||||
/// A sample of the random distribution.
|
||||
struct Sample
|
||||
{
|
||||
/// Set sample given the 3d coordinates.
|
||||
void setDir(float x, float y, float z) {
|
||||
dir.set(x, y, z);
|
||||
uv.set(acosf(z), atan2f(y, x));
|
||||
}
|
||||
|
||||
/// Set sample given the 2d parametric coordinates.
|
||||
void setUV(float u, float v) {
|
||||
uv.set(u, v);
|
||||
dir.set(sinf(u) * cosf(v), sinf(u) * sinf(v), cosf(u));
|
||||
}
|
||||
|
||||
Vector2 uv;
|
||||
Vector3 dir;
|
||||
};
|
||||
|
||||
inline void setSample(uint i, Distribution dist, float x, float y)
|
||||
{
|
||||
// Map uniform distribution in the square to desired domain.
|
||||
if( dist == Distribution_UniformSphere ) {
|
||||
m_sampleArray[i].setUV(acosf(1 - 2 * x), 2 * PI * y);
|
||||
}
|
||||
else if( dist == Distribution_UniformHemisphere ) {
|
||||
m_sampleArray[i].setUV(acosf(x), 2 * PI * y);
|
||||
}
|
||||
else {
|
||||
nvDebugCheck(dist == Distribution_CosineHemisphere);
|
||||
m_sampleArray[i].setUV(acosf(sqrtf(x)), 2 * PI * y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Random seed.
|
||||
MTRand m_rand;
|
||||
|
||||
/// Samples.
|
||||
Array<Sample> m_sampleArray;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_MATH_MONTECARLO_H
|
@ -1,54 +0,0 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#include <nvmath/Random.h>
|
||||
#include <time.h>
|
||||
|
||||
using namespace nv;
|
||||
|
||||
// Statics
|
||||
const uint16 Rand48::a0 = 0xE66D;
|
||||
const uint16 Rand48::a1 = 0xDEEC;
|
||||
const uint16 Rand48::a2 = 0x0005;
|
||||
const uint16 Rand48::c0 = 0x000B;
|
||||
|
||||
|
||||
/// Get a random seed based on the current time.
|
||||
uint Rand::randomSeed()
|
||||
{
|
||||
return (uint)time(NULL);
|
||||
}
|
||||
|
||||
|
||||
void MTRand::initialize( uint32 seed )
|
||||
{
|
||||
// Initialize generator state with seed
|
||||
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
|
||||
// In previous versions, most significant bits (MSBs) of the seed affect
|
||||
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
|
||||
uint32 *s = state;
|
||||
uint32 *r = state;
|
||||
int i = 1;
|
||||
*s++ = seed & 0xffffffffUL;
|
||||
for( ; i < N; ++i )
|
||||
{
|
||||
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
|
||||
r++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MTRand::reload()
|
||||
{
|
||||
// Generate N new values in state
|
||||
// Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
|
||||
uint32 *p = state;
|
||||
int i;
|
||||
for( i = N - M; i--; ++p )
|
||||
*p = twist( p[M], p[0], p[1] );
|
||||
for( i = M; --i; ++p )
|
||||
*p = twist( p[M-N], p[0], p[1] );
|
||||
*p = twist( p[M-N], p[0], state[0] );
|
||||
|
||||
left = N, next = state;
|
||||
}
|
||||
|
@ -1,368 +0,0 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#ifndef NV_MATH_RANDOM_H
|
||||
#define NV_MATH_RANDOM_H
|
||||
|
||||
#include <nvcore/Containers.h> // nextPowerOfTwo
|
||||
#include <nvmath/nvmath.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
/// Interface of the random number generators.
|
||||
class Rand
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~Rand() {}
|
||||
|
||||
enum time_e { Time };
|
||||
|
||||
/// Provide a new seed.
|
||||
virtual void seed( uint s ) { /* empty */ };
|
||||
|
||||
/// Get an integer random number.
|
||||
virtual uint get() = 0;
|
||||
|
||||
/// Get a random number on [0, max] interval.
|
||||
uint getRange( uint max )
|
||||
{
|
||||
uint n;
|
||||
// uint mask = Bitmask( max );
|
||||
// do { n = Get() & mask; } while( n > max );
|
||||
uint np2 = nextPowerOfTwo( max );
|
||||
do { n = get() & (np2-1); } while( n > max );
|
||||
return n;
|
||||
}
|
||||
|
||||
/// Random number on [0.0, 1.0] interval.
|
||||
float getFloat()
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32 i;
|
||||
float f;
|
||||
} pun;
|
||||
|
||||
pun.i = 0x3f800000UL | (get() & 0x007fffffUL);
|
||||
return pun.f - 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
/// Random number on [0.0, 1.0] interval.
|
||||
double getReal()
|
||||
{
|
||||
return double(get()) * (1.0/4294967295.0); // 2^32-1
|
||||
}
|
||||
|
||||
/// Random number on [0.0, 1.0) interval.
|
||||
double getRealExclusive()
|
||||
{
|
||||
return double(get()) * (1.0/4294967296.0); // 2^32
|
||||
}
|
||||
*/
|
||||
|
||||
/// Get the max value of the random number.
|
||||
uint max() const { return 4294967295U; }
|
||||
|
||||
// Get a random seed.
|
||||
static uint randomSeed();
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Very simple random number generator with low storage requirements.
|
||||
class SimpleRand : public Rand
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor that uses the current time as the seed.
|
||||
SimpleRand( time_e )
|
||||
{
|
||||
seed(randomSeed());
|
||||
}
|
||||
|
||||
/// Constructor that uses the given seed.
|
||||
SimpleRand( uint s = 0 )
|
||||
{
|
||||
seed(s);
|
||||
}
|
||||
|
||||
/// Set the given seed.
|
||||
virtual void seed( uint s )
|
||||
{
|
||||
current = s;
|
||||
}
|
||||
|
||||
/// Get a random number.
|
||||
virtual uint get()
|
||||
{
|
||||
return current = current * 1103515245 + 12345;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
uint current;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// Mersenne twister random number generator.
|
||||
class MTRand : public Rand
|
||||
{
|
||||
public:
|
||||
|
||||
enum { N = 624 }; // length of state vector
|
||||
enum { M = 397 };
|
||||
|
||||
/// Constructor that uses the current time as the seed.
|
||||
MTRand( time_e )
|
||||
{
|
||||
seed(randomSeed());
|
||||
}
|
||||
|
||||
/// Constructor that uses the given seed.
|
||||
MTRand( uint s = 0 )
|
||||
{
|
||||
seed(s);
|
||||
}
|
||||
|
||||
/// Constructor that uses the given seeds.
|
||||
NVMATH_API MTRand( const uint * seed_array, uint length );
|
||||
|
||||
|
||||
/// Provide a new seed.
|
||||
virtual void seed( uint s )
|
||||
{
|
||||
initialize(s);
|
||||
reload();
|
||||
}
|
||||
|
||||
/// Get a random number between 0 - 65536.
|
||||
virtual uint get()
|
||||
{
|
||||
// Pull a 32-bit integer from the generator state
|
||||
// Every other access function simply transforms the numbers extracted here
|
||||
if( left == 0 ) {
|
||||
reload();
|
||||
}
|
||||
left--;
|
||||
|
||||
uint s1;
|
||||
s1 = *next++;
|
||||
s1 ^= (s1 >> 11);
|
||||
s1 ^= (s1 << 7) & 0x9d2c5680U;
|
||||
s1 ^= (s1 << 15) & 0xefc60000U;
|
||||
return ( s1 ^ (s1 >> 18) );
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
NVMATH_API void initialize( uint32 seed );
|
||||
NVMATH_API void reload();
|
||||
|
||||
uint hiBit( uint u ) const { return u & 0x80000000U; }
|
||||
uint loBit( uint u ) const { return u & 0x00000001U; }
|
||||
uint loBits( uint u ) const { return u & 0x7fffffffU; }
|
||||
uint mixBits( uint u, uint v ) const { return hiBit(u) | loBits(v); }
|
||||
uint twist( uint m, uint s0, uint s1 ) const { return m ^ (mixBits(s0,s1)>>1) ^ ((~loBit(s1)+1) & 0x9908b0dfU); }
|
||||
|
||||
private:
|
||||
|
||||
uint state[N]; // internal state
|
||||
uint * next; // next value to get from state
|
||||
int left; // number of values left before reload needed
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** George Marsaglia's random number generator.
|
||||
* Code based on Thatcher Ulrich public domain source code:
|
||||
* http://cvs.sourceforge.net/viewcvs.py/tu-testbed/tu-testbed/base/tu_random.cpp?rev=1.7&view=auto
|
||||
*
|
||||
* PRNG code adapted from the complimentary-multiply-with-carry
|
||||
* code in the article: George Marsaglia, "Seeds for Random Number
|
||||
* Generators", Communications of the ACM, May 2003, Vol 46 No 5,
|
||||
* pp90-93.
|
||||
*
|
||||
* The article says:
|
||||
*
|
||||
* "Any one of the choices for seed table size and multiplier will
|
||||
* provide a RNG that has passed extensive tests of randomness,
|
||||
* particularly those in [3], yet is simple and fast --
|
||||
* approximately 30 million random 32-bit integers per second on a
|
||||
* 850MHz PC. The period is a*b^n, where a is the multiplier, n
|
||||
* the size of the seed table and b=2^32-1. (a is chosen so that
|
||||
* b is a primitive root of the prime a*b^n + 1.)"
|
||||
*
|
||||
* [3] Marsaglia, G., Zaman, A., and Tsang, W. Toward a universal
|
||||
* random number generator. _Statistics and Probability Letters
|
||||
* 8_ (1990), 35-39.
|
||||
*/
|
||||
class GMRand : public Rand
|
||||
{
|
||||
public:
|
||||
|
||||
enum { SEED_COUNT = 8 };
|
||||
|
||||
// const uint64 a = 123471786; // for SEED_COUNT=1024
|
||||
// const uint64 a = 123554632; // for SEED_COUNT=512
|
||||
// const uint64 a = 8001634; // for SEED_COUNT=255
|
||||
// const uint64 a = 8007626; // for SEED_COUNT=128
|
||||
// const uint64 a = 647535442; // for SEED_COUNT=64
|
||||
// const uint64 a = 547416522; // for SEED_COUNT=32
|
||||
// const uint64 a = 487198574; // for SEED_COUNT=16
|
||||
// const uint64 a = 716514398U; // for SEED_COUNT=8
|
||||
enum { a = 716514398U };
|
||||
|
||||
|
||||
GMRand( time_e )
|
||||
{
|
||||
seed(randomSeed());
|
||||
}
|
||||
|
||||
GMRand(uint s = 987654321)
|
||||
{
|
||||
seed(s);
|
||||
}
|
||||
|
||||
|
||||
/// Provide a new seed.
|
||||
virtual void seed( uint s )
|
||||
{
|
||||
c = 362436;
|
||||
i = SEED_COUNT - 1;
|
||||
|
||||
for(int i = 0; i < SEED_COUNT; i++) {
|
||||
s = s ^ (s << 13);
|
||||
s = s ^ (s >> 17);
|
||||
s = s ^ (s << 5);
|
||||
Q[i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a random number between 0 - 65536.
|
||||
virtual uint get()
|
||||
{
|
||||
const uint32 r = 0xFFFFFFFE;
|
||||
|
||||
uint64 t;
|
||||
uint32 x;
|
||||
|
||||
i = (i + 1) & (SEED_COUNT - 1);
|
||||
t = a * Q[i] + c;
|
||||
c = uint32(t >> 32);
|
||||
x = uint32(t + c);
|
||||
|
||||
if( x < c ) {
|
||||
x++;
|
||||
c++;
|
||||
}
|
||||
|
||||
uint32 val = r - x;
|
||||
Q[i] = val;
|
||||
return val;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
uint32 c;
|
||||
uint32 i;
|
||||
uint32 Q[8];
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Random number implementation from the GNU Sci. Lib. (GSL).
|
||||
* Adapted from Nicholas Chapman version:
|
||||
*
|
||||
* Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
|
||||
* This is the Unix rand48() generator. The generator returns the
|
||||
* upper 32 bits from each term of the sequence,
|
||||
*
|
||||
* x_{n+1} = (a x_n + c) mod m
|
||||
*
|
||||
* using 48-bit unsigned arithmetic, with a = 0x5DEECE66D , c = 0xB
|
||||
* and m = 2^48. The seed specifies the upper 32 bits of the initial
|
||||
* value, x_1, with the lower 16 bits set to 0x330E.
|
||||
*
|
||||
* The theoretical value of x_{10001} is 244131582646046.
|
||||
*
|
||||
* The period of this generator is ? FIXME (probably around 2^48).
|
||||
*/
|
||||
class Rand48 : public Rand
|
||||
{
|
||||
public:
|
||||
|
||||
Rand48( time_e )
|
||||
{
|
||||
seed(randomSeed());
|
||||
}
|
||||
|
||||
Rand48( uint s = 0x1234ABCD )
|
||||
{
|
||||
seed(s);
|
||||
}
|
||||
|
||||
|
||||
/** Set the given seed. */
|
||||
virtual void seed( uint s ) {
|
||||
vstate.x0 = 0x330E;
|
||||
vstate.x1 = uint16(s & 0xFFFF);
|
||||
vstate.x2 = uint16((s >> 16) & 0xFFFF);
|
||||
}
|
||||
|
||||
/** Get a random number. */
|
||||
virtual uint get() {
|
||||
|
||||
advance();
|
||||
|
||||
uint x1 = vstate.x1;
|
||||
uint x2 = vstate.x2;
|
||||
return (x2 << 16) + x1;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void advance()
|
||||
{
|
||||
/* work with unsigned long ints throughout to get correct integer
|
||||
promotions of any unsigned short ints */
|
||||
const uint32 x0 = vstate.x0;
|
||||
const uint32 x1 = vstate.x1;
|
||||
const uint32 x2 = vstate.x2;
|
||||
|
||||
uint32 a;
|
||||
a = a0 * x0 + c0;
|
||||
|
||||
vstate.x0 = uint16(a & 0xFFFF);
|
||||
a >>= 16;
|
||||
|
||||
/* although the next line may overflow we only need the top 16 bits
|
||||
in the following stage, so it does not matter */
|
||||
|
||||
a += a0 * x1 + a1 * x0;
|
||||
vstate.x1 = uint16(a & 0xFFFF);
|
||||
|
||||
a >>= 16;
|
||||
a += a0 * x2 + a1 * x1 + a2 * x0;
|
||||
vstate.x2 = uint16(a & 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
NVMATH_API static const uint16 a0, a1, a2, c0;
|
||||
|
||||
struct rand48_state_t {
|
||||
uint16 x0, x1, x2;
|
||||
} vstate;
|
||||
|
||||
};
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_MATH_RANDOM_H
|
Reference in New Issue
Block a user