[libmath-prime-util-perl] 28/55: Simple forpart

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:53:41 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.41
in repository libmath-prime-util-perl.

commit 7c3aca2989ab1098bf33a0fb59c9a886bbd5abe7
Author: Dana Jacobsen <dana at acm.org>
Date:   Wed May 7 18:35:47 2014 -0700

    Simple forpart
---
 TODO  |  6 ++++++
 XS.xs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/TODO b/TODO
index f8132c7..5743d8e 100644
--- a/TODO
+++ b/TODO
@@ -72,3 +72,9 @@
 - We don't use legendre_phi for other functions any more, but it'd be nice
   to speed it up using some ideas from the Ohana 2011 SAGE branch.  For example
   (10**13,10**5) takes 2.5x longer, albeit with 6x less memory.
+
+- forpart:
+    - alias with fordivisors to save space
+    - consider use of const_int since so many entries will be 1 or 2
+    - documentation (mention for partitions function, mention Pari 2.7)
+    - tests
diff --git a/XS.xs b/XS.xs
index b6206ab..9be868c 100644
--- a/XS.xs
+++ b/XS.xs
@@ -1227,3 +1227,55 @@ fordivisors (SV* block, IN SV* svn)
     }
     SvREFCNT_dec(svarg);
     Safefree(divs);
+
+void
+forpart (SV* block, IN SV* svn)
+  PROTOTYPE: &$
+  PREINIT:
+    UV i, m, h, n;
+    UV *x;
+    GV *gv;
+    HV *stash;
+    CV *cv;
+  PPCODE:
+    cv = sv_2cv(block, &stash, &gv, 0);
+    if (cv == Nullcv)
+      croak("Not a subroutine reference");
+    if (!_validate_int(aTHX_ svn, 0)) {
+      _vcallsubn(aTHX_ G_VOID|G_DISCARD, VCALL_ROOT, "_generic_forpart", 2);
+      return;
+    }
+    n = my_svuv(svn);
+
+    /* ZS1 algorithm from Zoghbi and Stojmenovic 1998) */
+    New(0, x, n+1, UV);
+    for(i = 0; i <= n; i++)  x[i] = 1;
+    x[1] = n;
+    m = 1;
+    h = 1;
+    {
+      { dSP; ENTER; SAVETMPS; PUSHMARK(SP);
+        XPUSHs(sv_2mortal(newSVuv(n)));
+        PUTBACK; call_sv((SV*)cv, G_VOID|G_DISCARD); FREETMPS; LEAVE;
+      }
+      while (x[1] != 1) {
+        if (x[h] == 2) {
+          m++;
+          x[h] = 1;
+          h--;
+        } else {
+          UV r,t;
+          r = x[h]-1;
+          t = m-h+1;
+          x[h] = r;
+          while (t >= r) {  h++;  x[h] = r;  t -= r;  }
+          if (t == 0) { m = h; }
+          else        { m = h+1;  if (t > 1) {  h++;  x[h] = t;  }  }
+        }
+        { dSP; ENTER; SAVETMPS; PUSHMARK(SP);
+          for (i = m; i >= 1; i--) { XPUSHs(sv_2mortal(newSVuv(x[i]))); }
+          PUTBACK; call_sv((SV*)cv, G_VOID|G_DISCARD); FREETMPS; LEAVE;
+        }
+      }
+    }
+    Safefree(x);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list