Program to find GCD of two polynomials

The objective is to write a program that finds greatest common divisor of two polynomials g(x) and h(x).

The task does not define what form we get those two polynomials, so let’s say we will get them in a form of a String, something like that:

``2x^3+5x^2+8x+3``

Let’s start splitting our problem into chunks and gather some information about the steps we would need to implement.

First, what is the greatest common divisor? In math, GCD of two or more integers, which are not all zero, is the largest positive integer that divides each of the integers (1).

How do we find it? One way is to use the Euclidean algorithm. The intuition behind this algorithm is such: we have A and B numbers. We divide A by B and get C. If C is 0 – then B is our GCD. If it is not 0, then we set A to B and B to the reminder and continue operation until we get 0.

gcd(a,0)=a gcd(a,b)=gcd( b,a\,mod\,b )

Let’s say we have 12 and 9. 12 mod 9 is 3. 9 mod 3 is 0. So our GCD is 3.

Ok, now we know about GCD and Euclidian algorithm. Next topic – Polynomials.

Polynomial is an expression consisting of variables (x,y,z etc) and coefficients, that involves only operations of addition, subtraction, and non-negative exponents of variables.

Example of a polynomial with single indeterminate ( variable ) x is

x^2-4x+7

An example in three variables is

x^3-2xyz^2-yz+7

Our objective states to find GCD of g(x) and h(x) polynomials, so we assume objective is to find GCD of single variable polynomials.

Also, for the sake of simplicity, we could say that polynomial consists of a list of monomials with the same variable. Each monomial is made of an optional coefficient, optional variable with optional non-negative integer exponent.

So in x^2-4x+7 we have list of monomials x^2, -4x and 7.

Now we have defined GCD and polynomials. But can we apply the Euclidean algorithm to find GCD for Polynomials? And the short answer is yes.

We will supose that  deg(g(x)) <= deg(h(x)).

Then we find two polynomials q(x) and r(x) that satisfy:

g(x) = q_0(x)h(x)+r_0(x) deg(r_0(x)) < deg(h(x))

Where q is quotient and r is reminder.

Then we set g_1(x)=h(x) and h_1(x)=r_0(x) .

And we repeat polynomial long division to get now polynomials q_1(x) r_1(x) g_1(x) h_1(x) and so on until we reach point when we get h_n(x)=0.

gcd(g,h)=gcd(g_1,h_1)=\cdots=gcd(g_n,0)=g_n

Lets conclude what we knwo at this point: we know what is GCD, we know abut Euclidean algorithm to find GCD, we know about polynomials and monomials and we know that we can apply Euclidean algorithm  to find GCD for polynomials.

There are some things to find out though. When applying the Euclidean algorithm to polynomials we use Polynomial long division for dividing a polynomial by a polynomial of the same or lower degree.

We will have to implement this either to get our quotient and remainder of the polynomial division.

  1. divide the first term of the dividend by the highest term of the divisor
  2. multiply the divisor by the result just obtained
  3. subtract the product just obtained from the appropriate terms of original  dividend
  4. repeat the previouss three steps except this time use the two terms that have just been written as the dividend.

Example:

Divide \frac{5-2x^2+3x^3}{x^2-1}

Step 1. Make sure polynomial is written in descending order. If any term missing, use a zero to fill in the missing term. In this case we should get:

x^2+0x-1\overline {)3x^3-2x^2+0x+5}

Step 2. Divide the term with the highest power inside the division symbol by the term with the highest power outside the division symbol. It his case, we have 3x^2 divided by x^2 which is 3x.

x^2+0x-1\overline {)3x^3-2x^2+0x+5} \quad 3x

Step 3. Multiply the answer obtained in the previous step by the polynomial in front of the division symbol. In this case we need to multiply 3x and x^2 – 1.

Step 3

Step 4: Subtract and bring down the next term.

Step 4

Step 5: Divide the term with the highest power inside the division symbol by the term with the highest power outside the division symbol. In this case, we have –2x2 divided by x2 which is –2.

Step 5

Step 6: Multiply (or distribute) the answer obtained in the previous step by the polynomial in front of the division symbol. In this case, we need to multiply –2 and x2 – 1.

Step 6

Step 7: Subtract and notice there are no more terms to bring down.

Step 7

The polynomial above the bar is the quotient q(x), and the number left over (3x+4) is the remainder r(x).

If A = BQ + R then

5-2x^2+3x^3 = (x^2-1)(3x-2) + (3x+4)

Step 8: Write the final answer. The term remaining after the last subtract step is the remainder and must be written as a fraction in the final answer.

Step 8 i.e. \frac{A}{B}= Q+\frac{R}{B}

(Example is taken from here )

Looking at those steps we can see that we will need to implement those primitive steps in our application:

  • Polynomial sort by exponents.
  • Polynomial missing term expansion.
  • Monomial division.
  • Monomial multiplication.
  • Monomial subtraction.

So now: we know what is GCD, we know about Euclidean algorithm to find GCD, we know about polynomials and monomials and we know that we can apply Euclidean algorithm  to find GCD for polynomials and then we know how to perform long division on polynomials.

At this point we have enough information and can start writing some code.

 

PowerBuilder, disable system menu`s close button

ulong ll_parent_hwnd
ulong ll_sys_menu_hwnd
ulong ll_sys_menu_close_flags
ulong ll_ret

n_cst_numerical u_num

ll_parent_hwnd = Handle(this.parentwindow())

ll_sys_menu_hwnd = GetSystemMenu(ll_parent_hwnd, FALSE)

ll_sys_menu_close_flags = GetMenuState(ll_sys_menu_hwnd, SC_CLOSE, MF_BYCOMMAND )

ll_ret = u_num.of_bitwiseand(ll_sys_menu_close_flags , MF_DISABLED)

ib_close_prev_enabled = (ll_ret = 0)

If ib_close_prev_enabled Then
EnableMenuItem (ll_sys_menu_hwnd, SC_CLOSE, MF_BYCOMMAND + MF_DISABLED + MF_GRAYED)
End If

 

And to enable it later:

If ib_close_prev_enabled Then
EnableMenuItem (GetSystemMenu(handle(parentwindow()), FALSE), SC_CLOSE, MF_BYCOMMAND + MF_ENABLED)
End If