c-kzg-4844/src/fft_fr_test.c

122 lines
4.6 KiB
C
Raw Normal View History

2021-02-01 20:15:45 +00:00
/*
* Copyright 2021 Benjamin Edgington
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "../inc/acutest.h"
2021-02-03 21:00:14 +00:00
#include "debug_util.h"
2021-02-01 20:15:45 +00:00
#include "fft_fr.h"
2021-02-04 21:23:34 +00:00
#include "blst_util.h"
2021-02-01 20:15:45 +00:00
const uint64_t inv_fft_expected[][4] =
{
{0x7fffffff80000008L, 0xa9ded2017fff2dffL, 0x199cec0404d0ec02L, 0x39f6d3a994cebea4L},
{0x27325dd08ac4cee9L, 0xcbb94f168ddacca9L, 0x6843be68485784b1L, 0x5a6faf9039451673L},
{0x16d00224dcf9382cL, 0xfee079062d1eaa93L, 0x3ce49204a2235046L, 0x163147176461030eL},
{0x10d6917f04735deaL, 0x7e04a13731049a48L, 0x42cbd9ab89d7b1f7L, 0x60546bd624850b42L},
{0x80007fff80000000L, 0x1fe05202bb00adffL, 0x6045d26b3fd26e6bL, 0x39f6d3a994cebea4L},
{0xe3388d354a80ed91L, 0x5849af2fc2cd4521L, 0xe3a64f3f31971b0bL, 0x33f1dda75bc30526L},
{0x16cf0224dcf9382cL, 0x12dd7903b71baa93L, 0xaf92c5362c204b76L, 0x163147176461030dL},
{0xf9925986d0d25e90L, 0xcdf85d0a339d7782L, 0xee7a9a5f0410e423L, 0x2e0d216170831056L},
{0x7fffffff80000000L, 0xa9ded2017fff2dffL, 0x199cec0404d0ec02L, 0x39f6d3a994cebea4L},
{0x066da6782f2da170L, 0x85c546f8cc60e47cL, 0x44bf3da90590f3e1L, 0x45e085f1b91a6cf1L},
{0xe930fdda2306c7d4L, 0x40e02aff48e2b16bL, 0x83a712d1dd818c8fL, 0x5dbc603bc53c7a3aL},
{0x1cc772c9b57f126fL, 0xfb73f4d33d3116ddL, 0x4f9388c8d80abcf9L, 0x3ffbc9abcdda7821L},
{0x7fff7fff80000000L, 0x33dd520044fdadffL, 0xd2f4059cc9cf699aL, 0x39f6d3a994cebea3L},
{0xef296e7ffb8ca216L, 0xd5b902cbcef9c1b6L, 0xf06dfe5c7fca260dL, 0x13993b7d05187205L},
{0xe92ffdda2306c7d4L, 0x54dd2afcd2dfb16bL, 0xf6554603677e87beL, 0x5dbc603bc53c7a39L},
{0xd8cda22e753b3117L, 0x880454ec72238f55L, 0xcaf6199fc14a5353L, 0x197df7c2f05866d4L}
};
2021-02-05 08:20:33 +00:00
void title(void) {;}
2021-02-01 20:15:45 +00:00
void compare_sft_fft(void) {
// Initialise: ascending values of i (could be anything), and arbitrary size
2021-02-02 23:06:42 +00:00
unsigned int size = 12;
FFTSettings fs;
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_SUCCESS);
2021-02-01 20:15:45 +00:00
blst_fr data[fs.max_width], out0[fs.max_width], out1[fs.max_width];
for (int i = 0; i < fs.max_width; i++) {
fr_from_uint64(data + i, i);
}
// Do both fast and slow transforms
2021-02-02 23:06:42 +00:00
fft_fr_slow(out0, data, 1, fs.expanded_roots_of_unity, 1, fs.max_width);
fft_fr_fast(out1, data, 1, fs.expanded_roots_of_unity, 1, fs.max_width);
2021-02-01 20:15:45 +00:00
// Verify the results are identical
for (int i = 0; i < fs.max_width; i++) {
TEST_CHECK(fr_equal(out0 + i, out1 + i));
}
free_fft_settings(&fs);
}
void roundtrip_fft(void) {
// Initialise: ascending values of i, and arbitrary size
unsigned int size = 12;
FFTSettings fs;
TEST_CHECK(new_fft_settings(&fs, size) == C_KZG_SUCCESS);
2021-02-01 20:15:45 +00:00
blst_fr data[fs.max_width], coeffs[fs.max_width];
for (int i = 0; i < fs.max_width; i++) {
fr_from_uint64(data + i, i);
}
// Forward and reverse FFT
2021-02-03 12:11:11 +00:00
TEST_CHECK(fft_fr(coeffs, data, &fs, false, fs.max_width) == C_KZG_SUCCESS);
TEST_CHECK(fft_fr(data, coeffs, &fs, true, fs.max_width) == C_KZG_SUCCESS);
2021-02-01 20:15:45 +00:00
// Verify that the result is still ascending values of i
for (int i = 0; i < fs.max_width; i++) {
blst_fr tmp;
fr_from_uint64(&tmp, i);
TEST_CHECK(fr_equal(&tmp, data + i));
}
free_fft_settings(&fs);
}
void inverse_fft(void) {
// Initialise: ascending values of i
FFTSettings fs;
TEST_CHECK(new_fft_settings(&fs, 4) == C_KZG_SUCCESS);
2021-02-01 20:15:45 +00:00
blst_fr data[fs.max_width], out[fs.max_width];
for (int i = 0; i < fs.max_width; i++) {
fr_from_uint64(&data[i], i);
}
// Inverst FFT
2021-02-03 12:11:11 +00:00
TEST_CHECK(fft_fr(out, data, &fs, true, fs.max_width) == C_KZG_SUCCESS);
2021-02-01 20:15:45 +00:00
// Verify against the known result, `inv_fft_expected`
int n = sizeof(inv_fft_expected) / sizeof(inv_fft_expected[0]);
TEST_CHECK(n == fs.max_width);
for (int i = 0; i < n; i++) {
blst_fr expected;
blst_fr_from_uint64(&expected, inv_fft_expected[i]);
TEST_CHECK(fr_equal(&expected, &out[i]));
}
free_fft_settings(&fs);
}
TEST_LIST =
{
2021-02-05 08:20:33 +00:00
{"FFT_FR_TEST", title},
2021-02-01 20:15:45 +00:00
{"compare_sft_fft", compare_sft_fft},
{"roundtrip_fft", roundtrip_fft},
{"inverse_fft", inverse_fft},
{ NULL, NULL } /* zero record marks the end of the list */
};