Extended polynomials in library NTL - c++

There is code is written using NTL library:
int main()
{
ZZ_p::init(ZZ(5)); // define GF(5)
ZZ_pX P;
BuildIrred(P, 4); // generate an irreducible polynomial P
// of degree 4 over GF(5)
ZZ_pE::init(P); // define GF(5^4)
ZZ_pEX f, g, h; // declare polynomials over GF(5^4)
random(f, 3); // f is a random, monic polynomial of degree 3
SetCoeff(f, 3);
cout << f << endl<< endl;
}
The output is:
[[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]]
For example, [1 2 3] is mean 3x² + 2x + 1.
What the form of notation polynomial over GF in this case?

Your question is a little bit difficult to understand. If I understand you right, the question is how to interpret the NTL representation [[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]] of a polynomial over the finite field with 5⁴ elements.
First: The elements in the finite field with 5⁴ elements (called GF(5⁴)) are represented as the polynomials GF(5)[X] mod f, where f is an irreducible polynomial of degree 4.
This means a polynomial over GF(5⁴) is a Polynomial where the coefficients are polynomials in GF(5)[X] mod f.
So [[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]] can be interpreted as
Y³ + (X³ + 3X² + 1)⋅Y² + (2X³ + 3X² + X + 2)⋅Y + (4X³ + X² + X + 3)
Notice: The comment in
random(f, 3); // f is a random, monic polynomial of degree 3
SetCoeff(f, 3);
is a little bit misleading. random(f,3) sets f to a random polynomial of degree less than 3. SetCoeff(f, 3) sets the coefficient of Y³ to 1 and after that it is a polynomial of degree 3.

Related

Can you get a list of the powers in a polynomial? Pari GP

I'm working with single variable polynomials with coefficients +1/-1 (and zero). These can be very long and the range of powers can be quite big. It would be convenient for me to view the powers as a vector - is there any way of doing this quickly? I had hoped there would be a command already in Pari to do this, but I can't seem to see one?
Just an example to confirm what I'm trying to do...
Input:x^10 - x^8 + x^5 - x^2 + x + 1
Desired output: [10, 8, 5, 2, 1, 0]
You can use Vecrev to get the polynomial coefficients. After that just enumerate them to select the zero-based positions of non-zeros. You want the following one-liner:
nonzeros(xs) = Vecrev([x[2]-1 | x <- select(x -> x[1] != 0, vector(#xs, i, [xs[i], i]))])
Now you can easily get the list of polynomial powers:
p = x^10 - x^8 + x^5 - x^2 + x + 1
nonzeros(Vecrev(p))
>> [10, 8, 5, 2, 1, 0]

Extend/Pad matrix in Eigen

Say I have
A = [1 2 3]
[4 5 6]
[7 8 9]
I want to pad it with the first row and first column or last row and last column as many times as needed to create A nxn. For example, A 4x4 would be
A = [1 1 2 3]
[1 1 2 3]
[4 4 5 6]
[7 7 8 9]
and A 5x5 would be
A = [1 1 2 3 3]
[1 1 2 3 3]
[4 4 5 6 6]
[7 7 8 9 9]
[7 7 8 9 9]
I'm aware that I could do A.conservativeResize(4,4) which gets me
A = [1 2 3 0]
[4 5 6 0]
[7 8 9 0]
[0 0 0 0]
then I could copy things around one by one, but is there a more efficient way to do this using Eigen?
You can workaround using a nullary-expression:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
Matrix3i A;
A.reshaped() = VectorXi::LinSpaced(9,1,9);
cout << A << "\n\n";
int N = 5;
MatrixXi B(N,N);
B = MatrixXi::NullaryExpr(N, N, [&A,N] (Index i,Index j) {
return A( std::max<Index>(0,i-(N-A.rows())),
std::max<Index>(0,j-(N-A.cols())) ); } );
cout << B << "\n\n";
}
Another approach would be to create a clamped sequence of indices like [0 0 0 1 2]:
struct pad {
Index size() const { return m_out_size; }
Index operator[] (Index i) const { return std::max<Index>(0,i-(m_out_size-m_in_size)); }
Index m_in_size, m_out_size;
};
B = A(pad{3,N}, pad{3,N});
This version requires the head of Eigen.
You can easily build on those examples to make them even more general and/or wrap them within functions.
Just as a note, it's not true that A.conservativeResize(4,4) will get you a matrix with the added rows filled with zeros. The Eigen documentation says,
In case values need to be appended to the matrix they will be uninitialized.
The new rows and columns will be filled with garbage, and seeing zeros is only a coincidence (unless you are compiling with a special preprocessor directive to Eigen). But this means that no unnecessary time is wasted writing zeros that you will overwrite anyway.
Note: this code demonstrates how to get a matrix with your original matrix in the top left corner:
The best way to fill multiple values at once is to use Eigen's block operations and setConstant. For example, if A is a matrix of size old_sizexold_size:
A.conservativeResize(n, n);
for (int i = 0; i < n; ++i) {
// Fill the end of each row and column
A.row(i).tail(n - old_size).setConstant(A(i, old_size - 1));
A.col(i).tail(n - old_size).setConstant(A(old_size - 1, i));
}
// Fill the bottom right block
A.bottomRightCorner(n - old_size, n - old_size).setConstant(A(old_size - 1, old_size - 1));
More importantly than being "efficient", these functions express your intent as a programmer.
Edit: To get a padded matrix with your original matrix in the middle:
I just noticed your example pads around the original matrix in the middle, not in the top left. In this case, there is little point to using conservativeResize(), because the original values will only be copied to the top left corner. An outline of the solution is:
Construct a new nxn matrix B of the desired size
Copy your original matrix to the middle using
int start = (n - old_size + 1)/2;
B.block(start, start, old_size, old_size) = A;
Fill in the outside values using block operations similar to my example above.

Recursive function (help me understand it by pen and paper)

First of all I have to say that I can use recursive functions on easy examples like Fibonacci, but I can't understand how to dry run (solve with pen and paper) this recursion :
#include<iostream>
using namespace std;
int max(int a, int b)
{
if(a>b)return a;
return b;
}
int f(int a, int b)
{
if(a==0)return b;
return max( f(a-1,2*b), f(a-1,2*b+1) );
}
int main()
{
cout<<f(8,0);
}
How do I do this with pen and paper, with say, a = 5 and b = 6?
We have always a depth of a (8)
Each invocations calls itself 2 times, once 2b and once 2b+1 is passed
The greater result of both calls is returned
As 2b + 1 > 2b only the right site of the max call is meaningful (2b + 1)
Now lets do the first iterations mathematically:
2 * b + 1 = 2^1 * b + 2^0
2 * (2^1 * b + 2^0) + 1 = 2^2 * b + 2^1 + 2^0
2 * (2^2 * b + 2^1 + 2^0) + 1 = 2^3 * b + 2^2 + 2^1 + 2^0
2 * (2^3 * b + 2^2 + 2^1 + 2^0) + 1 = 2^4 * b + 2^3 + 2^2 + 2^1 + 2^0
As you can see there is a system behind it. Because b = 0 for the first iteration, we can ignore the left side. The final value is thus:
2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7
=
1 + 2 + 4 + 8 + 16 + 32 + 64 + 128
=
255
If we run the programm we get the exact same value
Just to give some information there are algorithms that use a little more complex parameters, one basic example would be mergesort
Merging is simple:
Take two elements one from each array A and B.
Compare them and place smaller of two (say from A) in sorted list.
Take next element from A and compare with element in hand (from B).
Repeat until one of the array is exhausted.
Now place all remaining elements of non-empty array one by one.
Maybe you can find this doc useful
Or maybe this one
Assuming you want to analyzse the funciton on paper, I'll paste the result for f(1, 2)
f(2, 1) =
max( f(1, 2), f(1, 3) ) =
max ( max(f(0, 4), f(0, 5) , max(f(0, 6), f(0, 7) ) =
max ( max(4, 5) , max(6, 7) ) =
max (5, 7) =
7
Is up to you to follow the computations
Note: I'm also assuming you didn't miss a parenthesis here: 2*b+1

Find n-th set of a powerset

I'm trying to find the n-th set in a powerset. By n-th I mean that the powerset is generated in the following order -- first by the size, and then, lexicographically --, and so, the indices of the sets in the powerset of [a, b, c] is:
0 - []
1 - [a]
2 - [b]
3 - [c]
4 - [a, b]
5 - [a, c]
6 - [b, c]
7 - [a, b, c]
While looking for a solution, all I could find was an algorithm to return the n-th permutation of a list of elements -- for example, here.
Context:
I'm trying to retrieve the entire powerset of a vector V of elements, but I need to do this with one set at a time.
Requirements:
I can only maintain two vectors at the same time, the first one with the original items in the list, and the second one with the n-th set from the powerset of V -- that's why I'm willing to have an n-th set function here;
I need this to be done not in linear time on the space of solutions -- which means it cannot list all the sets and them pick the n-th one;
my initial idea is to use bits to represent the positions, and get a valid mapping for what I need -- as the "incomplete" solution I posted.
I don't have a closed form for the function, but I do have a bit-hacking non-looping next_combination function, which you're welcome to, if it helps. It assumes that you can fit the bit mask into some integer type, which is probably not an unreasonable assumption given that there are 264 possibilities for the 64-element set.
As the comment says, I find this definition of "lexicographical ordering" a bit odd, since I'd say lexicographical ordering would be: [], [a], [ab], [abc], [ac], [b], [bc], [c]. But I've had to do the "first by size, then lexicographical" enumeration before.
// Generate bitmaps representing all subsets of a set of k elements,
// in order first by (ascending) subset size, and then lexicographically.
// The elements correspond to the bits in increasing magnitude (so the
// first element in lexicographic order corresponds to the 2^0 bit.)
//
// This function generates and returns the next bit-pattern, in circular order
// (so that if the iteration is finished, it returns 0).
//
template<typename UnsignedInteger>
UnsignedInteger next_combination(UnsignedInteger comb, UnsignedInteger mask) {
UnsignedInteger last_one = comb & -comb;
UnsignedInteger last_zero = (comb + last_one) &~ comb & mask;
if (last_zero) return comb + last_one + (last_zero / (last_one * 2)) - 1;
else if (last_one > 1) return mask / (last_one / 2);
else return ~comb & 1;
}
Line 5 is doing the bit-hacking equivalent of the (extended) regular expression replacement, which finds the last 01 in the string, flips it to 10 and shifts all the following 1s all the way to the right.
s/01(1*)(0*)$/10\2\1/
Line 6 does this one (only if the previous one failed) to add one more 1 and shift the 1s all the way to the right:
s/(1*)0(0*)/\21\1/
I don't know if that explanation helps or hinders :)
Here's a quick and dirty driver (the command-line argument is the size of the set, default 5, maximum the number of bits in an unsigned long):
#include <iostream>
template<typename UnsignedInteger>
std::ostream& show(std::ostream& out, UnsignedInteger comb) {
out << '[';
char a = 'a';
for (UnsignedInteger i = 1; comb; i *= 2, ++a) {
if (i & comb) {
out << a;
comb -= i;
}
}
return out << ']';
}
int main(int argc, char** argv) {
unsigned int n = 5;
if (argc > 1) n = atoi(argv[1]);
unsigned long mask = (1UL << n) - 1;
unsigned long comb = 0;
do {
show(std::cout, comb) << std::endl;
comb = next_combination(comb, mask);
} while (comb);
return 0;
}
It's hard to believe that this function might be useful for a set of more than 64 elements, given the size of the enumeration, but it might be useful to enumerate some limited part, such as all subsets of three elements. In this case, the bit-hackery is only really useful if the modification fits in a single word. Fortunately, that's easy to test; you simply need to do the computation as above on the last word in the bitset, up to the test for last_zero being zero. (In this case, you don't need to bitand mask, and indeed you might want to choose a different way of specifying the set size.) If last_zero turns out to be zero (which will actually be pretty rare), then you need to do the transformation in some other way, but the principle is the same: find the first 0 which precedes a 1 (watch out for the case where the 0 is at the end of a word and the 1 at the beginning of the next one); change the 01 to 10, figure out how many 1s you need to move, and move them to the end.
Considering a list of elements L = [a, b, c], the powerset of L is given by:
P(L) = {
[],
[a], [b], [c],
[a, b], [a, c], [b, c],
[a, b, c]
}
Considering each position as a bit, you'd have the mappings:
id | positions - integer | desired set
0 | [0 0 0] - 0 | []
1 | [1 0 0] - 4 | [a]
2 | [0 1 0] - 2 | [b]
3 | [0 0 1] - 1 | [c]
4 | [1 1 0] - 6 | [a, b]
5 | [1 0 1] - 5 | [a, c]
6 | [0 1 1] - 3 | [b, c]
7 | [1 1 1] - 7 | [a, b, c]
As you see, the id is not directly mapped to the integers. A proper mapping needs to be applied, so that you have:
id | positions - integer | mapped - integer
0 | [0 0 0] - 0 | [0 0 0] - 0
1 | [1 0 0] - 4 | [0 0 1] - 1
2 | [0 1 0] - 2 | [0 1 0] - 2
3 | [0 0 1] - 1 | [0 1 1] - 3
4 | [1 1 0] - 6 | [1 0 0] - 4
5 | [1 0 1] - 5 | [1 0 1] - 5
6 | [0 1 1] - 3 | [1 1 0] - 6
7 | [1 1 1] - 7 | [1 1 1] - 7
As an attempt on solving this, I came up using a binary tree to do the mapping -- I'm posting it so that someone may see a solution from it:
#
______________|_____________
a / \
_____|_____ _______|______
b / \ / \
__|__ __|__ __|__ __|__
c / \ / \ / \ / \
[ ] [c] [b] [b, c] [a] [a, c] [a, b] [a, b, c]
index: 0 3 2 6 1 5 4 7
Suppose your set has size N.
So, there are (N choose k) sets of size k. You can find the right k (i.e. the size of the nth set) very quickly just by subtracting off (N choose k) from n until n is about to go negative. This reduces your problem to finding the nth k-subset of an N-set.
The first (N-1 choose k-1) k-subsets of your N-set will contain its least element. So, if n is less than (N-1 choose k-1), pick the first element and recurse on the rest of the set. Otherwise, you have one of the (N-1 choose k) other sets; throw away the first element, subtract (N-1 choose k-1) from n, and recurse.
Code:
#include <stdio.h>
int ch[88][88];
int choose(int n, int k) {
if (n<0||k<0||k>n) return 0;
if (!k||n==k) return 1;
if (ch[n][k]) return ch[n][k];
return ch[n][k] = choose(n-1,k-1) + choose(n-1,k);
}
int nthkset(int N, int n, int k) {
if (!n) return (1<<k)-1;
if (choose(N-1,k-1) > n) return 1 | (nthkset(N-1,n,k-1) << 1);
return nthkset(N-1,n-choose(N-1,k-1),k)<<1;
}
int nthset(int N, int n) {
for (int k = 0; k <= N; k++)
if (choose(N,k) > n) return nthkset(N,n,k);
else n -= choose(N,k);
return -1; // not enough subsets of [N].
}
int main() {
int N,n;
scanf("%i %i", &N, &n);
int a = nthset(N,n);
for (int i=0;i<N;i++) printf("%i", !!(a&1<<i));
printf("\n");
}

How to find Big-O notation of FFT multiplication under a loop

The Big-O notation of FFT Multiplication is O(nlogn). What is Big-O notation of a FFT multiplication under a loop as given in algorithm below? The code is given in matlab and FFTmulti is a function for FFT Multiplication of two polynomials
rG=1;
rN=1;
AreaFunc=[1 2 5 2 3 6 7 2 4 5 6];
N=length(AreaFunc);
for i=1:(N-1)
ref_coeff(i) = (AreaFunc(i+1) - AreaFunc(i)) / (AreaFunc(i+1) + AreaFunc(i));
end
ref_coeff=[ref_coeff rN];
G = (1 + rG) / 2;
A0 = [1]; B0 = [-rG];
for i = 1 : length(ref_coeff)
G = G * (1 + ref_coeff(i));
A1 = [-ref_coeff(i) 0]; B1 = [1 0];
An = [0 A0] + FFTmulti(A1,B0);
Bn = [0 -ref_coeff(i)*A0] + FFTmulti(B1,B0);
A0=An;
B0=Bn;
end
A0 =fliplr(A0);
num = zeros(1, (floor(N/2)));
num = [num G];
FFT complexity -for the best known optimization algorithms - is N*log2(N).
If you call it inside a loop of N, will be N^2 log2(N).