package polyofdm.cc.full;
import java.util.Set;
import polyofdm.matrixgen.Utils;
import Jama.Matrix;
public class FullCC {
public static Matrix createCancellationMatrix(int allCarriers,
Set<Integer> cancellationCarriers) {
validateDefinition(allCarriers, cancellationCarriers);
int[] usedCarriers = getUsedCarriers(allCarriers, cancellationCarriers);
int[] cCarriers = getCancellationCarriers(allCarriers, cancellationCarriers);
double[] weightings = Utils.createWeightings(allCarriers);
Matrix cancellationMatrix = new Matrix(cCarriers.length, usedCarriers.length);
for (int i = 0; i < cCarriers.length; i++) {
int cCarrier = cCarriers[i];
for (int j = 0; j < usedCarriers.length; j++) {
cancellationMatrix.set(i, j, calculateFactor(cCarrier, j, weightings, usedCarriers));
}
}
return cancellationMatrix;
}
private static void validateDefinition(int allCarriers, Set<Integer> cancellationCarriers) {
for (Integer i : cancellationCarriers) {
int intValue = i.intValue();
if (intValue>=allCarriers)
throw new IllegalArgumentException("CancellationCarrier is given with i=" + i + " but this >= all (" + allCarriers + ')');
if (intValue<0)
throw new IllegalArgumentException("CancellationCarrier is given with i=" + i + " but this is < 0");
}
}
private static double calculateFactor(int cCarrier, int usedCarrierIndex,
double[] weightings, int[] usedCarriers) {
int usedCarrier = usedCarriers[usedCarrierIndex];
double lagrangeNormFactor = calcLagrangePoly(usedCarrier, usedCarriers, usedCarrierIndex);
double value = calcLagrangePoly(cCarrier, usedCarriers, usedCarrierIndex);
return (value / lagrangeNormFactor) * (weightings[cCarrier]/weightings[usedCarrier]);
}
private static double calcLagrangePoly(int x, int[] roots, int index) {
double product = 1;
for (int i = 0; i < roots.length; i++) {
if (i!=index){
product = product * (x-roots[i]);
}
}
return product;
}
private static int[] getUsedCarriers(int allCarriers,
Set<Integer> cancellationCarriers) {
int[] usedCarriers = new int[allCarriers-cancellationCarriers.size()];
int counter = 0;
for (int pos = 0; pos < allCarriers; pos++) {
if (!cancellationCarriers.contains(pos))
usedCarriers[counter++] = pos;
}
return usedCarriers;
}
private static int[] getCancellationCarriers(int allCarriers,
Set<Integer> cancellationCarriers) {
int[] cCarriers = new int[cancellationCarriers.size()];
int counter = 0;
for (int pos = 0; pos < allCarriers; pos++) {
if (cancellationCarriers.contains(pos))
cCarriers[counter++] = pos;
}
return cCarriers;
}
}