386 lines
11 KiB
C++
386 lines
11 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "LearningArray.h"
|
|
|
|
#include "Math/Vector.h"
|
|
#include "Math/Quat.h"
|
|
|
|
namespace UE::Learning
|
|
{
|
|
struct FFrameSet;
|
|
struct FFrameRangeSet;
|
|
}
|
|
|
|
/**
|
|
* This is a simple hashing-based pseudo-random-number-generator
|
|
* that separates out the generation of random numbers from the
|
|
* mutation of the state. This is important for performance when
|
|
* generating a lot of random numbers, and with ispc this
|
|
* implementation can outperform FRandomStream by up to 100x while
|
|
* producing higher quality randomness.
|
|
*
|
|
* The basic way it works is that when generating multiple random
|
|
* numbers, rather than generating them one after the other each
|
|
* time mutating the state, you instead seed the random number
|
|
* generator individually for each number you want by xoring the
|
|
* state with another random number of your choice:
|
|
*
|
|
* float R0 = UE::Learning::Random::Float(State ^ 0x6591b5b6);
|
|
* float R1 = UE::Learning::Random::Float(State ^ 0x88f6747a);
|
|
*
|
|
* Once you're done generating numbers you can then mutate the state:
|
|
*
|
|
* State = UE::Learning::Random::Int(State ^ 0xec664ea3);
|
|
*
|
|
* Then, if you want to generate a large array of random numbers,
|
|
* each number can be generated independently using the index of
|
|
* the array to get the individual seed:
|
|
*
|
|
* for (int32 Idx = 0; Idx < Num; Idx++)
|
|
* {
|
|
* const uint32 Seed = UE::Learning::Random::Int(Idx ^ 0x56df2e17);
|
|
*
|
|
* Item[Idx] = UE::Learning::Random::Float(State ^ Seed);
|
|
* }
|
|
*
|
|
* State = UE::Learning::Random::Int(State ^ 0x017f54f9);
|
|
*
|
|
* As each number no longer needs to wait on the previous number
|
|
* to be generated and the state mutated, we can port this style
|
|
* of generation effectively to ispc and use a vectorized SIMD
|
|
* version to make it extremely fast.
|
|
*/
|
|
|
|
namespace UE::Learning::Random
|
|
{
|
|
/////////////////////////////////////////////////////////
|
|
//
|
|
// These functions generate random values without mutating the state
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
|
|
LEARNING_API uint32 Int(const uint32 State);
|
|
|
|
LEARNING_API float Float(const uint32 State);
|
|
|
|
LEARNING_API int32 IntInRange(const uint32 State, const int32 Min, const int32 Max);
|
|
|
|
LEARNING_API float Uniform(
|
|
const uint32 State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f);
|
|
|
|
LEARNING_API float Gaussian(
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f);
|
|
|
|
LEARNING_API FVector VectorGaussian(
|
|
const uint32 State,
|
|
const FVector Mean = FVector::ZeroVector,
|
|
const FVector Std = FVector::OneVector);
|
|
|
|
LEARNING_API float ClippedGaussian(
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f);
|
|
|
|
LEARNING_API FVector PlanarUniform(
|
|
const uint32 State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector PlanarGaussian(
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector PlanarClippedGaussian(
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector PlanarDirection(
|
|
const uint32 State,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FQuat Rotation(const uint32 Input);
|
|
|
|
LEARNING_API void IntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
const uint32 State);
|
|
|
|
LEARNING_API void IntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
const uint32 State,
|
|
const FIndexSet Indices);
|
|
|
|
LEARNING_API void FloatArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State);
|
|
|
|
LEARNING_API void UniformArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f);
|
|
|
|
LEARNING_API void GaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f);
|
|
|
|
LEARNING_API void ClippedGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f);
|
|
|
|
LEARNING_API void PlanarClippedGaussianArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
const uint32 State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API void PlanarDirectionArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
const uint32 State,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API void DistributionIndependantNormal(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const float Scale);
|
|
|
|
LEARNING_API void DistributionIndependantNormalMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const TLearningArrayView<1, const float> MaskedValues,
|
|
const float Scale);
|
|
|
|
LEARNING_API void DistributionMultinoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale);
|
|
|
|
LEARNING_API void DistributionMultinoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale);
|
|
|
|
LEARNING_API void DistributionBernoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale);
|
|
|
|
LEARNING_API void DistributionBernoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale);
|
|
|
|
LEARNING_API void FrameInFrameSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutFrameIdx,
|
|
const FFrameSet& FrameSet,
|
|
const uint32 State);
|
|
|
|
LEARNING_API void FrameInFrameRangeSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutRangeIdx,
|
|
int32& OutRangeFrame,
|
|
const FFrameRangeSet& FrameRangeSet,
|
|
const uint32 State);
|
|
|
|
/////////////////////////////////////////////////////////
|
|
//
|
|
// Here we provide a more normal interface which updates
|
|
// the state in-place each time a new value is generated
|
|
//
|
|
/////////////////////////////////////////////////////////
|
|
|
|
LEARNING_API uint32 SampleInt(uint32& State);
|
|
|
|
LEARNING_API float SampleFloat(uint32& State);
|
|
|
|
LEARNING_API int32 SampleIntInRange(uint32& State, const int32 Min, const int32 Max);
|
|
|
|
LEARNING_API float SampleUniform(
|
|
uint32& State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f);
|
|
|
|
LEARNING_API float SampleGaussian(
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f);
|
|
|
|
LEARNING_API FVector SampleVectorGaussian(
|
|
uint32& State,
|
|
const FVector Mean = FVector::ZeroVector,
|
|
const FVector Std = FVector::OneVector);
|
|
|
|
LEARNING_API float SampleClippedGaussian(
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f);
|
|
|
|
LEARNING_API FVector SamplePlanarUniform(
|
|
uint32& State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector SamplePlanarGaussian(
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector SamplePlanarClippedGaussian(
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FVector SamplePlanarDirection(
|
|
uint32& State,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API FQuat SampleRotation(uint32& State);
|
|
|
|
LEARNING_API void SampleIntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
uint32& State);
|
|
|
|
LEARNING_API void SampleIntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
uint32& State,
|
|
const FIndexSet Indices);
|
|
|
|
LEARNING_API void SampleFloatArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State);
|
|
|
|
LEARNING_API void SampleUniformArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Min = 0.0f,
|
|
const float Max = 1.0f);
|
|
|
|
LEARNING_API void SampleGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f);
|
|
|
|
LEARNING_API void SampleClippedGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f);
|
|
|
|
LEARNING_API void SamplePlanarClippedGaussianArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
uint32& State,
|
|
const float Mean = 0.0f,
|
|
const float Std = 1.0f,
|
|
const float Clip = 10.0f,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API void SamplePlanarDirectionArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
uint32& State,
|
|
const FVector Axis0 = FVector::ForwardVector,
|
|
const FVector Axis1 = FVector::RightVector);
|
|
|
|
LEARNING_API void SampleDistributionIndependantNormal(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleDistributionIndependantNormalMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const TLearningArrayView<1, const float> MaskedValues,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleDistributionMultinoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleDistributionMultinoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleDistributionBernoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleDistributionBernoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale);
|
|
|
|
LEARNING_API void SampleFrameInFrameSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutFrameIdx,
|
|
uint32& State,
|
|
const FFrameSet& FrameSet);
|
|
|
|
LEARNING_API void SampleFrameInFrameRangeSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutRangeIdx,
|
|
int32& OutRangeFrame,
|
|
uint32& State,
|
|
const FFrameRangeSet& FrameRangeSet);
|
|
} |