I'm implementing in code an algorithm for computing inverse polynomials in the NTRU cryptosystem, and I'm using the paper "Almost Inverses and Fast NTRU Key Creation" by Joseph H. Silverman. I implemented the second pseudo-code as:
int inverse_mod_p(polynomial *r, polynomial *a)
{
int k;
int16_t b[NTRU_N + 1], c[NTRU_N + 1], f[NTRU_N + 1], g[NTRU_N + 1];
int i;
int16_t aux;
int zero_f;
int constant_f;
int deg_fg;
memset(b, 0, (NTRU_N + 1) * sizeof(int16_t));
b[0] = 1;
memset(c, 0, (NTRU_N + 1) * sizeof(int16_t));
memcpy(f, a->coeffs, NTRU_N * sizeof(int16_t));
f[NTRU_N] = 0;
memset(g, 0, (NTRU_N + 1) * sizeof(int16_t));
g[0] = -1;
g[NTRU_N] = 1;
while (1)
{
zero_f = 1;
for (i = 0; i < NTRU_N + 1; i++)
{
if (f[i] != 0)
{
zero_f = 0;
break;
}
}
if (zero_f)
return 1;
while (f[0] == 0)
{
for (i = 0; i < NTRU_N; i++)
{
f[i] = f[i + 1];
c[NTRU_N - i] = c[NTRU_N - i - 1];
}
f[NTRU_N] = 0;
c[0] = 0;
k++;
}
constant_f = 1;
for (i = 1; i < NTRU_N + 1; i++)
{
if (f[i] != 0)
{
constant_f = 0;
break;
}
}
if (constant_f)
break;
deg_fg = 0;
for (i = NTRU_N; i >= 0; i--)
{
if (f[i] == 0 && g[i] != 0)
{
deg_fg = 1;
break;
}
else if (f[i] != 0 && g[i] == 0)
{
break;
}
}
if (deg_fg)
{
for (i = 0; i < NTRU_N + 1; i++)
{
aux = f[i];
f[i] = g[i];
g[i] = aux;
aux = b[i];
b[i] = c[i];
c[i] = aux;
}
}
if (f[0] == g[0])
{
for (i = 0; i < NTRU_N + 1; i++)
{
f[i] = (f[i] - g[i] + 3) % 3;
b[i] = (b[i] - c[i] + 3) % 3;
}
}
else
{
for (i = 0; i < NTRU_N + 1; i++)
{
f[i] = (f[i] + g[i] + 3) % 3;
b[i] = (b[i] + c[i] + 3) % 3;
}
}
}
k = k % NTRU_N;
for (i = NTRU_N - 1; i >= 0; i--)
{
if (i - k < 0)
r->coeffs[i - k + NTRU_N] = b[i] * f[0];
else
r->coeffs[i - k] = b[i] * f[0];
}
for (i = 0; i < NTRU_N; i++)
r->coeffs[i] = (r->coeffs[i] + 3) % 3;
return 0;
}
But this seems to be wrong. I tested it using the example giveng in Wikipedia: https://en.wikipedia.org/wiki/NTRUEncrypt . The polynomial -1 + x + x^2 - x^4 + x^6 + x^9 - x^10 should have as inverse the polynomial 1 + 2x + 2x^3 + 2x^4 + x^5 + 2x^7 + x^8 - x^10 , but I got the following result:
Polinomial:
-1 1 1 0 -1 0 1 0 0 1 -1
Inverse polinomial:
0 2 2 1 0 2 1 2 0 1 2
Where is the error in the implementation?
Related
T(n) = 2T(n-1) + 1, T(0) = 1
how to solve it
Solve each of the following recurrences using the Iteration Method:
In c++ you can do it like this
int t[n + 1];
t[0] = 1;
for(int i = 1; i <= n; ++i){
t[i] = 2 * t[i - 1] + 1;
}
What is the Time Complexity of the function below? n > 0
Function fun(n){
Let count = 0;
For( I = 0; I < n; I++){
For(j = 0; j < n; j /= 2) {
For(h = 0; h < n; h /= 2) {
Count = count + 1;
}
}
}
Return count;
}
I have O(n * (n * log n² )) , but something tells me i might be wrong.
The above loop is an infinite loop. time complexity for this cannot be determined, unless the problem statement is updated properly!
Function fun(n){
Let count = 0;
For( I = 0; I < n; I++){
// will run infinitely even if you change j /= 2 to j *= 2, because initial value is 0
For(j = 0; j < n; j /= 2) {
// will run infinitely even if you change h /= 2 to h *= 2, because initial value is 0
For(h = 0; h < n; h /= 2) {
Count = count + 1;
}
}
}
Return count;
}
Whats wrong with this code ? Not able able to search missing number in a consecutive array using binary search.
a = [1,2,3,4,5,7,8]
lent = len(a)
beg =0
end = lent-1
while beg < end:
mid = (beg + end) / 2
if (a[mid]-a[beg])==(mid - beg):
beg = mid + 1
else:
end = mid -1
if(beg == end):
mid = (beg + end) / 2
print "missing"
print a[0]+ beg
Update #1: Yes, there was another one mistake. You're right. Here's updated version
Try this variant:
a = [1,2,3,4,5,7,8]
lent = len(a)
beg =0
end = lent-1
while beg < end:
mid = (beg + end) / 2
if (a[mid]-a[beg])==(mid - beg):
beg = mid
else:
end = mid
if abs(beg-end) <= 1:
print "missing: %s" % (a[0] + max(beg, mid),)
Result:
missing: 6
Also, try use functions, so you could easily test and debug your code on different lists:
def find_missing(a):
lent = len(a)
beg =0
end = lent-1
while beg < end:
mid = (beg + end) / 2
if (a[mid]-a[beg])==(mid - beg):
beg = mid
else:
end = mid
if abs(beg-end) <= 1:
return a[0] + max(beg, mid)
a = [1,2,3,4,5,7,8]
print find_missing(a)
a = [1,3,4,5,6]
print find_missing(a)
a = [1,2,3,4,5,7,8,9,10]
print find_missing(a)
Result:
6
2
6
//Implementation of the algorithm using java.
static int missingNumber(int [] nums) {
int i=0;
while(i < nums.length) {
int correct = nums[i];
if (nums[i] < nums.length && nums[i] != nums[correct]) {
swap(nums, i, correct);
} else {
i++;
}
}
for( int index=0; index<nums.length; index++){
if(index != nums[index]) {
return index;
}
}
return nums.length;
}
static void swap(int[] nums, int first, int second) {
int temp = nums[first];
nums[first] = nums[second];
nums[second] = temp;
}
int findMiss(int arr[], int low, int high)
{
if(low>high)
return -1;
if(arr[low]-1 != low)
return arr[low]-1;
int mid = (low + high) / 2;
if(arr[mid]-1 != mid)
return findMiss(arr,low,mid);
else
return findMiss(arr,mid+1,high);
}
First of all, of course I saw similar questions and solutions, but my implementation is a little bit different.
The main problem is that, the my code works only for one process, but it doesn't work for more processes.
I don't know what is the cause of this... Probably in communication between processes but I can't figure it out ;/
#include <mpi.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
int x = 0;
double kk;
int proces;
int numprocs;
int right_neigh, left_neigh, up_neigh, down_neigh;
int tag = 99;
static const int n = 6; //size of matrices
int psa[n][n]; //nxn
int psb[n][n];
int pra[n][n];
int prb[n][n];
int c[n][n];
for (int i = 0; i < n; i++) { //let's make fist matrix
for (int j = 0; j < n; j++) {
psa[i][j] = (int)rand() % 100 + 1;
psb[i][j] = (int)rand() % 100 + 1;
c[i][j] = 0;
}
}
for (int i = 0; i < n; i++) { //an the 2nd one
for (int j = 0; j < n; j++) {
pra[i][j] = psa[i][j];
prb[i][j] = psb[i][j];
}
}
MPI_Status statRecv[2];
MPI_Request reqSend[2], reqRecv[2];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &proces);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
int PP = numprocs;
double np = numprocs;
kk = sqrt(np);
int k = (int)kk;
if (proces < k) // below neighbour set
{
left_neigh = (proces + k - 1) % k;
right_neigh = (proces + k + 1) % k;
up_neigh = ((k - 1)*k) + proces;
}
if (proces == k)
{
left_neigh = ((proces + k - 1) % k) + k;
right_neigh = ((proces + k + 1) % k) + k;
up_neigh = proces - k;
}
if (proces > k)
{
x = proces / k;
left_neigh = ((proces + k - 1) % k) + x * k;
right_neigh = ((proces + k + 1) % k) + x * k;
up_neigh = proces - k;
}
if (proces == 0 || (proces / k) < (k - 1))
{
down_neigh = proces + k;
}
if ((proces / k) == (k - 1))
{
down_neigh = proces - ((k - 1)*k);
}
x = 0;
for(int kk = 0; kk < PP; kk++) //algorithm
{
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
for (int k = 0; k < n / PP; k++)
{
c[i][j] += psa[i][k] * psb[k][j];
}
}
}
MPI_Irecv(pra, n*n / PP / PP,MPI_FLOAT,left_neigh, tag,MPI_COMM_WORLD, reqRecv);
MPI_Irecv(prb, n*n / PP / PP,MPI_FLOAT,down_neigh,tag,MPI_COMM_WORLD,&reqRecv[1]);
MPI_Isend(psa, n*n / PP / PP,MPI_FLOAT,right_neigh,tag,MPI_COMM_WORLD, reqSend);
MPI_Isend(psb, n*n / PP / PP,MPI_FLOAT,up_neigh,tag,MPI_COMM_WORLD,&reqSend[1]);
MPI_Wait(reqRecv, statRecv);
}
cout << "A" << endl; //show result
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << pra[i][j] << " ";
}
cout << endl;
}
cout << "B" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << prb[i][j] << " ";
}
cout << endl;
}
cout << "C" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << c[i][j] << " ";
}
cout << endl;
}
MPI_Finalize();
return 0;
}
Ok I made it. Now everything is cool, my friend helped me out. But Admin please do not remove it, it can be helpful for someone.
#include <mpi.h>
#include <stdio.h>
#include <math.h>
#include <iostream> using namespace std; int main(int argc, char **argv) { int x = 0; double kk; int proces; int numprocs; int prawy_sasiad, lewy_sasiad, gorny_sasiad, dolny_sasiad; int tag = 99;
static const int n = 4; //rozmiar tablic
const int PP = 2; // pierwiastek z liczby procesow
int A[n][n] = {}, B[n][n] = {};
for (int i = 0; i < n; i++) {//inicjalizacja macierzy glownych
for (int j = 0; j < n; j++) {
A[i][j] = (int)rand() % 100 + 1;
B[i][j] = (int)rand() % 100 + 1;
}
}
/*
int val = 1;
for (int i = 0; i < n; i++) { //inicjalizacja macierzy glownych
for (int j = 0; j < n; j++) {
A[i][j] = val;
B[i][j] = val;
val++;
}
}
*/
MPI_Status statRecv2;
MPI_Request reqSend2, reqRecv2;
MPI_Status statRecv[2];
MPI_Request reqSend[2], reqRecv[2];
MPI_Init(0, 0);
MPI_Comm_rank(MPI_COMM_WORLD, &proces);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
int pra[n / PP][n / PP] = {}, psa[n / PP][n / PP] = {};// podmacierze
int prb[n / PP][n / PP] = {}, psb[n / PP][n / PP] = {};
//int C[n / PP][n / PP] = {};//wynikowa
int C[n][n] = {};//wynikowa
//cout << proces << endl;
for (int i = 0; i < n / PP; i++)//podzielenie macierzy glownej na podmacierze, kazdy proces otrzymuje inna podmacierz
{
for (int j = 0; j < n / PP; j++)
{
psa[i][j] = A[proces / PP*(n / PP) + i][proces%PP*(n / PP) + j];
psb[i][j] = B[proces / PP*(n / PP) + i][proces%PP*(n / PP) + j];
//cout << A[proces / PP*(n / PP) + i][proces%PP*(n / PP) + j] << " ";
}
//cout << endl;
}
double np = numprocs;
kk = sqrt(np);
int k = (int)kk;
if (proces < k) // ustawienie sasiadow
{
lewy_sasiad = (proces + k - 1) % k;
prawy_sasiad = (proces + k + 1) % k;
gorny_sasiad = ((k - 1)*k) + proces;
}
if (proces == k)
{
lewy_sasiad = ((proces + k - 1) % k) + k;
prawy_sasiad = ((proces + k + 1) % k) + k;
gorny_sasiad = proces - k;
}
if (proces > k)
{
x = proces / k;
lewy_sasiad = ((proces + k - 1) % k) + x * k;
prawy_sasiad = ((proces + k + 1) % k) + x * k;
gorny_sasiad = proces - k;
}
if (proces == 0 || (proces / k) < (k - 1))
{
dolny_sasiad = proces + k;
}
if ((proces / k) == (k - 1))
{
dolny_sasiad = proces - ((k - 1)*k);
}
x = 0;
int p = 0;
do{ //przesuniecia
if (p < proces / PP)// w wierszu
{
MPI_Irecv(pra, n*n / PP / PP, MPI_FLOAT, prawy_sasiad, tag, MPI_COMM_WORLD, &reqRecv2);
MPI_Isend(psa, n*n / PP / PP, MPI_FLOAT, lewy_sasiad, tag, MPI_COMM_WORLD, &reqSend2);
MPI_Wait(&reqRecv2, &statRecv2);
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
psa[i][j] = pra[i][j];
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
if (p < proces % PP)// i w kolumnie
{
MPI_Irecv(prb, n*n / PP / PP, MPI_FLOAT, dolny_sasiad, tag, MPI_COMM_WORLD, &reqRecv2);
MPI_Isend(psb, n*n / PP / PP, MPI_FLOAT, gorny_sasiad, tag, MPI_COMM_WORLD, &reqSend2);
MPI_Wait(&reqRecv2, &statRecv2);
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
psb[i][j] = prb[i][j];
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
p++;
} while (p < n);
//MPI_Barrier(MPI_COMM_WORLD);
for (int kkk = 0; kkk < PP; kkk++) //algorytm
{
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
for (int k = 0; k < n / PP; k++)
{
C[i][j] += psa[i][k] * psb[k][j];
}
}
}
MPI_Irecv(pra, n*n / PP / PP, MPI_FLOAT, prawy_sasiad, tag, MPI_COMM_WORLD, reqRecv);
MPI_Irecv(prb, n*n / PP / PP, MPI_FLOAT, dolny_sasiad, tag, MPI_COMM_WORLD, &reqRecv[1]);
MPI_Isend(psa, n*n / PP / PP, MPI_FLOAT, lewy_sasiad, tag, MPI_COMM_WORLD, reqSend);
MPI_Isend(psb, n*n / PP / PP, MPI_FLOAT, gorny_sasiad, tag, MPI_COMM_WORLD, &reqSend[1]);
MPI_Wait(reqRecv, statRecv);
MPI_Barrier(MPI_COMM_WORLD);
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
psa[i][j] = pra[i][j];
}
}
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
psb[i][j] = prb[i][j];
}
}
}
cout << "Proces: " << proces << " ";
for (int i = 0; i < n / PP; i++)
{
for (int j = 0; j < n / PP; j++)
{
cout << C[i][j] << " ";
}
}
MPI_Finalize();
return 0;
}
I had a requirement in Bullet physics with Opengl where I have modelview matrix but need to get the same matrix by calling gluLookAt. Thanks in advance.
From any 4x4 matrix we can get gluLookAt parameters which are CameraPos, CameraTarget, UpVector.
Here is the code to get CameraPos, CameraTarget, UpVector from ModelView matrix.
float modelViewMat[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelViewMat);
// Here instead of model view matrix we can pass any 4x4 matrix.
float params[9];
GetGluLookAtParameters(modelViewMat, params);
CameraPos.x = params[0];
CameraPos.y = params[1];
CameraPos.z = params[2];
CameraTarget.x = params[3];
CameraTarget.y = params[4];
CameraTarget.z = params[5];
UpVector.x = params[6];
UpVector.y = params[7];
UpVector.z = params[8];
void GetGluLookAtParameters(float* m, float* gluLookAtParams)
{
VECTOR3D sideVector(m[0], m[4], m[8]);
VECTOR3D upVector(m[1], m[5], m[9]);
VECTOR3D forwardVector(-m[2], -m[6], -m[10]);
sideVector.Normalize();
upVector.Normalize();
forwardVector.Normalize();
float rotMat[16];
memcpy(rotMat, m, 16*sizeof(float));
rotMat[12] = rotMat[13] = rotMat[14] = rotMat[3] = rotMat[7] = rotMat[11] = 0.0f;
rotMat[15] = 1.0f;
float rotInvert[16];
__gluInvertMatrixd(rotMat, rotInvert);
float transMat[16];
memset(transMat, 0, 16*sizeof(float));
transMat[0] = transMat[5] = transMat[10] = transMat[15] = 1.0f;
MultMat(rotInvert, m, transMat);
gluLookAtParams[0] = -transMat[12];
gluLookAtParams[1] = -transMat[13];
gluLookAtParams[2] = -transMat[14];
gluLookAtParams[3] = -transMat[12] + forwardVector.x;
gluLookAtParams[4] = -transMat[13] + forwardVector.y;
gluLookAtParams[5] = -transMat[14] + forwardVector.z;
gluLookAtParams[6] = upVector.x;
gluLookAtParams[7] = upVector.y;
gluLookAtParams[8] = upVector.z;
}
void MultMat(float* a, float* b, float* result)
{
result[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
result[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
result[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
result[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];
result[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7];
result[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7];
result[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
result[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];
result[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11];
result[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11];
result[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
result[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];
result[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15];
result[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15];
result[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
result[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];
}
int __gluInvertMatrixd(const float src[16], float inverse[16])
{
int i, j, k, swap;
float t;
GLfloat temp[4][4];
for (i=0; i<4; i++)
for (j=0; j<4; j++)
temp[i][j] = src[i*4+j];
for(int i=0;i<16;i++)
inverse[i] = 0;
inverse[0] = inverse[5] = inverse[10] = inverse[15] = 1.0f;
for(i=0; i<4; i++)
{
swap = i;
for (j = i + 1; j < 4; j++)
if (fabs(temp[j][i]) > fabs(temp[i][i]))
swap = j;
if (swap != i) {
//Swap rows.
for (k = 0; k < 4; k++) {
t = temp[i][k];
temp[i][k] = temp[swap][k];
temp[swap][k] = t;
t = inverse[i*4+k];
inverse[i*4+k] = inverse[swap*4+k];
inverse[swap*4+k] = t;
}
}
if (temp[i][i] == 0)
return 0;
t = temp[i][i];
for (k = 0; k < 4; k++) {
temp[i][k] /= t;
inverse[i*4+k] /= t;
}
for (j = 0; j < 4; j++) {
if (j != i) {
t = temp[j][i];
for (k = 0; k < 4; k++) {
temp[j][k] -= temp[i][k]*t;
inverse[j*4+k] -= inverse[i*4+k]*t;
}
}
}
}
return 1;
}