package interference;
import java.util.Random;
import math.UFunctions;
public class AlphaStableRandom {
public static double[] generateNext(int noTotalNodes, int radio_range, double perActiveNodes, int sizeOut) {
// ------------------------------------------------------
// Parameters of Alpha-Stable distribution
// ------------------------------------------------------
double b = 2.0;
double alpha = 2.0 / b;
double area = Math.PI * radio_range * radio_range; // circular area
// around a single
// node
double activeNodes = perActiveNodes / 100;
double lambda = (noTotalNodes / area) * activeNodes; // spatial density
// of network
double temp = 0; // constant in alpha-stable distribution formula
double c1 = 0;
double c2 = 0;
double c3 = 0;
if (alpha == 1) {
temp = 2 / Math.PI;
} else {
c1 = 1 - alpha;
c2 = UFunctions.gamma(Math.ceil(2 - alpha));
c3 = Math.cos((Math.PI * alpha) / 2);
temp = c1 / (c2 * c3);
}
double scale_para = 3.1623; // scale parameter of rayleigh distribution
double expected_value_Q = Math.pow(2, 1 / b) * Math.pow(scale_para, 2.0 / b) * UFunctions.gamma((1 / b) + 1);
double sigma = (lambda) * (Math.PI * temp) * (expected_value_Q);
int beta = 0;
int delta = 0;
// ------------------------------------------------------
// Alpha-Stable distribution Function
// ------------------------------------------------------
double[] outsizen = new double[sizeOut];
double mean = 0.0, std = 1.0;
Random rng = new Random();
for (int i = 0; i < sizeOut; i++) {
outsizen[i] = mean + std * rng.nextGaussian();
}
double[] outsize = new double[sizeOut];
for (int i = 0; i < outsize.length; i++) {
outsize[i] = Math.random();
}
double[] r = new double[sizeOut];
double[] V = new double[sizeOut];
double[] W = new double[sizeOut];
double[] chunk1 = new double[sizeOut];
double[] chunk2 = new double[sizeOut];
double[] chunk3 = new double[sizeOut];
double[] chunk4 = new double[sizeOut];
double[] chunk5 = new double[sizeOut];
double[] chunk6 = new double[sizeOut];
double[] chunk7 = new double[sizeOut];
if (alpha == 2) {
for (int i = 0; i < sizeOut; i++) {
r[i] = Math.sqrt(2) * outsizen[i];
}
} else if (alpha == 1 && beta == 0) { // Cauchy distribution
for (int i = 0; i < sizeOut; i++) {
r[i] = Math.tan(Math.PI / 2 * (2 * outsize[i] - 1));
}
} else if (alpha == .5 && Math.abs(beta) == 1) { // Levy distribution
// (a.k.a. Pearson
// V)
for (int i = 0; i < sizeOut; i++) {
r[i] = beta / Math.pow(outsizen[i], 2);
}
} else if (beta == 0) { // Symmetric alpha-stable
for (int i = 0; i < sizeOut; i++) {
V[i] = Math.PI / 2 * (2 * outsize[i] - 1);
W[i] = -Math.log10(outsize[i]);
chunk1[i] = Math.sin(alpha * V[i]);
chunk2[i] = Math.pow(Math.cos(V[i]), (1 / alpha));
chunk3[i] = Math.cos(V[i] * (1 - alpha));
chunk4[i] = (1 - alpha) / alpha;
chunk5[i] = chunk3[i] / W[i];
chunk6[i] = Math.pow(chunk5[i], chunk4[i]);
chunk7[i] = chunk2[i] * chunk6[i];
r[i] = chunk1[i] / chunk7[i];
}
} else if (alpha != 1) { // General case, alpha not 1
double constant = beta * Math.tan(Math.PI * alpha / 2);
double B = Math.atan(constant);
double S = Math.pow((1 + constant * constant), (1 / (2 * alpha)));
for (int i = 0; i < sizeOut; i++) {
V[i] = Math.PI / 2 * (2 * outsize[i] - 1);
W[i] = -Math.log(outsize[i]);
chunk1[i] = S * Math.sin(alpha * V[i] + B);
chunk2[i] = Math.pow((Math.cos(V[i])), (1 / alpha));
chunk3[i] = Math.cos((1 - alpha) * V[i] - B);
chunk4[i] = chunk3[i] / W[i];
chunk5[i] = ((1 - alpha) / alpha);
chunk6[i] = Math.pow(chunk4[i], chunk5[i]);
chunk7[i] = chunk2[i] * chunk6[i];
r[i] = chunk1[i] / chunk7[i];
}
} else { // General case, alpha = 1
double[] sclshftV = new double[sizeOut];
double piover2 = Math.PI / 2;
for (int i = 0; i < sizeOut; i++) {
V[i] = Math.PI / 2 * (2 * outsize[i] - 1);
W[i] = -Math.log(outsize[i]);
sclshftV[i] = piover2 + beta * V[i];
r[i] = 1 / piover2 * (sclshftV[i] * Math.tan(V[i])
- beta * Math.log((piover2 * W[i] * Math.cos(V[i])) / sclshftV[i]));
}
}
// Scale and shift
if (alpha != 1) {
for (int i = 0; i < sizeOut; i++) {
r[i] = sigma * r[i] + delta;
}
} else {
for (int i = 0; i < sizeOut; i++) {
r[i] = sigma * r[i] + (2 / Math.PI) * beta * sigma * Math.log(sigma) + delta;
}
}
return r;
}
}