///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2018 F4EXB                                                      //
// written by Edouard Griffiths                                                  //
//                                                                               //
// This program is free software; you can redistribute it and/or modify          //
// it under the terms of the GNU General Public License as published by          //
// the Free Software Foundation as version 3 of the License, or                  //
// (at your option) any later version.                                           //
//                                                                               //
// This program is distributed in the hope that it will be useful,               //
// but WITHOUT ANY WARRANTY; without even the implied warranty of                //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
// GNU General Public License V3 for more details.                               //
//                                                                               //
// You should have received a copy of the GNU General Public License             //
// along with this program. If not, see <http://www.gnu.org/licenses/>.          //
///////////////////////////////////////////////////////////////////////////////////

#include "fixedtraits.h"

// 1.0 = 2^28 internal representation

// ln(1/2^n), n = index+1 then list is reversed
const int64_t FixedTraits<28>::log_two_power_n_reversed[35] = {
    0x18429946ELL,
    0x1791272EFLL,
    0x16DFB516FLL,
    0x162E42FF0LL,
    0x157CD0E70LL,
    0x14CB5ECF1LL,
    0x1419ECB71LL,
    0x13687A9F2LL,
    0x12B708872LL,
    0x1205966F3LL,
    0x115424573LL,
    0x10A2B23F4LL,
    0xFF140274LL,
    0xF3FCE0F5LL,
    0xE8E5BF75LL,
    0xDDCE9DF6LL,
    0xD2B77C76LL,
    0xC7A05AF7LL,
    0xBC893977LL,
    0xB17217F8LL,
    0xA65AF679LL,
    0x9B43D4F9LL,
    0x902CB379LL,
    0x851591FaLL,
    0x79FE707bLL,
    0x6EE74EFbLL,
    0x63D02D7BLL,
    0x58B90BFcLL,
    0x4DA1EA7CLL,
    0x428AC8FdLL,
    0x3773A77DLL,
    0x2C5C85FeLL,
    0x2145647ELL,
    0x162E42FfLL,
    0xB17217FLL
};

// ln(1+2^-n), n = index+1
const int64_t FixedTraits<28>::log_one_plus_two_power_minus_n[28] = {
    0x67CC8FBLL,
    0x391FEF9LL,
    0x1E27077LL,
    0xF85186LL,
    0x7E0A6CLL,
    0x3F8151LL,
    0x1FE02ALL,
    0xFF805LL,
    0x7FE01LL,
    0x3FF80LL,
    0x1FFE0LL,
    0xFFF8LL,
    0x7FFELL,
    0x4000LL,
    0x2000LL,
    0x1000LL,
    0x800LL,
    0x400LL,
    0x200LL,
    0x100LL,
    0x80LL,
    0x40LL,
    0x20LL,
    0x10LL,
    0x8LL,
    0x4LL,
    0x2LL,
    0x1LL
};

// ln(1/1-2^-n), n = index+1
const int64_t FixedTraits<28>::log_one_over_one_minus_two_power_minus_n[28] = {
    0xB172180LL,
    0x49A5884LL,
    0x222F1D0LL,
    0x108598BLL,
    0x820AECLL,
    0x408159LL,
    0x20202BLL,
    0x100805LL,
    0x80201LL,
    0x40080LL,
    0x20020LL,
    0x10008LL,
    0x8002LL,
    0x4001LL,
    0x2000LL,
    0x1000LL,
    0x800LL,
    0x400LL,
    0x200LL,
    0x100LL,
    0x80LL,
    0x40LL,
    0x20LL,
    0x10LL,
    0x8LL,
    0x4LL,
    0x2LL,
    0x1LL
};

const int64_t FixedTraits<28>::arctantab[32] = {
    297197971,
    210828714,
    124459457,
    65760959,
    33381290,
    16755422,
    8385879,
    4193963,
    2097109,
    1048571,
    524287,
    262144,
    131072,
    65536,
    32768,
    16384,
    8192,
    4096,
    2048,
    1024,
    512,
    256,
    128,
    64,
    32,
    16,
    8,
    4,
    2,
    1,
    0,
    0
};

// 1.0 = 2^16 internal representation

const int64_t  FixedTraits<16>::log_two_power_n_reversed[47] = {
    2135026LL,
    2089600LL,
    2044174LL,
    1998748LL,
    1953322LL,
    1907896LL,
    1862470LL,
    1817044LL,
    1771618LL,
    1726192LL,
    1680765LL,
    1635339LL,
    1589913LL,
    1544487LL,
    1499061LL,
    1453635LL,
    1408209LL,
    1362783LL,
    1317357LL,
    1271931LL,
    1226505LL,
    1181078LL,
    1135652LL,
    1090226LL,
    1044800LL,
    999374LL,
    953948LL,
    908522LL,
    863096LL,
    817670LL,
    772244LL,
    726817LL,
    681391LL,
    635965LL,
    590539LL,
    545113LL,
    499687LL,
    454261LL,
    408835LL,
    363409LL,
    317983LL,
    272557LL,
    227130LL,
    181704LL,
    136278LL,
    90852LL,
    45426LL
};

const int64_t  FixedTraits<16>::log_one_plus_two_power_minus_n[16] = {
    26573LL,
    14624LL,
    7719LL,
    3973LL,
    2017LL,
    1016LL,
    510LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<16>::log_one_over_one_minus_two_power_minus_n[16] = {
    45426LL,
    18854LL,
    8751LL,
    4230LL,
    2081LL,
    1032LL,
    514LL,
    257LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<16>::arctantab[32] = {
    72558LL,
    51471LL,
    30385LL,
    16054LL,
    8149LL,
    4090LL,
    2047LL,
    1023LL,
    511LL,
    255LL,
    127LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL
};

// 1.0 = 2^23 internal representation

const int64_t  FixedTraits<23>::log_two_power_n_reversed[40] = {
    232581599LL,
    226767059LL,
    220952519LL,
    215137979LL,
    209323439LL,
    203508899LL,
    197694359LL,
    191879819LL,
    186065279LL,
    180250740LL,
    174436200LL,
    168621660LL,
    162807120LL,
    156992580LL,
    151178040LL,
    145363500LL,
    139548960LL,
    133734420LL,
    127919880LL,
    122105340LL,
    116290800LL,
    110476260LL,
    104661720LL,
    98847180LL,
    93032640LL,
    87218100LL,
    81403560LL,
    75589020LL,
    69774480LL,
    63959940LL,
    58145400LL,
    52330860LL,
    46516320LL,
    40701780LL,
    34887240LL,
    29072700LL,
    23258160LL,
    17443620LL,
    11629080LL,
    5814540LL
};

const int64_t  FixedTraits<23>::log_one_plus_two_power_minus_n[23] = {
    3401288LL,
    1871864LL,
    988036LL,
    508556LL,
    258131LL,
    130059LL,
    65281LL,
    32704LL,
    16368LL,
    8188LL,
    4095LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<23>::log_one_over_one_minus_two_power_minus_n[23] = {
    5814540LL,
    2413252LL,
    1120143LL,
    541388LL,
    266327LL,
    132107LL,
    65793LL,
    32832LL,
    16400LL,
    8196LL,
    4097LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<23>::arctantab[32] = {
    9287436LL,
    6588397LL,
    3889358LL,
    2055029LL,
    1043165LL,
    523606LL,
    262058LL,
    131061LL,
    65534LL,
    32767LL,
    16383LL,
    8192LL,
    4096LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL
};

// 1.0 = 2^24 internal representation

const int64_t  FixedTraits<24>::log_two_power_n_reversed[39] = {
    453534119LL,
    441905039LL,
    430275959LL,
    418646879LL,
    407017799LL,
    395388719LL,
    383759639LL,
    372130559LL,
    360501479LL,
    348872399LL,
    337243319LL,
    325614239LL,
    313985159LL,
    302356079LL,
    290726999LL,
    279097919LL,
    267468839LL,
    255839759LL,
    244210679LL,
    232581599LL,
    220952519LL,
    209323439LL,
    197694359LL,
    186065279LL,
    174436200LL,
    162807120LL,
    151178040LL,
    139548960LL,
    127919880LL,
    116290800LL,
    104661720LL,
    93032640LL,
    81403560LL,
    69774480LL,
    58145400LL,
    46516320LL,
    34887240LL,
    23258160LL,
    11629080LL
};

const int64_t  FixedTraits<24>::log_one_plus_two_power_minus_n[24] = {
    6802576LL,
    3743728LL,
    1976071LL,
    1017112LL,
    516263LL,
    260117LL,
    130563LL,
    65408LL,
    32736LL,
    16376LL,
    8190LL,
    4096LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<24>::log_one_over_one_minus_two_power_minus_n[24] = {
    11629080LL,
    4826504LL,
    2240285LL,
    1082777LL,
    532655LL,
    264214LL,
    131587LL,
    65664LL,
    32800LL,
    16392LL,
    8194LL,
    4097LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL
};

const int64_t  FixedTraits<24>::arctantab[32] = {
    18574873LL,
    13176794LL,
    7778716LL,
    4110059LL,
    2086330LL,
    1047213LL,
    524117LL,
    262122LL,
    131069LL,
    65535LL,
    32767LL,
    16384LL,
    8192LL,
    4096LL,
    2048LL,
    1024LL,
    512LL,
    256LL,
    128LL,
    64LL,
    32LL,
    16LL,
    8LL,
    4LL,
    2LL,
    1LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL,
    0LL
};