-1

I am creating a polynomial calculator for 2 polynomials in C++. For different operations, I have created different functions. Below is my approach for the function for multiplication. For multiplying, first I must save all the possible degrees. This should mean a max of highest degree of polynomial1+polynomial2, and least of smallest degree of either. I am first just saving all the possible degree options taking into consideration polynomial1 and polynomial 2. I will then sort the degrees in descending order, perform calculations on coefficients, and save the coefficient according to the degree calculated.

However I am unable to properly save all the possible degree options, and can't spot the error. The values that are actually being saved, I can't seem to understand, why they are being saved, and where is the error. I am writing this program without utilising external libraries like for performing calculations. Kindly spot the error, and how I can successfully save all the possible degree options correctly. The comments are my understanding of what is happening/ should be happening. Thanks.

The ideal output should be: "99, 97, 95, 93, 91, 89, 98, 96, 94, 92, 90, 88...."

The current output is: "99 96 93 90 87 84 81 78 75 72 688904896 32629 119 114 109 104 97 94 89 84 79 74 1377809792 65258 218 210 202 194 184 178"

#include <iostream>
using namespace std;


void multiply(int degree_poly1[], int terms_poly1, int degree_poly2[], int terms_poly2, int degree_result[])
{
    int temp=0;
    
    for(int a=0; a<terms_poly1*terms_poly2; a++)
    {//this is first term
        
        //degrees
        for(int b=0; b<=a; b++)
        {//this is 2nd term
            
            if(degree_result[b]==0){
            //checks if location is empty or not
            //dr[0]=0, so go on
            
            temp=degree_poly1[a]+degree_poly2[b];
            
            for(int c=0; c<=b; c++)
            {
                if(temp==degree_result[c]){
                    //checks if there is already a value temp in previous array throughout. yes means stop
                    break;
                    
                }
                
                if(temp!=degree_result[c]){
                    //checks
                    degree_result[b]=temp;
                    
                }
                
                }
                temp=0;
            }
            
        }
        
    }
    
    
    for(int a=0; a<terms_poly1*terms_poly2; a++)
    {
        cout<<degree_result[a]<<" ";
    }
    
}

int main()
{
    
        int degree_poly11[10]={79,78,77,76,75}, terms_poly11=5, degree_poly22[10]={20,18,16,14,12}, terms_poly22=6, degree_resultt[100]={};
    /*
    The whole program saves a polynomial 5x^9 + 7x^3 + 2x^2 as coefficients 5,7,2 in coefficient1[0], coefficient1[1], coefficient1[2] AND the degrees 9,3,2 in degree_poly11[0], degree_poly11[1], degree_poly11[2]. terms_poly11 gives the no. of total terms in the equation i.e. 3. 
    This array is currently not present here but is present in complete program. 
    Similarly for another polynomial2 in coefficient22[] and degree_poly22[].
    */
    
    multiply(degree_poly11, terms_poly11, degree_poly22, terms_poly22, degree_resultt);
    
    return 0;
}
  • did you try your calculations with pen and paper? I am already lost at the first line. Why is there a loop till `terms_poly1*terms_poly2` ? And what is `a` ? Giving good names to variables should be the very first measure against bugs – 463035818_is_not_an_ai Jul 04 '22 at 18:07
  • 3
    With all due respect, the logic in `multiply` makes no sense to me whatsoever. That ain't how you multiply polynomials. – Igor Tandetnik Jul 04 '22 at 18:18
  • @463035818_is_not_a_number Loop till terms_poly1*terms_poly2 because if you have 5 terms in poly 1, and 6 in poly2, the max number of degree possibilities of x should be 5*6, and not more then that in my opinion. That's the amount of degrees we need to save. I want to save all the possible degrees [ x^degree] that are possible with [polynomial1^degree] multiplying with [polynomial2^degree]. – Usamah Irsalan Jul 04 '22 at 18:23
  • @IgorTandetnik I'm not yet on the multiplication part. I am first saving all the relevant degrees [coefficient(x^degree)] that are possible with multiplication of polynomial1[termx]*polynomial2[termy]. Hope you get what I am trying to say. If not, I'll try to rephrase. – Usamah Irsalan Jul 04 '22 at 18:26
  • no if poly1 is of degree m and poly2 is of degree n then the degree of poly1*poly2 is at most m+n. You write it in text "This should mean a max of highest degree of polynomial1+polynomial2" but in the code you use `*` – 463035818_is_not_an_ai Jul 04 '22 at 18:29
  • Hmm... I wonder if meaningful variable names would help here. It does look archaic to use single-letter names with no meaning, such as `a`. What if `degree_poly1[a]` instead looked like `degree_poly1[index1]` so that it is clear what the variable is used for? (Would the range of values for `index1` still make sense?) – JaMiT Jul 04 '22 at 18:30
  • @JaMiT The ideal output should be: "99, 97, 95, 93, 91, 89, 98, 96, 94, 92, 90, 88...." The current output is: "99 96 93 90 87 84 81 78 75 72 688904896 32629 119 114 109 104 97 94 89 84 79 74 1377809792 65258 218 210 202 194 184 178" – Usamah Irsalan Jul 04 '22 at 18:32
  • `int degree_poly11[10]={79,78,77,76,75,74,73,72,71,70}, terms_poly11=5` I'm a bit lost, here. What do the elements of that array represent? Why are there 10 of them and `terms_poly11` is only 5? – Bob__ Jul 04 '22 at 18:36
  • Suggestion: Use sanitizers to help spot logic mistakes. Eg: https://godbolt.org/z/qvY8YxfjK – user4581301 Jul 04 '22 at 18:37
  • @JaMiT I have updated the code with a comment explaining the variable names I have used, and the logic I have in mind. The variables in the for loops are all different counters. – Usamah Irsalan Jul 04 '22 at 18:48
  • @JaMiT Thanks for guiding. I have updated the information in the question now. – Usamah Irsalan Jul 04 '22 at 18:53
  • @Bob__ I have added a comment in the main body explaining the variable names. I had purposefully put in values greater than the max count for checking if it stops at the required amount i.e. 5 terms only. – Usamah Irsalan Jul 04 '22 at 18:55
  • @UsamahIrsalan *Kindly spot the error* -- No, it doesn't work that way. What you should be doing before posting your question is for you to [debug your code](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) and tell us where the problem is or what your debugging session suggests where the problem is. Waiting for a volunteer to debug your code while you wait isn't how StackOverflow works. In no way should you be in a position of having written all of this code, and just not know what to do if something breaks down. – PaulMcKenzie Jul 04 '22 at 18:57
  • 5 * 6 == 30, neither of the two arrays has that many elements but still you use `a` and `b` (which go till 30) as indices into the arrays. Irrespective of any other logic issues, this cannot be correct. You are accessing the arrays out of bounds – 463035818_is_not_an_ai Jul 04 '22 at 18:58
  • @Bob__ I have shortened the values in the array to only 5 and 6 now, for ease of understanding. – Usamah Irsalan Jul 04 '22 at 19:00
  • 4
    suggestion: start small. Try to calculate `(x+1)*(x-1)` result should be `x^2 -1`. – 463035818_is_not_an_ai Jul 04 '22 at 19:00
  • @UsamahIrsalan *"I have updated the code with a comment explaining the variable names I have used"* -- variable names should be chosen so that there is no need for comments explaining them. – JaMiT Jul 04 '22 at 19:04
  • Your second loop loops `b` from `0` to `a` but there aren't `a+1` elements in `degree_poly1` or `degree_poly2`. There aren't even `a+1` elements in `degree_result`. You've botched the logic of how to accomplish what you're doing. The resultant terms is a _cartesian product_ of the terms of each polynomial. i.e.: for each term a in A, for each term b in B --> produce the term a * b. Some will have the same degree, of course. – Wyck Jul 04 '22 at 19:04
  • 1
    @UsamahIrsalan As suggested, it makes no sense to try and write code to multiply a 5 degree polynomial if a single degree polynomial won't work. If it doesn't work with polynomials of 1 degree, it isn't going to work with one that is 5 degrees. Concentrate on getting a 1 degree polynomial to work first. Once you get that working, the code to make 5 degree polynomials to work will need very little adjustment, if any. – PaulMcKenzie Jul 04 '22 at 19:05
  • The *comment* says that for each polynomial you should have an array of degrees, an array of coefficients and a number of terms. The *source code* only has the arrays of "degrees" and the number of terms. Something very important got lost in translation (a [mre] should still make some sense). May I suggest a `std::vector>` to store the terms? – Bob__ Jul 04 '22 at 19:14

1 Answers1

0

One problem in your code is

temp=degree_poly1[a]+degree_poly2[b];

both a and b loop till 30, but both arrays have only 10 elements. You are accessing the arrays out of bounds and your code has undefined behavior. Even if all the rest would be ok, the output of the code could be anything because of this out-of-bounds access.


It is hard to understand the intended logic of your multiply function. Naming variables is a big issue in your code. a, b and c are completely meaningless to the reader of the code. Though already in main names are confusing.

You have

int degree_poly11[10]={79,78,77,76,75}, terms_poly11=5, ...;

I suppose degree_poly11 are the coefficients of the first polynome. Further, I guess that terms_poly11=5 is the degree of the polynome. If thats the case then name them like that.

When you need arrays of variable size you should think: std::vector.

I suggest to take pen and paper and calculate some examples (not one, but some). When you multiply two polynomials, their degrees add up and the coefficients are:

 ( poly1 * poly2)_{i} = sum_{j,k,j+k==i} ( poly1_{j} * poly2_{k} )

ie, the i-th coefficient is a sum of all products of coefficients from the input polynomials, such that their indices add up to i. Frankly, I don't see anything like that in your code.

Just this directly translated to code can look like this:

#include <vector>
#include <iostream>

std::vector<double> mult(const std::vector<double>& a,const std::vector<double>& b) {
    std::vector<double> result(a.size() + b.size() - 1);
    for (int i=0; i< result.size(); ++i) {
        for (int j = 0; j <= i && j < a.size(); ++j) {
            int k = i-j;
            if (k >= b.size()) continue;
            result[i] += a[j] * b[k];
        }
    }
    return result;
}


int main(){
    auto res = mult( {-1,1},{1,1});
    for (int i=0;i<res.size();++i){
        std::cout << res[i] << "*x^" << i << " + ";
    }
}

Output is:

-1*x^0 + 0*x^1 + 1*x^2 + 

Seems to be correct, because (x+1)*(x-1) == (x^2 -1). I didn't test more yet.

(x+1) and (x-1) are of degree 1, thats one less than they have coefficients, and the result has one coefficient more than its degree (a polynomial of degree 0 is a constant, it has 1 coefficient). Hence the size of the output vector a.size() + b.size() - 1.

The outer loop is to calculate i-th coefficient. Loop counters are choosen such that all combinations of j and k that add up to i are passed and included in the sum. Because I know my first attempt is off by one somewhere I have additional checks to be sure that j < a.size() and k < b.size().

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185