SICP Exercise 1.19 PQ transformation - sicp

T(p,q) transforms the pair (a,b) according to a <-- bq + aq + ap and b <-- bp + aq.
Can someone explain how this transformation works?

Just as you wrote,
T(p,q)
(a, -----------> ( bq + aq + ap ,
b) bp + aq )
In pseudocode,
T(p,q)(a,b) = ( b*q + a*q + a*p , b*p + a*q )
The transformation T(p,q), given a pair (a,b), calculates two new values,
a2 = b*q + a*q + a*p , and
b2 = b*p + a*q
and then constructs a pair, (a2,b2), and returns it as the result.

Related

Multiplication over GF(256) in SAGE

I am trying to reproduce the multiplication over GF(256) of this question. Specifically, I am trying d4*02 in sage. According to the authors, this multiplication is 饾煼饾煻饾煼饾煼饾煻饾煻饾煼饾煼. In Sage I tried
k.<a> = FiniteField(256, impl='givaro', repr='int')
print(k((a**2+a**4+a**6+a**7)*(a))) # a**2+a**4+a**6+a**7 is d4 and a is 2
181
But 181 is not equal to 饾煼饾煻饾煼饾煼饾煻饾煻饾煼饾煼. What I am doing wrong? Could you help me, please?
You need to give your finite field constructor the correct modulus for Rijndael.
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
r = (a^7 + a^6 + a^4 + a^2) * a
v = r.integer_representation()
print(r, v, hex(v))
Output
a^7 + a^5 + a^4 + a + 1 179 0xb3
It's usually more convenient to specify field elements using integers. Eg,
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
kint = k._cache.fetch_int
p, q = [kint(u) for u in (0xd4, 0x02)]
r = p * q
v = r.integer_representation()
print(r, v, hex(v))
Alternatively, you can use a list and a dict to convert integers to and from field elements. The following code does the second multiplication from the linked question.
# Rijndael finite field
k.<a> = GF(2^8, modulus=x^8+x^4+x^3+x+1)
i2f = sorted(k)
f2i = {v: i for i, v in enumerate(i2f)}
p, q = [i2f[u] for u in (0xbf, 0x03)]
print(p)
print(q)
r = p * q
v = f2i[r]
print(r, v, hex(v))
Output
a^7 + a^5 + a^4 + a^3 + a^2 + a + 1
a + 1
a^7 + a^6 + a^4 + a^3 + a 218 0xda

Boolean algebra simplification exercise

So I have been given the following expression, but I cannot seem to solve it, can anyone do this and show the steps please?
Prove XY'Z + XYZ' + XYZ = XY + XZ
XY'Z + XYZ' + XYZ = XY + XZ
Notice X and Z are common factors between XY'Z and XYZ.
XZ(Y' + Y) + XYZ' =
Y' + Y is equal to 1 (if Y=0 then Y'=1 and so 0 + 1 = 1, that is 0 or 1 = 1. Similarly, if Y=1 then Y'=0 and so 1 + 0 = 1). Therefore, what you get is:
XZ路1 + XYZ' =
XZ路1 = XZ since A路1 = A (if A=0 then 0路1 is 0 and if A=1 then 1路1 = 1). Now the function is simplified to:
XZ + XYZ' =
Notice once again X is a common factor between XZ and XYZ'.
X(Z + YZ') =
Notice this time that Z + YZ' is a special case of the distributive law, which is A + A'B = A + B. This is because if we apply the general distributive law A + BC = (A + B)路(A + C) then we get A + A'B = (A + A')路(A + B) = 1路(A + B) = A + B. Following this reasoning we get to simplify the function even further:
X(Z + Y) =
All that's left is for us to use the distributive law and we finally arrive to the final result:
XY + XZ
Please note that nothing is written between variables, an AND operator (or "路" symbol) is assumed. It's just a way to save space.

Curve Fit 5 points

I am trying to curve fit 5 points in C. I have used this code from a previous post (Can sombody simplify this equation for me?) to do 4 points, but now I need to add another point.
// Input data: arrays x[] and y[]
// x[1],x[2],x[3],x[4] - X values
// y[1],y[2],y[3],y[4] - Y values
// Calculations
A = 0
B = 0
C = 0
D = 0
S1 = x[1] + x[2] + x[3] + x[4]
S2 = x[1]*x[2] + x[1]*x[3] + x[1]*x[4] + x[2]*x[3] + x[2]*x[4] + x[3]*x[4]
S3 = x[1]*x[2]*x[3] + x[1]*x[2]*x[4] + x[1]*x[3]*x[4] + x[2]*x[3]*x[4]
for i = 1 to 4 loop
C0 = y[i]/(((4*x[i]-3*S1)*x[i]+2*S2)*x[i]-S3)
C1 = C0*(S1 - x[i])
C2 = S2*C0 - C1*x[i]
C3 = S3*C0 - C2*x[i]
A = A + C0
B = B - C1
C = C + C2
D = D - C3
end-loop
// Result: A, B, C, D
I have been trying to covert this to a 5 point curve fit, but am having trouble figuring out what goes inside the loop:
// Input data: arrays x[] and y[]
// x[1],x[2],x[3],x[4],x[5] - X values
// y[1],y[2],y[3],y[4],y[5] - Y values
// Calculations
A = 0
B = 0
C = 0
D = 0
E = 0
S1 = x[1] + x[2] + x[3] + x[4]
S2 = x[1]*x[2] + x[1]*x[3] + x[1]*x[4] + x[2]*x[3] + x[2]*x[4] + x[3]*x[4]
S3 = x[1]*x[2]*x[3] + x[1]*x[2]*x[4] + x[1]*x[3]*x[4] + x[2]*x[3]*x[4]
S4 = x[1]*x[2]*x[3]*x[4] + x[1]*x[2]*x[3]*[5] + x[1]*x[2]*x[4]*[5] + x[1]*x[3]*x[4]*[5] + x[2]*x[3]*x[4]*[5]
for i = 1 to 4 loop
C0 = ??
C1 = ??
C2 = ??
C3 = ??
C4 = ??
A = A + C0
B = B - C1
C = C + C2
D = D - C3
E = E + C4
end-loop
// Result: A, B, C, D, E
any help in filling out the C0...C4 would be appreciated. I know this has to do with the matrices but I have not been able to figure it out. examples with pseudo code or real code would be most helpful.
thanks
I refuse to miss this opportunity to generalize. :)
Instead, we're going to learn a little bit about Lagrange polynomials and the Newton Divided Difference Method of their computation.
Lagrange Polynomials
Given n+1 data points, the interpolating polynomial is
where l_j(i) is
.
What this means is that we can find the polynomial approximating the n+1 points, regardless of spacing, etc, by just summing these polynomials. However, this is a bit of a pain and I wouldn't want to do it in C. Let's take a look at Newton Polynomials.
Newton Polynomials
Same start, given n+1 data points, the approximating polynomial is going to be
where each n(x) is
with a coefficient of
, being the divided difference.
The final form end's up looking like
.
As you can see, the formula is pretty easy given the divided difference values. You just do each new divided difference and multiply by each point so far. It should be noted that you'll end up with a polynomial of degree n from n+1 points.
Divided Difference
All that's left is to define the divided difference which is really best explained by these two pictures:
and
.
With this information, a C implementation should be reasonable to do. I hope this helps and I hope you learned something! :)
If the x values are equally spaced with x2-x1=h, x3-x2=h, x4-x3=h and x5-x4=h then
C0 = y1;
C1 = -(25*y1-48*y2+36*y3-16*y4+3*y5)/(12*h);
C2 = (35*y1-104*y2+114*y3-56*y4+11*y5)/(24*h*h);
C3 = -(5*y1-18*y2+24*y3-14*y4+3*y5)/(12*h*h*h);
C4 = (y1-4*y2+6*y3-4*y4+y5)/(24*h*h*h*h);
y(x) = C0+C1*(x-x1)+C2*(x-x1)^2+C3*(x-x1)^3+C4*(x-x1)^4
// where `^` denotes exponentiation (and not XOR).

Solve Linear System Over Finite Field with Module

Is there in sage, any instruction to solve a linear system equations
module p(x) (polynomial over finite field), where the system coefficients are polynomials over finite field in any indeterminate?. I know that for integers exists something like, example
sage: I6 = IntegerModRing(6)
sage: M = random_matrix(I6, 4, 4)
sage: v = random_vector(I6, 4)
sage: M \ v
(4, 0, 2, 1)
Here my code
F.<a> = GF(2^4)
PR = PolynomialRing(F,'X')
X = PR.gen()
a11 = (a^2)*(X^3)+(a^11)*(X^2)+1
a12 = (a)*(X^4)+(a^13)*(X^3)+X+1
a13 = X^2+(a^13)*(X^3)+a*(X^2)+1
a21 = X^3
a22 = X+a
a23 = X^2+X^3+a*X
a31 = (a^12)*X+a*(X^2)
a32 = (a^8)*(X^2)+X^2+X^3
a33 = a*X + (a^2)*(X^3)
M = matrix([[a11,a12,a13],[a21,a22,a23],[a31,a32,a33]])
v = vector([(a^6)*(X^14)+X^13+X,a*(X^2)+(X^3)*(a^11)+X^2+X+a^12,(a^8)*(X^7)+a*(X^2)+(a^12)* (X^13)+X^3+X^2+X+1])
p = (a^2 + a)*X^3 + (a + 1)*X^2 + (a^2 + 1)*X + 1 # is than 6 in the firs code
I'm trying
matrix(PolynomialModRing(p),M)\vector(PolynomialModRing(p),v)
but PolynomialModRing not exist ...
EDIT
another person talk me that I will make
R.<Xbar> = PR.quotient(PR.ideal(p))
# change your formulas to Xbar instead of X
A \ b
# ==> (a^3 + a, a^2, (a^3 + a^2)*Xbar^2 + (a + 1)*Xbar + a^3 + a)
this work fine but Now I'm trying to apply the Chinese Theorem Remainder after the code, then .... I defined
q = X^18 + a*X^15 + a*X^12 + X^11 + (a + 1)*X^2 + a
r = a^3*X^3 + (a^3 + a^2 + a)*X^2 + (a^2 + 1)*X + a^3 + a^2 + a
#p,q and r are relatively prime
and I'm trying ...
crt([(A\b)[0],(A\b)[1],(A\b)[2]],[p,q,r])
but I get
File "element.pyx", line 344, in sage.structure.element.Element.getattr (sage/structure/element.c:3871)
File "misc.pyx", line 251, in sage.structure.misc.getattr_from_other_class (sage/structure/misc.c:1606)
AttributeError: 'PolynomialQuotientRing_field_with_category.element_class' object has no attribute 'quo_rem'
I'm thinking that problem is the change Xbar to X
Here my complete example to integers
from numpy import arange, eye, linalg
#2x-3y+2z=21
#x+4y-z=1
#-x+2y+z=17
A = matrix([[2,-3,2],[1,4,-1],[-1,2,1]])
b=vector([21,1,17])
p=[17,11,13]
d=det(A)
dlist=[0,0,0]
ylist=matrix(IntegerModRing(p[i]),[[2,-3,2],[1,4,-1], [-1,2,1]])\vector(IntegerModRing(p[i]),[21,1,17])
p1=[int(ylist[0]),int(ylist[1]),int(ylist[2])]
CRT(p1,p)
Maybe... this is what you want? Continuing your example:
G = F.extension(p) # This is what you want for "PolynomialModRing(p)
matrix(G,M)\vector(G,v)
which outputs
(a^3 + a, a^2, (a^3 + a^2)*X^2 + (a + 1)*X + a^3 + a)
In your question you ask "where the system coefficients are polynomials over finite field in any indeterminate" so what I'm doing above is NOT what you have actually asked, which would be a weird question to ask given your example. So, I'm going to just try to read your mind... :-)

Recursive cumulative function

I need to write a cumulative summation function in R but I've been hitting a brick wall. The function has the following structure:
a*x1
a*x2 + a^2*x1
a*x3 + a^2*x2 + a^3*x1
a*x4 + a^2*x3 + a^3*x2 + a^4*x1
And so on. cumsum doesn't seem to work for this type of function. Is there any way this could be implemented in R?
Since your recursion is
u[n+1] = a * ( x[n+1] + u[n] )
i.e.,
u[n+1]/a = x[n+1] + a * u[n]/a,
you can use filter:
x <- 1:5
a <- 2
a*filter(1:5, a, method="recursive")
# Compare with the expected values
a*x[1]
a*x[2] + a^2*x[1]
a*x[3] + a^2*x[2] + a^3*x[1]
a*x[4] + a^2*x[3] + a^3*x[2] + a^4*x[1]

Resources