package edu.ucla.nesl.mca.feature;
import java.util.ArrayList;
import android.os.Bundle;
import android.util.Log;
import edu.ucla.nesl.mca.classifier.LogUtil;
public class Feature {
public enum OPType {
NOMINAL(1), REAL(2);
private final int num;
OPType(int value) {
this.num = value;
}
public int num() {
return this.num;
}
}
private int id;
private String name;
private int sensor;
private OPType opType;
private double dataValue;
private boolean isResult;
private int windowSize;
private ArrayList<String> dataSet; // only used if NOMINAL
private Bundle data;
private int parameter;
private Trigger triggerOn = null;
private Trigger triggerOff = null;
// public Trigger getTrigger() {
// return trigger;
// }
//
// public void setTrigger(int feature, String operator, double threshold) {
// this.trigger = new Trigger(feature, operator, threshold);
// }
//
// public int getTriggerFeature() {
// return this.trigger.feature;
// }
//
// public RealOperator getTriggerRealOperator() {
// return this.trigger.realOp;
// }
//
// public double getTriggerThreshold() {
// return this.trigger.threshold;
// }
public Trigger getTriggerOn() {
return triggerOn;
}
public void setTriggerOn(Trigger triggerOn) {
this.triggerOn = triggerOn;
}
public Trigger getTriggerOff() {
return triggerOff;
}
public void setTriggerOff(Trigger triggerOff) {
this.triggerOff = triggerOff;
}
public Feature() {
dataSet = new ArrayList<String>();
windowSize = 100;
}
public int getWindowSize() {
return windowSize;
}
public void setWindowSize(int windowSize) {
this.windowSize = windowSize;
}
public boolean isResult() {
return isResult;
}
public void setResult(boolean isResult) {
this.isResult = isResult;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSensor() {
return sensor;
}
public void setSensor(int sensor) {
this.sensor = sensor;
}
public OPType getOpType() {
return opType;
}
public void setOpType(OPType opType) {
this.opType = opType;
}
public void addMembership(String mem) {
dataSet.add(mem);
}
public double getDataValue() {
return dataValue;
}
public void setDataValue(double dataValue) {
this.dataValue = dataValue;
}
public Bundle getData() {
return data;
}
public void setData(Bundle data) {
this.data = data;
}
public Object evaluate(double parameter) {
// compute the current value using parameter
if (this.sensor == SensorProfile.GPS) {
if (this.name.equals(SensorProfile.SPEED)) {
this.dataValue = Math.random() * 20.0;
Log.i("Feature", "current speed=" + dataValue);
return this.dataValue;
}
}
else if (this.sensor == SensorProfile.ACCELEROMETER) {
double[] accData = AlgorithmUtil.magnititute(
data.getDoubleArray("AccX"), data.getDoubleArray("AccY"),
data.getDoubleArray("AccZ"));
int dataSize = accData.length;
// double sum = 0.0, avg = 0.0, var = 0.0;
// for (int i = 0; i < dataSize; i++) {
// sum += accData[i];
// }
//
// avg = sum / dataSize;
// sum = 0.0;
// for (int i = 0; i < dataSize; i++) {
// sum += Math.pow((accData[i] - avg), 2.0);
// }
// var = sum / dataSize;
if (!AlgorithmUtil.getOutdoor()) {
double accFft[] = new double[5];
accFft[0] = AlgorithmUtil.goertzel(accData, 1., dataSize);
accFft[1] = AlgorithmUtil.goertzel(accData, 2., dataSize);
accFft[2] = AlgorithmUtil.goertzel(accData, 3., dataSize);
accFft[3] = AlgorithmUtil.goertzel(accData, 4., dataSize);
accFft[4] = AlgorithmUtil.goertzel(accData, 5., dataSize);
int newVal = 0;
if (accFft[0] + accFft[1] + accFft[2] + accFft[3] + accFft[4] < AlgorithmUtil.INDOOR_THRESHOLD) {
newVal = 0;
}
else {
newVal = 1;
}
if (AlgorithmUtil.ioq.size() == AlgorithmUtil.QUEUE_SIZE){
AlgorithmUtil.ioScore -= AlgorithmUtil.ioq.removeLast();
}
AlgorithmUtil.ioq.addFirst(newVal);
AlgorithmUtil.ioScore += newVal;
if (AlgorithmUtil.ioScore > AlgorithmUtil.QUEUE_SIZE / 2) {
AlgorithmUtil.setOutdoor();
AlgorithmUtil.ioq.clear();
AlgorithmUtil.ioScore = 0;
}
}
double s = 0.0, a0 = 0.0, v = 0.0;
double a[] = new double[10];
for (int i = 0; i < dataSize; i++) {
accData[i] = accData[i] / 310.;
s += accData[i];
}
a0 = s / dataSize;
s = 0.0;
a[1] = AlgorithmUtil.goertzel(accData, 1., dataSize);
a[2] = AlgorithmUtil.goertzel(accData, 2., dataSize);
a[3] = AlgorithmUtil.goertzel(accData, 3., dataSize);
a[4] = AlgorithmUtil.goertzel(accData, 4., dataSize);
a[5] = AlgorithmUtil.goertzel(accData, 5., dataSize);
a[6] = AlgorithmUtil.goertzel(accData, 6., dataSize);
a[7] = AlgorithmUtil.goertzel(accData, 7., dataSize);
a[8] = AlgorithmUtil.goertzel(accData, 8., dataSize);
a[9] = AlgorithmUtil.goertzel(accData, 9., dataSize);
a[0] = AlgorithmUtil.goertzel(accData, 10., dataSize);
for (int i = 0; i < dataSize; i++) {
s += Math.pow((accData[i] - a0), 2.0);
}
v = s / dataSize;
if (this.name.equals(SensorProfile.VARIANCE)) {
this.dataValue = v;
LogUtil.features.add(this);
return this.dataValue;
}
else if (this.name.equals(SensorProfile.ENERGYCOEFFICIENT)) {
this.parameter = (int)parameter;
this.dataValue = a[(int)parameter];
LogUtil.features.add(this);
return this.dataValue;
}
else if (this.name.equals(SensorProfile.INDOOR)) {
if (AlgorithmUtil.getOutdoor()) {
this.dataValue = 1.0;
}
else {
this.dataValue = 0.0;
}
return this.dataValue;
}
}
return Double.MIN_VALUE;
}
public int getParameter() {
return parameter;
}
public void setParameter(int parameter) {
this.parameter = parameter;
}
}