HoloLens 2 Gait Training
The purpose of this project is to create gait training application.
Loading...
Searching...
No Matches
PinkNoise.cs
Go to the documentation of this file.
1using Microsoft.MixedReality.Toolkit.UI;
2using System;
3using System.Collections.Generic;
4using System.Linq;
5using System.Numerics;
6using UnityEngine;
7
12{
13 #region Private Variables
17 private float m_AlphaValue = 0.99f;
18
21 private int m_SampleSize2X = 5000;
22
24 private float m_SqrtOfTwo = 0.0f;
25
28 private List<double> m_GKSqrt;
29
30 #endregion
31
35 protected override void Awake()
36 {
37 base.Awake();
38 m_GKSqrt = new List<double>();
39 m_SqrtOfTwo = Mathf.Sqrt( 2.0f );
41 m_DistributionButton.GetComponent<Interactable>().IsEnabled = true;
42 }
43
48 protected override void PopulateVariablesWithDataFromUI()
49 {
50 base.PopulateVariablesWithDataFromUI();
52 m_SampleSize /= 2;
53 }
54
59 public override void GenerateNewDistribution()
60 {
61 base.GenerateNewDistribution();
63 }
64
69 public override void ApplyPattern()
70 {
72 bool noiseAppliedState = ( m_NoiseValueList.Count >= ( m_SampleSize2X - 2 ) ) ? true : false;
73 SetReadyMessage( noiseAppliedState, "Pink" );
74 }
75
79 protected override void CalculateNoise()
80 {
81 float value = 0.0f;
83
84 foreach( float unscaledSignal in m_StandardNoiseDistribution )
85 {
86 value = m_MeanPeriod + ( m_SDPeriod / m_NoiseSTD ) * unscaledSignal;
87 m_NoiseValueList.Add( value );
88 }
89 }
90
95 private void CalculateGKSQRT()
96 {
97
98 int basePinkNoiseArrLen = ( m_SampleSize2X - 2 );
99 List<double> gammak = new List<double>();
100
101 if( m_GKSqrt.Any() == true )
102 {
103 m_GKSqrt.Clear();
104 }
105
106 for( int i = 0; i < m_SampleSize; i++ )
107 {
108 double first = Math.Pow( ( Mathf.Abs( i - 1 ) ), ( 2 * m_AlphaValue ) );
109
110 double second = 2 * ( Math.Pow( i, ( 2 * m_AlphaValue ) ) );
111
112 double third = Math.Pow( ( i + 1 ), ( 2 * m_AlphaValue ) );
113
114 double result = ( first - second + third ) / 2.0;
115 gammak.Add( result * basePinkNoiseArrLen );
116 }
117
118 for( int i = ( m_SampleSize - 2 ); i > 0; i-- )
119 {
120 gammak.Add( gammak[i] );
121 }
122
123 Complex[] GammakComplex = new Complex[gammak.Count];
124
125 for( int i = 0; i < gammak.Count; i++ )
126 {
127 Complex gamComp = new Complex( ( gammak[i] / gammak.Count ), 0.0 );
128 GammakComplex[i] = gamComp;
129 }
130
131 gammak.Clear();
132
133 IDFTReal( ref GammakComplex );
134
135 }
136
140 protected override void CalculateBaseNoise()
141 {
142 if( m_StandardNoiseDistribution.Count > 0 )
143 {
145 }
146
147 List<float> basePinkNoise = new List<float>();
148 List<float> leftHalf = new List<float>();
149 List<float> rightHalf = new List<float>();
150
151 Complex[] basePinkNoiseComplexArr = new Complex[m_SampleSize2X - 2];
152
154
155 // Generate GaussianDistribution Random values and multiple each value with the multiplier ( mean + SD )
156 for( int i = 0; i < m_SampleSize2X; i++ )
157 {
158 basePinkNoise.Add( m_Multiplier * (float)m_GaussianDistribution.RandomGauss( (double)m_Mean, (double)m_NoiseSTD ) );
159
160 if( i < m_SampleSize )
161 {
162 leftHalf.Add( basePinkNoise[i] );
163 }
164 else
165 {
166 rightHalf.Add( basePinkNoise[i] );
167 }
168 }
169
170 basePinkNoise.Clear();
171
172 rightHalf[0] = 0;
173 leftHalf[0] = leftHalf[0] * m_SqrtOfTwo;
174
175 rightHalf[m_SampleSize - 1] = 0;
176 leftHalf[m_SampleSize - 1] = leftHalf[m_SampleSize - 1] * m_SqrtOfTwo;
177
178 for( int i = (m_SampleSize - 2); i > 0; i-- )
179 {
180 leftHalf.Add(leftHalf[i]);
181 rightHalf.Add(-rightHalf[i]);
182 }
183
184 for( int i = 0; i < rightHalf.Count; i++ )
185 {
186 Complex myComplex = new Complex( leftHalf[i], rightHalf[i] );
187 basePinkNoiseComplexArr[i] = myComplex;
188 }
189
190 leftHalf.Clear();
191 rightHalf.Clear();
192
193 bool noZeroFlag = true;
194
196
197 for( int i = 0; i < m_GKSqrt.Count; i++ )
198 {
199 if( Mathf.Approximately( (float)m_GKSqrt[i], 0.0f ) )
200 {
201 noZeroFlag = false;
202 break;
203 }
204 }
205
206 if( noZeroFlag == true )
207 {
208 int basePinkNoiseComplexArrLen = basePinkNoiseComplexArr.Length;
209
210 for( int i = 0; i < basePinkNoiseComplexArrLen; i++ )
211 {
212 m_GKSqrt[i] = Math.Sqrt( m_GKSqrt[i] );
213 basePinkNoiseComplexArr[i] = Complex.Multiply( basePinkNoiseComplexArr[i], m_GKSqrt[i] );
214 }
215
216 IDFT( ref basePinkNoiseComplexArr );
217
218 for( int i = 0; i < basePinkNoiseComplexArrLen; i++ )
219 {
220 double power = Math.Pow( ( m_SampleSize - 1 ), ( -0.5 ) );
221 Complex intermediateResult = Complex.Multiply( power, basePinkNoiseComplexArr[i] );
222 Complex result = Complex.Multiply( intermediateResult, 0.5 );
223 m_StandardNoiseDistribution.Add( (float)result.Real );
224 }
225
226 m_Title.text = "Distribution is Ready";
227 }
228 else
229 {
230 m_Title.text = "Distribution is NOT Ready";
231 }
232 }
233
239 private void IDFT( ref Complex[] X )
240 {
241 // Number of spectrum elements
242 int N = X.Length;
243 Complex[] x = new Complex[N];
244
245 for( int n = 0; n < N; n++ )
246 {
247 Complex sum = 0;
248
249 for( int k = 0; k < N; k++ )
250 {
251 sum += X[k] * Complex.Exp( Complex.ImaginaryOne * 2 * Math.PI * (k * n) / Convert.ToDouble(N) );
252 }
253
254 // As a result we expect only real values (if our calculations are correct imaginary values should be equal or close to zero)
255 x[n] = sum;
256 }
257
258 Array.Clear( X, 0, N );
259
260 for( int i = 0; i < N; i++ )
261 {
262 X[i] = x[i];
263 }
264 }
265
271 private void IDFTReal( ref Complex[] X )
272 {
273 int N = X.Length; // Number of spectrum elements
274
275 for( int n = 0; n < N; n++ )
276 {
277 Complex sum = 0;
278
279 for( int k = 0; k < N; k++ )
280 {
281 sum += X[k] * Complex.Exp( Complex.ImaginaryOne * 2 * Math.PI * (k * n) / Convert.ToDouble(N) );
282 }
283
284 // As a result we expect only real values (if our calculations are correct imaginary values should be equal or close to zero)
285 m_GKSqrt.Add( sum.Real );
286 }
287 }
288}
const float m_NoiseSTD
Hold the standard distribution.
float m_MeanPeriod
Hold the Mean Period Value.
void ConvertToZScore(ref List< float > basePinkNoiseList)
This converts Z values to Z Score values. May get off a small amount due to round error.
List< float > m_StandardNoiseDistribution
A List to hold Normal(Gaussian) distribution.
int m_SampleSize
Defines how many samples we want.
float m_SDPeriod
Hold the standard distribution period.
List< float > m_NoiseValueList
This list stores the calculated colored noise values.
float m_Multiplier
Used this as a multiplier to calculate pink noise.
const float m_Mean
Hold the Mean value.
void SetReadyMessage(bool flag, string lbl)
Indicate noise is successgully applied or not.
GaussianDistribution m_GaussianDistribution
Reference to GaussianDistribution script.
GameObject m_DistributionButton
double RandomGauss(double mu=0, double sigma=1)
Obtains normally (Gaussian) distrubuted random numbers, using the Box-Muller transformation....
override void ApplyPattern()
Calculate the noise according to the user input. Mapped to NoiseDataPanel ApplyPattern button.
Definition: PinkNoise.cs:69
void IDFTReal(ref Complex[] X)
Calculates inverse Discrete Fourier Transform of given spectrum X
Definition: PinkNoise.cs:271
override void GenerateNewDistribution()
Generate a new normal(Gaussian) distribution Mapped to NoiseDataPanel NewDistribution button.
Definition: PinkNoise.cs:59
void CalculateGKSQRT()
This value is used to calculate base pink noise TODO -> We can parellize this in future.
Definition: PinkNoise.cs:95
override void Awake()
Definition: PinkNoise.cs:35
float m_AlphaValue
For pink noise 0.99 For white noise 0.5 In future, we might need to add different values.
Definition: PinkNoise.cs:17
override void CalculateNoise()
Scale the base pink noise.
Definition: PinkNoise.cs:79
override void CalculateBaseNoise()
Calculate the base pink noise value.
Definition: PinkNoise.cs:140
List< double > m_GKSqrt
A list to hold GKSqrt values. This is just an intermidiate value use to calculate base Pink noise.
Definition: PinkNoise.cs:28
int m_SampleSize2X
2 * sample size. We calculate 2X with X sample size.
Definition: PinkNoise.cs:21
void IDFT(ref Complex[] X)
Calculates inverse Discrete Fourier Transform of given spectrum X
Definition: PinkNoise.cs:239
float m_SqrtOfTwo
Used this to calculate pink noise.
Definition: PinkNoise.cs:24
override void PopulateVariablesWithDataFromUI()
Populate data variables used to alter noise. The data are gained through UI lables which are set by t...
Definition: PinkNoise.cs:48