コード例 #1
0
        private void UpdateModel(PpmContext minimumContext)
        {
            PpmState   state = PpmState.Zero;
            PpmContext Successor;
            PpmContext currentContext = maximumContext;
            uint       numberStatistics;
            uint       ns1;
            uint       cf;
            uint       sf;
            uint       s0;
            uint       foundStateFrequency = foundState.Frequency;
            byte       foundStateSymbol    = foundState.Symbol;
            byte       symbol;
            byte       flag;

            PpmContext foundStateSuccessor = foundState.Successor;
            PpmContext context             = minimumContext.Suffix;

            if ((foundStateFrequency < MaximumFrequency / 4) && (context != PpmContext.Zero))
            {
                if (context.NumberStatistics != 0)
                {
                    state = context.Statistics;
                    if (state.Symbol != foundStateSymbol)
                    {
                        do
                        {
                            symbol = state[1].Symbol;
                            state++;
                        } while (symbol != foundStateSymbol);
                        if (state[0].Frequency >= state[-1].Frequency)
                        {
                            Swap(state[0], state[-1]);
                            state--;
                        }
                    }
                    cf = (uint)((state.Frequency < MaximumFrequency - 9) ? 2 : 0);
                    state.Frequency          += (byte)cf;
                    context.SummaryFrequency += (byte)cf;
                }
                else
                {
                    state            = context.FirstState;
                    state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
                }
            }

            if (orderFall == 0 && foundStateSuccessor != PpmContext.Zero)
            {
                foundState.Successor = CreateSuccessors(true, state, minimumContext);
                if (foundState.Successor == PpmContext.Zero)
                {
                    goto RestartModel;
                }
                maximumContext = foundState.Successor;
                return;
            }

            Allocator.Text[0] = foundStateSymbol;
            Allocator.Text++;
            Successor = Allocator.Text;

            if (Allocator.Text >= Allocator.BaseUnit)
            {
                goto RestartModel;
            }

            if (foundStateSuccessor != PpmContext.Zero)
            {
                if (foundStateSuccessor < Allocator.BaseUnit)
                {
                    foundStateSuccessor = CreateSuccessors(false, state, minimumContext);
                }
            }
            else
            {
                foundStateSuccessor = ReduceOrder(state, minimumContext);
            }

            if (foundStateSuccessor == PpmContext.Zero)
            {
                goto RestartModel;
            }

            if (--orderFall == 0)
            {
                Successor       = foundStateSuccessor;
                Allocator.Text -= (maximumContext != minimumContext) ? 1 : 0;
            }
            else if (method > ModelRestorationMethod.Freeze)
            {
                Successor      = foundStateSuccessor;
                Allocator.Text = Allocator.Heap;
                orderFall      = 0;
            }

            numberStatistics = minimumContext.NumberStatistics;
            s0   = minimumContext.SummaryFrequency - numberStatistics - foundStateFrequency;
            flag = (byte)((foundStateSymbol >= 0x40) ? 0x08 : 0x00);
            for (; currentContext != minimumContext; currentContext = currentContext.Suffix)
            {
                ns1 = currentContext.NumberStatistics;
                if (ns1 != 0)
                {
                    if ((ns1 & 1) != 0)
                    {
                        state = Allocator.ExpandUnits(currentContext.Statistics, (ns1 + 1) >> 1);
                        if (state == PpmState.Zero)
                        {
                            goto RestartModel;
                        }
                        currentContext.Statistics = state;
                    }
                    currentContext.SummaryFrequency += (ushort)((3 * ns1 + 1 < numberStatistics) ? 1 : 0);
                }
                else
                {
                    state = Allocator.AllocateUnits(1);
                    if (state == PpmState.Zero)
                    {
                        goto RestartModel;
                    }
                    Copy(state, currentContext.FirstState);
                    currentContext.Statistics = state;
                    if (state.Frequency < MaximumFrequency / 4 - 1)
                    {
                        state.Frequency += state.Frequency;
                    }
                    else
                    {
                        state.Frequency = (byte)(MaximumFrequency - 4);
                    }
                    currentContext.SummaryFrequency =
                        (ushort)(state.Frequency + initialEscape + ((numberStatistics > 2) ? 1 : 0));
                }

                cf = (uint)(2 * foundStateFrequency * (currentContext.SummaryFrequency + 6));
                sf = s0 + currentContext.SummaryFrequency;

                if (cf < 6 * sf)
                {
                    cf = (uint)(1 + ((cf > sf) ? 1 : 0) + ((cf >= 4 * sf) ? 1 : 0));
                    currentContext.SummaryFrequency += 4;
                }
                else
                {
                    cf = (uint)(4 + ((cf > 9 * sf) ? 1 : 0) + ((cf > 12 * sf) ? 1 : 0) + ((cf > 15 * sf) ? 1 : 0));
                    currentContext.SummaryFrequency += (ushort)cf;
                }

                state                 = currentContext.Statistics + (++currentContext.NumberStatistics);
                state.Successor       = Successor;
                state.Symbol          = foundStateSymbol;
                state.Frequency       = (byte)cf;
                currentContext.Flags |= flag;
            }

            maximumContext = foundStateSuccessor;
            return;

RestartModel:
            RestoreModel(currentContext, minimumContext, foundStateSuccessor);
        }