Browse Source

Breaching the core.

<https://www.youtube.com/watch?v=DoQleiZj3Tk>
Michele Orrù 11 years ago
parent
commit
ad8f26695c

+ 1 - 1
book/dixon.tex

@@ -154,7 +154,7 @@ and storing dependencies into a \emph{history matrix} $H$.
     \Comment reduce
     \Comment reduce
       \For{$i=0 \strong{ to } f$}
       \For{$i=0 \strong{ to } f$}
         \If{$M_{i, j} = 1$}
         \If{$M_{i, j} = 1$}
-          \For{$i' = i \strong{ to } f$}
+          \For{$i' = i+1 \strong{ to } f$}
             \If{$M_{i', k} = 1$}
             \If{$M_{i', k} = 1$}
               \State $M_{i'} = Mi \xor M_{i'}$
               \State $M_{i'} = Mi \xor M_{i'}$
               \State $H_{i'} = H_i \xor H_{i'}$
               \State $H_{i'} = H_i \xor H_{i'}$

+ 29 - 0
src/questions/dixon.c

@@ -22,6 +22,7 @@
 #include <openssl/bn.h>
 #include <openssl/bn.h>
 
 
 #include "qa/questions/questions.h"
 #include "qa/questions/questions.h"
+#include "qa/questions/qstrings.h"
 #include "qa/questions/qdixon.h"
 #include "qa/questions/qdixon.h"
 
 
 
 
@@ -68,6 +69,34 @@ matrix_free(matrix_t *m)
   free(m);
   free(m);
 }
 }
 
 
+/*
+ * \ref Kernel into a binary matrix.
+ *
+ * Discover linear dependencies using a refined version of the Gauss-Jordan
+ * algorithm, from Brillhart and Morrison.
+ *
+ * \return h, the history matrix
+ *
+ */
+matrix_t *
+kernel(matrix_t *m)
+{
+  int i, j, k;
+  matrix_t *h = identity_matrix_new(m->f);
+
+  for (j=0; j!=m->r; j++)
+    for (i=0;  i != m->f; i++)
+      if (m->M[i][j]) {
+        for (k=i+1; k != m->f; k++)
+          if (m->M[k][j]) {
+            vxor(m->M[k], m->M[k], m->M[i], m->r);
+            vxor(h->M[k], h->M[k], h->M[i], h->r);
+          }
+        break;
+      }
+
+  return h;
+}
 
 
 qa_question_t DixonQuestion = {
 qa_question_t DixonQuestion = {
   .name = "dixon",
   .name = "dixon",

+ 4 - 1
src/questions/include/qdixon.h

@@ -4,15 +4,18 @@
 extern struct qa_question DixonQuestion;
 extern struct qa_question DixonQuestion;
 
 
 typedef struct matrix {
 typedef struct matrix {
-  uint8_t  **M;
+  char  **M;
   size_t f;
   size_t f;
   size_t r;
   size_t r;
 } matrix_t;
 } matrix_t;
 
 
 
 
 matrix_t* identity_matrix_new(int d);
 matrix_t* identity_matrix_new(int d);
+
 matrix_t* matrix_new(int r, int c);
 matrix_t* matrix_new(int r, int c);
+
 void matrix_free(matrix_t *m);
 void matrix_free(matrix_t *m);
 
 
+matrix_t *kernel(matrix_t *m);
 
 
 #endif /* _QA_DIXON_H_ */
 #endif /* _QA_DIXON_H_ */

+ 4 - 2
src/questions/include/qstrings.h

@@ -1,8 +1,10 @@
 #ifndef _QA_QSTRINGS_H_
 #ifndef _QA_QSTRINGS_H_
 #define _QA_QSTRINGS_H_
 #define _QA_QSTRINGS_H_
 
 
-int is_vzero(const void *v, size_t len);
+int
+is_vzero(const void *v, size_t len);
 
 
-void vxor(void *u, const void *v, const void *w, size_t len);
+void
+vxor(void *u, const void *v, const void *w, size_t len);
 
 
 #endif /* _QA_QSTRINGS_H_ */
 #endif /* _QA_QSTRINGS_H_ */

+ 46 - 1
src/questions/tests/test_dixon.c

@@ -1,8 +1,10 @@
+#include <assert.h>
 #include <stdint.h>
 #include <stdint.h>
+#include <string.h>
 #include <unistd.h>
 #include <unistd.h>
-#include <assert.h>
 
 
 #include "qa/questions/qdixon.h"
 #include "qa/questions/qdixon.h"
+#include "qa/questions/qstrings.h"
 
 
 
 
 void test_matrix(void)
 void test_matrix(void)
@@ -23,10 +25,53 @@ void test_matrix(void)
   matrix_free(m);
   matrix_free(m);
 }
 }
 
 
+
+void
+test_kernel(void)
+{
+  matrix_t *m;
+  matrix_t *h;
+
+
+  /* test with a canonical base in (𝔽₂)³ */
+  m = identity_matrix_new(3);
+  assert(m->M[0][0] == 1);
+  h = kernel(m);
+
+  assert(m->M[0][0] == 1);
+  assert(!is_vzero(m->M[0], 3));
+  assert(!is_vzero(m->M[1], 3));
+  assert(!is_vzero(m->M[2], 3));
+
+  matrix_free(m);
+  matrix_free(h);
+
+  /* test with a redundant system */
+  m = matrix_new(4, 3);
+  memcpy(m->M[0], "\0\1\0", 3);
+  memcpy(m->M[1], "\0\1\1", 3);
+  memcpy(m->M[2], "\0\1\1", 3);
+  memcpy(m->M[3], "\0\1\1", 3);
+  h = kernel(m);
+  /* only two vectors are linearly independent */
+  assert(!is_vzero(m->M[0], 3));
+  assert(!is_vzero(m->M[1], 3));
+  assert(is_vzero(m->M[2], 3));
+  assert(is_vzero(m->M[3], 3));
+  /* test history matrix */
+  assert(h->M[0][0] == 1 && h->M[0][1] == 0);
+  assert(h->M[1][1] == 1 && h->M[1][0] == 1);
+  assert(h->M[2][1] == 1 && h->M[2][2] == 1);
+  assert(h->f == 4 && h->r == 4);
+  assert(h->M[3][2] == 0);
+}
+
+
 int
 int
 main(int argc, char **argv)
 main(int argc, char **argv)
 {
 {
   test_matrix();
   test_matrix();
+  test_kernel();
 
 
   return 0;
   return 0;
 }
 }

+ 6 - 2
src/questions/tests/test_qstrings.c

@@ -3,7 +3,8 @@
 
 
 #include "qa/questions/qstrings.h"
 #include "qa/questions/qstrings.h"
 
 
-void test_is_vzero(void)
+void
+test_is_vzero(void)
 {
 {
   const char *v = "\x0\x0\x0\x1\x0\x1";
   const char *v = "\x0\x0\x0\x1\x0\x1";
 
 
@@ -13,7 +14,8 @@ void test_is_vzero(void)
 }
 }
 
 
 
 
-void test_vxor(void)
+void
+test_vxor(void)
 {
 {
   size_t i;
   size_t i;
   char v[10] = "\0\1\0\1\0\1\0\1\0\1";
   char v[10] = "\0\1\0\1\0\1\0\1\0\1";
@@ -31,6 +33,8 @@ void test_vxor(void)
     assert(v[i] == 0);
     assert(v[i] == 0);
 
 
 }
 }
+
+
 int main(int argc, char **argv)
 int main(int argc, char **argv)
 {
 {
   test_is_vzero();
   test_is_vzero();