package is2.data;
import gnu.trove.TIntDoubleHashMap;
import is2.parser.Parser;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public final class FVR extends IFV {
private FVR subfv1;
private FVR subfv2;
private boolean negateSecondSubFV = false;
private int size;
// content of the nodes NxC
private int m_index[];
private float m_value[];
// type of the nodes NxT
public FVR() {
this(10);
}
public FVR(int initialCapacity) {
m_index = new int[initialCapacity];
m_value = new float[initialCapacity];
}
/*
* public FVR (FVR fv1, FVR fv2) { subfv1 = fv1; subfv2 = fv2; }
*/
public FVR(FVR fv1, FVR fv2, boolean negSecond) {
this(0);
subfv1 = fv1;
subfv2 = fv2;
negateSecondSubFV = negSecond;
}
/**
* Read a feature vector
*
* @param index
* @param value
*/
public FVR(DataInputStream dos, int capacity) throws IOException {
this(capacity);
size = m_index.length;
for (int i = 0; i < size; i++) {
m_index[i] = dos.readInt();
}
}
/**
* Read a feature vector
*
* @param index
* @param value
*/
public FVR(DataInputStream dos) throws IOException {
this(dos.readInt());
size = m_index.length;
for (int i = 0; i < size; i++) {
m_index[i] = dos.readInt();
}
}
/**
* Increases the capacity of this <tt>Graph</tt> instance, if necessary, to
* ensure that it can hold at least the number of nodes specified by the
* minimum capacity argument.
*
* @param minCapacity the desired minimum capacity.
*/
private void ensureCapacity(int minCapacity) {
if (minCapacity > m_index.length) {
int oldIndex[] = m_index;
float oldValue[] = m_value;
int newCapacity = (m_index.length * 3) / 2 + 1;
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
m_index = new int[newCapacity];
m_value = new float[newCapacity];
System.arraycopy(oldIndex, 0, m_index, 0, oldIndex.length);
System.arraycopy(oldValue, 0, m_value, 0, oldValue.length);
}
}
final public int size() {
return size;
}
final public boolean isEmpty() {
return size == 0;
}
@Override
final public void clear() {
size = 0;
}
final public int createFeature(int i, float v) {
ensureCapacity(size + 1);
m_index[size] = i;
m_value[size] = v;
size++;
return size - 1;
}
/*
* final public int createFeature(int i) {
*
* ensureCapacity(size+1); m_index[size] =i; size++; return size-1; }
*/
final public int getIndex(int i) {
return m_index[i];
}
public void setIndex(int p, int i) {
m_index[p] = i;
}
/**
* Trims the capacity of this <tt>Graph</tt> instance to true size. An
* application can use this operation to minimize the storage of an
* <tt>Graph</tt> instance.
*/
public void trimToSize() {
if (size < m_index.length) {
int oldIndex[] = m_index;
m_index = new int[size];
System.arraycopy(oldIndex, 0, m_index, 0, size);
}
}
@Override
final public void add(int i) {
if (i >= 0) {
ensureCapacity(size + 1);
m_index[size] = i;
m_value[size] = 1.0f;
size++;
}
}
final public void add(int i, float f) {
if (i >= 0) {
createFeature(i, f);
}
}
// fv1 - fv2
public FVR getDistVector(FVR fl2) {
return new FVR(this, fl2, true);
}
public double getScore(double[] parameters, boolean negate) {
double score = 0.0;
if (null != subfv1) {
score += subfv1.getScore(parameters, negate);
if (null != subfv2) {
if (negate) {
score += subfv2.getScore(parameters, !negateSecondSubFV);
} else {
score += subfv2.getScore(parameters, negateSecondSubFV);
}
}
}
if (negate) {
for (int i = 0; i < size; i++) {
score -= parameters[m_index[i]];
}
} else {
for (int i = 0; i < size; i++) {
score += parameters[m_index[i]];
}
}
return score;
}
final public float getScore(float[] parameters, boolean negate) {
float score = 0.0F;
if (null != subfv1) {
score += subfv1.getScore(parameters, negate);
if (null != subfv2) {
if (negate) {
score += subfv2.getScore(parameters, !negateSecondSubFV);
} else {
score += subfv2.getScore(parameters, negateSecondSubFV);
}
}
}
// warning changed the value
if (negate) {
for (int i = 0; i < size; i++) {
score -= parameters[m_index[i]] * m_value[i];
}
} else {
for (int i = 0; i < size; i++) {
score += parameters[m_index[i]] * m_value[i];
}
}
return score;
}
final public int getScore(short[] parameters, boolean negate) {
int score = 0;
if (null != subfv1) {
score += subfv1.getScore(parameters, negate);
if (null != subfv2) {
if (negate) {
score += subfv2.getScore(parameters, !negateSecondSubFV);
} else {
score += subfv2.getScore(parameters, negateSecondSubFV);
}
}
}
// warning changed the value
if (negate) {
for (int i = 0; i < size; i++) {
score -= parameters[m_index[i]] * m_value[i];
}
} else {
for (int i = 0; i < size; i++) {
score += parameters[m_index[i]] * m_value[i];
}
}
return score;
}
public final void update(float[] parameters, float[] total, double alpha_k, double upd, boolean negate) {
if (null != subfv1) {
subfv1.update(parameters, total, alpha_k, upd, negate);
if (null != subfv2 && negate) {
subfv2.update(parameters, total, alpha_k, upd, !negateSecondSubFV);
} else {
subfv2.update(parameters, total, alpha_k, upd, negateSecondSubFV);
}
}
if (negate) {
for (int i = 0; i < size; i++) {
parameters[getIndex(i)] -= alpha_k * m_value[i];
total[getIndex(i)] -= upd * alpha_k * m_value[i];
}
} else {
for (int i = 0; i < size; i++) {
parameters[getIndex(i)] += alpha_k * m_value[i];
total[getIndex(i)] += upd * alpha_k * m_value[i]; //
}
}
}
// private static IntIntHash hm1;
// private static IntIntHash hm2;
private static TIntDoubleHashMap hd1;
private static TIntDoubleHashMap hd2;
public int dotProduct(FVR fl2) {
if (hd1 == null) {
hd1 = new TIntDoubleHashMap(size(), 0.4F);
} else {
hd1.clear();
}
addFeaturesToMap(hd1);
if (hd2 == null) {
hd2 = new TIntDoubleHashMap(fl2.size, 0.4F);
} else {
hd2.clear();
}
fl2.addFeaturesToMap(hd2);
int[] keys = hd1.keys();
int result = 0;
for (int i = 0; i < keys.length; i++) {
result += hd1.get(keys[i]) * hd2.get(keys[i]);
}
return result;
}
private void addFeaturesToMap(TIntDoubleHashMap map) {
if (null != subfv1) {
subfv1.addFeaturesToMap(map);
if (null != subfv2) {
subfv2.addFeaturesToMap(map, negateSecondSubFV);
}
}
for (int i = 0; i < size; i++) {
if (!map.adjustValue(getIndex(i), m_value[i])) {
map.put(getIndex(i), m_value[i]);
}
}
}
private void addFeaturesToMap(IntIntHash map, boolean negate) {
if (null != subfv1) {
subfv1.addFeaturesToMap(map, negate);
if (null != subfv2) {
if (negate) {
subfv2.addFeaturesToMap(map, !negateSecondSubFV);
} else {
subfv2.addFeaturesToMap(map, negateSecondSubFV);
}
}
}
if (negate) {
for (int i = 0; i < size; i++) {
if (!map.adjustValue(getIndex(i), -1)) {
map.put(getIndex(i), -1);
}
}
} else {
for (int i = 0; i < size; i++) {
if (!map.adjustValue(getIndex(i), 1)) {
map.put(getIndex(i), 1);
}
}
}
}
private void addFeaturesToMap(TIntDoubleHashMap map, boolean negate) {
if (null != subfv1) {
subfv1.addFeaturesToMap(map, negate);
if (null != subfv2) {
if (negate) {
subfv2.addFeaturesToMap(map, !negateSecondSubFV);
} else {
subfv2.addFeaturesToMap(map, negateSecondSubFV);
}
}
}
if (negate) {
for (int i = 0; i < size; i++) {
if (!map.adjustValue(getIndex(i), -m_value[i])) {
map.put(getIndex(i), -m_value[i]);
}
}
} else {
for (int i = 0; i < size; i++) {
if (!map.adjustValue(getIndex(i), m_value[i])) {
map.put(getIndex(i), m_value[i]);
}
}
}
}
@Override
public final String toString() {
StringBuilder sb = new StringBuilder();
toString(sb);
return sb.toString();
}
private void toString(StringBuilder sb) {
if (null != subfv1) {
subfv1.toString(sb);
if (null != subfv2) {
subfv2.toString(sb);
}
}
for (int i = 0; i < size; i++) {
sb.append(getIndex(i)).append('=').append(m_value[i]).append(' ');
}
}
public void writeKeys(DataOutputStream dos) throws IOException {
// int keys[] = keys();
// dos.writeInt(keys.length);
// for(int i=0;i<keys.length;i++) {
// dos.writeInt(keys[i]);
// }
//int keys[] = keys();
dos.writeInt(size);
for (int i = 0; i < size; i++) {
dos.writeInt(m_index[i]);
}
}
/*
*
* final public static FVR cat(FVR f1,FVR f2) { if (f1==null) return f2; if
* (f2==null) return f1; return new FVR(f1, f2); }
*
* final public static FVR cat(FVR f1,FVR f2, FVR f3) { return FVR.cat(f1,
* FVR.cat(f2, f3)); } final public static FVR cat(FVR f1,FVR f2, FVR f3,
* FVR f4) { return FVR.cat(f1, FVR.cat(f2, FVR.cat(f3, f4))); }
*/
public static FVR read(DataInputStream dis) throws IOException {
int cap = dis.readInt();
if (cap == 0) {
return null;
}
return new FVR(dis, cap);
}
/*
* (non-Javadoc) @see is2.IFV#getScore()
*/
@Override
public double getScore() {
Parser.out.println("not implemented");
new Exception().printStackTrace();
// TODO Auto-generated method stub
return 0;
}
/*
* (non-Javadoc) @see is2.IFV#clone()
*/
@Override
public IFV clone() {
FVR f = new FVR(this.size);
for (int i = 0; i < this.size; i++) {
f.m_index[i] = m_index[i];
f.m_value[i] = m_value[i];
}
f.size = this.size;
return f;
}
}