// file: $isip/class/algo/FourierTransform/ft_06.cc
// version: $Id: ft_06.cc 7667 2002-01-31 21:41:47Z zheng $
//

// isip include files
//
#include "FourierTransform.h"
 
// method: isPower
//
// arguments:
//  long& exponent: (output) the required exponent
//  long base: (input) base provided by the user  
//  long value: (input) input value to check
//
// return: a boolean value indicating status
//
// this method computes exponent_a = log (base_a) of order_d;
// it returns false if order of the fourier transform requested for is
// not a power of base_a
//
boolean FourierTransform::isPower(long& exponent_a, long base_a,
				  long value_a) {
  
  // define local variables
  //
  long i = 1;
  exponent_a = 0;

  // compute the count of power of base_a
  //
  while (i < value_a) {
    i = (long)(base_a * i);
    exponent_a = (long)(exponent_a + 1);
  }

  // if not power of two return false
  //
  if (i != value_a) {
    return false;
  }
  
  // exit gracefully
  //
  return true;  
}

// method: validateImplementation
//
// arguments: none
//
// return: a boolean value indicating status
//
// this method insures that the input order is a valid value for the given
// implementation
//
boolean FourierTransform::validateImplementation() {

  // if the algorithm is DFT or DCT then all orders are good
  //
  if (algorithm_d != FFT) {
    return true;
  }

  // define the exponent such that 2**m = order_d, else we must be using
  // a DFT
  //
  long m;

  if (!isPower(m, (long)2, order_d)) {
    if (resolution_d == AUTO) {
      order_d.pow(2, m);
    }
    else {
      return false;
    }
  }

  // else: if m is not a power of 4 and the radix 4 implementation has
  // been requested (which requires a power of 4), generate an error
  //
  if ((implementation_d == RADIX_4) && (!isPower(m, (long)4, order_d))) {
    if (resolution_d == AUTO) {
      order_d *= 2;
    }
    else {
      return false;
    }
  }
  
  // else: if the order is less than 16 and the QF implementation has
  // been requested, generate an error
  //
  else if ((implementation_d == QF) && (order_d < (long)16)) {
    if (resolution_d == AUTO) {
      order_d = 16;
    }
    else {
      return false;
    }
  }
  
  // exit gracefully
  //
  return true;
}
