package is2.data; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; public final class FV extends IFV { private FV subfv1; private FV subfv2; private boolean negateSecondSubFV = false; private int size; // content of the nodes NxC private int m_index[]; // type of the nodes NxT public FV() { this(10); } public FV(int initialCapacity) { m_index = new int[initialCapacity]; } public FV(FV fv1, FV fv2) { subfv1 = fv1; subfv2 = fv2; } public FV(FV fv1, FV fv2, boolean negSecond) { this(0); subfv1 = fv1; subfv2 = fv2; negateSecondSubFV = negSecond; } /** * Read a feature vector * * @param index * @param value */ public FV(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 FV(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; int newCapacity = (m_index.length * 3) / 2 + 1; if (newCapacity < minCapacity) { newCapacity = minCapacity; } m_index = new int[newCapacity]; System.arraycopy(oldIndex, 0, m_index, 0, oldIndex.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, double v) { ensureCapacity(size + 1); m_index[size] = i; 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; size++; } } final public void add(int[] i) { for (int k = 0; k < i.length; k++) { add(i[k]); } } final public void put(int i, double f) { if (i >= 0) { createFeature(i, f); } } // fv1 - fv2 public FV getDistVector(FV fl2) { return new FV(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 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 void update(double[] parameters, double[] total, double alpha_k, double upd) { update(parameters, total, alpha_k, upd, false); } public final void update(double[] parameters, double[] total, double alpha_k, double upd, boolean negate) { if (null != subfv1) { subfv1.update(parameters, total, alpha_k, upd, negate); if (null != subfv2) { if (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[m_index[i]] -= alpha_k;//*getValue(i); total[m_index[i]] -= upd * alpha_k;//*getValue(i); } } else { for (int i = 0; i < size; i++) { parameters[m_index[i]] += alpha_k;//*getValue(i); total[m_index[i]] += upd * alpha_k;//*getValue(i); } } } public final void update(short[] parameters, short[] total, double alpha_k, double upd, boolean negate) { if (null != subfv1) { subfv1.update(parameters, total, alpha_k, upd, negate); if (null != subfv2) { if (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[m_index[i]] -= alpha_k;//*getValue(i); total[m_index[i]] -= upd * alpha_k;//*getValue(i); } } else { for (int i = 0; i < size; i++) { parameters[m_index[i]] += alpha_k;//*getValue(i); total[m_index[i]] += upd * alpha_k;//*getValue(i); } } } 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; total[getIndex(i)] -= upd * alpha_k; } } else { for (int i = 0; i < size; i++) { parameters[getIndex(i)] += alpha_k; total[getIndex(i)] += upd * alpha_k; // } } } public final void update(float[] parameters, float[] total, double alpha_k, double upd, boolean negate, float[] totalp, Long2IntInterface li) { if (null != subfv1) { subfv1.update(parameters, total, alpha_k, upd, negate, totalp, li); if (null != subfv2 && negate) { subfv2.update(parameters, total, alpha_k, upd, !negateSecondSubFV, totalp, li); } else { subfv2.update(parameters, total, alpha_k, upd, negateSecondSubFV, totalp, li); } } if (negate) { for (int i = 0; i < size; i++) { parameters[getIndex(i)] -= alpha_k; total[getIndex(i)] -= upd * alpha_k; totalp[li.l2i(getIndex(i))] -= upd * alpha_k; // totalp[getIndex(i)] -=upd*alpha_k; } } else { for (int i = 0; i < size; i++) { parameters[getIndex(i)] += alpha_k; total[getIndex(i)] += upd * alpha_k; // totalp[li.l2i(getIndex(i))] += upd * alpha_k; // totalp[getIndex(i)] +=upd*alpha_k; } } } private static IntIntHash hm1; private static IntIntHash hm2; public int dotProduct(FV fl2) { if (hm1 == null) { hm1 = new IntIntHash(size(), 0.4F); } else { hm1.clear(); } addFeaturesToMap(hm1); if (hm2 == null) { hm2 = new IntIntHash(fl2.size, 0.4F); } else { hm2.clear(); } fl2.addFeaturesToMap(hm2); int[] keys = hm1.keys(); int result = 0; for (int i = 0; i < keys.length; i++) { result += hm1.get(keys[i]) * hm2.get(keys[i]); } return result; } public double twoNorm(FV fl2) { if (hm1 == null) { hm1 = new IntIntHash(size(), 0.4F); } else { hm1.clear(); } addFeaturesToMap(hm1); if (hm2 == null) { hm2 = new IntIntHash(fl2.size, 0.4F); } else { hm2.clear(); } fl2.addFeaturesToMap(hm2); int[] keys = hm1.keys(); int result = 0; for (int i = 0; i < keys.length; i++) { result += hm1.get(keys[i]) * hm2.get(keys[i]); } return Math.sqrt((double) result); } public void addFeaturesToMap(IntIntHash 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), 1)) { map.put(getIndex(i), 1); } } } 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); } } } } @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(' '); } } 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]); } } public void readKeys(DataInputStream dos) throws IOException { int keys = dos.readInt(); for (int i = 0; i < keys; i++) { createFeature(dos.readInt(), 1.0); } } public static FV cat(FV f1, FV f2) { if (f1 == null) { return f2; } if (f2 == null) { return f1; } return new FV(f1, f2); } public static FV cat(FV f1, FV f2, FV f3) { return FV.cat(f1, FV.cat(f2, f3)); } public static FV cat(FV f1, FV f2, FV f3, FV f4) { return FV.cat(f1, FV.cat(f2, FV.cat(f3, f4))); } public static FV read(DataInputStream dis) throws IOException { int cap = dis.readInt(); if (cap == 0) { return null; } return new FV(dis, cap); } /* * (non-Javadoc) @see is2.IFV#getScore() */ @Override public double getScore() { //System.out.println("not implemented"); // TODO Auto-generated method stub return 0; } /* * (non-Javadoc) @see is2.IFV#clone() */ @Override public IFV clone() { FV f = new FV(this.size); System.arraycopy(m_index, 0, f.m_index, 0, this.size); f.size = this.size; return f; } }