8 static const float PI=3.1415926535897932384626433832795f;
19 return (UnitCirclePoint.y>=0.0f)?(-UnitCirclePoint.x):(2.0f+UnitCirclePoint.x);
22 return (UnitCirclePoint._m01_m11>=0.0f)?(-UnitCirclePoint._m00_m10):(2.0f+UnitCirclePoint._m00_m10);
25 return (UnitCirclePoint._m01_m11_m21>=0.0f)?(-UnitCirclePoint._m00_m10_m20):(2.0f+UnitCirclePoint._m00_m10_m20);
28 return (UnitCirclePoint._m01_m11_m21_m31>=0.0f)?(-UnitCirclePoint._m00_m10_m20_m30):(2.0f+UnitCirclePoint._m00_m10_m20_m30);
31 [unroll]
for(
int i=0;i!=5;++i){
32 pOutParameter[i]=((pUnitCirclePoint[i].y>=0.0f)?(-pUnitCirclePoint[i].x):(2.0f+pUnitCirclePoint[i].x));
44 return dot((pParameter.yz<pParameter[0])?pWeight.yz:float2(0.0f,0.0f),float2(1.0f,1.0f));
51 float3x2 MomentVector;
52 MomentVector[0]=float2(1.0f,0.0f);
53 sincos(2.0f*PI*Point,MomentVector[1].y,MomentVector[1].x);
54 MomentVector[2]=
Square(MomentVector[1]);
62 float3x2 MomentVector;
63 MomentVector[0]=float2(1.0f,0.0f);
64 MomentVector[1]=CirclePoint;
65 MomentVector[2]=
Square(MomentVector[1]);
77 float2 b1=pTrigonometricMoment[0];
78 float2 b2=pTrigonometricMoment[1];
89 float InvDenominator=1.0f/dot(pOutRoot._m21_m01_m11-pOutRoot._m11_m21_m01,pOutRoot._m00_m10_m20);
90 pOutWeight[0]= dot(float3(pOutRoot[1].y-b1.y,b1.y-pOutRoot[2].y,pOutRoot[2].y-pOutRoot[1].y),float3(pOutRoot[2].x,pOutRoot[1].x,b1.x))*InvDenominator;
91 pOutWeight[1]=-dot(float3(pOutRoot[0].y-b1.y,b1.y-pOutRoot[2].y,pOutRoot[2].y-pOutRoot[0].y),float3(pOutRoot[2].x,pOutRoot[0].x,b1.x))*InvDenominator;
92 pOutWeight[2]=1.0f-pOutWeight[0]-pOutWeight[1];
105 bool SwapRoots=(pAdditionalParameter.x>pAdditionalParameter.y);
108 pRoot[1]=(SwapRoots?pAdditionalRoot[1]:pAdditionalRoot[0]);
109 pRoot[2]=(SwapRoots?pAdditionalRoot[0]:pAdditionalRoot[1]);
110 pAdditionalParameter=SwapRoots?pAdditionalParameter.yx:pAdditionalParameter.xy;
114 (pAdditionalParameter.y<PrescribedParameter)?float4(pRoot[1],1.0f,1.0f):(
115 (pAdditionalParameter.x<PrescribedParameter)?float4(pRoot[0],0.0f,1.0f):
116 float4(0.0f,0.0f,0.0f,0.0f));
118 float2 b1=pTrigonometricMoment[0];
119 float Quotient=dot(float3(Switch.y-b1.y,b1.y-pRoot[2].y,pRoot[2].y-Switch.y),float3(pRoot[2].x,Switch.x,b1.x))
120 /dot(pRoot._m21_m01_m11-pRoot._m11_m21_m01,pRoot._m00_m10_m20);
121 return Switch[2]-Switch[3]*Quotient;
127 void GetExtremalWeightHelpers2(out float3x2 OutMomentEnd,out float3x2 OutInvertedMomentEnd,out float3x2 OutInvertedMomentOne,out float2 OutEndDotOne,out
float OutOneDotOne,float2 pTrigonometricMoment[2],
float IntervalEnd){
131 OutInvertedMomentEnd=
SolveToeplitzSystem(pTrigonometricMoment[0],pTrigonometricMoment[1],OutMomentEnd[1],OutMomentEnd[2]);
133 OutInvertedMomentOne=
SolveToeplitzSystem(pTrigonometricMoment[0],pTrigonometricMoment[1],float2(1.0f,0.0f),float2(1.0f,0.0f));
135 OutEndDotOne=
Conjugate(OutInvertedMomentEnd[0]+OutInvertedMomentEnd[1]+OutInvertedMomentEnd[2]);
136 OutOneDotOne=dot(OutInvertedMomentOne._m00_m10_m20,float3(1.0f,1.0f,1.0f));
146 float4x2
GetWeightMapCriticalPoints(float3x2 MomentEnd,float3x2 InvertedMomentEnd,float2 EndDotOne,
float OneDotOne,float2 pTrigonometricMoment[2],
float IntervalEnd){
148 float2 pCoefficient[5]={float2(0.0f,0.0f),float2(0.0f,0.0f),float2(0.0f,0.0f),float2(0.0f,0.0f),float2(0.0f,0.0f)};
150 float3x3 ToeplitzInverseReal,ToeplitzInverseImaginary;
151 GetToeplitzInverse(ToeplitzInverseReal,ToeplitzInverseImaginary,pTrigonometricMoment);
154 [unroll]
for(
int i=0;i!=3;++i){
155 [unroll]
for(
int j=0;j!=3;++j){
156 float2 InverseToeplitzEntry=float2(ToeplitzInverseReal[i][j],ToeplitzInverseImaginary[i][j]);
157 pCoefficient[2+j-i]+=(j-i)*InverseToeplitzEntry;
161 for(
int i=0;i!=5;++i){
162 pCoefficient[i]=
Multiply(pCoefficient[i],EndDotOne);
165 float3x2 InvertedMomentOne;
166 InvertedMomentOne._m00_m10_m20=mul(ToeplitzInverseReal,float3(1.0f,1.0f,1.0f));
167 InvertedMomentOne._m01_m11_m21=mul(ToeplitzInverseImaginary,float3(1.0f,1.0f,1.0f));
171 [unroll]
for(
int i=0;i!=3;++i){
172 [unroll]
for(
int j=0;j!=3;++j){
173 float2 EndTimesOne=
Multiply(InvertedMomentOne[i],
Conjugate(InvertedMomentEnd[j]));
174 pCoefficient[2+j-i]-=(j-i)*EndTimesOne;
179 float4x2 pCriticalPoint=
GetRoots(pCoefficient);
182 [unroll]
for(
int i=0;i!=4;++i){
183 pCriticalPoint[i]=normalize(pCriticalPoint[i]);
185 return pCriticalPoint;
199 bool SwapRootsOne=(pRootOneParameter[2]<pRootOneParameter[1]);
200 pRootOneParameter.yz=SwapRootsOne?pRootOneParameter.zy:pRootOneParameter.yz;
201 pWeightOne.yz=SwapRootsOne?pWeightOne.zy:pWeightOne.yz;
204 sincos(2.0f*PI*IntervalEnd,SegmentEnd.y,SegmentEnd.x);
209 if(IntervalEndParameter<pRootOneParameter[1]){
214 float3x2 MomentEnd,InvertedMomentEnd,InvertedMomentOne;
217 GetExtremalWeightHelpers2(MomentEnd,InvertedMomentEnd,InvertedMomentOne,EndDotOne,OneDotOne,pTrigonometricMoment,IntervalEnd);
222 if(IntervalEndParameter<pRootOneParameter[2]){
224 float4x2 pCriticalPoint=
GetWeightMapCriticalPoints(MomentEnd,InvertedMomentEnd,EndDotOne,OneDotOne,pTrigonometricMoment,IntervalEnd);
231 bool SwapRootsEnd=(pRootEndParameter[2]<pRootEndParameter[1]);
232 float MinFirstRootParameter=SwapRootsEnd?pRootEndParameter[2]:pRootEndParameter[1];
233 float MinFirstWeight=SwapRootsEnd?pWeightEnd[2]:pWeightEnd[1];
236 bool RootFound=
false;
238 [unroll]
for(
int i=0;i!=4;++i){
239 if(MinFirstRootParameter<=pCriticalPointParameter[i] && pCriticalPointParameter[i]<=pRootOneParameter[1]){
240 FirstRoot=pCriticalPoint[i];
248 return (MinFirstWeight>pWeightOne[1])?pWeightOne[0]:0.0f;
251 float3x2 MomentFirst;
252 MomentFirst[0]=float2(1.0f,0.0f);
253 MomentFirst[1]=FirstRoot;
254 MomentFirst[2]=
Square(FirstRoot);
255 float2 FirstDotEnd=
Dot(MomentFirst,InvertedMomentEnd);
256 float2 FirstDotOne=
Dot(MomentFirst,InvertedMomentOne);
259 return max(0.0f,min(pWeightOne[0],Weight));
264 float EndDotEnd=
Dot(MomentEnd,InvertedMomentEnd).x;
265 float Weight=(
Magnitude(EndDotOne)-EndDotEnd)/(dot(EndDotOne,EndDotOne)-OneDotOne*EndDotEnd);
267 return max(0.0f,min(pWeightOne[0],Weight));
279 float2 pModifiedMoment[2]={
280 (pTrigonometricMoment[0]-float2(WeightAtOne,0.0f))/(1.0f-WeightAtOne),
281 (pTrigonometricMoment[1]-float2(WeightAtOne,0.0f))/(1.0f-WeightAtOne)};
285 return saturate(CanonicalWeight*(1.0f-WeightAtOne));
float2 Conjugate(float2 Z)
void GetToeplitzInverse(out float3x3 OutToeplitzInverseReal, out float3x3 OutToeplitzInverseImaginary, float2 pTrigonometricMoment[2])
float GetMinimizingWeightAtOne(float2 pTrigonometricMoment[2], float IntervalEnd)
float2 Divide(float2 Numerator, float2 Denominator)
void Get2TMSMCanonicalDistribution(out float3 pOutWeight, out float3x2 pOutRoot, float2 pTrigonometricMoment[2], float PrescribedRoot)
float2 Dot(float3x2 LHS, float3x2 RHS)
float2 Multiply(float2 LHS, float2 RHS)
float3x2 SolveToeplitzSystem(float2 TrigonometricMoment1, float2 TrigonometricMoment2, float2 RHS1, float2 RHS2)
float GetWeightExclusive(float3 pWeight, float3x2 pRoot)
float3x2 MomentGeneratingFunction2(float Point)
float CircleToParameter(float2 UnitCirclePoint)
float Magnitude(float2 Z)
float Get2TMSMMinimalWeight(float2 pTrigonometricMoment[2], float IntervalEnd)
float4x2 GetWeightMapCriticalPoints(float3x2 MomentEnd, float3x2 InvertedMomentEnd, float2 EndDotOne, float OneDotOne, float2 pTrigonometricMoment[2], float IntervalEnd)
void GetExtremalWeightHelpers2(out float3x2 OutMomentEnd, out float3x2 OutInvertedMomentEnd, out float3x2 OutInvertedMomentOne, out float2 OutEndDotOne, out float OutOneDotOne, float2 pTrigonometricMoment[2], float IntervalEnd)
float Get2TMSMCanonicalWeightExclusive(float2 pTrigonometricMoment[2], float PrescribedRoot)