How to increase enough stack size in Pari/Gp for command to work - polynomials

I am working with GP and minimum polynomials as follows running on ASUS x75:
(19:25) gp > elt=Mod(a*x^3+b*x^2+c*x+d,('x^5-1)/('x-1))
%122 = Mod(a*x^3 + b*x^2 + c*x + d, x^4 + x^3 + x^2 + x + 1)
(19:25) gp > (poly=minpoly(elt,x='x))
%123 = x^4 + (a + (b + (c - 4*d)))*x^3 + (a^2 + (-3*b + (2*c - 3*d))*a + (b^2 + (2*c - 3*d)*b + (c^2 - 3*d*c + 6*d^2)))*x^2 + (a^3 + (-2*b + (3*c - 2*d))*a^2 + (-2*b^2 + (c + 6*d)*b + (-2*c^2 - 4*d*c + 3*d^2))*a + (b^3 + (-2*c - 2*d)*b^2 + (3*c^2 - 4*d*c + 3*d^2)*b + (c^3 - 2*d*c^2 + 3*d^2*c - 4*d^3)))*x + (a^4 + (-b + (-c - d))*a^3 + (b^2 + (2*c + 2*d)*b + (c^2 - 3*d*c + d^2))*a^2 + (-b^3 + (-3*c + 2*d)*b^2 + (2*c^2 - d*c - 3*d^2)*b + (-c^3 + 2*d*c^2 + 2*d^2*c - d^3))*a + (b^4 + (-c - d)*b^3 + (c^2 + 2*d*c + d^2)*b^2 + (-c^3 - 3*d*c^2 + 2*d^2*c - d^3)*b + (c^4 - d*c^3 + d^2*c^2 - d^3*c + d^4)))
The first command came out successfully, while the second one below did finish successfully and gave an allocatemem() error. How is it possible to get the second command to work, without overheating the computer or program exhaustion? And the WHOLE output to command below this is needed. Thanks for the help.
(19:23) gp > elt=Mod(a*x^5+b*x^4+c*x^3+d*x^2+e*x+f,('x^7-1)/('x-1))
%120 = Mod(a*x^5 + b*x^4 + c*x^3 + d*x^2 + e*x + f, x^6 + x^5 + x^4 + x^3 + x^2 + x + 1)
(19:23) gp > (poly=minpoly(elt,x='x))
*** at top-level: poly=minpoly(elt,x='x)
*** ^-----------------
*** minpoly: the PARI stack overflows !
current stack size: 9000000 (8.583 Mbytes)
[hint] you can increase GP stack with allocatemem()

You can increase the PARI/GP's heap up to any limit you want at run-time following the example below (demonstrates how to set heap size to 120000000 bytes):
default(parisize, 120000000)

default(parisize, 10000000000) is more than 8 GB and in my case was
enough to make advanced calculations with matrices.

Related

SymPy unable to simplify solution

I am trying to solve the following system of equation using sympy.
from sympy import *
n = 4
K = 2
a = symbols(f"a_:{int(n)}", real=True)
b = symbols(f"b_:{int(n)}", real=True)
X = symbols(f"X_:{int(K)}", real=True)
Y = symbols(f"Y_:{int(K)}", real=True)
lambda_ = symbols("lambda",real=True)
mu = symbols(f"mu_:{int(K)}", real=True)
list_eq = [
# (1)
Eq(a[0] + a[1] + a[2] + a[3], 0),
Eq(a[0] + a[1], X[0]),
Eq(a[2] + a[3], X[1]),
# (2)
Eq(b[0] + b[1] + b[2] + b[3], 0),
Eq(b[0] + b[1], Y[0]),
Eq(b[2] + b[3], Y[1]),
# (3)
Eq(b[0], a[0] - lambda_ - mu[0]),
Eq(b[1], a[1] - lambda_ - mu[0]),
Eq(b[2], a[2] - lambda_ - mu[1]),
Eq(b[3], a[3] - lambda_ - mu[1]),
]
solve(list_eq, dict=True)
[{X_0: -b_2 - b_3 + mu_0 - mu_1,
X_1: b_2 + b_3 - mu_0 + mu_1,
Y_0: -b_2 - b_3,
Y_1: b_2 + b_3,
a_0: -b_1 - b_2 - b_3 + mu_0/2 - mu_1/2,
a_1: b_1 + mu_0/2 - mu_1/2,
a_2: b_2 - mu_0/2 + mu_1/2,
a_3: b_3 - mu_0/2 + mu_1/2,
b_0: -b_1 - b_2 - b_3,
lambda: -mu_0/2 - mu_1/2}]
The analytical solution for b is
b_0 = a_0 + (1/2)*(Y_0 - X_0)
b_1 = a_1 + (1/2)*(Y_0 - X_0)
b_2 = a_2 + (1/2)*(Y_1 - X_1)
b_3 = a_3 + (1/2)*(Y_1 - X_1)
However sympy does not manage to simplify the results and is still using mu_0 and mu_1 in the solution.
Is it possible to simplify those variables in the solution ?
For more details, the system i'm trying to solve is an optimization problem under constraints:
min_b || a - b ||^2 such that b_0 + b_1 + b_2 + b_3 = 0 and b_0 + b_1 = Y_0 and b_2 + b_3 = Y_1.
We assume that a_0 + a_1 + a_2 + a_3 = 0 and a_0 + a_1 = X_0 and a_2 + a_3 = X_1.
Therefore, the equations (1) are the assumptions on a and the equations (2) and (3) are the KKT equations.
You can eliminate variables from a system of linear or polynomial equations using a Groebner basis:
In [61]: G = groebner(list_eq, [*mu, lambda_, *b, *a, *X, *Y])
In [62]: for eq in G: pprint(eq)
X₁ - Y₁ + 2⋅λ + 2⋅μ₀
-X₁ + Y₁ + 2⋅λ + 2⋅μ₁
X₁ + Y₁ + 2⋅a₁ + 2⋅b₀
-X₁ + Y₁ - 2⋅a₁ + 2⋅b₁
-X₁ - Y₁ + 2⋅a₃ + 2⋅b₂
X₁ - Y₁ - 2⋅a₃ + 2⋅b₃
X₁ + a₀ + a₁
-X₁ + a₂ + a₃
X₀ + X₁
Y₀ + Y₁
Here the first two equations have mu and lambda but the others have these symbols eliminated. You can use G[2:] to get the equations that do not involve mu and lambda. The order of the symbols in a lex Groebner basis determines which symbols are eliminated first from the equations. You can solve specifically for b in terms of a, X and Y by picking out the equations involving b:
In [63]: solve(G[2:6], b)
Out[63]:
⎧ X₁ Y₁ X₁ Y₁ X₁ Y₁ X₁ Y₁ ⎫
⎨b₀: - ── - ── - a₁, b₁: ── - ── + a₁, b₂: ── + ── - a₃, b₃: - ── + ── + a₃⎬
⎩ 2 2 2 2 2 2 2 2 ⎭
This is not exactly the form you suggested but the form of solution for the problem is not unique because of the constraints among the variables it is expressed in. There are many equivalent ways to express b in terms of a, X and Y even after eliminating mu and lambda because a, X and Y are not independent (they are 8 symbols connected by 4 constraints).
Sometimes adding auxiliary equations with the pattern you desire and indicating what you don't want as a solution variable can help you get closer to what you desired:
[38] eqs = list_eq + [Y[0]-X[0]-var('z0'), Y[1]-X[1]-var('z1')]
[39] sol = Dict(solve(eqs, exclude=a, dict=True)[0]); sol

How to represent the elements of the Galois filed GF(2^8) and perform arithmetic in NTL library

I am new to NTL library for its GF2X, GF2E, GF2EX, etc. Now, I want to perform multiplication on the Galois field GF(2^8). The problem is as following:
Rijndael (standardised as AES) uses the characteristic 2 finite field with 256 elements,
which can also be called the Galois field GF(2^8).
It employs the following reducing polynomial for multiplication:
x^8 + x^4 + x^3 + x^1 + 1.
For example, {53} • {CA} = {01} in Rijndael's field because
(x^6 + x^4 + x + 1)(x^7 + x^6 + x^3 + x)
= (x^13 + x^12 + x^9 + x^7) + (x^11 + x^10 + x^7 + x^5) + (x^8 + x^7 + x^4 + x^2) + (x^7 + x^6 + x^3 + x)
= x^13 + x^12 + x^9 + x^11 + x^10 + x^5 + x^8 + x^4 + x^2 + x^6 + x^3 + x
= x^13 + x^12 + x^11 + x^10 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + x^2 + x
and
x^13 + x^12 + x^11 + x^10 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + x^2 + x modulo x^8 + x^4 + x^3 + x^1 + 1
= (11111101111110 mod 100011011)
= {3F7E mod 11B} = {01}
= 1 (decimal)
My question is how to represent the reducing polynomial x^8 + x^4 + x^3 + x^1 + 1 and the polynomials x^6 + x^4 + x + 1 and x^7 + x^6 + x^3 + x in NTL. Then perform multiplication on these polynomials, and get the result {01}.
This is a good example for me to use this library.
Again, I don't know NTL, and I'm running Visual Studio 2015 on Windows 7. I've downloaded what I need, but have to build a library with all the supplied source files which will take a while to figure out. However, based on another answer, this should get you started. First, initialize the reducing polynomial for GF(256):
GF2X P; // apparently the length doesn't need to be set
SetCoeff(P, 0, 1);
SetCoeff(P, 1, 1);
SetCoeff(P, 3, 1);
SetCoeff(P, 4, 1);
SetCoeff(P, 8, 1);
GF2E::init(P);
Next, assign variables as polynomials:
GF2X A;
SetCoeff(A, 0, 1);
SetCoeff(A, 1, 1);
SetCoeff(A, 4, 1);
SetCoeff(A, 6, 1);
GF2X B;
SetCoeff(B, 1, 1);
SetCoeff(B, 3, 1);
SetCoeff(B, 6, 1);
SetCoeff(B, 7, 1);
GF2X C;
Looks like there is an override for multiply so this would work assuming that the multiply override is based on the GF(2^8) extension field GF2E::init(P).
C = A * B:
As commented after the question, NTL is more oriented to large fields. For GF(256) it would be faster to use bytes and lookup tables. For up to GF(2^64), xmm register intrinsics with carryless multiply (PCLMULQDQ) can be used to implement finite field math quickly without tables (some constants will be needed, the polynomial and it's multiplicative inverse). For fields greater than GF(2^64), extended precision math methods would be needed. For fields GF(p^n), where p != 2 and n > 1, unsigned integers can be used with lookup tables. Building the tables would involve some mapping between integers and GF(p) polynomial coefficients.

Why can't the subs function of the sympy replace the value of the symbol sometimes?

I have the following code:
u_ini = 0.1
v_ini = 0.1
z_ini = 0.1 # 初始化三个拉格朗日乘子
q = 0
lis = list(range(2))
u = list(sp.symbols('u:{}'.format(len(lis))))
v = list(sp.symbols('v:{}'.format(len(lis))))
z = sp.symbols('z')
p = list(sp.symbols('p:{}'.format(len(lis))))
lag1 = 0
lag2 = 0
lag3 = 0
p_symbol_sum = np.sum(p)
for i in range(k):
if i < k-1:
lag1 += B*ts_ratio[i]*sp.log(1+g[i]*p[i]/(sgm_2+g[i]*np.sum(p[i+1:k])),2)-q*(af_eff*p[i]+Pc-eh_eff*(1-ts_ratio[i])*g[i]*p_symbol_sum)
lag2 -= u[i] * (R_min - ts_ratio[i] * B * sp.log(1 + g[i] * p[i] / (sgm_2 + g[i] * np.sum(p[i + 1:k])),2))
elif i == k-1:
lag1 += B*ts_ratio[i]*sp.log(1+g[i]*p[i]/(sgm_2+g[i]*p[i]),2)-q*(af_eff*p[i]+Pc-eh_eff*(1-ts_ratio[i])*g[i]*p_symbol_sum)
lag2 -= u[i] * (R_min - ts_ratio[i] * B * sp.log(1+g[i]*p[i]/(sgm_2+g[i]*p[i]),2))
lag3 -= v[i] * (E_min - (1 - ts_ratio[i])*eh_eff*g[i]*p_symbol_sum) + z * (p[i] - p_max)
lag_fun = lag1 + lag2 + lag3
print("lag_fun:",lag_fun)
for i in range(k):
lag_fun.subs([(u[i],u_ini), (v[i],v_ini), (z,z_ini), (p[i],p_ini)]).evalf()
print("lag_fun:",lag_fun)
Why does the value of the expression not change after I count down the subs of the second line。
This is the output of the program. The first line is the output before using subs. The second is the output after using subs. Why hasn't it changed?
lag_fun: -u0*(-0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 2) - u1*(-0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2) + 2) - v0*(-0.00205304939574879*p0 - 0.00205304939574879*p1 + 0.2) - v1*(-0.000619546556085859*p0 - 0.000619546556085859*p1 + 0.2) - z*(p0 - 20) - z*(p1 - 20) + 0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2)
lag_fun: -u0*(-0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 2) - u1*(-0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2) + 2) - v0*(-0.00205304939574879*p0 - 0.00205304939574879*p1 + 0.2) - v1*(-0.000619546556085859*p0 - 0.000619546556085859*p1 + 0.2) - z*(p0 - 20) - z*(p1 - 20) + 0.5*log(0.0410609879149758*p0/(0.0410609879149758*p1 + 0.001) + 1)/log(2) + 0.5*log(0.0123909311217172*p1/(0.0123909311217172*p1 + 0.001) + 1)/log(2)
subs doesn't change anything in place, you have to capture the result for the same reason that this loop fails to change x:
>>> x = 0
>>> for i in range(10): x + 1
>>> x
0
So it must be
lag_fun = lag_fun.subs(etc...)

R: cannot grep() on "+" character?

Here is my data:
> rep$strand
[1] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[58] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +
[115] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[172] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
[229] + + + + + + + + + + + + + + + + + + + +
In hopes of separating the "+" from the "-", I tried running the following commands.
grepl("-",rep$strand) #this gives me a list of TRUE/FALSE that seems correct
grepl("+",rep$strand) #this is all TRUE for some mysterious reason
I can't figure out why the same grepl() command would work on "-" but not on "+".
Use
grepl("\\+", rep$strand)
or
grepl("+", rep$strand, fixed = TRUE)
or
"+" == rep$strand

How is make_heap in C++ implemented to have complexity of 3N?

I wonder what's the algorithm of make_heap in in C++ such that the complexity is 3*N? Only way I can think of to make a heap by inserting elements have complexity of O(N Log N). Thanks a lot!
You represent the heap as an array. The two elements below the i'th element are at positions 2i+1 and 2i+2. If the array has n elements then, starting from the end, take each element, and let it "fall" to the right place in the heap. This is O(n) to run.
Why? Well for n/2 of the elements there are no children. For n/4 there is a subtree of height 1. For n/8 there is a subtree of height 2. For n/16 a subtree of height 3. And so on. So we get the series n/22 + 2n/23 + 3n/24 + ... = (n/2)(1 * (1/2 + 1/4 + 1/8 + . ...) + (1/2) * (1/2 + 1/4 + 1/8 + . ...) + (1/4) * (1/2 + 1/4 + 1/8 + . ...) + ...) = (n/2) * (1 * 1 + (1/2) * 1 + (1/4) * 1 + ...) = (n/2) * 2 = n. Or, formatted maybe more readably to see the geometric series that are being summed:
n/2^2 + 2n/2^3 + 3n/2^4 + ...
= (n/2^2 + n/2^3 + n/2^4 + ...)
+ (n/2^3 + n/2^4 + ...)
+ (n/2^4 + ...)
+ ...
= n/2^2 (1 + 1/2 + 1/2^4 + ...)
+ n/2^3 (1 + 1/2 + 1/2^3 + ...)
+ n/2^4 (1 + 1/2 + 1/2^3 + ...)
+ ...
= n/2^2 * 2
+ n/2^3 * 2
+ n/2^4 * 2
+ ...
= n/2 + n/2^2 + n/2^3 + ...
= n(1/2 + 1/4 + 1/8 + ...)
= n
And the trick we used repeatedly is that we can sum the geometric series with
1 + 1/2 + 1/4 + 1/8 + ...
= (1 + 1/2 + 1/4 + 1/8 + ...) (1 - 1/2)/(1 - 1/2)
= (1 * (1 - 1/2)
+ 1/2 * (1 - 1/2)
+ 1/4 * (1 - 1/2)
+ 1/8 * (1 - 1/2)
+ ...) / (1 - 1/2)
= (1 - 1/2
+ 1/2 - 1/4
+ 1/4 - 1/8
+ 1/8 - 1/16
+ ...) / (1 - 1/2)
= 1 / (1 - 1/2)
= 1 / (1/2)
= 2
So the total number of "see if I need to fall one more, and if so which way do I fall? comparisons comes to n. But you get round-off from discretization, so you always come out to less than n sets of swaps to figure out. Each of which requires at most 3 comparisons. (Compare root to each child to see if it needs to fall, then the children to each other if the root was larger than both children.)