Triangular noise
Eduard Kas
Does anybody know a way to create noise based on the triangular distribution, in a similar way as enoise and gnoise are used to generate the uniform distribution and the normal distribution, respectively? I have managed to calculate the probability density function for the triangular distribution, using two separate functions (one function for the range up to and including the mode and another function for the range beyond the mode) but do not know how to proceed from that point onwards. Any help would be highly welcome.
Eduard
The standard approach for generating noise from any distribution function is called the "Rejection" method. See, for example:
http://en.wikipedia.org/wiki/Rejection_sampling
I hope this helps,
A.G.
WaveMetrics, Inc.
November 9, 2009 at 02:38 pm - Permalink
I once had a similar problem. I have written a function that may be what you're looking for. The function returns a number in the intervall [-1,1] whereas p(-1)=p(1)=0 and the probability is linear in both intervalls [-1,0] and [0,1].
variable V_triangle
do
V_triangle=enoise(1)
while(abs(V_triangle)+enoise(0.5)+0.5 > 1)
return V_triangle
end
I think you can easily adjust the function to your needs.
November 10, 2009 at 06:02 am - Permalink
A.G., can the rejection method also be used when we try to generate noise from a triangular distribution that is characterised by two instead of one function? (For an asymmetrical triangular distribution with a lower scale of 10, an upper scale of 50, and a mode of 40, I have calculated the probability density functions (x-10)/600 and (50-x)/200).
And what distribution can best be used to sample from? Is that one uniform distribution or the combination of two uniform distributions, such as U (0,50) for the width and U (0,0.06) for the height of a rectangle that envelopes the triangular distribution.
Andreas, the function which you wrote is also helpful. What I get from it is that you are in fact drawing from a symmetrical triangular distribution with a zero mode and lower and upper scale parameters of -1 and +1. I am thinking about ways in which the function might be extended so that it can also be used for asymmetrical triangular distributions, but suggestions are of course always welcome.
Eduard
November 10, 2009 at 02:39 pm - Permalink
I have modified the function a bit.
variable lowerScale,upperScale,mode
variable V_triangle
variable scale=(upperScale-lowerScale)/2
variable scaleShift=lowerScale+scale
variable slope1=1/(mode-lowerScale)
variable slope2=1/(mode-upperScale)
variable rejectionVar,whileVar
do
V_triangle=enoise(scale)+scaleShift // range: [lowerScale,upperScale]
rejectionVar=enoise(0.5)+0.5 // range: [0,1]
// test, if V_triangle lies between lowerScale and mode or mode and upperScale,
// for the former case calculate slope of the line trough points (V_triangle,rejectionVar) and (lowerScale,0)
// and reject V_triangle if this slope is greater than slope1 -> whileVar=1
// for the latter case calculate slope of the line trough points (V_triangle,rejectionVar) and (upperScale,0)
// and reject V_triangle if this slope is less than slope2 -> whileVar=1
whileVar= V_triangle<mode ? (rejectionVar/(V_triangle-lowerScale)>slope1) : (rejectionVar/(V_triangle-upperScale)<slope2)
while(whileVar)
return V_triangle
end
The funtion test if a point defined by two random values x and y lies inside of the triangle or outside. The triangle is defined in an x/y coordinate system by three points (lowerScale,0), (mode,1) and (upperScale,0). For the former case accept x as a valid sampling value, for the latter case reject it.
November 11, 2009 at 04:47 am - Permalink
Thank you very much for the code. You contributed much more than I could have hoped for and the function delivers what I am looking for. I have one final question if I may. Do you know a way to transfer the outcome of the function (V_triangle) to a wave, so that I can collect for example 100 accepted sample values? So far the only way I see is to repeat the command Print assymTriangle(10,50,40) or an equivalent command a 100 times.
Thanks again for any reply.
Eduard
November 11, 2009 at 12:13 pm - Permalink
You can even create a histogram to illustrate the sampling:
Histogram/B={10,1,40} W_triangularNoise,W_triangularNoise_Hist;DelayUpdate
Display W_triangularNoise_Hist
November 12, 2009 at 01:28 am - Permalink
Eduard
November 12, 2009 at 01:48 pm - Permalink