Optimizing Miller-Rabin Primality Test in Python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I'm writing a Miller-Rabin primality test in Python. While I've briefly looked at how others approached the problem, I decided to try solving the problem on my own. Aside from my choice of language, how could I go about optimizing this code? Any suggestions are welcome and don't hesitate to be brutally honest.



def miller_rabin_primality_test(n):

def mr_check_one(n):
m = n - 1
n = n - 1
k = 1

while n % 2**k == 0:
m = n / 2**k
k = k + 1

return(m)

def mr_check_two(n, m, a = [2, 3]):

for i in range(0, len(a)):
a = a[i]
b = pow(a, m, n)
i = 0

if(b == n - 1 or b == 1):
return True

while(b != n - 1 and i < 7):
b = pow(b, 2, n)
i = i + 1

if(b != n - 1):
return False
else:
return True


m = mr_check_one(n)
r = mr_check_two(n, m)

return(r)






share|improve this question



























    up vote
    4
    down vote

    favorite












    I'm writing a Miller-Rabin primality test in Python. While I've briefly looked at how others approached the problem, I decided to try solving the problem on my own. Aside from my choice of language, how could I go about optimizing this code? Any suggestions are welcome and don't hesitate to be brutally honest.



    def miller_rabin_primality_test(n):

    def mr_check_one(n):
    m = n - 1
    n = n - 1
    k = 1

    while n % 2**k == 0:
    m = n / 2**k
    k = k + 1

    return(m)

    def mr_check_two(n, m, a = [2, 3]):

    for i in range(0, len(a)):
    a = a[i]
    b = pow(a, m, n)
    i = 0

    if(b == n - 1 or b == 1):
    return True

    while(b != n - 1 and i < 7):
    b = pow(b, 2, n)
    i = i + 1

    if(b != n - 1):
    return False
    else:
    return True


    m = mr_check_one(n)
    r = mr_check_two(n, m)

    return(r)






    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I'm writing a Miller-Rabin primality test in Python. While I've briefly looked at how others approached the problem, I decided to try solving the problem on my own. Aside from my choice of language, how could I go about optimizing this code? Any suggestions are welcome and don't hesitate to be brutally honest.



      def miller_rabin_primality_test(n):

      def mr_check_one(n):
      m = n - 1
      n = n - 1
      k = 1

      while n % 2**k == 0:
      m = n / 2**k
      k = k + 1

      return(m)

      def mr_check_two(n, m, a = [2, 3]):

      for i in range(0, len(a)):
      a = a[i]
      b = pow(a, m, n)
      i = 0

      if(b == n - 1 or b == 1):
      return True

      while(b != n - 1 and i < 7):
      b = pow(b, 2, n)
      i = i + 1

      if(b != n - 1):
      return False
      else:
      return True


      m = mr_check_one(n)
      r = mr_check_two(n, m)

      return(r)






      share|improve this question













      I'm writing a Miller-Rabin primality test in Python. While I've briefly looked at how others approached the problem, I decided to try solving the problem on my own. Aside from my choice of language, how could I go about optimizing this code? Any suggestions are welcome and don't hesitate to be brutally honest.



      def miller_rabin_primality_test(n):

      def mr_check_one(n):
      m = n - 1
      n = n - 1
      k = 1

      while n % 2**k == 0:
      m = n / 2**k
      k = k + 1

      return(m)

      def mr_check_two(n, m, a = [2, 3]):

      for i in range(0, len(a)):
      a = a[i]
      b = pow(a, m, n)
      i = 0

      if(b == n - 1 or b == 1):
      return True

      while(b != n - 1 and i < 7):
      b = pow(b, 2, n)
      i = i + 1

      if(b != n - 1):
      return False
      else:
      return True


      m = mr_check_one(n)
      r = mr_check_two(n, m)

      return(r)








      share|improve this question












      share|improve this question




      share|improve this question








      edited Mar 6 at 13:06









      Toby Speight

      17.7k13490




      17.7k13490









      asked Mar 5 at 0:32









      D. Senack

      364




      364




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          One obvious change to make is that mr_check_one(n) does a much more expensive loop than necessary. Here is a much simpler and faster version.



          def mr_check_one(n):
          m = n - 1

          n = n - 1
          k = 1
          while n % 2 == 0:
          k += 1
          n /= 2

          return(m / 2**k)


          Also, your second function seems really broken. You allegedly loop over a, but in your first time through you redefine a, reset i and return before going through the loop more than once.






          share|improve this answer





















          • Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
            – D. Senack
            Mar 6 at 3:45











          • I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
            – Oscar Smith
            Mar 6 at 3:50










          • I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
            – D. Senack
            Mar 6 at 4:41










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188829%2foptimizing-miller-rabin-primality-test-in-python%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote













          One obvious change to make is that mr_check_one(n) does a much more expensive loop than necessary. Here is a much simpler and faster version.



          def mr_check_one(n):
          m = n - 1

          n = n - 1
          k = 1
          while n % 2 == 0:
          k += 1
          n /= 2

          return(m / 2**k)


          Also, your second function seems really broken. You allegedly loop over a, but in your first time through you redefine a, reset i and return before going through the loop more than once.






          share|improve this answer





















          • Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
            – D. Senack
            Mar 6 at 3:45











          • I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
            – Oscar Smith
            Mar 6 at 3:50










          • I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
            – D. Senack
            Mar 6 at 4:41














          up vote
          1
          down vote













          One obvious change to make is that mr_check_one(n) does a much more expensive loop than necessary. Here is a much simpler and faster version.



          def mr_check_one(n):
          m = n - 1

          n = n - 1
          k = 1
          while n % 2 == 0:
          k += 1
          n /= 2

          return(m / 2**k)


          Also, your second function seems really broken. You allegedly loop over a, but in your first time through you redefine a, reset i and return before going through the loop more than once.






          share|improve this answer





















          • Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
            – D. Senack
            Mar 6 at 3:45











          • I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
            – Oscar Smith
            Mar 6 at 3:50










          • I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
            – D. Senack
            Mar 6 at 4:41












          up vote
          1
          down vote










          up vote
          1
          down vote









          One obvious change to make is that mr_check_one(n) does a much more expensive loop than necessary. Here is a much simpler and faster version.



          def mr_check_one(n):
          m = n - 1

          n = n - 1
          k = 1
          while n % 2 == 0:
          k += 1
          n /= 2

          return(m / 2**k)


          Also, your second function seems really broken. You allegedly loop over a, but in your first time through you redefine a, reset i and return before going through the loop more than once.






          share|improve this answer













          One obvious change to make is that mr_check_one(n) does a much more expensive loop than necessary. Here is a much simpler and faster version.



          def mr_check_one(n):
          m = n - 1

          n = n - 1
          k = 1
          while n % 2 == 0:
          k += 1
          n /= 2

          return(m / 2**k)


          Also, your second function seems really broken. You allegedly loop over a, but in your first time through you redefine a, reset i and return before going through the loop more than once.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Mar 6 at 3:12









          Oscar Smith

          2,625922




          2,625922











          • Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
            – D. Senack
            Mar 6 at 3:45











          • I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
            – Oscar Smith
            Mar 6 at 3:50










          • I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
            – D. Senack
            Mar 6 at 4:41
















          • Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
            – D. Senack
            Mar 6 at 3:45











          • I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
            – Oscar Smith
            Mar 6 at 3:50










          • I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
            – D. Senack
            Mar 6 at 4:41















          Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
          – D. Senack
          Mar 6 at 3:45





          Thanks for the suggestion on the first function. As for the second, I want to check all results of mr_check_one for 2^m mod n AND 3^m mod n (m being the result of mr_check_one). I was trying to loop over again with a different "a" value. Does that make any sense? I wasn't really sure how to go about it. Any ideas?
          – D. Senack
          Mar 6 at 3:45













          I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
          – Oscar Smith
          Mar 6 at 3:50




          I think so, but that means your code is pretty badly broken and thus more appropriate for stackoverflow or similar.
          – Oscar Smith
          Mar 6 at 3:50












          I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
          – D. Senack
          Mar 6 at 4:41




          I rewrote the second function. Hopefully, it's a little better. At a minimum, it is more modular and, perhaps, easier to understand. If you still think it seems pretty badly broken I'll post it over at StackOverflow. Thanks for the insights.
          – D. Senack
          Mar 6 at 4:41












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188829%2foptimizing-miller-rabin-primality-test-in-python%23new-answer', 'question_page');

          );

          Post as a guest