com.expleague.ml.models.CNF Maven / Gradle / Ivy
package com.expleague.ml.models;
import com.expleague.commons.math.MathTools;
import com.expleague.commons.math.vectors.Vec;
import com.expleague.ml.BFGrid;
import com.expleague.ml.BinOptimizedModel;
import com.expleague.ml.data.impl.BinarizedDataSet;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
/**
* User: solar
* Date: 29.11.12
* Time: 5:35
*/
public class CNF extends RegionBase {
private final Clause[] clauses;
public CNF(final Clause[] conditions, final double inside, final BFGrid grid) {
super(grid, inside, 0.);
this.clauses = conditions;
}
public CNF(final Clause[] conditions, final double inside, final double outside, final BFGrid grid) {
super(grid, inside, outside);
this.clauses = conditions;
}
@Override
public boolean contains(final Vec point) {
for (final Clause clause : clauses) {
if (!clause.contains(point)) {
return false;
}
}
return true;
}
@Override
public boolean contains(final BinarizedDataSet bds, final int pindex) {
for (final Clause clause : clauses) {
if (!clause.contains(bds, pindex)) {
return false;
}
}
return true;
}
public static class Clause extends RegionBase implements BinOptimizedModel {
public static Clause Empty = new Clause(null);
public final Condition[] conditions;
public Clause(final BFGrid grid, final Condition... conditions) {
super(grid, 1., 0);
@SuppressWarnings("unchecked")
final List optimizedConditions = new ArrayList<>(conditions.length);
for(int i = 0; i < conditions.length; i++) {
final Condition next = conditions[i];
boolean optimizedOut = false;
for (int j = 0; j < optimizedConditions.size() && !optimizedOut; j++) {
final Condition condition = optimizedConditions.get(j);
if (condition.feature == next.feature) {
condition.used.or(next.used);
optimizedOut = true;
}
}
if (!optimizedOut)
optimizedConditions.add(new Condition(next.feature, (BitSet)next.used.clone()));
}
this.conditions = optimizedConditions.size() != conditions.length ? optimizedConditions.toArray(new Condition[optimizedConditions.size()]) : conditions;
}
@Override
public boolean contains(final BinarizedDataSet bds, final int pindex) {
if (conditions.length == 0)
return true;
for(int i = 0; i < conditions.length; i++) {
final Condition condition = conditions[i];
if (condition.contains(bds, pindex))
return true;
}
return false;
}
@Override
public boolean contains(final Vec x) {
if (conditions.length == 0)
return true;
for(int i = 0; i < conditions.length; i++) {
final Condition condition = conditions[i];
if (condition.contains(x))
return true;
}
return false;
}
@Override
public String toString() {
return Arrays.toString(conditions);
}
public double cardinality() {
double cardinality = conditions.length;
for(int i = 0; i < conditions.length; i++) {
cardinality += conditions[i].cardinality();
}
return cardinality;
}
}
public static class Condition {
public final int findex;
public final BFGrid.Row feature;
public final BitSet used;
public Condition(final BFGrid.Row feature, final BitSet bins) {
this.findex = feature.findex();
this.feature = feature;
this.used = bins;
}
public int cardinality() {
int prev = -1;
int cardinality = 0;
for (int i = 0; i < used.cardinality(); i++) {
final int next = used.nextSetBit(prev + 1);
if (next != prev+1) {
cardinality += 2;
}
else if(prev < 0)
cardinality++;
prev = next;
}
if (prev == feature.size())
cardinality--;
return cardinality;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("f[").append(feature.findex()).append("] \\in ");
final NumberFormat pp = MathTools.numberFormatter();
int prev = -1;
for (int next = used.nextSetBit(0); next >= 0; next = used.nextSetBit(next+1)) {
if (next != prev+1) {
if (prev >= 0)
builder.append(",").append(pp.format(feature.condition(prev))).append("]");
builder.append("(").append(pp.format(feature.condition(next - 1)));
}
else if (prev < 0) {
builder.append("(-∞");
}
prev = next;
}
if (prev == feature.size())
builder.append(",+∞)");
else
builder.append(",").append(pp.format(feature.condition(prev))).append("]");
return builder.toString();
}
public boolean contains(final BinarizedDataSet bds, final int pindex) {
return used.get(bds.bins(findex)[pindex]);
}
public boolean contains(final Vec x) {
final double val = x.get(findex);
return used.get(feature.bin(val));
}
}
}