/***************************************************************************** * * * 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. * * * *****************************************************************************/ /* TODO: * Instead of storing C*Lambda, store Lambda and do just one multiplication by C when calculating delta values. * Store ny2=ny*ny */ #include "trace-n.h" #include "foxstuff.h" TraceN::TraceN (int _ny, cftype *_A, cftype *_C, int _n, GetAtoi *_atoi) { valid = 0; lambda = NULL; ny = _ny; checkthat (ny <= MAX_NY,"ny > %d in TraceN ctor",MAX_NY); A = _A; C = _C; n = _n; atoi = _atoi; checkmemptr (lambda = new cftype [n * ny]); for (int i=0; i < (n*ny); i++) lambda[i] = 0.0; Reset(); valid = 1; } TraceN::~TraceN() { delete[] lambda; } void TraceN::Reset() { T = -1; // so next time is 0 p = -1; // so next buffer position is 0 T0 = 0; for (int i=0; i < ny; i++) Lambda[i] = 0.0; for (int i=0; i < ny; i++) CAtop[i] = C[i]; // Get C*A^p = C } void TraceN::Next (cftype e) { T++; p++; if (p >= n) p = 0; if (p==0) { T0 = T; for (int i=0; i T || t < 0),"Bad t in TraceN::GetDelta (1)"); i = t-T0; // i = buffer position for this time if (i < 0) { i += n; myassert (i > p,"Bad t in TraceN::GetDelta (2)"); } // now i is in the range 0..n-1 myassert (i != p+1,"Bad t in TraceN::GetDelta (3)"); if (i <= p) { if (i > 0) { // get result = (lambda[p] - lambda[i-1]) * A^(-i) cftype tmp[MAX_NY]; for (int j=0; jPostMulByAtoMinus (result,tmp,i); return result; } else { // get result = lambda[p] * A^(-i) atoi->PostMulByAtoMinus (result,lambda + p*ny,i); return result; } } else { // get result = (lambda[n-1]-lambda[i-1])*A^(-i) + lambda[p]*A^(T0-t) cftype tmp[MAX_NY]; for (int j=0; jPostMulByAtoMinus (result,tmp,i); atoi->PostMulByAtoPlus (tmp,lambda + p*ny,T0-t); for (int j=0; j #include cftype frandom() { return cftype(random())/cftype(RAND_MAX); } // Data for a 4x4 matrix with these eigenvalues: -0.2,-0.4,-0.6,-0.8 static cftype Adata[16] = { -0.32146477377367, 0.01342048538994, -0.32683564574661, -0.25927359552655, -0.47937936441504, -0.59080345828772, 0.75112028936896, 0.01403422329742, 0.13624192938211, 0.09771365160561, -0.68725222645531, -0.30401969355492, 0.04009943559339, -0.01845933875761, -0.15025144173708, -0.40047954148329}; static cftype Cdata[4] = { 0.72864159177390, 0.31798791565074, 0.84764863450093, 0.14789135101475}; int main() { int ny = 4; int n = 200; cftype e,estore[n]; // calculate and store C*A^i for i=1..19 cftype CAi[20][4]; cftype tmp[4]; for (int i=0; i<4; i++) tmp[i] = CAi[0][i] = Cdata[i]; for (int i=1; i<20; i++) { // get CAi[i] = tmp * Adata for (int j=0; j<4; j++) { cftype sum = 0.0; for (int k=0; k<4; k++) sum += tmp[k] * Adata[k*4 + j]; CAi[i][j] = sum; } for (int j=0; j<4; j++) tmp[j] = CAi[i][j]; } // print out those matrices // for (int i=0; i<20; i++) { // for (int j=0; j<4; j++) printf ("%8.4f ",CAi[i][j]); // printf ("\n"); // } GetAtoi atoi (4, Adata, 20); TraceN trace (4, Adata, Cdata, 20, &atoi); srandom(time(NULL)); e = 0; for (int T=0; T= 18) tstart = T-18; for (int t=tstart; t<=T; t++) { // calc delta_t the hard way cftype delta1[4]; for (int i=0; i<4; i++) delta1[i] = 0.0; for (int i=t; i<=T; i++) { for (int j=0; j<4; j++) delta1[j] += estore[i] * CAi[i-t][j]; } // printf ("T=%3d t=%3d delta1 = %.8f %.8f %.8f %.8f\n",T,t, // delta1[0], delta1[1], delta1[2], delta1[3]); // calc delta_t the easy way cftype *delta2 = trace.GetDelta (t); printf ("T=%3d t=%3d delta1-delta2=%12.8f %12.8f %12.8f %12.8f\n",T,t, delta1[0]-delta2[0], delta1[1]-delta2[1], delta1[2]-delta2[2], delta1[3]-delta2[3]); } } return 0; } */