#include <vector>
#include <iostream>
#include <memory>
#include "Division.h"
/*
The 2 vectors must be the same size. Do not put leading zeroes, instead move the vector.
Vectors must be at least 4 long.
[0,1,-4,0]/[0,0,0,1] this is no good
this is better:
[1,-4,0,0]/[0,0,1,0] this will work
This is pre-alpha build 18/12/2021
*/
int main()
{
/*Power z^= 0,-1,-2,-3,-4.....
descending powers to the right
*/
std::vector<double>vect1{ 0,4,0,0}; // numerator
std::vector<double>vect2{ 1,-1.2,0.2,0};// denominator
int temp{}, temp2{};// temp2 is for future functionality
std::cout << "Enter repititions: \n";
std::cin >> temp;
//--------------------should NOT need to change anything below this line
Numerator num1(vect1, temp);
Denom den1(vect2);
num1.print();
std::cout << "/";
den1.print();
std::cout << "=\n";
//-------------------------create pointers
std::shared_ptr<Numerator>ptr1 = std::make_shared<Numerator>((num1 / den1)); // perform the calculation
std::shared_ptr<Denom>ptr2 = std::make_shared<Denom>(den1);
PowerComputation displayPower(ptr1, ptr2, temp2);
//------------------------display result
std::cout << displayPower;
}
#ifndef DIVISION_H
#define DIVISION_H
#include <iostream>
template<typename T>
size_t finder(const std::vector<T>& vect); // find the first non-zero term's index
class Denom
{
public:
Denom(const std::vector<double>& v1) {denominator = v1;}
double& operator[](size_t i);
size_t getSize()const { return denominator.size(); }
double getElement()const ; // extract non-zero element
void print()const;
std::vector<double> getDenominator()const { return denominator; }
private:
std::vector<double>denominator;
};
class Numerator
{
public:
Numerator(const std::vector<double>& v1, int temp)
{
numerator = v1;
repetition = temp;
}
Numerator& operator/(Denom&);// does the heavy lifting
void print()const;
std::vector<double> getNumerator()const { return numerator; }
std::vector<double> getAnswer()const { return answer; }
private:
std::vector<double>numerator;
std::vector<double>answer;
int repetition{};
};
class PowerComputation
{
public:
PowerComputation(std::shared_ptr<Numerator>num, std::shared_ptr<Denom>denom,int maxPower);// take in pointers
friend std::ostream& operator<<(std::ostream& output, const PowerComputation&);
private:
std::shared_ptr<Numerator>num=nullptr;
std::shared_ptr<Denom>denom=nullptr;
int maxPower{};// future functionality will be added for maxPower computation
};
#endif
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include "Division.h"
template<typename T>
size_t finder(const std::vector<T>& vect)
{
for (size_t i{}; i < vect.size(); ++i)
{
if (vect[i])
{
return i; // return the vector index
}
}
return 0; // otherwise return nothing
}
double Denom::getElement()const// extract the first non-zero element from the denom
{
return denominator[finder(denominator)];
}
double& Denom::operator[](size_t i)
{
return denominator[i];
}
Numerator& Numerator::operator/(Denom& denom)
{
if (numerator[0] == 0)
{
answer.push_back(0);// first answer is always zero in this case
answer.push_back(numerator[1] / denom.getElement());
// vector(names array for simplicity) for intermediate steps
std::vector<double>array1{0};
std::vector<double>array2{0};
for (size_t i{}; i < denom.getSize(); ++i)// multiply
{
array1.push_back((numerator[1] / denom.getElement()) * denom[i]);
}
for (size_t i{}; i < denom.getSize(); ++i)// subtract
{
array2.push_back(numerator[i] - array1[i]);
}
for (size_t i{}; i < denom.getSize(); ++i) // store next value
{
if (array2[i])
{
answer.push_back((array2[i] / denom.getElement()) );
break;
}
}
for (size_t rr{}; rr < repetition - 3;++rr)// 3 answers have already been stored
{
for (size_t i{}; i < denom.getSize(); ++i) // create new subtracting factor
{
if (array2[i])
{
for (size_t k{}; k < denom.getSize(); ++k)
{
array1[k] = (array2[i] / denom.getElement()) * denom[k];
}
break;
}
}
size_t counter =finder(array2);
std::rotate(array2.begin(), array2.begin() + counter, array2.end()); // shift the vector for subtraction
for (size_t i{}; i < denom.getSize(); ++i) // subtract for next step
{
array2[i] = array2[i] - array1[i];
}
answer.push_back(array2[1] / denom.getElement());
}
return *this;
}
/* -------------------------------------------------------if the first answer value is not 0----*/
else {
answer.push_back(numerator[0] / denom.getElement());
// vector(named array for simplicity) for intermediate steps
std::vector<double>array1;
std::vector<double>array2;
for (size_t i{}; i < denom.getSize(); ++i)// multiply
{
array1.push_back((numerator[0] / denom.getElement()) * denom[i]);
}
size_t counter = finder(array1);
std::rotate(array1.begin(), array1.begin() + counter, array1.end()); // shift the vector for subtraction
for (size_t i{}; i < denom.getSize(); ++i)// subtract
{
array2.push_back(numerator[i] - array1[i]);
}
for (size_t i{}; i < denom.getSize(); ++i) // store next value
{
if (array2[i])
{
answer.push_back(array2[i] /denom.getElement() );
break;
}
}
for (size_t rr{}; rr < (repetition - 2); ++rr) // two values have already been stored
{
for (size_t i{}; i < denom.getSize(); ++i) // create new subtracting factor
{
if (array2[i])
{
for (size_t k{}; k < denom.getSize(); ++k)
{
array1[k] = (array2[i] / denom.getElement()) * denom[k];
}
break;
}
}
counter = finder(array2);// re-use counter
std::rotate(array2.begin(), array2.begin() + counter, array2.end()); // shift the vector for subtraction
if (finder(array1) > 0)// align the vectors for subtraction
{
std::rotate(array1.begin(), array1.begin() + finder(array1), array1.end()); // shift the vector for subtraction
}
for (size_t i{}; i < denom.getSize(); ++i) // subtract for next step
{
array2[i] = array2[i] - array1[i];
}
if (!(array2[1] / denom.getElement()) )
{
answer.push_back(array2[1] / denom.getElement() );
std::cout << "This is fully divisable.\n";
return *this;
break;// terminate if in rare cases answer is zero
}
answer.push_back(array2[1] / denom.getElement());
}
return *this;
}
}
void Numerator::print()const
{
std::cout << "[ ";
for (int i{}; i < numerator.size(); ++i)
{
std::cout << numerator[i] << "z^" << (-1 * i) << " ";
}
std::cout << " ]";
}
void Denom::print()const
{
std::cout << "[ ";
for (int i{};i<denominator.size();++i)
{
std::cout << denominator[i] << "z^"<< (-1 * i) <<" ";
}
std::cout << " ]";
}
PowerComputation::PowerComputation(std::shared_ptr<Numerator>num, std::shared_ptr<Denom>denom,int maxPower)
{
this->num = num;
this->denom = denom;
this->maxPower = maxPower;
}
std::ostream& operator<<(std::ostream& output, const PowerComputation& pow)
{
int minus{};// arbitrary integer for power
if ( finder(pow.num->getNumerator()) )//check if the numerator has a leading zero term
{
output << "[";
for (int i{};i< pow.num->getAnswer().size(); ++i)
{
if ( (pow.num->getAnswer())[i] )
{
output << pow.num->getAnswer()[i] << "z^"
<< -1 * static_cast<int>(finder(pow.num->getNumerator())) - minus << " ";
++minus;
}
else
{
output << pow.num->getAnswer()[i] << " ";
}
}
output << "]\n";
return output;
}
if (finder(pow.denom->getDenominator()))//check if the denominator has a leading zero term
{
output << "[";
for (int i{};i< pow.num->getAnswer().size(); ++i)
{
if ((pow.num->getAnswer())[i])
{
output << pow.num->getAnswer()[i] << "z^"
<< static_cast<int>(finder(pow.denom->getDenominator())) - minus << " ";
++minus;
}
else
{
output << pow.num->getAnswer()[i] << " ";
}
}
output << "]\n";
return output;
}
else// no leading zero terms
{
output << "[";
for (int i{}; i < pow.num->getAnswer().size(); ++i)
{
output << pow.num->getAnswer()[i] << "z^"
<< static_cast<int>(finder(pow.num->getNumerator())) - minus << " ";
++minus;
}
output << "]\n";
return output;
}
}