/*****************************************************************************
 *                                                                           *
 * FOX Controller Library, Version 1.3.3.                                    *
 *                                                                           *
 * Copyright (C) 1998,1999,2000 Russell Smith (rl.smith@auckland.ac.nz)      *
 *                                                                           *
 * The FOX Controller Library is free software; you can redistribute it      *
 * and/or modify it under the terms of the GNU Library General Public        *
 * License as published by the Free Software Foundation; either version      *
 * 2 of the License, or (at your option) any later version.                  *
 *                                                                           *
 * The FOX Controller Library is distributed in the hope that it will be     *
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of    *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
 * Library General Public License for more details.                          *
 *                                                                           *
 * You should have received a copy of the GNU Library General Public         *
 * License along with the Fox Controller Library; see the file COPYING.LIB.  *
 * If not, write to the Free Software Foundation, Inc., 59 Temple Place -    *
 * Suite 330, Boston, MA 02111-1307, USA.                                    *
 *                                                                           *
 *****************************************************************************/

/*

Given an ny*ny matrix A, lets you quickly find A^i and A^(-i), for values of
i from 0..n-1.

*/

#ifndef __ATOI_H
#define __ATOI_H

#include "foxstuff.h"
#include "cftype-n.h"


class GetAtoi {
  int valid;		// set to 1 if constructor successfull
  int ny,ny2,n;		// ny2=ny^2
  cftype *Atoi;		// A^(i)  for i=0..(n-1)  (size = ny*ny * n)
  cftype *invAtoi;	// A^(-i) for i=0..(n-1)  (size = ny*ny * n)

public:
  GetAtoi (int _ny, cftype *A, int _n);
    // Initialize for a given ny, matrix A and buffer size n.
    // If initialization is unsuccessful in user mode a fatal error occurrs.
    // If initialization is unsuccessful in kernel mode then the constructor
    // returns and Valid() returns 0. The object can be safely destructed.
  ~GetAtoi();

  int Valid() { return valid; }

  // Get result = q * A^(+/-i)  , result and q are 1*ny vectors.
  void PostMulByAtoPlus  (cftype *result, cftype *q, int i)
    { myassert (i >= 0 && i < n,"bad i in PostMulByAtoPlus()");
      MatrixMultiply1 (ny,result,q,Atoi + (ny2 * i)); }
  void PostMulByAtoMinus (cftype *result, cftype *q, int i)
    { myassert (i >= 0 && i < n,"bad i in PostMulByAtoMinus()");
      MatrixMultiply1 (ny,result,q,invAtoi + (ny2 * i)); }

  // Get result = A^(+/-i) * q  , result and q are ny*1 vectors.
  void PreMulByAtoPlus  (cftype *result, cftype *q, int i)
    { myassert (i >= 0 && i < n,"bad i in PreMulByAtoPlus");
      MatrixMultiply2 (ny,result,Atoi + (ny2 * i),q); }
  void PreMulByAtoMinus (cftype *result, cftype *q, int i)
    { myassert (i >= 0 && i < n,"bad i in PreMulByAtoMinus");
      MatrixMultiply2 (ny,result,invAtoi + (ny2 * i),q); }
};


#endif
