# Thread: fcm1 - open source order-1 cm encoder

1. ## fcm1 - open source order-1 cm encoder

OK, let me introduce some encoder. Continuing fpaq0f2-like, experimental encoders, I made a new one - check out my variant of an order-1 cm. Source code included:
fcm1.zip

2. Brief description:

Each counter consists from a two states a la FPAQ0P - fast and slow one, which are summarized together.

For mixing a probabilities from order-1 and order-0 we use followed formula:

((p2*3)+p1)/4

p2 - Probability from an order-1 context
p1 - Probability from an order-0 context

If:
p2 = 0.5
i.e. order-1 context for the first time occurs, we use probability from an order-0 only.

Any thoughts?

EDIT:
In final version, we use:
((p2*15)+p1)/16

3. Originally Posted by encode
OK, let me introduce some encoder. Continuing fpaq0f2-like, experimental encoders, I made a new one - check out my variant of an order-1 cm. Source code included:
fcm1.zip

Thanks Ilia! I have uploaded it to my site along with my own speed optimised compile.

4. One can't generalize this, but you give far too much weight to order 0. The 2d SSE visualizations (SSE for mixing) in the old form showed that the SSE function mostly looked like a plane, which was dominated by the order 1 model. That means, order 0 gave almost no contribution.
How much does your slow counter/fast counter mix improve over a standalone counter?

5. Originally Posted by toffer
How much does your slow counter/fast counter mix improve over a standalone counter?
Notable difference... You may check it for yourself!

6. Updated archive with a new compile which is at almost 2X times faster!

7. Hm as i said giving order 0 such a high weight is totally wrong:

-> 22.459.785 bytes (plain order1) vs. 23.783.905 bytes (orders01) on SFC

I just changed this:

Code:
//  int P() {
//    int p1=counter0[c0].P();
//    int p2=counter1[c1][c0].P();
//
//    return (p2!=(1<<16)?((p2*3)+p1)>>7:p1>>5);
//  }

int P() {
return counter1[c1][c0].P()>>5;
}

8. I'm not so sure. It's a matter of tuning for specific file type and specific situation...

Static weights form PAQ1 are: 4, 9, 16, ...

sfc.7z:
p2*3: 23,789,646 bytes
p2*7: 22,869,851 bytes
p2*15: 22,535,420 bytes
plain order-1: 22,487,664 bytes
p2*31: 22,425,582 bytes
p2*63: 22,403,145 bytes
...

9. Originally Posted by encode
Updated archive with a new compile which is at almost 2X times faster!
Originally Posted by toffer
Hm as i said giving order 0 such a high weight is totally wrong:

-> 22.459.785 bytes (plain order1) vs. 23.783.905 bytes (orders01) on SFC

I just changed this:

Code:
//  int P() {
//    int p1=counter0[c0].P();
//    int p2=counter1[c1][c0].P();
//
//    return (p2!=(1<<16)?((p2*3)+p1)>>7:p1>>5);
//  }

int P() {
return counter1[c1][c0].P()>>5;
}
Thanks Ilia, and toffer! I have updated my archive.