    001    package org.maltparser.ml.lib;
    002
    003    import java.io.Serializable;
    004
    005    import org.maltparser.core.helper.HashMap;
    006
    007    /**
    008     * The purpose of the feature map is to map MaltParser's column based features together with the symbol code from the symbol table to
    009     * unique indices suitable for liblinear and libsvm.  A feature column position are combined together with the symbol code in a
    010     * 64-bit key (Long), where 16 bits are reserved for the position and 48 bits are reserved for the symbol code.
    011     *
    012     * @author Johan Hall
    013     *
    014     */
    015    public class FeatureMap  implements Serializable {
    016            private static final long serialVersionUID = 7526471155622776147L;
    017            private HashMap<Long,Integer> map;
    018            private int featureCounter;
    019
    020            /**
    021             * Creates a feature map and sets the feature counter to 1
    022             */
    023            public FeatureMap() {
    024                    map = new HashMap<Long, Integer>();
    025                    this.featureCounter = 1;
    026            }
    027
    028            /**
    029             * Adds a mapping from a combination of the position in the column-based feature vector and the symbol code to
    030             * an index value suitable for liblinear and libsvm.
    031             *
    032             * @param featurePosition a position in the column-based feature vector
    033             * @param code a symbol code
    034             * @return the index value
    035             */
    036            public int addIndex(int featurePosition, int code) {
    037                    long key = ((((long)featurePosition) << 48) | (long)code);
    038                    Integer index = map.get(key);
    039                    if (index == null) {
    040                            index = featureCounter++;
    041                            map.put(key, index);
    042                    }
    043                    return index.intValue();
    044            }
    045
    046            /**
    047             * Return
    048             *
    049             * @param featurePosition the position in the column-based feature vector
    050             * @param code the symbol code suitable for liblinear and libsvm
    051             * @return the index value if it exists, otherwise -1
    052             */
    053            public int getIndex(int featurePosition, int code) {
    054                    long key = ((((long)featurePosition) << 48) | (long)code);
    055                    Integer index = map.get(key);
    056                    return (index == null)?-1:index;
    057            }
    058
    059
    060            public int addIndex(int featurePosition, int code1, int code2) {
    061                    long key = ((((long)featurePosition) << 48) | (((long)code1) << 24) | (long)code2);
    062                    Integer index = map.get(key);
    063                    if (index == null) {
    064                            index = featureCounter++;
    065                            map.put(key, index);
    066                    }
    067                    return index.intValue();
    068            }
    069
    070            public int getIndex(int featurePosition, int code1, int code2) {
    071                    long key = ((((long)featurePosition) << 48) | (((long)code1) << 24) | (long)code2);
    072                    Integer index = map.get(key);
    073                    return (index == null)?-1:index;
    074            }
    075
    076            /**
    077             * @return the size of the map
    078             */
    079            public int size() {
    080                    return map.size();
    081            }
    082
    083            /**
    084             * @return the current value of the feature counter.
    085             */
    086            public int getFeatureCounter() {
    087                    return featureCounter;
    088            }
    089    }