I am trying to learn Bayes Network and I have a problem that I would like some clarification on.
Given the table
CPT
What would the p(Aggression=high|Anger=Partly,Hostility=Yes) be? My answer is 0.5.
My thought process is that Anger and Hostility are dependent, so according to the info given, the probability of partly anger and yes hostility is 0.5.
Aggression is independent of the two, so it would just be P(aggression)*0.5= 0.5.
Would this be a correct assumption?
Short answer: My value for p(Aggression=high|Anger=Partly,Hostility=Yes) is 100%.
If Aggression were indepent of Hostility and Anger, it would not matter what evidence you have.
So p(Aggression) was the maximum of the 3 values p(Agg=low), p(Agg=high), p(Agg=veryhigh).
However the 3*9 table implies p(Agg) = p(Hos, Ang) and it is not independent.
I have tried to model your CPT (upper table) with the free software "Samiam".
I doing so I've entered the values from the CPT for the Aggression node in Samiam.
For the priors: I am assuming someone who is in Anger 5% of the time, partly angry 15% of the time, and 80% not angry; and hostile 10% of the time, partly hostile 30% or not hostile 60% of the time.
See screenshots:
Table values for Aggression Node:
With Observed Evidence - Value of Aggression=High goes up to 100%:
I've also attached the samiam file:
net
{
propagationenginegenerator1791944048146838126L = "edu.ucla.belief.approx.BeliefPropagationSettings#20ece334";
recoveryenginegenerator6944530267470113528l = "edu.ucla.util.SettingsImpl#49f77e1b";
node_size = (130.0 55.0);
huginenginegenerator3061656038650325130L = "edu.ucla.belief.inference.JoinTreeSettings#71a1d859";
}
node Aggression
{
states = ("Low" "High" "VeryHigh" );
position = (268 -263);
diagnosistype = "AUXILIARY";
DSLxSUBMODEL = "Root Submodel";
ismapvariable = "false";
ID = "variable2";
label = "Aggression";
DSLxEXTRA_DEFINITIONxDIAGNOSIS_TYPE = "AUXILIARY";
excludepolicy = "include whole CPT";
}
node Anger
{
states = ("no" "partly" "yes" );
position = (118 -48);
diagnosistype = "AUXILIARY";
DSLxSUBMODEL = "Root Submodel";
ismapvariable = "false";
ID = "variable0";
label = "Anger";
DSLxEXTRA_DEFINITIONxDIAGNOSIS_TYPE = "AUXILIARY";
excludepolicy = "include whole CPT";
}
node Hostility
{
states = ("No" "Partly" "Yes" );
position = (351 -46);
diagnosistype = "AUXILIARY";
DSLxSUBMODEL = "Root Submodel";
ismapvariable = "false";
ID = "variable1";
label = "Hostility";
DSLxEXTRA_DEFINITIONxDIAGNOSIS_TYPE = "AUXILIARY";
excludepolicy = "include whole CPT";
}
potential ( Aggression | Anger Hostility )
{
data = ((( 1.0 0.0 0.0 )
( 0.5 0.5 0.0 )
( 0.5 0.0 0.5 ))
(( 0.5 0.5 0.0 )
( 0.5 0.5 0.0 )
( 0.0 1.0 0.0 ))
(( 0.5 0.0 0.5 )
( 0.0 0.5 0.5 )
( 0.0 0.0 1.0 )));
}
potential ( Anger | )
{
data = ( 0.8 0.15 0.05 );
}
potential ( Hostility | )
{
data = ( 0.6 0.3 0.1 );
}
Related
For educational purposes I want to implement the 1-dimensional Perlin Noise algorithm in Kotlin. I familiarized myself with the algorithm here and here.
I think I understood the basic concept, however my implementation can return values greater than 1. I expect the result of the call perlin(x) to be in the range 0 to 1. I can't figure out where I'm mistaken, so maybe someone can point me in the right direction. For simplicity I use simple linear interpolation instead of smoothstep or other advanced techniques for now.
class PerlinNoiseGenerator(seed: Int, private val boundary: Int = 10) {
private var random = Random(seed)
private val noise = DoubleArray(boundary) {
random.nextDouble()
}
fun perlin(x: Double, persistence: Double = 0.5, numberOfOctaves: Int = 8): Double {
var total = 0.0
for (i in 0 until numberOfOctaves) {
val amplitude = persistence.pow(i) // height of the crests
val frequency = 2.0.pow(i) // number of crests per unit distance
val octave = amplitude * noise(x * frequency)
total += octave
}
return total
}
private fun noise(t: Double): Double {
val x = t.toInt()
val x0 = x % boundary
val x1 = if (x0 == boundary - 1) 0 else x0 + 1
val between = t - x
val y0 = noise[x0]
val y1 = noise[x1]
return lerp(y0, y1, between)
}
private fun lerp(a: Double, b: Double, alpha: Double): Double {
return a + alpha * (b - a)
}
}
For example if you would use these random generated noises
private val noise = doubleArrayOf(0.77, 0.02, 0.63, 0.74, 0.49, 0.22, 0.19, 0.76, 0.16, 0.08)
You would end up with an image like this:
where the green line is the calculated Perlin Noise of 8 octaves with a persistence of 0.5. As you can see the sum of all octaves at x=0 for example is greater than 1. (The blue line being the first octave noise(x) and the orange one being the second octave 0.5 * noise(2x)).
What am I doing wrong?
Thanks in advance.
Note: I'm aware that the Simplex Noise algorithm is the successor of Perlin Noise, however for educational purposes I want to implement Perlin Noise first. I'm also aware that my boundary should be set to something in the magnitude of 256 but for simplicity I just used 10 for now.
I've been digging around and found this article which introduces a value to normalize the results returned by Perlin(x). Essentially the amplitudes are summed up and the total is divided by this value. This seems to make sense since we could have "bad luck" and have a y-value of 1.0 in the first octave, followed by a 0.5 in the next, etc. So dividing by the sum of the amplitudes (1.5 in this case with 2 octaves) seems reasonable to keep the values in the range 0 - 1.
However, I'm unsure if this is the preferred way since none of the other resource uses this technique.
The modified code would look like this:
fun perlin(x: Double, persistence: Double = 0.5, numberOfOctaves: Int = 8): Double {
var total = 0.0
var amplitudeSum = 0.0 //used for normalizing results to 0.0 - 1.0
for (i in 0 until numberOfOctaves) {
val amplitude = persistence.pow(i) // height of the crests
val frequency = 2.0.pow(i) // frequency (number of crests per unit distance) doubles per octave
val octave = amplitude * noise(x * frequency)
total += octave
amplitudeSum += amplitude
}
return total / amplitudeSum
}
The code at the bottom will replicate the problem, just copy and paste it into R.
What I want is for the mean and precision to be (-100, 100) 30% of the time, and (200, 1000) for 70% of the time. Think of it as lined up in a, b, and p.
So 'pick' should be 1 30% of the time, and 2 70% of the time.
What actually happens is that on every iteration, pick is 2 (or 1 if the first element of p is the larger one). You can see this in the summary, where the quantiles for 'pick', 'testa', and 'testb' remain unchanged throughout. The strangest thing is that if you remove the likelihood loop, pick then works exactly as intended.
I hope this explains the problem, if not let me know. It's my first time posting so I'm bound to have messed things up.
library(rjags)
n = 10
y <- rnorm(n, 5, 10)
a = c(-100, 200)
b = c(100, 1000)
p = c(0.3, 0.7)
## Model
mod_str = "model{
# Likelihood
for (i in 1:n){
y[i] ~ dnorm(mu, 10)
}
# ISSUE HERE: MIXTURE PRIOR
mu ~ dnorm(a[pick], b[pick])
pick ~ dcat(p[1:2])
testa = a[pick]
testb = b[pick]
}"
model = jags.model(textConnection(mod_str), data = list(y = y, n=n, a=a, b=b, p=p), n.chains=1)
update(model, 10000)
res = coda.samples(model, variable.names = c('pick', 'testa', 'testb', 'mu'), n.iter = 10000)
summary(res)
I think you are having problems for a couple of reasons. First, the data that you have supplied to the model (i.e., y) is not a mixture of normal distributions. As a result, the model itself has no need to mix. I would instead generate data something like this:
set.seed(320)
# number of samples
n <- 10
# Because it is a mixture of 2 we can just use an indicator variable.
# here, pick (in the long run), would be '1' 30% of the time.
pick <- rbinom(n, 1, p[1])
# generate the data. b is in terms of precision so we are converting this
# to standard deviations (which is what R wants).
y_det <- pick * rnorm(n, a[1], sqrt(1/b[1])) + (1 - pick) * rnorm(n, a[2], sqrt(1/b[2]))
# add a small amount of noise, can change to be more as necessary.
y <- rnorm(n, y_det, 1)
These data look more like what you would want to supply to a mixture model.
Following this, I would code the model up in a similar way as I did the data generation process. I want some indicator variable to jump between the two normal distributions. Thus, mu may change for each scalar in y.
mod_str = "model{
# Likelihood
for (i in 1:n){
y[i] ~ dnorm(mu[i], 10)
mu[i] <- mu_ind[i] * a_mu + (1 - mu_ind[i]) * b_mu
mu_ind[i] ~ dbern(p[1])
}
a_mu ~ dnorm(a[1], b[1])
b_mu ~ dnorm(a[2], b[2])
}"
model = jags.model(textConnection(mod_str), data = list(y = y, n=n, a=a, b=b, p=p), n.chains=1)
update(model, 10000)
res = coda.samples(model, variable.names = c('mu_ind', 'a_mu', 'b_mu'), n.iter = 10000)
summary(res)
2.5% 25% 50% 75% 97.5%
a_mu -100.4 -100.3 -100.2 -100.1 -100
b_mu 199.9 200.0 200.0 200.0 200
mu_ind[1] 0.0 0.0 0.0 0.0 0
mu_ind[2] 1.0 1.0 1.0 1.0 1
mu_ind[3] 0.0 0.0 0.0 0.0 0
mu_ind[4] 1.0 1.0 1.0 1.0 1
mu_ind[5] 0.0 0.0 0.0 0.0 0
mu_ind[6] 0.0 0.0 0.0 0.0 0
mu_ind[7] 1.0 1.0 1.0 1.0 1
mu_ind[8] 0.0 0.0 0.0 0.0 0
mu_ind[9] 0.0 0.0 0.0 0.0 0
mu_ind[10] 1.0 1.0 1.0 1.0 1
If you supplied more data, you would (in the long run) have the indicator variable mu_ind take the value of 1 30% of the time. If you had more than 2 distributions you could instead use dcat. Thus, an alternative and more generalized way of doing this would be (and I am borrowing heavily from this post by John Kruschke):
mod_str = "model {
# Likelihood:
for( i in 1 : n ) {
y[i] ~ dnorm( mu[i] , 10 )
mu[i] <- muOfpick[ pick[i] ]
pick[i] ~ dcat( p[1:2] )
}
# Prior:
for ( i in 1:2 ) {
muOfpick[i] ~ dnorm( a[i] , b[i] )
}
}"
model = jags.model(textConnection(mod_str), data = list(y = y, n=n, a=a, b=b, p=p), n.chains=1)
update(model, 10000)
res = coda.samples(model, variable.names = c('pick', 'muOfpick'), n.iter = 10000)
summary(res)
2.5% 25% 50% 75% 97.5%
muOfpick[1] -100.4 -100.3 -100.2 -100.1 -100
muOfpick[2] 199.9 200.0 200.0 200.0 200
pick[1] 2.0 2.0 2.0 2.0 2
pick[2] 1.0 1.0 1.0 1.0 1
pick[3] 2.0 2.0 2.0 2.0 2
pick[4] 1.0 1.0 1.0 1.0 1
pick[5] 2.0 2.0 2.0 2.0 2
pick[6] 2.0 2.0 2.0 2.0 2
pick[7] 1.0 1.0 1.0 1.0 1
pick[8] 2.0 2.0 2.0 2.0 2
pick[9] 2.0 2.0 2.0 2.0 2
pick[10] 1.0 1.0 1.0 1.0 1
The link above includes even more priors (e.g., a Dirichlet prior on the probabilities incorporated into the Categorical distribution).
Here is my code in matlab:
x = [1 2 3 4];
result = fft(x);
a = real(result);
b = imag(result);
Result from matlab:
a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]
And my runnable code in objective-c:
int length = 4;
float* x = (float *)malloc(sizeof(float) * length);
x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;
// Setup the length
vDSP_Length log2n = log2f(length);
// Calculate the weights array. This is a one-off operation.
FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
// For an FFT, numSamples must be a power of 2, i.e. is always even
int nOver2 = length/2;
// Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));
// Generate a split complex vector from the sample data
vDSP_ctoz((COMPLEX*)x, 2, &A, 1, nOver2);
// Perform a forward FFT using fftSetup and A
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);
//Take the fft and scale appropriately
Float32 mFFTNormFactor = 0.5;
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, nOver2);
printf("After FFT: \n");
printf("%.2f | %.2f \n",A.realp[0], 0.0);
for (int i = 1; i< nOver2; i++) {
printf("%.2f | %.2f \n",A.realp[i], A.imagp[i]);
}
printf("%.2f | %.2f \n",A.imagp[0], 0.0);
The output from objective c:
After FFT:
10.0 | 0.0
-2.0 | 2.0
The results are so close. I wonder where is the rest ? I know missed something but don't know what is it.
Updated: I found another answer here . I updated the output
After FFT:
10.0 | 0.0
-2.0 | 2.0
-2.0 | 0.0
but even that there's still 1 element missing -2.0 | -2.0
Performing a FFT delivers a right hand spectrum and a left hand spectrum.
If you have N samples the frequencies you will return are:
( -f(N/2), -f(N/2-1), ... -f(1), f(0), f(1), f(2), ..., f(N/2-1) )
If A(f(i)) is the complex amplitude A of the frequency component f(i) the following relation is true:
Real{A(f(i)} = Real{A(-f(i))} and Imag{A(f(i)} = -Imag{A(-f(i))}
This means, the information of the right hand spectrum and the left hand spectrum is the same. However, the sign of the imaginary part is different.
Matlab returns the frequency in a different order.
Matlab order is:
( f(0), f(1), f(2), ..., f(N/2-1) -f(N/2), -f(N/2-1), ... -f(1), )
To get the upper order use the Matlab function fftshift().
In the case of 4 Samples you have got in Matlab:
a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]
This means:
A(f(0)) = 10 (DC value)
A(f(1)) = -2 + 2i (first frequency component of the right hand spectrum)
A(-f(2) = -2 ( second frequency component of the left hand spectrum)
A(-f(1) = -2 - 2i ( first frequency component of the left hand spectrum)
I do not understand your objective-C code.
However, it seems to me that the program returns the right hand spectrum only.
So anything is perfect.
I have tested while loop below and don’t understand the result.
var x: Float = 0.0
var counter = 0
while x < 1.41
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x) // 1.5
How is it possible to have the result x = 1.5 for the used while condition where x < 14.1 ? How to explain this result?
Update:
and one more. Why the results are different for Double and Float ?
var x: Double = -0.5
var counter = 0
while x < 1.0
{
x += 0.1
counter += 1
}
print (counter) // 16
print (x)//1.1
var x: Float = -0.5
var counter = 0
while x < 1.0
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x)//1.0
Update 2
and another one. Why there is no difference for < and <= conditions. Does it mean that usage of <= has no sense for floating point ?
var x: Double = 0.0
var counter = 0
while x < 1.5
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x) //1.5
var x: Double = 0.0
var counter = 0
while x <= 1.5
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x) //1.5
What else would you expect? The loop is executed 15 times. On the 14th time, x is 1.4 and so you add another 0.1, making it 1.5.
If you expect the loop to terminate at 1.4, you should increment x before checking the while condition, not after that.
If you expect the loop to terminate on 1.41, your increment is wrong and you should do
x += 0.01
instead, making it 141 iterations.
As for the second question, I am aware that Float should not be used for monetary calculations and such due to its lack of precision. However, I trusted Double so far, and the while loop in run 15 actually claims the Double value to be less than 1.0 while it is reported to be 1.0. We have got a precision problem here, as we can see if we substract x from 1.0:
print(1.0-x)
which returns: 1.11022302462516e-16
At the same time, Float seems to be unprecise in the other direction. In the last run, it is a little bigger than 0.9 (0.9 + 5.96046e-08), making it bigger than 10 in the following run.
The reason why Double and Float are wrong in different directions is just a matter of how the values are stored, and the result will be different depending on the number. For example, with 2.0 both actual values are bigger: Double by 4.440892..e-16 and Float by 2.38419e-07. For 3.0 Double is bigger by 1.33226e-15 and Float smaller by 7.1525e-07.
The same problems occur using x.isLess(than: 1.0), but this method is the basis for the < operator as of https://developer.apple.com/reference/swift/floatingpoint/1849403-isless
isLessThanOrEqualTo(1.0), on the other hand, seems to work reliably as expected.
This answer is pretty much a question itself by now, so I'm curious if anyone has an in-depth explanation of this...
Update
The more I think about it, the less of a Swift problem it is. Basically, you have that problem in all floating point calculations, because they are never precise. Both Float and Double are not precise, Double is just twice as accurate. However, this means that comparisons like == are useless with floating point values unless they are both rounded. Therefore, good advice in loops like those of yours with a known precision (in your case one decimal) would be to round to that precision before doing any kind of comparison. For example, this would fix the loop:
var x: Double = -0.5
var counter = 0
while (round(x * 1000) / 1000) < 1.0
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x)//1.0
var x: Float = -0.5
var counter = 0
while (round(x * 1000) / 1000) < 1.0
{
x += 0.1
counter += 1
}
print (counter) // 15
print (x)//1.0
I have a sprite that moves along a vector (-0.7,-0.3). I have another point whose coordinates I have - let's call them (xB|yB). Now, quite some time ago I learned to calculate the perpendicular distance from a vector to a point (first formula on this page http://en.wikipedia.org/wiki/Perpendicular_distance). However I tried it, and if I log it, it returns an unbelievably high value that is 100% false. So what do I do wrong ? Have a look at the image I provided.
incomingVector = (-0.7,-0.3) //this is the vector the sprite is moving along
bh.position is the point I want to calculate the distance to
Here is the code:
// first I am working out the c Value in the formula in the link given above
CGPoint pointFromVector = CGPointMake(bh.incomingVector.x*theSprite.position.x,bh.incomingVector.y*theSprite.position.y);
float result = pointFromVector.x + pointFromVector.y;
float result2 = (-1)*result;
//now I use the formula
float test = (bh.incomingVector.x * bh.position.x + bh.incomingVector.y * bh.position.y + result2)/sqrt(pow(bh.incomingVector.x, 2)+pow(bh.incomingVector.y, 2));
//the distance has to be positive, so I do the following
if(test < 0){
test *= (-1);
}
let us implement the formula again, according to the contents of your original link.
we have a vector for the line: V(a; b)
we have a point on the line (the centre of the sprite): P(x1, y1)
we have another point somewhere else: B(xB, yB)
for the testing here are two rows of random values:
a = -0.7; b = -0.3; x1 = 7; y1 = 7; xB = 5; yB = 5;
a = -0.7; b = -0.3; x1 = 7; y1 = 7; xB = 5.5; yB = 4;
the numerator is the following then: (it seems you are calculating the numerator an unknown way, I don't understand why you did it because this is the proper way to calculate the numerator for the linked formula, perhaps this is why you got totally wrong distances.)
float _numerator = abs((b * xB) - (a * yB) - (b * x1) + (a * y1));
// for the 1. test values: (-0.3 * 5) - (-0.7 * 5) - (-0.3 * 7) + (-0.7 * 7) = -1.5 + 3.5 + 2.1 - 4.9 = -0.8 => abs(-0.8) = 0.8
// for the 2. test values: (-0.3 * 5.5) - (-0.7 * 4) - (-0.3 * 7) + (-0.7 * 7) = -1.65 + 2.8 + 2.1 - 4.9 = -1.65 => abs(-1.65) = 1.65
the denominator is the following then:
float _denomimator = sqrt((a * a) + (b * b));
// for the 1. test values: (-0.7 * -0.7) + (-0.3 * -0.3) = 0.49 + 0.09 = 0.58 => sort(0.58) = 0.76
// for the 2. test values: (-0.7 * -0.7) + (-0.3 * -0.3) = 0.49 + 0.09 = 0.58 => sort(0.58) = 0.76
the distance is obvious now:
float _distance = _numerator / _denominator;
// for the 1. test values: 0.8 / 0.76 = 1.05
// for the 2. test values: 1.65 / 0.76 = 2.17
and these results (1.05 and 2.17) are the correct distances exactly for our random values, if you can draw the lines and the points on the paper you can measure the distance and you would get the same values, using standard ruler.