/// <summary> /// Puts a sample into statistics. /// </summary> /// <param name="linXform">Linear transform.</param> public void Put(LinXForm linXform) { Helper.ThrowIfNull(linXform); for (int i = 0; linXform.Bias != null && i < linXform.Bias.Length; i++) { Bias[i].Put(linXform.Bias[i]); } for (int i = 0; i < linXform.Blocks.Count; i++) { UniStatistic[,] staticBlock = Blocks[i]; float[,] block = linXform.Blocks[i]; for (int j = 0; j < linXform.Blocks[i].GetLength(0); j++) { for (int k = 0; k < linXform.Blocks[i].GetLength(1); k++) { staticBlock[j, k].Put(block[j, k]); } } } }
/// <summary> /// Loads one linear transform from the stream. /// </summary> /// <param name="sr">Stream reader that contains the transform matrix.</param> /// <returns>The loaded linear transform.</returns> private LinXForm LoadLinearTransform(StreamReader sr) { LinXForm xform = new LinXForm(); Regex idPattern = new Regex(@"<LINXFORM>\s+(\d+)"); Regex vecSizePattern = new Regex(@"<VECSIZE>\s+(\d+)"); Regex biasPattern = new Regex(@"<BIAS>\s+(\d+)"); string offsetTag = "<OFFSET>", blockInfoTag = "<BLOCKINFO>"; // Process "<LINXFORM> " string line = sr.ReadLine(); Match match = idPattern.Match(line); Debug.Assert(match.Success); xform.ID = int.Parse(match.Groups[1].Value); // Process "<VECSIZE> " line = sr.ReadLine(); match = vecSizePattern.Match(line); Debug.Assert(match.Success); xform.VecSize = int.Parse(match.Groups[1].Value); // Process "<OFFSET>" in mean form or "<LOGDET>" in var form line = sr.ReadLine(); if (line == offsetTag) { // Process "<BIAS>" line = sr.ReadLine(); match = biasPattern.Match(line); Debug.Assert(match.Success); xform.Bias = new float[int.Parse(match.Groups[1].Value)]; line = sr.ReadLine(); string[] sArr = line.Trim().Split(new char[] { ' ' }); Debug.Assert(xform.Bias.Length == sArr.Length); for (int i = 0; i < xform.Bias.Length; ++i) { xform.Bias[i] = float.Parse(sArr[i]); } } while (!line.StartsWith(blockInfoTag)) { line = sr.ReadLine(); } // Process "<BLOCKINFO> " string[] strArr = line.Split(new char[] { ' ' }); Debug.Assert(strArr[0] == blockInfoTag); int numBlock = int.Parse(strArr[1]); for (int i = 0; i < numBlock; ++i) { int blockSize = int.Parse(strArr[i + 2]); float[,] matrix = new float[blockSize, blockSize]; xform.Blocks.Add(matrix); sr.ReadLine(); // Skip "<BLOCK>" sr.ReadLine(); // Skip "<XFORM>" // Loads transform matrix value. for (int j = 0; j < blockSize; ++j) { line = sr.ReadLine(); string[] sArr = line.Trim().Split(new char[] { ' ' }); Debug.Assert(blockSize == sArr.Length); for (int k = 0; k < blockSize; ++k) { matrix[j, k] = float.Parse(sArr[k]); } } } return xform; }
/// <summary> /// Puts a sample into this list. /// </summary> /// <param name="linXform">Linear transform.</param> /// <param name="streamOrder">Dynamic stream order.</param> public void Put(LinXForm linXform, DynamicOrder streamOrder) { Helper.ThrowIfNull(linXform); if (!_linXformStatistics.ContainsKey(streamOrder)) { _linXformStatistics.Add(streamOrder, new LinXformStatistic(linXform)); } _linXformStatistics[streamOrder].Put(linXform); }
/// <summary> /// Initializes a new instance of the LinXformStatistic class. /// </summary> /// <param name="linXform">Linear transform.</param> public LinXformStatistic(LinXForm linXform) { if (linXform.Bias != null) { _bias = new UniStatistic[linXform.Bias.Length]; for (int i = 0; i < _bias.Length; i++) { _bias[i] = new UniStatistic(); } } _blocks = new List<UniStatistic[,]>(); for (int i = 0; i < linXform.Blocks.Count; i++) { float[,] block = linXform.Blocks[i]; UniStatistic[,] matrix = new UniStatistic[block.GetLength(0), block.GetLength(1)]; for (int j = 0; j < block.GetLength(0); j++) { for (int k = 0; k < block.GetLength(1); k++) { matrix[j, k] = new UniStatistic(); } } _blocks.Add(matrix); } }
/// <summary> /// Write out one linear transform to be 4-byte aligned. /// </summary> /// <param name="writer">Binary writer.</param> /// <param name="linXform">Linear transform to write out.</param> /// <param name="streamOrder">Dynamic order of the stream of current linear transform.</param> /// <param name="hasBias">Indicate transform whether has bias info.</param> /// <param name="bandWidth">Band width of linear transform matrix.</param> /// <returns>Number of bytes written out.</returns> protected uint WriteFourBytesAlignedLinXform(DataWriter writer, LinXForm linXform, DynamicOrder streamOrder, bool hasBias, uint bandWidth = 0) { Helper.ThrowIfNull(writer); Helper.ThrowIfNull(linXform); uint size = Write(writer, linXform, streamOrder, hasBias, bandWidth); if (size == 0) { throw new InvalidDataException(Helper.NeutralFormat("Zero length of linXform is not allowed.")); } // Pad zero bytes if needed to align with 4-bytes if (size % sizeof(uint) > 0) { size += writer.Write(new byte[sizeof(uint) - (size % sizeof(uint))]); } Debug.Assert(size % sizeof(uint) == 0, "Data should be 4-byte aligned."); return size; }
/// <summary> /// Read linear transform. /// </summary> /// <param name="reader">Binary reader to read linear transform.</param> /// <param name="dimension">Dimension of the linear transform to read.</param> /// <param name="blockSizes">Size of each linear transform sub matrix to read.</param> /// <param name="streamOrder">The dynamic order of current linear transform to read.</param> /// <param name="hasBias">Indicate transform whether has bias info.</param> /// <param name="bandWidth">Band width of linear transform matrix.</param> /// <returns>Linear transform.</returns> protected virtual LinXForm ReadOneLinXform(BinaryReader reader, int dimension, List<int> blockSizes, DynamicOrder streamOrder, bool hasBias, uint bandWidth) { Helper.ThrowIfNull(reader); LinXForm linXform = new LinXForm(); linXform.VecSize = dimension; if (hasBias) { Debug.Assert(Config.BiasBits == sizeof(float) * 8, "Only 32-bit float value is supported here"); linXform.Bias = new float[dimension]; for (int i = 0; i < linXform.VecSize; i++) { linXform.Bias[i] = reader.ReadSingle(); } } Debug.Assert(Config.MatrixBits == sizeof(float) * 8, "Only 32-bit float value is supported here"); for (int i = 0; i < blockSizes.Count; i++) { float[,] block = new float[blockSizes[i], blockSizes[i]]; for (int j = 0; j < blockSizes[i]; j++) { for (int k = 0; k < blockSizes[i]; k++) { if (k < j - bandWidth || k > j + bandWidth) { block[j, k] = 0; } else { block[j, k] = reader.ReadSingle(); } } } linXform.Blocks.Add(block); } return linXform; }
/// <summary> /// Write out linear transform. /// </summary> /// <param name="writer">Binary writer.</param> /// <param name="linXform">Linear transform.</param> /// <param name="streamOrder">The dynamic order of stream, to which the linear transform belongs.</param> /// <param name="hasBias">Indicate transform whether has bias info.</param> /// <param name="bandWidth">Band width of linear transform matrix.</param> /// <returns>Size of bytes written.</returns> protected virtual uint Write(DataWriter writer, LinXForm linXform, DynamicOrder streamOrder, bool hasBias, uint bandWidth) { Helper.ThrowIfNull(writer); Helper.ThrowIfNull(linXform); uint size = 0; Debug.Assert(Config.BiasBits == sizeof(float) * 8, "Only 32-bit float value is supported here"); Debug.Assert(Config.MatrixBits == sizeof(float) * 8, "Only 32-bit float value is supported here"); for (int i = 0; hasBias && i < linXform.VecSize; i++) { size += writer.Write(linXform.Bias[i]); } for (int i = 0; i < linXform.Blocks.Count; i++) { for (int j = 0; j < linXform.Blocks[i].GetLength(0); j++) { for (int k = 0; k < linXform.Blocks[i].GetLength(1); k++) { if (k >= j - bandWidth && k <= j + bandWidth) { size += writer.Write(linXform.Blocks[i][j, k]); } } } } return size; }
/// <summary> /// Read linear transform. /// </summary> /// <param name="reader">Binary reader to read linear transforms.</param> /// <param name="dimension">Dimension of the linear transform to read.</param> /// <param name="blockSizes">Size of each linear transform sub matrix to read.</param> /// <param name="streamOrder">The dynamic order of current linear transform to read.</param> /// <param name="meanXform">Transform for Gaussian mean.</param> /// <param name="varXform">Transform for Gaussian variance.</param> public virtual void ReadLinXform(BinaryReader reader, int dimension, List<int> blockSizes, DynamicOrder streamOrder, out LinXForm meanXform, out LinXForm varXform) { Helper.ThrowIfNull(reader); long orgPos = reader.BaseStream.Position; meanXform = null; varXform = null; if (Config.HasMeanXform) { meanXform = ReadFourBytesAlignedLinXform(reader, dimension, blockSizes, streamOrder, Config.HasMeanBias, Config.MeanBandWidth); } if (Config.HasVarXform) { varXform = ReadFourBytesAlignedLinXform(reader, dimension, blockSizes, streamOrder, Config.HasVarBias); } if (Encoder != null) { // ramp up the encoder long size = reader.BaseStream.Position - orgPos; reader.BaseStream.Position = orgPos; Encoder.WarmUpData(reader.ReadBytes((int)size), 1); } }
public virtual uint Write(DataWriter writer, LinXForm meanXform, LinXForm varXform, DynamicOrder streamOrder) { Helper.ThrowIfNull(writer); Helper.ThrowIfNull(meanXform); Helper.ThrowIfNull(varXform); DataWriter orgWriter = writer; MemoryStream linXformsBuf = null; if (EnableCompress) { linXformsBuf = new MemoryStream(); writer = new DataWriter(linXformsBuf); } uint size = 0; if (Config.HasMeanXform) { MeanStatistic.Put(meanXform, streamOrder); size += WriteFourBytesAlignedLinXform(writer, meanXform, streamOrder, Config.HasMeanBias, Config.MeanBandWidth); } if (Config.HasVarXform) { VarStatistic.Put(varXform, streamOrder); size += WriteFourBytesAlignedLinXform(writer, varXform, streamOrder, Config.HasVarBias); } if (EnableCompress) { size = orgWriter.Write(Encoder.Encode(linXformsBuf.ToArray())); if (size % sizeof(uint) != 0) { size += orgWriter.Write(new byte[sizeof(uint) - (size % sizeof(uint))]); } writer = orgWriter; } return size; }