001    package calhoun.analysis.crf.io;
002    
003    import java.util.Collection;
004    import java.util.HashMap;
005    
006    import calhoun.util.Assert;
007    
008    /** represents an input sequence that also contains a sequence of hidden states.
009     * @param <A> the elements which make up the input sequence which is part of this training sequence 
010     */
011    public class TrainingSequence<A> implements InputSequence<A> {
012            private static final long serialVersionUID = -443081006327395045L;
013            InputSequence<? extends A> x;
014            int[] y;
015            HashMap<String,TrainingSequence> componentMap;
016            
017            /** constructs a training sequence using just the input sequence.  The hidden sequence needs to be added later
018             * using setY.
019             * @param xArg the input sequence the hidden states correspond to
020             */
021            public TrainingSequence(InputSequence<? extends A> xArg) {
022                    this.x = xArg;
023            }
024            
025            /** constructs a training sequence using these input and hidden sequences
026             * @param xArg the input sequence the hidden states correspond to
027             * @param yArg the state indices of the values of the hidden states
028             */
029            public TrainingSequence(InputSequence<? extends A> xArg, int[] yArg) {
030                    this.x = xArg;
031                    this.y = yArg;
032                    Assert.a(y.length == x.length(), "Lengths differ between input and training sequences.  Hidden = " + y.length  + "   Observed = " + x.length());
033            }
034            
035            /** gets the underlying input sequence
036             * @return the underlying input sequence
037             */
038            public InputSequence<? extends A> getInputSequence() {
039                    return x;
040            }
041    
042            /** gets the vector of hidden state indices
043             * @return an array of ints containing the index of the hidden state at each position in the sequence */
044            public int[] getY() {
045                    return y;
046            }
047            
048            /** sets the vector of hidden state indices.  Must be the same length as the previsouly specified inputs
049             * @param hiddenStates an array of ints containing the index of the hidden state at each position in the sequence */
050            public void setY(int[] hiddenStates) {
051                    Assert.a(hiddenStates.length == x.length(), "Lengths differ between input and training sequences.  Hidden = " + hiddenStates.length  + "   Observed = " + x.length());
052                    y = hiddenStates;
053            }
054            
055            /** gets the hidden state index at a particular position
056             * @param x1 the 0-based position at which to get the hidden state index
057             * @return the hidden state index at this position
058             */
059            public int getY(int x1) {
060                    return y[x1];
061            }
062            
063            /** sets the hidden state index at a particular position
064             * @param x the 0-based position at which to get the hidden state index
065             * @param z the vlaue of the hidden state index to set for this position
066             */
067            public void setY(int x,int z) {
068                    y[x] = z;
069            }
070    
071            /** gets the value of the underlying input sequence at a particular position
072             * @param ix a zero-based index into the input sequence
073             * @return the value of the input sequence at the position
074             */
075            public A getX(int ix) {
076                    return x.getX(ix);
077            }
078    
079            /** gets the length of the input and training sequences
080             * @return the length of the training sequence
081             */
082            public int length() {
083                    return x == null ? 0 : x.length();
084            }
085            
086            public InputSequence<?> getComponent(String name) {
087                    return getTrainingComponent(name);
088            }
089    
090            public Collection<String> listComponents() {
091                    return x.listComponents();
092            }
093    
094            /** returns a new TrainingSequence created by taking a single component of the input sequence and
095             * pairing it with the hidden states for this Training Sequence.  The input sequence must be a composite.
096             * @param name the name of the component to extract from the composite input sequence
097             * @return a new TrainingSequence created from teh extracted input sequence component
098             */
099            public TrainingSequence getTrainingComponent(String name) {
100                    if(componentMap == null) {
101                            componentMap = new HashMap<String, TrainingSequence>();
102                    }
103                    TrainingSequence ret = componentMap.get(name);
104                    if(ret == null) {
105                            ret = new TrainingSequence(x.getComponent(name), y);
106                            componentMap.put(name, ret);
107                    }
108                    return ret;
109            }
110    
111            public TrainingSequence<A> subSequence(int start, int end) {              
112                    Assert.a(start >= 1);
113                    Assert.a(end <= this.length());
114                    Assert.a(start <= end);
115                    int[] newdata = new int[end-start+1];
116                    for (int j=0; j<(end-start+1); j++) {
117                            newdata[j] = y[j+start-1];
118                    }
119            
120                    TrainingSequence<A> TS = new TrainingSequence<A>(this.x.subSequence(start,end),newdata);    
121                    return TS;
122            }
123    
124            @Override
125            public String toString() {
126                    return x+ " + training.";
127            }
128    }