private Pool <ISenone> CreateTiedSenonePool(float distFloor, float varianceFloor)
        {
            var pool = new Pool <ISenone>("senones");

            var numMeans             = MeansPool.Size;
            var numVariances         = VariancePool.Size;
            var numGaussiansPerState = MixtureWeightsPool.GauPerState;
            var numSenones           = MixtureWeightsPool.StatesNum;
            var numStreams           = MixtureWeightsPool.StreamsNum;

            this.LogInfo("Senones " + numSenones);
            this.LogInfo("Gaussians Per State " + numGaussiansPerState);
            this.LogInfo("Means " + numMeans);
            this.LogInfo("Variances " + numVariances);

            Debug.Assert(numGaussiansPerState > 0);
            Debug.Assert(numVariances == _numBase * numGaussiansPerState * numStreams);
            Debug.Assert(numMeans == _numBase * numGaussiansPerState * numStreams);

            var meansTransformationMatrix = MeansTransformationMatrixPool == null ? null
                    : MeansTransformationMatrixPool.Get(0);
            var meansTransformationVector = MeansTransformationVectorPool == null ? null
                    : MeansTransformationVectorPool.Get(0);
            var varianceTransformationMatrix = VarianceTransformationMatrixPool == null ? null
                    : VarianceTransformationMatrixPool.Get(0);
            var varianceTransformationVector = VarianceTransformationVectorPool == null ? null
                    : VarianceTransformationVectorPool.Get(0);

            _phoneticTiedMixtures = new MixtureComponentSet[_numBase];
            for (var i = 0; i < _numBase; i++)
            {
                var mixtureComponents = new List <PrunableMixtureComponent[]>();
                for (var j = 0; j < numStreams; j++)
                {
                    var featMixtureComponents = new PrunableMixtureComponent[numGaussiansPerState];
                    for (var k = 0; k < numGaussiansPerState; k++)
                    {
                        var whichGaussian = i * numGaussiansPerState * numStreams + j * numGaussiansPerState + k;
                        featMixtureComponents[k] = new PrunableMixtureComponent(
                            MeansPool.Get(whichGaussian),
                            meansTransformationMatrix, meansTransformationVector,
                            VariancePool.Get(whichGaussian),
                            varianceTransformationMatrix,
                            varianceTransformationVector, distFloor, varianceFloor, k);
                    }
                    mixtureComponents.Add(featMixtureComponents);
                }
                _phoneticTiedMixtures[i] = new MixtureComponentSet(mixtureComponents, _topGauNum);
            }

            for (var i = 0; i < numSenones; i++)
            {
                ISenone senone = new SetBasedGaussianMixture(MixtureWeightsPool, _phoneticTiedMixtures[Senone2Ci[i]], i);
                pool.Put(i, senone);
            }
            return(pool);
        }
        /**
         * /// Creates the senone pool from the rest of the pools.
         * ///
         * /// @param distFloor
         * ///            the lowest allowed score
         * /// @param varianceFloor
         * ///            the lowest allowed variance
         * /// @return the senone pool
         */
        public Pool <ISenone> CreateSenonePool(float distFloor, float varianceFloor)
        {
            var pool                  = new Pool <ISenone>("senones");
            var numMeans              = MeansPool.Size;
            var numVariances          = VariancePool.Size;
            var numGaussiansPerSenone = MixtureWeightsPool.GauPerState;
            var numSenones            = MixtureWeightsPool.StatesNum;
            var numStreams            = MixtureWeightsPool.StreamsNum;
            var whichGaussian         = 0;

            this.LogInfo("Senones " + numSenones);
            this.LogInfo("Gaussians Per Senone " + numGaussiansPerSenone);
            this.LogInfo("Means " + numMeans);
            this.LogInfo("Variances " + numVariances);

            Debug.Assert(numGaussiansPerSenone > 0);
            Debug.Assert(numVariances == numSenones * numGaussiansPerSenone);
            Debug.Assert(numMeans == numSenones * numGaussiansPerSenone);

            var meansTransformationMatrix = MeansTransformationMatrixPool == null ? null
                    : MeansTransformationMatrixPool.Get(0);
            var meansTransformationVector = MeansTransformationVectorPool == null ? null
                    : MeansTransformationVectorPool.Get(0);
            var varianceTransformationMatrix = VarianceTransformationMatrixPool == null ? null
                    : VarianceTransformationMatrixPool.Get(0);
            var varianceTransformationVector = VarianceTransformationVectorPool == null ? null
                    : VarianceTransformationVectorPool.Get(0);

            for (var i = 0; i < numSenones; i++)
            {
                var mixtureComponents = new MixtureComponent[numGaussiansPerSenone
                                                             * numStreams];
                for (var j = 0; j < numGaussiansPerSenone; j++)
                {
                    mixtureComponents[j] = new MixtureComponent(
                        MeansPool.Get(whichGaussian),
                        meansTransformationMatrix, meansTransformationVector,
                        VariancePool.Get(whichGaussian),
                        varianceTransformationMatrix,
                        varianceTransformationVector, distFloor, varianceFloor);

                    whichGaussian++;
                }

                ISenone senone = new GaussianMixture(MixtureWeightsPool, mixtureComponents, i);
                pool.Put(i, senone);
            }
            return(pool);
        }
        public void Update(Transform transform, ClusteredDensityFileData clusters)
        {
            for (var index = 0; index < MeansPool.Size; index++)
            {
                var transformClass = clusters.GetClassIndex(index);
                var tmean          = new float[VectorLength[0]];
                var mean           = MeansPool.Get(index);

                for (var l = 0; l < VectorLength[0]; l++)
                {
                    tmean[l] = 0;
                    for (var m = 0; m < VectorLength[0]; m++)
                    {
                        tmean[l] += transform.As[transformClass][0][l][m]
                                    * mean[m];
                    }
                    tmean[l] += transform.Bs[transformClass][0][l];
                }
                Array.Copy(tmean, 0, mean, 0, tmean.Length);
            }
        }