907 lines
21 KiB
C++
907 lines
21 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LearningRandom.h"
|
|
|
|
#include "LearningFrameSet.h"
|
|
#include "LearningFrameRangeSet.h"
|
|
|
|
#if UE_LEARNING_ISPC
|
|
#include "Learning.ispc.generated.h"
|
|
#endif
|
|
|
|
namespace UE::Learning::Random
|
|
{
|
|
static inline float UniformToGaussian(const float R1, const float R2)
|
|
{
|
|
return FMath::Sqrt(-2.0f * FMath::Loge(FMath::Max(R1, UE_SMALL_NUMBER))) * FMath::Cos(R2 * UE_TWO_PI);
|
|
}
|
|
|
|
static inline float Sigmoid(const float X)
|
|
{
|
|
return 1.0f / (1.0f + FMath::Exp(-X));
|
|
}
|
|
|
|
uint32 Int(const uint32 State)
|
|
{
|
|
// Here we use a simple xor and shift based
|
|
// hashing algorithm which is appropriate for
|
|
// vectorization using ISPC
|
|
uint32 X = State ^ 0xb74eaecf;
|
|
X = ((X >> 16) ^ X) * 0x45d9f3b;
|
|
X = ((X >> 16) ^ X) * 0x45d9f3b;
|
|
return (X >> 16) ^ X;
|
|
}
|
|
|
|
float Float(const uint32 State)
|
|
{
|
|
// Same approach as used in FRandomStream
|
|
float Output;
|
|
*((uint32*)(&Output)) = 0x3F800000U | (Int(State ^ 0x1c89a74a) >> 9);
|
|
return Output - 1.0f;
|
|
}
|
|
|
|
int32 IntInRange(const uint32 State, const int32 Min, const int32 Max)
|
|
{
|
|
const int32 Range = (Max - Min) + 1;
|
|
return Min + ((Range > 0) ? FMath::TruncToInt(Float(State ^ 0x7d3b208a) * (float)(Range)) : 0);
|
|
}
|
|
|
|
float Uniform(
|
|
const uint32 State,
|
|
const float Min,
|
|
const float Max)
|
|
{
|
|
return (Max - Min) * Float(State ^ 0x72404541) + Min;
|
|
}
|
|
|
|
float Gaussian(
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std)
|
|
{
|
|
return Std * UniformToGaussian(
|
|
Float(State ^ 0x4855e88f),
|
|
Float(State ^ 0x0eedb850)) + Mean;
|
|
}
|
|
|
|
FVector VectorGaussian(
|
|
const uint32 State,
|
|
const FVector Mean,
|
|
const FVector Std)
|
|
{
|
|
return FVector(
|
|
Gaussian(State ^ 0x0c7eaaf3, Mean.X, Std.X),
|
|
Gaussian(State ^ 0x109be32d, Mean.Y, Std.Y),
|
|
Gaussian(State ^ 0xed839d93, Mean.Z, Std.Z));
|
|
}
|
|
|
|
float ClippedGaussian(
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip)
|
|
{
|
|
return FMath::Clamp(Gaussian(State ^ 0xf3ce904a, Mean, Std), -Std * Clip, Std * Clip);
|
|
}
|
|
|
|
FVector PlanarUniform(
|
|
const uint32 State,
|
|
const float Min,
|
|
const float Max,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
return
|
|
Uniform(Int(State ^ 0x0fd71b1d), Min, Max) * Axis0 +
|
|
Uniform(Int(State ^ 0x0a25cffa), Min, Max) * Axis1;
|
|
}
|
|
|
|
FVector PlanarGaussian(
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
return
|
|
Gaussian(Int(State ^ 0x371f49fd), Mean, Std) * Axis0 +
|
|
Gaussian(Int(State ^ 0xcf35268a), Mean, Std) * Axis1;
|
|
}
|
|
|
|
FVector PlanarClippedGaussian(
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
return
|
|
ClippedGaussian(Int(State ^ 0xa29f129d), Mean, Std, Clip) * Axis0 +
|
|
ClippedGaussian(Int(State ^ 0x8facd15b), Mean, Std, Clip) * Axis1;
|
|
}
|
|
|
|
FVector PlanarDirection(
|
|
const uint32 State,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
return PlanarGaussian(State ^ 0x46b8aa96, 0.0f, 1.0f, Axis0, Axis1).GetSafeNormal(UE_SMALL_NUMBER, Axis0);
|
|
}
|
|
|
|
FQuat Rotation(const uint32 State)
|
|
{
|
|
FQuat Rotation = FQuat(
|
|
Gaussian(Int(State ^ 0x21ed962e)),
|
|
Gaussian(Int(State ^ 0xeac13a67)),
|
|
Gaussian(Int(State ^ 0xb6f2db89)),
|
|
Gaussian(Int(State ^ 0xc10cd5e4))).GetNormalized();
|
|
|
|
Rotation.EnforceShortestArcWith(FQuat::Identity);
|
|
return Rotation;
|
|
}
|
|
|
|
void IntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
const uint32 State)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::IntArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomIntArray(
|
|
Output.GetData(),
|
|
ElementNum,
|
|
State);
|
|
#else
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Int(State ^ 0xbed25b30 ^ Int(ElementIdx ^ 0xb521a8d9));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LEARNING_API void IntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
const uint32 State,
|
|
const FIndexSet Indices)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::IntArray);
|
|
|
|
if (Indices.IsSlice() && Indices.Num() > 4)
|
|
{
|
|
IntArray(
|
|
Output.Slice(Indices.GetSliceStart(), Indices.GetSliceNum()),
|
|
State);
|
|
}
|
|
else
|
|
{
|
|
for (const int32 ElementIdx : Indices)
|
|
{
|
|
Output[ElementIdx] = Int(State ^ 0xbed25b30 ^ Int(ElementIdx ^ 0xb521a8d9));
|
|
}
|
|
}
|
|
}
|
|
|
|
void FloatArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::FloatArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomFloatArray(
|
|
Output.GetData(),
|
|
ElementNum,
|
|
State);
|
|
#else
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Float(State ^ 0xf955fac7 ^ Int(ElementIdx ^ 0xcd989d6f));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void UniformArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Min,
|
|
const float Max)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::UniformArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomUniformArray(
|
|
Output.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Min,
|
|
Max);
|
|
#else
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Uniform(State ^ 0x5f15554c ^ Int(ElementIdx ^ 0x242735e0), Min, Max);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void GaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::GaussianArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomGaussianArray(
|
|
Output.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Mean,
|
|
Std);
|
|
#else
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Gaussian(State ^ 0x7b5d5f62 ^ Int(ElementIdx ^ 0x546ab965), Mean, Std);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ClippedGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::ClippedGaussianArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = ClippedGaussian(State ^ 0x11a760f7 ^ Int(ElementIdx ^ 0x1dfc9b77), Mean, Std, Clip);
|
|
}
|
|
}
|
|
|
|
void PlanarClippedGaussianArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
const uint32 State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::PlanarClippedGaussianArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = PlanarClippedGaussian(State ^ 0x5eeac916 ^ Int(ElementIdx ^ 0x8527618d), Mean, Std, Clip, Axis0, Axis1);
|
|
}
|
|
}
|
|
|
|
void PlanarDirectionArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
const uint32 State,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::PlanarDirectionArray);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = PlanarDirection(State ^ 0xd80bd375 ^ Int(ElementIdx ^ 0x50d8c207), Axis0, Axis1);
|
|
}
|
|
}
|
|
|
|
void DistributionIndependantNormal(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const float Scale)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionIndependantNormal);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomDistributionIndependantNormal(
|
|
Output.GetData(),
|
|
Mean.GetData(),
|
|
LogStd.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Scale);
|
|
#else
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Mean[ElementIdx];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Gaussian(State ^ 0x7db0e4e9 ^ Int(ElementIdx ^ 0xf4976a00), Mean[ElementIdx], Scale * FMath::Exp(FMath::Min(LogStd[ElementIdx], 10.0f)));
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionIndependantNormalMasked);
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomDistributionIndependantNormalMasked(
|
|
Output.GetData(),
|
|
Mean.GetData(),
|
|
LogStd.GetData(),
|
|
Masked.GetData(),
|
|
MaskedValues.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Scale);
|
|
#else
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Masked[ElementIdx] ? MaskedValues[ElementIdx] : Mean[ElementIdx];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Masked[ElementIdx] ? MaskedValues[ElementIdx] : Gaussian(State ^ 0x0a006c6b ^ Int(ElementIdx ^ 0x6fe1d121), Mean[ElementIdx], Scale * FMath::Exp(FMath::Min(LogStd[ElementIdx], 10.0f)));
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void DistributionMultinoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionMultinoulli);
|
|
|
|
check(Output.Num() == Logits.Num());
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
if (ElementNum == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float MaxValue = -UE_MAX_FLT;
|
|
uint32 MaxIdx = INDEX_NONE;
|
|
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
if (Logits[ElementIdx] > MaxValue)
|
|
{
|
|
MaxValue = Logits[ElementIdx];
|
|
MaxIdx = ElementIdx;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
const float ElementValue = Logits[ElementIdx] / Scale - FMath::Loge(-FMath::Loge(Uniform(State ^ 0x7a156b37 ^ Int(ElementIdx ^ 0x0c71bebb))));
|
|
|
|
if (ElementValue > MaxValue)
|
|
{
|
|
MaxValue = ElementValue;
|
|
MaxIdx = ElementIdx;
|
|
}
|
|
}
|
|
}
|
|
|
|
check(MaxIdx != INDEX_NONE);
|
|
|
|
Array::Zero(Output);
|
|
Output[MaxIdx] = 1.0f;
|
|
}
|
|
|
|
void DistributionMultinoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionMultinoulliMasked);
|
|
|
|
check(Output.Num() == Logits.Num());
|
|
check(Logits.Num() == Masked.Num());
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
if (ElementNum == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float MaxValue = -UE_MAX_FLT;
|
|
uint32 MaxIdx = INDEX_NONE;
|
|
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
if (!Masked[ElementIdx] && Logits[ElementIdx] > MaxValue)
|
|
{
|
|
MaxValue = Logits[ElementIdx];
|
|
MaxIdx = ElementIdx;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
if (!Masked[ElementIdx])
|
|
{
|
|
const float ElementValue = Logits[ElementIdx] / Scale - FMath::Loge(-FMath::Loge(Uniform(State ^ 0x93575b09 ^ Int(ElementIdx ^ 0xa0c6ac79))));
|
|
|
|
if (ElementValue > MaxValue)
|
|
{
|
|
MaxValue = ElementValue;
|
|
MaxIdx = ElementIdx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
check(MaxIdx != INDEX_NONE);
|
|
|
|
Array::Zero(Output);
|
|
Output[MaxIdx] = 1.0f;
|
|
}
|
|
|
|
void DistributionBernoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionBernoulli);
|
|
|
|
check(Output.Num() == Logits.Num());
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomDistributionBernoulli(
|
|
Output.GetData(),
|
|
Logits.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Scale);
|
|
#else
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Logits[ElementIdx] > 0.0f ? 1.0f : 0.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = Sigmoid(Logits[ElementIdx] / Scale) > Uniform(State ^ 0xf4021a46 ^ Int(ElementIdx ^ 0x7a8cc64e)) ? 1.0f : 0.0f;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
void DistributionBernoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
const uint32 State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale)
|
|
{
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(Learning::Random::DistributionBernoulliMasked);
|
|
|
|
check(Output.Num() == Logits.Num());
|
|
check(Logits.Num() == Masked.Num());
|
|
|
|
const int32 ElementNum = Output.Num();
|
|
|
|
#if UE_LEARNING_ISPC
|
|
ispc::LearningRandomDistributionBernoulliMasked(
|
|
Output.GetData(),
|
|
Logits.GetData(),
|
|
Masked.GetData(),
|
|
ElementNum,
|
|
State,
|
|
Scale);
|
|
#else
|
|
if (Scale < UE_SMALL_NUMBER)
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = !Masked[ElementIdx] && Logits[ElementIdx] > 0.0f ? 1.0f : 0.0f;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 ElementIdx = 0; ElementIdx < ElementNum; ElementIdx++)
|
|
{
|
|
Output[ElementIdx] = !Masked[ElementIdx] && Sigmoid(Logits[ElementIdx] / Scale) > Uniform(State ^ 0x8c992b7f ^ Int(ElementIdx ^ 0x1953d0fc)) ? 1.0f : 0.0f;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void FrameInFrameSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutFrameIdx,
|
|
const FFrameSet& FrameSet,
|
|
const uint32 State)
|
|
{
|
|
const int32 TotalFrameNum = FrameSet.GetTotalFrameNum();
|
|
const int32 FrameOffset = IntInRange(0x26810f69 ^ State, 0, TotalFrameNum - 1);
|
|
const bool bFound = FrameSet.FindOffset(OutEntryIdx, OutFrameIdx, FrameOffset);
|
|
check(bFound);
|
|
}
|
|
|
|
void FrameInFrameRangeSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutRangeIdx,
|
|
int32& OutRangeFrame,
|
|
const FFrameRangeSet& FrameRangeSet,
|
|
const uint32 State)
|
|
{
|
|
const int32 TotalFrameNum = FrameRangeSet.GetTotalFrameNum();
|
|
const int32 FrameOffset = IntInRange(0x76ad14bb ^ State, 0, TotalFrameNum - 1);
|
|
const bool bFound = FrameRangeSet.FindOffset(OutEntryIdx, OutRangeIdx, OutRangeFrame, FrameOffset);
|
|
check(bFound);
|
|
}
|
|
|
|
////////////
|
|
|
|
uint32 SampleInt(uint32& State)
|
|
{
|
|
State = Int(State ^ 0xba3030e4);
|
|
return Int(State ^ 0xfdb4f6bf);
|
|
}
|
|
|
|
float SampleFloat(uint32& State)
|
|
{
|
|
State = Int(State ^ 0x2b056265);
|
|
return Float(State ^ 0xd29c58ed);
|
|
}
|
|
|
|
int32 SampleIntInRange(uint32& State, const int32 Min, const int32 Max)
|
|
{
|
|
State = Int(State ^ 0xf732b4b4);
|
|
return IntInRange(State ^ 0x755e1fe4, Min, Max);
|
|
}
|
|
|
|
float SampleUniform(
|
|
uint32& State,
|
|
const float Min,
|
|
const float Max)
|
|
{
|
|
State = Int(State ^ 0x462b86af);
|
|
return Uniform(State ^ 0x0c9be5a2, Min, Max);
|
|
}
|
|
|
|
float SampleGaussian(
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std)
|
|
{
|
|
State = Int(State ^ 0xca0ae9bd);
|
|
return Gaussian(State ^ 0x5df36815, Mean, Std);
|
|
}
|
|
|
|
FVector SampleVectorGaussian(
|
|
uint32& State,
|
|
const FVector Mean,
|
|
const FVector Std)
|
|
{
|
|
State = Int(State ^ 0x9efa29b7);
|
|
return VectorGaussian(State ^ 0x57167b59, Mean, Std);
|
|
}
|
|
|
|
float SampleClippedGaussian(
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip)
|
|
{
|
|
State = Int(State ^ 0xcc10710e);
|
|
return ClippedGaussian(State ^ 0xcfc12df0, Mean, Std, Clip);
|
|
}
|
|
|
|
FVector SamplePlanarUniform(
|
|
uint32& State,
|
|
const float Min,
|
|
const float Max,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0x4d3d153f);
|
|
return PlanarUniform(State ^ 0x28b92167, Min, Max, Axis0, Axis1);
|
|
}
|
|
|
|
FVector SamplePlanarGaussian(
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0xafce90a5);
|
|
return PlanarGaussian(State ^ 0x8a6579c3, Mean, Std, Axis0, Axis1);
|
|
}
|
|
|
|
FVector SamplePlanarClippedGaussian(
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0xf4af224c);
|
|
return PlanarClippedGaussian(State ^ 0x45ccf24f, Mean, Std, Clip, Axis0, Axis1);
|
|
}
|
|
|
|
FVector SamplePlanarDirection(
|
|
uint32& State,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0xc763d831);
|
|
return PlanarDirection(State ^ 0x2898da60, Axis0);
|
|
}
|
|
|
|
FQuat SampleRotation(uint32& State)
|
|
{
|
|
State = Int(State ^ 0xa8a56b0c);
|
|
return Rotation(State ^ 0xeb4ff4d2);
|
|
}
|
|
|
|
void SampleIntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
uint32& State)
|
|
{
|
|
State = Int(State ^ 0xab9c9ee3);
|
|
IntArray(Output, State ^ 0x6adcdb41);
|
|
}
|
|
|
|
void SampleIntArray(
|
|
TLearningArrayView<1, uint32> Output,
|
|
uint32& State,
|
|
const FIndexSet Indices)
|
|
{
|
|
State = Int(State ^ 0xab9c9ee3);
|
|
IntArray(Output, State ^ 0x6adcdb41, Indices);
|
|
}
|
|
|
|
void SampleFloatArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State)
|
|
{
|
|
State = Int(State ^ 0x543e2434);
|
|
FloatArray(Output, State ^ 0x8a0b0503);
|
|
}
|
|
|
|
void SampleUniformArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Min,
|
|
const float Max)
|
|
{
|
|
State = Int(State ^ 0x8f086d42);
|
|
UniformArray(Output, State ^ 0x2f3ca619, Min, Max);
|
|
}
|
|
|
|
void SampleGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std)
|
|
{
|
|
State = Int(State ^ 0x82a69d18);
|
|
GaussianArray(Output, State ^ 0xf2381309, Mean, Std);
|
|
}
|
|
|
|
void SampleClippedGaussianArray(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip)
|
|
{
|
|
State = Int(State ^ 0xb96fa3cf);
|
|
ClippedGaussianArray(Output, State ^ 0xfc1bc4a9, Mean, Std, Clip);
|
|
}
|
|
|
|
void SamplePlanarClippedGaussianArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
uint32& State,
|
|
const float Mean,
|
|
const float Std,
|
|
const float Clip,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0xb538a8b5);
|
|
PlanarClippedGaussianArray(Output, State ^ 0x73a55e65, Mean, Std, Clip, Axis0, Axis1);
|
|
}
|
|
|
|
void SamplePlanarDirectionArray(
|
|
TLearningArrayView<1, FVector> Output,
|
|
uint32& State,
|
|
const FVector Axis0,
|
|
const FVector Axis1)
|
|
{
|
|
State = Int(State ^ 0x3219c5db);
|
|
PlanarDirectionArray(Output, State ^ 0x6bfd3e6a, Axis0, Axis1);
|
|
}
|
|
|
|
void SampleDistributionIndependantNormal(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Mean,
|
|
const TLearningArrayView<1, const float> LogStd,
|
|
const float Scale)
|
|
{
|
|
State = Int(State ^ 0x984c4d5f);
|
|
DistributionIndependantNormal(
|
|
Output,
|
|
State,
|
|
Mean,
|
|
LogStd,
|
|
Scale);
|
|
}
|
|
|
|
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)
|
|
{
|
|
State = Int(State ^ 0xc58f03a8);
|
|
DistributionIndependantNormalMasked(
|
|
Output,
|
|
State,
|
|
Mean,
|
|
LogStd,
|
|
Masked,
|
|
MaskedValues,
|
|
Scale);
|
|
}
|
|
|
|
void SampleDistributionMultinoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale)
|
|
{
|
|
State = Int(State ^ 0xc9261d09);
|
|
DistributionMultinoulli(
|
|
Output,
|
|
State,
|
|
Logits,
|
|
Scale);
|
|
}
|
|
|
|
void SampleDistributionMultinoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale)
|
|
{
|
|
State = Int(State ^ 0xb744ea38);
|
|
DistributionMultinoulliMasked(
|
|
Output,
|
|
State,
|
|
Logits,
|
|
Masked,
|
|
Scale);
|
|
}
|
|
|
|
void SampleDistributionBernoulli(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const float Scale)
|
|
{
|
|
State = Int(State ^ 0xfeba3d63);
|
|
DistributionBernoulli(
|
|
Output,
|
|
State,
|
|
Logits,
|
|
Scale);
|
|
}
|
|
|
|
void SampleDistributionBernoulliMasked(
|
|
TLearningArrayView<1, float> Output,
|
|
uint32& State,
|
|
const TLearningArrayView<1, const float> Logits,
|
|
const TLearningArrayView<1, const bool> Masked,
|
|
const float Scale)
|
|
{
|
|
State = Int(State ^ 0x21610d4a);
|
|
DistributionBernoulliMasked(
|
|
Output,
|
|
State,
|
|
Logits,
|
|
Masked,
|
|
Scale);
|
|
}
|
|
|
|
|
|
void SampleFrameInFrameSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutFrameIdx,
|
|
uint32& State,
|
|
const FFrameSet& FrameSet)
|
|
{
|
|
State = Int(State ^ 0xfbfed01a);
|
|
FrameInFrameSet(
|
|
OutEntryIdx,
|
|
OutFrameIdx,
|
|
FrameSet,
|
|
State ^ 0xef6c39f5);
|
|
}
|
|
|
|
void SampleFrameInFrameRangeSet(
|
|
int32& OutEntryIdx,
|
|
int32& OutRangeIdx,
|
|
int32& OutRangeFrame,
|
|
uint32& State,
|
|
const FFrameRangeSet& FrameRangeSet)
|
|
{
|
|
State = Int(State ^ 0x54f54418);
|
|
FrameInFrameRangeSet(
|
|
OutEntryIdx,
|
|
OutRangeIdx,
|
|
OutRangeFrame,
|
|
FrameRangeSet,
|
|
State ^ 0xec5ae556);
|
|
}
|
|
} |