All Downloads are FREE. Search and download functionalities are using the official Maven repository.

marytts.features.FeatureVector Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2000-2009 DFKI GmbH.
 * All Rights Reserved.  Use is subject to license terms.
 *
 * This file is part of MARY TTS.
 *
 * MARY TTS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 *
 */
package marytts.features;

import java.io.DataOutput;
import java.io.IOException;

/**
 * Compact representation of a list of byte-valued, short-valued and float-valued (continuous) features. In the user interface,
 * features are identified through one index number, covering all three types of features. For example, a feature vector
 * consisting of three bytes, four shorts and two floats will have nine features. Use getByteFeature(), getShortFeature() and
 * getContinuousFeature() to access the features as primitives; note that you have to respect the index restrictions, i.e. in the
 * example, calling getShortFeature(6) would be OK, but getShortFeature(2) or getShortFeature(8) would throw an
 * IndexOutOfBoundsException. Use isShortFeature(i) to test whether a given feature is a short feature. Alternatively, you can use
 * an Object interface to access all features in a uniform way: getFeature(i) will return a Number object for all valid indexes.
 * 
 * @author Marc Schröder
 *
 */
public class FeatureVector {
	public enum FeatureType {
		byteValued, shortValued, floatValued
	};

	public final int unitIndex;
	public final byte[] byteValuedDiscreteFeatures;
	public final short[] shortValuedDiscreteFeatures;
	public final float[] continuousFeatures;

	public FeatureVector(byte[] byteValuedDiscreteFeatures, short[] shortValuedDiscreteFeatures, float[] continuousFeatures,
			int setUnitIndex) {
		this.byteValuedDiscreteFeatures = byteValuedDiscreteFeatures;
		this.shortValuedDiscreteFeatures = shortValuedDiscreteFeatures;
		this.continuousFeatures = continuousFeatures;
		if (setUnitIndex < 0) {
			throw new RuntimeException("The unit index can't be negative or null when instanciating a new feature vector.");
		}
		this.unitIndex = setUnitIndex;
	}

	/**
	 * Is this an edge vector?
	 * 
	 * @param edgeIndex
	 *            edge index
	 * @return isEdge
	 */
	public boolean isEdgeVector(int edgeIndex) {
		String edgeValue = getFeature(edgeIndex).toString();
		return (!edgeValue.equals(FeatureDefinition.NULLVALUE));
	}

	public FeatureType getFeatureType(int featureIndex) {
		FeatureType t = null;
		if (featureIndex < 0
				|| featureIndex >= byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length
						+ continuousFeatures.length) {
			throw new IllegalArgumentException("Index " + featureIndex + " is out of range [0, " + getLength() + "[");
		}
		if (featureIndex < byteValuedDiscreteFeatures.length) {
			t = FeatureType.byteValued;
		} else if (featureIndex < byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length) {
			t = FeatureType.shortValued;
		} else if (featureIndex < byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length
				+ continuousFeatures.length) {
			t = FeatureType.floatValued;
		}
		return t;
	}

	/**
	 * Get the total number of features in this feature vector.
	 * 
	 * @return the number of features, irrespective of their type
	 */
	public int getLength() {
		return byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length + continuousFeatures.length;
	}

	/**
	 * Get the index of the unit to which the current feature vector applies.
	 * 
	 * @return The related unit index.
	 */
	public int getUnitIndex() {
		return (unitIndex);
	}

	/**
	 * The number of byte features in this feature vector.
	 * 
	 * @return a number of byte features, possibly 0.
	 */
	public int getNumberOfByteFeatures() {
		return byteValuedDiscreteFeatures.length;
	}

	/**
	 * The number of short features in this feature vector.
	 * 
	 * @return a number of short features, possibly 0.
	 */
	public int getNumberOfShortFeatures() {
		return shortValuedDiscreteFeatures.length;
	}

	/**
	 * The number of continuous features in this feature vector.
	 * 
	 * @return a number of continuous features, possibly 0.
	 */
	public int getNumberOfContinuousFeatures() {
		return continuousFeatures.length;
	}

	/**
	 * A uniform way to access features in this feature vector.
	 * 
	 * @param index
	 *            a feature index between 0 and getLength()-1
	 * @return a Number object, which will be a Byte, a Short or a Float depending on the type of the feature with the given index
	 *         number.
	 */
	public Number getFeature(int index) {
		if (index < byteValuedDiscreteFeatures.length)
			return new Byte(byteValuedDiscreteFeatures[index]);
		index -= byteValuedDiscreteFeatures.length;
		if (index < shortValuedDiscreteFeatures.length)
			return new Short(shortValuedDiscreteFeatures[index]);
		index -= shortValuedDiscreteFeatures.length;
		if (index < continuousFeatures.length)
			return new Float(continuousFeatures[index]);
		throw new IndexOutOfBoundsException();
	}

	/**
	 * A wrapper to getFeature(), to get the result as an int value, e.g., for subsequent array indexing.
	 * 
	 * @param index
	 *            A feature index between 0 and getLength()-1.
	 * @return The feature value, as an int.
	 * 
	 * @see FeatureVector#getFeature(int)
	 */
	public int getFeatureAsInt(int index) {
		return (getFeature(index).intValue());
	}

	/**
	 * A wrapper to getFeature(), to get the result as an String value, e.g., for subsequent System.out output.
	 * 
	 * @param index
	 *            A feature index between 0 and getLength()-1.
	 * @param feaDef
	 *            A FeatureDefinition object allowing to decode the feature value.
	 * @return The feature value, as a String.
	 * 
	 * @see FeatureVector#getFeature(int)
	 */
	public String getFeatureAsString(int index, FeatureDefinition feaDef) {
		if (index < byteValuedDiscreteFeatures.length)
			return feaDef.getFeatureValueAsString(index, byteValuedDiscreteFeatures[index]);
		throw new IndexOutOfBoundsException();
	}

	/**
	 * An efficient way to access byte-valued features in this feature vector.
	 * 
	 * @param index
	 *            the index number of the byte-valued feature in this feature vector.
	 * @return the byte value of the feature with the given index.
	 * @throws IndexOutOfBoundsException
	 *             if index<0 or index ≥ getNumberOfByteFeatures(). check {@link #getNumberOfByteFeatures()} . check
	 *             {@link #isByteFeature(int index)} .
	 */
	public final byte getByteFeature(int index) {
		if (index < 0 || index >= byteValuedDiscreteFeatures.length) {
			throw new IndexOutOfBoundsException(index + " is not between 0 and " + byteValuedDiscreteFeatures.length);
		}
		return byteValuedDiscreteFeatures[index];
	}

	/**
	 * An efficient way to access short-valued features in this feature vector.
	 * 
	 * @param index
	 *            the index number of the short-valued feature in this feature vector.
	 * @return the short value of the feature with the given index.
	 * @throws IndexOutOfBoundsException
	 *             if index<getNumberOfByteFeatures() or index ≥ getNumberOfByteFeatures()+getNumberOfShortFeatures().
	 * @see #getNumberOfByteFeatures()
	 * @see #getNumberOfShortFeatures()
	 * @see #isShortFeature(int index)
	 */
	public final short getShortFeature(int index) {
		return shortValuedDiscreteFeatures[index - byteValuedDiscreteFeatures.length];
	}

	/**
	 * An efficient way to access continuous features in this feature vector.
	 * 
	 * @param index
	 *            the index number of the continuous feature in this feature vector.
	 * @return the float value of the feature with the given index.
	 * @throws IndexOutOfBoundsException
	 *             if index<getNumberOfByteFeatures()+getNumberOfShortFeatures() or index ≥ getLength().
	 * @see #getNumberOfByteFeatures()
	 * @see #getNumberOfShortFeatures()
	 * @see #getNumberOfContinuousFeatures()
	 * @see #getLength()
	 * @see #isContinuousFeature(int index)
	 */
	public final float getContinuousFeature(int index) {
		return continuousFeatures[index - byteValuedDiscreteFeatures.length - shortValuedDiscreteFeatures.length];
	}

	/**
	 * Test whether the feature with the given index number is a byte feature.
	 * 
	 * @param index
	 *            index
	 * @return This will return true exactly if getByteFeature(index) would return a value without throwing an exception, i.e. if
	 *         index≥0 and index < getNumberOfByteFeatures().
	 */
	public boolean isByteFeature(int index) {
		return 0 <= index && index < byteValuedDiscreteFeatures.length;
	}

	/**
	 * Test whether the feature with the given index number is a short feature.
	 * 
	 * @param index
	 *            index
	 * @return This will return true exactly if getShortFeature(index) would return a value without throwing an exception, i.e. if
	 *         index≥getNumberOfByteFeatures() and index < getNumberOfByteFeatures()+getNumberOfShortFeatures().
	 */
	public boolean isShortFeature(int index) {
		return byteValuedDiscreteFeatures.length <= index
				&& index < byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length;
	}

	/**
	 * Test whether the feature with the given index number is a continuous feature.
	 * 
	 * @param index
	 *            index
	 * @return This will return true exactly if getContinuousFeature(index) would return a value without throwing an exception,
	 *         i.e. if index≥getNumberOfByteFeatures()+getNumberOfShortFeatures() and index < getLength().
	 */
	public boolean isContinuousFeature(int index) {
		return byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length <= index
				&& index < byteValuedDiscreteFeatures.length + shortValuedDiscreteFeatures.length + continuousFeatures.length;
	}

	public byte[] getByteValuedDiscreteFeatures() {
		return byteValuedDiscreteFeatures;
	}

	public short[] getShortValuedDiscreteFeatures() {
		return shortValuedDiscreteFeatures;
	}

	public float[] getContinuousFeatures() {
		return continuousFeatures;
	}

	/**
	 * Write a binary representation of this feature vector to the given data output.
	 * 
	 * @param out
	 *            the DataOutputStream or RandomAccessFile in which to write the binary representation of the feature vector.
	 * @throws IOException
	 *             IOException
	 */
	public void writeTo(DataOutput out) throws IOException {
		if (byteValuedDiscreteFeatures != null) {
			out.write(byteValuedDiscreteFeatures);
		}
		if (shortValuedDiscreteFeatures != null) {
			for (int i = 0; i < shortValuedDiscreteFeatures.length; i++) {
				out.writeShort(shortValuedDiscreteFeatures[i]);
			}
		}
		if (continuousFeatures != null) {
			for (int i = 0; i < continuousFeatures.length; i++) {
				out.writeFloat(continuousFeatures[i]);
			}
		}
	}

	/**
	 * Return a string representation of this set of target features; feature values separated by spaces.
	 * 
	 * @return out.toString
	 */
	public String toString() {
		StringBuilder out = new StringBuilder();
		for (int i = 0; i < byteValuedDiscreteFeatures.length; i++) {
			if (out.length() > 0)
				out.append(" ");
			out.append((int) byteValuedDiscreteFeatures[i]);
		}
		for (int i = 0; i < shortValuedDiscreteFeatures.length; i++) {
			if (out.length() > 0)
				out.append(" ");
			out.append((int) shortValuedDiscreteFeatures[i]);
		}
		for (int i = 0; i < continuousFeatures.length; i++) {
			if (out.length() > 0)
				out.append(" ");
			out.append(continuousFeatures[i]);
		}
		return out.toString();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy