{"id":2551,"date":"2026-02-02T10:43:44","date_gmt":"2026-02-02T10:43:44","guid":{"rendered":"https:\/\/demo.materiamedica.net\/demo6\/?p=2551"},"modified":"2026-02-02T10:43:44","modified_gmt":"2026-02-02T10:43:44","slug":"chapter-10-ufunc-finding-gcd","status":"publish","type":"post","link":"https:\/\/demo.materiamedica.net\/demo6\/chapter-10-ufunc-finding-gcd\/","title":{"rendered":"Chapter 10: ufunc Finding GCD"},"content":{"rendered":"<h3 dir=\"auto\">1. What is GCD? (quick but important reminder)<\/h3>\n<p dir=\"auto\">The <strong>Greatest Common Divisor<\/strong> (also called Greatest Common Factor or Highest Common Factor) of two or more integers is the <strong>largest positive integer<\/strong> that divides all of them <strong>without leaving a remainder<\/strong>.<\/p>\n<p dir=\"auto\">Examples:<\/p>\n<ul dir=\"auto\">\n<li>GCD(12, 18) = 6<\/li>\n<li>GCD(48, 60, 36) = 12<\/li>\n<li>GCD(7, 13) = 1 (coprime numbers)<\/li>\n<li>GCD(0, 0) = 0 (by convention in most libraries)<\/li>\n<\/ul>\n<h3 dir=\"auto\">2. NumPy has built-in GCD support \u2013 since when?<\/h3>\n<p dir=\"auto\">Important timeline:<\/p>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Version<\/th>\n<th data-col-size=\"sm\">Has np.gcd?<\/th>\n<th data-col-size=\"sm\">Has np.gcd.reduce?<\/th>\n<th data-col-size=\"xl\">Recommendation<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">&lt; 1.9<\/td>\n<td data-col-size=\"sm\">No<\/td>\n<td data-col-size=\"sm\">No<\/td>\n<td data-col-size=\"xl\">You must implement it<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">1.9 \u2013 1.17<\/td>\n<td data-col-size=\"sm\">Yes<\/td>\n<td data-col-size=\"sm\">No<\/td>\n<td data-col-size=\"xl\">Use np.gcd for pairs<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">\u2265 1.18<\/td>\n<td data-col-size=\"sm\">Yes<\/td>\n<td data-col-size=\"sm\">Yes<\/td>\n<td data-col-size=\"xl\">Use np.gcd and np.gcd.reduce<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">Today (2025) almost everyone is on 1.20+ or 2.x, so we can use the modern functions.<\/p>\n<h3 dir=\"auto\">3. The two main GCD functions you need<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"sm\">Function<\/th>\n<th data-col-size=\"xl\">What it does<\/th>\n<th data-col-size=\"lg\">Returns<\/th>\n<th data-col-size=\"md\">Typical usage<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"sm\">np.gcd(a, b)<\/td>\n<td data-col-size=\"xl\">Element-wise GCD of two arrays (or scalars)<\/td>\n<td data-col-size=\"lg\">array or scalar<\/td>\n<td data-col-size=\"md\">pairwise GCD<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"sm\">np.gcd.reduce(arr)<\/td>\n<td data-col-size=\"xl\">GCD of all elements in array (or along axis)<\/td>\n<td data-col-size=\"lg\">scalar or reduced array<\/td>\n<td data-col-size=\"md\">GCD of many numbers<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">4. Basic usage examples \u2013 scalars and pairs<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>print(\"GCD of 12 and 18:\", np.gcd(12, 18))          # 6\r\nprint(\"GCD of 48 and 60:\", np.gcd(48, 60))          # 12\r\nprint(\"GCD of 7 and 13:\",  np.gcd(7, 13))           # 1\r\nprint(\"GCD of 0 and 25:\",  np.gcd(0, 25))           # 25\r\nprint(\"GCD of 0 and 0:\",   np.gcd(0, 0))            # 0<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Element-wise on arrays<\/strong> (very powerful)<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>a = np.array([12, 48, 7, 0, 30])\r\nb = np.array([18, 60, 13, 25, 42])\r\n\r\nprint(\"Pairwise GCD:\", np.gcd(a, b))\r\n# [ 6 12  1 25  6]<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">5. Finding GCD of many numbers \u2013 np.gcd.reduce<\/h3>\n<p dir=\"auto\">This is the most common real need.<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>numbers = np.array([12, 18, 24, 36, 48])\r\n\r\nprint(\"GCD of all:\", np.gcd.reduce(numbers))        # 6\r\n\r\n# More realistic example\r\nperiods = np.array([12, 18, 30, 45, 60])\r\nprint(\"When do all cycles repeat together?\", np.gcd.reduce(periods))   # 6<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Along an axis<\/strong> (very useful with 2D data)<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>matrix = np.array([\r\n    [12, 18, 24],\r\n    [30, 45, 60],\r\n    [36, 48, 72]\r\n])\r\n\r\nprint(\"GCD of each column:\", np.gcd.reduce(matrix, axis=0))\r\n# [ 6  3 12]\r\n\r\nprint(\"GCD of each row:\", np.gcd.reduce(matrix, axis=1))\r\n# [ 6 15 12]<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">6. Realistic examples you will actually meet<\/h3>\n<p dir=\"auto\"><strong>Example 1 \u2013 Finding when multiple periodic events align again<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code># Three machines need service every 15, 24, and 40 days\r\nservice_interval = np.array([15, 24, 40])\r\n\r\nfirst_common_day = np.lcm.reduce(service_interval)   # if you have lcm\r\nprint(\"First common service day:\", first_common_day)  # 120\r\n\r\n# But if we only have GCD for some reason (example)\r\nprint(\"GCD of intervals:\", np.gcd.reduce(service_interval))  # 1<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Example 2 \u2013 Simplifying fractions (classic school problem)<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>numerators   = np.array([12, 18, 24, 36])\r\ndenominators = np.array([30, 45, 60, 72])\r\n\r\ncommon_divisor = np.gcd(numerators, denominators)\r\n\r\nsimplified_num = numerators   \/\/ common_divisor\r\nsimplified_den = denominators \/\/ common_divisor\r\n\r\nprint(\"Original fractions:\")\r\nfor n, d in zip(numerators, denominators):\r\n    print(f\"{n}\/{d}\", end=\"  \")\r\n\r\nprint(\"\\nSimplified:\")\r\nfor n, d in zip(simplified_num, simplified_den):\r\n    print(f\"{n}\/{d}\", end=\"  \")<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Example 3 \u2013 Finding GCD of array elements along axis<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code># Measurements from 4 sensors over 100 time steps\r\n# Want GCD of readings per sensor (example scenario)\r\nreadings = np.random.randint(10, 200, size=(100, 4)) * 5   # multiples of 5\r\n\r\ngcd_per_sensor = np.gcd.reduce(readings, axis=0)\r\n\r\nprint(\"GCD of all readings per sensor:\", gcd_per_sensor)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Example 4 \u2013 Batch GCD computation (very common in coding problems)<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code># Multiple pairs at once\r\npairs = np.array([\r\n    [12, 18],\r\n    [48, 60],\r\n    [7, 13],\r\n    [100, 125],\r\n    [0, 50]\r\n])\r\n\r\nprint(\"GCD of each pair:\")\r\nprint(np.gcd(pairs[:,0], pairs[:,1]))\r\n# [ 6 12  1 25 50]<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">7. Summary \u2013 NumPy GCD Quick Reference<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"lg\">Situation<\/th>\n<th data-col-size=\"lg\">Best syntax (modern NumPy)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"lg\">GCD of two numbers<\/td>\n<td data-col-size=\"lg\">np.gcd(a, b)<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Pairwise GCD of two arrays<\/td>\n<td data-col-size=\"lg\">np.gcd(array1, array2)<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">GCD of many numbers (whole array)<\/td>\n<td data-col-size=\"lg\">np.gcd.reduce(array)<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">GCD along axis (rows\/columns)<\/td>\n<td data-col-size=\"lg\">np.gcd.reduce(array, axis=0 or 1)<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"lg\">Older NumPy (before 1.18)<\/td>\n<td data-col-size=\"lg\">Implement with abs(a*b) \/\/ np.gcd(a,b)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">Final teacher advice (very important)<\/h3>\n<p dir=\"auto\"><strong>Golden rule #1<\/strong> <strong>If your NumPy is 1.18 or newer \u2192 always use np.gcd and np.gcd.reduce<\/strong> \u2014 they are optimized and clean.<\/p>\n<p dir=\"auto\"><strong>Golden rule #2<\/strong> <strong>When you want GCD of more than two numbers, always use .reduce()<\/strong> \u2014 never write a loop.<\/p>\n<p dir=\"auto\"><strong>Golden rule #3<\/strong> <strong>GCD is always positive<\/strong> \u2014 NumPy returns positive values even if inputs are negative.<\/p>\n<p dir=\"auto\"><strong>Golden rule #4<\/strong> <strong>GCD(a, 0) = |a|<\/strong> <strong>GCD(0, 0) = 0<\/strong> (by convention)<\/p>\n<p dir=\"auto\"><strong>Golden rule #5<\/strong> LCM and GCD are closely related:<\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Python<\/div>\n<div>\n<pre tabindex=\"0\"><code>lcm(a, b) = abs(a * b) \/\/ gcd(a, b)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\">So if you have np.gcd, you can easily build LCM yourself.<\/p>\n<p dir=\"auto\">Would you like to continue with any of these next?<\/p>\n<ul dir=\"auto\">\n<li>How to find LCM using GCD (very common follow-up)<\/li>\n<li>GCD of more than two numbers efficiently<\/li>\n<li>Common GCD coding competition patterns<\/li>\n<li>Realistic mini-project: fraction simplification or cycle alignment<\/li>\n<li>Handling very large numbers (when GCD is used in modular arithmetic)<\/li>\n<\/ul>\n<p dir=\"auto\">Just tell me what you want to focus on next! \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What is GCD? (quick but important reminder) The Greatest Common Divisor (also called Greatest Common Factor or Highest Common Factor) of two or more integers is the largest positive integer that divides all&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[75],"tags":[],"class_list":["post-2551","post","type-post","status-publish","format-standard","hentry","category-numpy"],"_links":{"self":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2551","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/comments?post=2551"}],"version-history":[{"count":1,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2551\/revisions"}],"predecessor-version":[{"id":2552,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2551\/revisions\/2552"}],"wp:attachment":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/media?parent=2551"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/categories?post=2551"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/tags?post=2551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}