Files
UnrealEngine/Engine/Plugins/Experimental/LearningAgents/Source/Learning/Public/LearningRandom.h
2025-05-18 13:04:45 +08:00

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);
}