//
// LiDIA - a library for computational number theory
//   Copyright (c) 1994, 1995, 1996 by the LiDIA Group
//
// File        : cast_appl.cc
// Author      : Thomas Papanikolaou (TP)

/*
$Id: test_roots.c,v 1.2 1997/01/24 09:47:00 neis Exp $
*/

#include <LiDIA/timer.h>

#include <LiDIA/polynomial.h>

void
shell(bigcomplex * v, int n)
{
  int gap, i, j, c;
  bigcomplex temp;

  for (gap = n / 2; gap > 0; gap /= 2)
    for (i = gap; i < n; i++){
      c = (abs(v[i - gap]) > abs(v[i]));
      for (j = i - gap; j >= 0 && c; j -= gap){
	c = (abs(v[j]) > abs(v[j + gap]));
	temp = v[j];
	v[j] = v[j + gap];
	v[j + gap] = temp;
      }
    }
}

main()
{

  long t;
  polynomial <bigcomplex> Q;
  bigcomplex x, *rt;
  timer T;
  int i = 0;
  char ch = 'y';

  while (ch == 'y'){
    cout << "\f\n\n";
    cout << " A root finding algorithm over C\n";
    cout << " -------------------------------\n\n";
    cout << " Solve for x in C          \n\n";
    cout << "             n               \n";
    cout << "           _____             \n";
    cout << "           \\                \n";
    cout << "            \\        i      \n";
    cout << " f(x)   =    )   a  x   =  0 \n";
    cout << "            /     i          \n";
    cout << "           /____             \n";
    cout << "           i = 0             \n";
    cout << "                             \n";
    cout << " Enter the working precision := "<<flush;
    cin >> i;
    bigfloat::precision(i);
    cout << "\n";
    cout << " Enter a polynomial\n\n";
    cout << " f(x) := "<<flush;
    cin >> Q;
    rt = new bigcomplex[Q.degree()];
    cout << "\n The roots of f(x) := " << Q;
    cout << "\n (in a random order) are :"<<endl;
    T.start_timer();
    roots(Q, rt);
    T.stop_timer();
    cout << T;
    shell(rt, Q.degree());
    for (i = 0; i < Q.degree(); i++){
      cout << "\n %" << i + 1 << ": " << rt[i] << endl;
      cout << " eval f(%" << i + 1 << ") : " << Q(rt[i]) << endl;
    }

    delete[] rt;
    cout << "\n\n One more time (y/n) ? : "<<endl;
    cin >> ch;
  }
}
