/** * Constructor. */ public Jackknife(JackknifeBlades blades) { if (!(blades.InnerProduct ^ blades.EuclideanDistance)) { throw new ArgumentException("!(blades.InnerProduct ^ blades.EuclideanDistance)"); } this.Blades = blades; templates = new List <JackknifeTemplate>(); }
/** * Constructor. */ public Jackknife(JackknifeBlades blades) { if (!(blades.InnerProduct ^ blades.EuclideanDistance)) { throw new ArgumentException("!(blades.InnerProduct ^ blades.EuclideanDistance)"); } this.Blades = blades; templates = new List <JackknifeTemplate>(); templateLenghts = new Dictionary <int, int>(); maxTemplateLen = 0; minTemplateLen = int.MaxValue; }
/** * Constructor. */ public JackknifeTemplate(JackknifeBlades blades, Sample sample) { this.Sample = sample; GestureId = sample.GestureId; // Any default value less than zero will ensure if // lower bounding is disabled, we don't cull any // instance. LB = -1; // A default value of one will ensure that the DTW // score is not modified when all correction factors // are disabled. CF = 1; // A default value that will never cause rejection. // So if the recognizer is not trained, things will // still work as expected. RejectionThreshold = double.PositiveInfinity; Lower = new List <Vector>(); Upper = new List <Vector>(); // Extract import information about the sample. Features = new JackknifeFeatures(blades, sample.Trajectory); List <Vector> vecs = Features.Vecs; int componentCnt = vecs[0].Size; // For each component find the min and max value // within the radius (Sakoe-Chiba band). for (int i = 0; i < vecs.Count; i++) { Vector maximum = new Vector(double.NegativeInfinity, componentCnt); Vector minimum = new Vector(double.PositiveInfinity, componentCnt); for (int j = Math.Max(0, i - blades.Radius); j < Math.Min(i + blades.Radius + 1, vecs.Count); j++) { for (int k = 0; k < componentCnt; k++) { maximum[k] = Math.Max(maximum[k], vecs[j][k]); minimum[k] = Math.Min(minimum[k], vecs[j][k]); } } Upper.Add(maximum); Lower.Add(minimum); } }
/** * The main data extraction work is done in the constructor. * * This is where we: * * 1) Resample the trajectory to a fixed number * of points (resample_cnt). * * 2) Calculate the normalized direction vector * between each resampled point or the z-score * normalized points. * * 3) Extract correction factor related data. * * It is highly recommended that the sample trajectory points * have been smoothed with a low pass filter before calling * this function. A simple exponential smoothing filter will * probably be adequate for most case. */ public JackknifeFeatures(JackknifeBlades blades, List <Vector> points) { this.Vecs = new List <Vector>(); // Number of components per point. int m = points[0].Size; // resample the trajectory to a fixed number of points this.Pts = Mathematics.Resample(points, blades.ResampleCnt); // To track the bounding box widths, // start with one point and expand. Vector minimum = new Vector(Pts[0].Data); Vector maximum = new Vector(Pts[0].Data); // The abs distance traversed starts with zeros. this.Abs = new Vector(0, m); // Incrementally extract information. for (int i = 1; i < blades.ResampleCnt; i++) { // In-between point direction vector. Vector vec = Pts[i] - Pts[i - 1]; // Update correction factor features. for (int j = 0; j < m; j++) { this.Abs[j] += Math.Abs(vec[j]); minimum[j] = Math.Min(minimum[j], Pts[i][j]); maximum[j] = Math.Max(maximum[j], Pts[i][j]); } // Save the points or direction vectors, // depending on the selected measure. if (blades.InnerProduct) { this.Vecs.Add(vec.Normalize()); } else if (blades.EuclideanDistance) { // In ED scenario, make sure not to forget first point as // loop starts at 1. if (i == 1) { this.Vecs.Add(Pts[0]); } this.Vecs.Add(Pts[i]); } else { throw new Exception("This should not happen!"); } } // Z-score normalize the vecs if required, // typically only if using euclidean distance if (blades.ZNormalize) { Mathematics.ZNormalize(this.Vecs); } // normalize the correction factor vectors this.Abs.Normalize(); this.Bb = (maximum - minimum).Normalize(); }