Sophie

Sophie

distrib > Mandriva > current > i586 > media > contrib-release-src > by-pkgid > b25d724ee973777b54d62422e3dd76b8 > files > 2

iml-1.0.2-4mdv2010.0.src.rpm

diff -p -up iml-1.0.2/src/nullspace.c.orig iml-1.0.2/src/nullspace.c
--- iml-1.0.2/src/nullspace.c.orig	2009-05-08 20:11:29.000000000 -0300
+++ iml-1.0.2/src/nullspace.c	2009-05-08 20:11:53.000000000 -0300
@@ -187,3 +187,150 @@ nullspaceLong(const long n, const long m
     return s;
 
 }
+
+/*
+ * Calling Sequence:
+ *   nullspaceLong(n, m, A, mp_N_pass)
+ *
+ * Summary: Compute the right nullspace of A. In this function A is a
+ * 1-dimensional mpz_t array.
+ *
+ * Input:  n: long, row dimension of A
+ *         m: long, column dimension of A
+ *         A: 1-dim mpz_t array length n*m, representing n x m matrix
+ *            in row major order
+ *
+ * Output:
+ *   - *mp_N_pass: points to a 1-dim mpz_t array of length m*s, where s is the 
+ *                dimension of the right nullspace of A
+ *   - the dimension s of the nullspace is returned
+ *
+ * Notes:
+ *   - The matrix A is represented by one-dimension array in row major order.
+ *   - Space for what mp_N_points to is allocated by this procedure: if the
+ *     nullspace is empty, mp_N_pass is set to NULL.
+ */
+
+long
+nullspaceMP(const long n, const long m, const mpz_t *A, mpz_t * *mp_N_pass)
+{
+    long i, j, k, r, s, *P, *rp, *Pt, *rpt, flag, temp;
+    double *DA;
+    FiniteField p, d = 1;
+    mpz_t *mp_B, *mp_N, mp_D, mp_t1, mp_t2, *C, mp_r;
+
+    mpz_init(mp_r);
+
+    P = XCALLOC(long, n + 1);
+    rp = XCALLOC(long, n + 1);
+    while (1) {
+	p = RandPrime(15, 19);
+	DA = XCALLOC(double, n * m);
+	for (i = 0; i < n * m; i++) {
+  	    mpz_mod_ui (mp_r, A[i], p);
+	    DA[i] = mpz_get_d(mp_r);
+	}
+	for (i = 0; i < n + 1; i++) {
+	    P[i] = i;
+	    rp[i] = 0;
+	}
+	d = 1;
+	RowEchelonTransform(p, DA, n, m, 1, 1, 0, 0, P, rp, &d);
+	XFREE(DA);
+	r = rp[0];
+	s = m - r;
+	if (s == 0) {
+	    *mp_N_pass = NULL;
+	} else if (r == 0) {
+	    flag = 1;
+	    for (i = 0; i < n * m; i++)
+		if ( mpz_cmp_si(A[i],0) )
+		    flag = 0;
+	    if (!flag)
+		continue;
+	    mp_N = XCALLOC(mpz_t, m * m);
+	    for (i = 0; i < m; i++) {
+		for (j = 0; j < m; j++)
+		    mpz_init_set_ui(mp_N[i * m + j], 0);
+		mpz_set_ui(mp_N[i * m + i], 1);
+	    }
+	    *mp_N_pass = mp_N;
+	} else {		/* r>0 and s>0 */
+
+	    Pt = revseq(r, n, P);
+	    rpt = revseq(r, m, rp);
+
+	    C = XCALLOC(mpz_t, r * r);
+	    for (i = 0; i < r; i++)
+		for (j = 0; j < r; j++)
+		    mpz_init_set(C[i * r + j], A[Pt[i] * m + rpt[j]]);
+
+	    mp_B = XCALLOC(mpz_t, r * s);
+	    for (i = 0; i < r; i++)
+		for (j = 0; j < s; j++)
+		    mpz_init_set(mp_B[i * s + j], A[Pt[i] * m + rpt[r + j]]);
+
+	    mpz_init(mp_D);
+	    mp_N = XCALLOC(mpz_t, m * s);
+	    for (i = 0; i < m * s; i++)
+		mpz_init(mp_N[i]);
+
+
+	    nonsingSolvLlhsMM(RightSolu, r, s, C, mp_B, mp_N, mp_D);
+
+	    mpz_neg(mp_D, mp_D);
+	    for (i = 0; i < s; i++)
+		mpz_set(mp_N[(r + i) * s + i], mp_D);
+
+	    for (i = 0; i < r*r; i++)
+	        mpz_clear(C[i]);
+	    XFREE(C);
+
+	    for (i = 0; i < r * s; i++)
+		mpz_clear(mp_B[i]);
+	    XFREE(mp_B);
+	    mpz_clear(mp_D);
+
+	    for (i = r; i >= 1; i--)
+		for (j = 0; j < s; j++)
+		    mpz_swap(mp_N[(i - 1) * s + j],
+			     mp_N[(rp[i] - 1) * s + j]);
+
+	    *mp_N_pass = mp_N;
+
+	    flag = 1;
+	    mpz_init(mp_t1);
+	    mpz_init(mp_t2);
+	    for (i = r; i < n && flag; i++) {
+		for (j = 0; j < s && flag; j++) {
+		    mpz_set_ui(mp_t2, 0);
+		    for (k = 0; k < m; k++) {
+			mpz_mul(mp_t1, mp_N[k * s + j],  A[Pt[i] * m + k]);
+			mpz_add(mp_t2, mp_t2, mp_t1);
+		    }
+		    if (mpz_sgn(mp_t2) != 0)
+			flag = 0;
+		}
+	    }
+	    mpz_clear(mp_t1);
+	    mpz_clear(mp_t2);
+
+	    XFREE(Pt);
+	    XFREE(rpt);
+
+	    if (!flag) {
+		for (i = 0; i < m * s; i++)
+		    mpz_clear(mp_N[i]);
+		XFREE(mp_N);
+		continue;
+	    }
+	}
+	break;
+    }
+    XFREE(P);
+    XFREE(rp);
+
+    mpz_clear(mp_r);
+    return s;
+
+}
diff -p -up iml-1.0.2/src/nullspace.h.orig iml-1.0.2/src/nullspace.h
--- iml-1.0.2/src/nullspace.h.orig	2009-05-08 20:12:44.000000000 -0300
+++ iml-1.0.2/src/nullspace.h	2009-05-08 20:13:10.000000000 -0300
@@ -58,5 +58,9 @@ long nullspaceLong(const long n, 
 		   const long *A, 
 		   mpz_t * *mp_N_pass);
 
+long nullspaceMP(const long n,
+		 const long m,
+		 const mpz_t *A,
+		 mpz_t * *mp_N_pass);
 
 #endif /* !IML_NULLSPACE_H */