<file_sep>// to compile
// g++ test_CQCGL1dRpo_arpack.cc -std=c++11 -O3  -march=corei7 -msse4 -msse2 -I$EIGEN -I$RESH/include -I$XDAPPS/arpackpp/include -L$RESH/lib -lCQCGL1dRpo_arpack -lCQCGL1dRpo -lCQCGL1d -lmyfft -lfftw3 -lm -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -llapack -larpack -lsuperlu -lopenblas 

#include <iostream>
#include <arsnsym.h>
#include <Eigen/Dense>
#include "CQCGL1dRpo_arpack.hpp"

using namespace std;
using namespace Eigen;
using namespace denseRoutines;

#define cee(x) (cout << (x) << endl << endl)

#define CASE_10


int main(int argc, char **argv){

#ifdef CASE_10
    //======================================================================
    // to visulize the limit cycle first 
    const int N = 1024;
    const double L = 50;
    double Bi = 1.4;
    double Gi = -3.9;
    
    CQCGL1dRpo_arpack cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoHopfBiGi.h5";
    cgl.calEVParaSeq(file, std::vector<double>{Bi}, std::vector<double>{Gi}, 10, true);


#endif
#ifdef CASE_20
    //======================================================================
    // test vc2vr and vr2vc
    MatrixXd A(10, 10); 
    A.setRandom();
    VectorXcd e;
    MatrixXcd v;
    std::tie(e, v) = evEig(A, 2);

    cee(e);
    cee(v);
    
    MatrixXd vr = vc2vr(v);
    cee(vr);

    MatrixXcd vc = vr2vc(e, vr);
    cee(vc);

#endif

    return 0;
}
<file_sep>#!/bin/bash

# usage:
# ./createAll 0 => compile all cases
# ./createAll 1 => single thread caes

DEST=/usr/local/home/xiong/00git/research/lib/boostPython/ 

# compile single thread library
if [ $1 -eq 0 ] || [ $1 -eq 1 ]; then
    mv Jamroot jam.tmp && cp jam.tmp Jamroot
    perl -p -i -e 's/choice = \d/choice = 1/' Jamroot
    perl -p -i -e 's/py_CQCGL2d.cc/pytmp.cc/' Jamroot
    perl -p -e 's/MODULE\(py_CQCGL2d\S*\)/MODULE\(py_CQCGL2d\)/' py_CQCGL2d.cc > pytmp.cc
    rm -rf bin pylib
    b2 && mv pylib/py_CQCGL2d*.so $DEST && mv jam.tmp Jamroot && rm pytmp.cc && rm -rf bin pylib
    echo
    echo "compile single thread library"
fi

# compile multi fftw threads library
if [ $1 -eq 0 ] || [ $1 -eq 2 ]; then
    mv Jamroot jam.tmp && cp jam.tmp Jamroot
    perl -p -i -e 's/choice = \d/choice = 2/' Jamroot
    perl -p -i -e 's/py_CQCGL2d.cc/pytmp.cc/' Jamroot
    perl -p -e 's/MODULE\(py_CQCGL2d\S*\)/MODULE\(py_CQCGL2d_threads\)/' py_CQCGL2d.cc > pytmp.cc
    rm -rf bin pylib
    b2 && mv pylib/py_CQCGL2d*.so $DEST && mv jam.tmp Jamroot && rm pytmp.cc && rm -rf bin pylib
    echo 
    echo "compile multi fftw threads library"
fi

############################################################
# for req lib

# compile single thread library
if [ $1 -eq 0 ] || [ $1 -eq 3 ]; then
    mv Jamroot jam.tmp && cp jam.tmp Jamroot
    perl -p -i -e 's/choice = \d/choice = 3/' Jamroot
    perl -p -i -e 's/py_CQCGL2dReq.cc/pytmp.cc/' Jamroot
    perl -p -e 's/MODULE\(py_CQCGL2dReq\S*\)/MODULE\(py_CQCGL2dReq\)/' py_CQCGL2dReq.cc > pytmp.cc
    rm -rf bin pylib
    b2 && mv pylib/py_CQCGL2dReq*.so $DEST && mv jam.tmp Jamroot && rm pytmp.cc && rm -rf bin pylib
    echo
    echo "compile single thread library"
fi

# compile multi fftw threads library
if [ $1 -eq 0 ] || [ $1 -eq 4 ]; then
    mv Jamroot jam.tmp && cp jam.tmp Jamroot
    perl -p -i -e 's/choice = \d/choice = 4/' Jamroot
    perl -p -i -e 's/py_CQCGL2dReq.cc/pytmp.cc/' Jamroot
    perl -p -e 's/MODULE\(py_CQCGL2dReq\S*\)/MODULE\(py_CQCGL2dReq_threads\)/' py_CQCGL2dReq.cc > pytmp.cc
    rm -rf bin pylib
    b2 && mv pylib/py_CQCGL2dReq*.so $DEST && mv jam.tmp Jamroot && rm pytmp.cc && rm -rf bin pylib
    echo 
    echo "compile multi fftw threads library"
fi
<file_sep>/** \mainpage some frequently used spase matrix related routines 
 *
 *  \section sec_intro Introduction
 *  \section sec_use usage
 *  Example:
 *  \code
 *  g++ yourfile.cc /path/to/sparseRoutines.cc -I/path/to/sparseRoutines.hpp -I/path/to/eigen -std=c++0x
 *  \endcode
 */

#ifndef SPARSEROUTINES_H
#define SPARSEROUTINES_H

#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>
#include <iostream>

namespace sparseRoutines {

    struct KeepDiag{
	inline bool operator() (const int& row, const int& col,
				const double&) const{
	    return row == col;
	}
    };
    
    std::vector<Eigen::Triplet<double> >
    triMat(const Eigen::MatrixXd &A, const size_t M = 0 , 
	   const size_t N = 0);
    
    std::vector<Eigen::Triplet<double> >
    triDiag(const size_t n, const double x,
	    const size_t M = 0, const size_t N = 0 );

    std::vector<Eigen::Triplet<double> >
    triDiag(const Eigen::VectorXd &D, const size_t M, const size_t N);
    
}

#endif	// SPARSEROUTINES_H

<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3 -march=corei7 -msse4.2' MEXcqcgl1d.cpp cqcgl1d.cc
 * -I../../include -I/usr/include/eigen3 -lm -lfftw3
 * */
#include "cqcgl1d.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>
using Eigen::ArrayXXd; using Eigen::ArrayXXcd;
using Eigen::ArrayXd; using Eigen::ArrayXcd;
using Eigen::Map;

static ArrayXXd intg(double *a0, int N, double d,  double h, int nstp, int np,
		     double Mu, double Br, double Bi, double Dr, double Di, 
		     double Gr, double Gi){
  Cqcgl1d cgl(N, d, h, Mu, Br, Bi, Dr, Di, Gr, Gi);
  Map<ArrayXd> v0(a0, 2*N);
  ArrayXXd aa = cgl.intg(v0, nstp, np);
  return aa;
}

static Cqcgl1d::CGLaj intgj(double *a0, int N, double d, double h, int nstp,
			    int np, int nqr, double Mu, double Br, double Bi,
			    double Dr, double Di, double Gr, double Gi){
  Cqcgl1d cgl(N, d, h, Mu, Br, Bi, Dr, Di, Gr, Gi);
  Map<ArrayXd> v0(a0, 2*N);
  Cqcgl1d::CGLaj aj = cgl.intgj(v0, nstp, np, nqr);
  
  return aj;
}

void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
  double *a0 = mxGetPr(prhs[0]);
  int N = mxGetScalar(prhs[1]);
  double d = mxGetScalar(prhs[2]);
  double h = mxGetScalar(prhs[3]);
  int nstp = mxGetScalar(prhs[4]);
  int np = mxGetScalar(prhs[5]);
  int nqr = mxGetScalar(prhs[6]);
  double Mu = mxGetScalar(prhs[7]);
  double Br = mxGetScalar(prhs[8]);
  double Bi = mxGetScalar(prhs[9]);
  double Dr = mxGetScalar(prhs[10]);
  double Di = mxGetScalar(prhs[11]);
  double Gr = mxGetScalar(prhs[12]);
  double Gi = mxGetScalar(prhs[13]);
  mwSize isJ = mxGetScalar(prhs[14]);

  
  if( 0 == isJ){
    plhs[0] = mxCreateDoubleMatrix(2*N, nstp/np+1, mxREAL);
    ArrayXXd aa = intg(a0, N, d, h, nstp, np, Mu, Br, Bi, Dr, Di, Gr, Gi);
    memcpy(mxGetPr(plhs[0]), &aa(0,0), (nstp/np+1)*(2*N)*sizeof(double));
  } else {
    plhs[0] = mxCreateDoubleMatrix(2*N, nstp/np+1, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(2*N*2*N, nstp/nqr, mxREAL);
    Cqcgl1d::CGLaj aj = intgj(a0, N, d, h, nstp, np, nqr, Mu, Br, Bi, Dr, Di, Gr, Gi);
    memcpy(mxGetPr(plhs[0]), &(aj.aa(0,0)), (nstp/np+1)*(2*N)*sizeof(double));
    memcpy(mxGetPr(plhs[1]), &(aj.daa(0,0)), (nstp/nqr)*(2*N)*(2*N)*sizeof(double));
  }
}
<file_sep>/* How to compile this program:
 * h5c++ ksDimension.cc ./ksint/ksint.cc ./ped/ped.cc ./readks/readks.cc
 * -std=c++0x -I$XDAPPS/eigen/include/eigen3 -I../include/ -lfftw3 -O3 -march=corei7
 * -msse4 -msse2
 *
 * or (Note : libreadks.a is static library, so the following order is important)
 *
 * h5c++ ksDimension.cc -std=c++0x -I$XDAPPS/eigen/include/eigen3 -I../include -L../lib -lreadks -lksint -lped  -lfftw3 -O3 -march=corei7 -msse4 -msse2
 */
#include "ksint.hpp"
#include "ped.hpp"
#include "readks.hpp"
#include <Eigen/Dense>
#include <tuple>
#include <string>
#include <iostream>
#include <fstream>
#include <cmath>
#include <ctime>
#include <vector>

using namespace std;
using namespace Eigen;

/** @brief  calculate the actual subspace bound and the indicator whether the actual
 *          bound is the same as specified.
 *
 * @param[in] subspDim subspace bounds. Each column is a 4-vector storing dimension of
 *                     two subspaces.
 * @param[in] ixSp subspace index, i.e the left and right bounds
 * @see indexSubspace
 * @return a pair of integer matrix. The first one is actual subspace bound.
 *         The second one indicate whether the bounds are the same as specified.
 */
std::pair<MatrixXi, MatrixXi> 
subspBound(const MatrixXi subspDim, const MatrixXi ixSp){
  assert(subspDim.rows() == 4); // two subspaces have 4 indices.
  const int M = subspDim.cols();
  MatrixXi boundStrict(MatrixXi::Zero(4,M));
  MatrixXi bound(4, M);
  
  for(size_t i = 0; i < M; i++){
    int L1 = ixSp(subspDim(0,i), 0); bound(0,i) = L1;
    int R1 = ixSp(subspDim(1,i), 1); bound(1,i) = R1;
    int L2 = ixSp(subspDim(2,i), 0); bound(2,i) = L2;
    int R2 = ixSp(subspDim(3,i), 1); bound(3,i) = R2;
    if(L1 == subspDim(0,i)) boundStrict(0,i) = 1;
    if(R1 == subspDim(1,i)) boundStrict(1,i) = 1;
    if(L2 == subspDim(2,i)) boundStrict(2,i) = 1;
    if(R2 == subspDim(3,i)) boundStrict(3,i) = 1;
  }
  
  return std::make_pair(bound, boundStrict);
  
}


/** @brief calculate the cos() of the largest angle
 *         between the two subspaces spanned by the
 *         columns of matrices A and B.
 */
double angleSubspace(const Ref<const MatrixXd> &A,
		     const Ref<const MatrixXd> &B){
  assert(A.rows() == B.rows());
  const int N = A.rows();
  const int M1 = A.cols();
  const int M2 = B.cols();
  MatrixXd thinQa(MatrixXd::Identity(N,M1));
  MatrixXd thinQb(MatrixXd::Identity(N,M2));
  
  ColPivHouseholderQR<MatrixXd> qra(A);
  thinQa = qra.householderQ() * thinQa;

  ColPivHouseholderQR<MatrixXd> qrb(B);
  thinQb = qrb.householderQ() * thinQb;
  
  JacobiSVD<MatrixXd> svd(thinQa.transpose() * thinQb);
  VectorXd sv = svd.singularValues();
  
  return sv.maxCoeff();
}

double angleSpaceVector(const Ref<const MatrixXd> &Q,
			const Ref<const VectorXd> &V){
  assert( Q.rows() == V.rows());
  VectorXd P = Q.transpose() * V;
  double cos2 = P.squaredNorm() / V.squaredNorm(); /* cos^2 */

  return sqrt(1-cos2);
}


/** @brief calculate angle between two subspaces along an upo
 *
 *  @param[in] fileName file that stores the ppo/rpo information
 *  @param[in] ppType ppo or rpo
 *  @param[in] ppId id of the periodic orbit
 *  @param[in] subspDim 4xM2  matrix storing the bounds of subspaces
 *  @return first matrix : each row stores the angles at one point
 *          second matrix: matrix indicating whether bounds are the
 *          same as specified
 *  @see subspBound
 */
std::pair<MatrixXd, MatrixXi> 
anglePO(ReadKS &readks, const string ppType,
	const int ppId, const MatrixXi subspDim){
  assert(subspDim.rows() == 4);
  MatrixXd eigVals = readks.readKSe(ppType, ppId); // Floquet exponents
  MatrixXd eigVecs = readks.readKSve(ppType, ppId);// Floquet vectors
  // left and right bounds
  MatrixXi ixSp = readks.indexSubspace(eigVals.col(2), eigVals.col(0)); 
  
  const int N = sqrt(eigVecs.rows());
  const int M = eigVecs.cols();
  const int M2 = subspDim.cols();
  MatrixXd ang_po(M, M2);
  
  // calculate the exact bound of this indices.
  std::pair<MatrixXi, MatrixXi> tmp = subspBound(subspDim, ixSp);
  MatrixXi &bound = tmp.first;
  MatrixXi &boundStrict = tmp.second;

  for(size_t i = 0; i < M; i++){
    MatrixXd ve = eigVecs.col(i);
    ve.resize(N, N);
    for(size_t j = 0; j < M2; j++){      
      double ang = angleSubspace(ve.middleCols(bound(0, j), bound(1,j)-bound(0,j)+1), 
				 ve.middleCols(bound(2, j), bound(3,j)-bound(2,j)+1) );
      ang_po(i, j) = ang;
    }
  }
  
  return std::make_pair(ang_po, boundStrict);
}

/** @brief normalize each row of a matrix  */
void normc(MatrixXd &A){
  int m = A.cols();
  for(size_t i = 0; i < m; i++) 
    A.col(i).array() = A.col(i).array() / A.col(i).norm();
}

/** @brief calculate the minimal distance between an ergodic
 *         trajectory and one ppo/rpo.
 * @note the cols of ppo/rpo should be the same as its corresponding
 *       Flqouet vectors, otherwise, there maybe index flow when calling
 *       difAngle(). For example, you can do it in the following way:
 *       \code
 *        minDistance(ergodicHat, aaHat.leftCols(aaHat.cols()-1), tolClose)
 *       \endcode
 */
std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd>
minDistance(const MatrixXd &ergodic, const MatrixXd &aa, const double tolClose){
  const int n = ergodic.rows();
  const int m = ergodic.cols();
  const int n2 = aa.rows();
  const int m2 = aa.cols();
  assert(n2 == n);
  
  VectorXi minIndexPo(m);
  VectorXi minIndexErgodic(m);
  VectorXd minDis(m);
  MatrixXd minDifv(n, m);

  size_t tracker = 0;
  for(size_t i = 0; i < m; i++){
    MatrixXd dif = aa.colwise() - ergodic.col(i);// relation is inversed.
    VectorXd colNorm(m2);
    for(size_t j = 0; j < m2; j++) colNorm(j) = dif.col(j).norm();
    int r, c;
    double closest = colNorm.minCoeff(&r, &c); 
    if(closest < tolClose){
      minIndexPo(tracker) = r;
      minIndexErgodic(tracker) = i;
      minDis(tracker) = closest;
      minDifv.col(tracker++) = -dif.col(r);
    }
  }
  return std::make_tuple(minDifv.leftCols(tracker), minIndexErgodic.head(tracker),
			 minIndexPo.head(tracker), minDis.head(tracker));
}

std::pair<std::vector<int>, std::vector<int> >
consecutiveWindow(const VectorXi &index, const int window){
  const int n = index.size();
  std::vector<int> start, dur;

  int pos = 0;
  while (pos < n-1) {
    int span = 0;
    for (size_t i = pos; i < n-1; i++) { // note i < n-1
      if(index(i) == index(i+1)-1) span++;
      else break;
    }
    if(span >= window){
      start.push_back(pos);
      dur.push_back(span);
    }
    if(span > 0) pos += span;
    else pos++;
  }
  return make_pair(start, dur);
}

vector<int>
interp(KS &ks, const Ref<const MatrixXd> &ergodic, const MatrixXd &aa,
       const VectorXi &indx, double threashold){
  const int n = ergodic.rows();
  const int m = ergodic.cols();
  const int n2 = aa.rows();
  const int m2 = aa.cols();
  assert(n2 == n);
  
  vector<int> filter;
  for (int i = 0; i < m; i++) {
    VectorXd x = aa.col(indx(i));
    VectorXd velo = ks.veToSlice( ks.velocity(x), x ); 
    VectorXd difv = ergodic.col(i) - x;
    double u = difv.dot(velo);
    if (fabs(u) / (velo.norm() * difv.norm()) < threashold ){
      filter.push_back(i);
    }
  }
  
  return filter;
  
}

std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd>
minDistance(const MatrixXd &ergodic, const MatrixXd &aa, const double tolClose, const int window){

  std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd> min_distance = minDistance(ergodic, aa, tolClose); 
  MatrixXd &minDifv = std::get<0>(min_distance); 
  VectorXi &minIndexErgodic = std::get<1>(min_distance);  
  VectorXi &minIndexPo = std::get<2>(min_distance);
  VectorXd &minDis = std::get<3>(min_distance);

  std::pair<std::vector<int>, std::vector<int> > consecutive =
    consecutiveWindow(minIndexErgodic, window);   
  std::vector<int> &start = consecutive.first;
  std::vector<int> &dur = consecutive.second;
  int sum = 0;
  for (std::vector<int>::iterator i = dur.begin(); i != dur.end(); i++) {
    sum += *i;
  }

  MatrixXd minDifv2(minDifv.rows(), sum);
  VectorXi minIndexErgodic2(sum);
  VectorXi minIndexPo2(sum);
  VectorXd minDis2(sum);
  
  size_t pos = 0;
  for(size_t i = 0; i < dur.size(); i++){ 
    minDifv2.middleCols(pos, dur[i]) = minDifv.middleCols(start[i], dur[i]);
    minIndexErgodic2.segment(pos, dur[i]) = minIndexErgodic.segment(start[i], dur[i]);
    minIndexPo2.segment(pos, dur[i]) = minIndexPo.segment(start[i], dur[i]);
    minDis2.segment(pos, dur[i]) = minDis.segment(start[i], dur[i]);

    pos += dur[i];
  }

  return std::make_tuple(minDifv2, minIndexErgodic2, minIndexPo2, minDis2);
}


/** @brief
 * ve has dimension [N, M*trunc]
 */
MatrixXd veTrunc(const MatrixXd ve, const int pos, const int trunc = 0){
  int Trunc = trunc;
  if(trunc == 0) Trunc = ve.rows();

  const int N = ve.rows();
  const int M = ve.cols() / Trunc;
  assert(ve.cols()%M == 0);
  
  MatrixXd newVe(N, (Trunc-1)*M);
  for(size_t i = 0; i < M; i++){
    newVe.middleCols(i*(Trunc-1), pos) = ve.middleCols(i*Trunc, pos);
    newVe.middleCols(i*(Trunc-1)+pos, Trunc-1-pos) = 
      ve.middleCols(i*Trunc+pos+1, Trunc-1-pos);
  }
  return newVe;
}

/** @brief calculate the angle between difference vectors and the subspaces spanned
 *  by Flqouet vectors.
 *
 *  @param[in] subsp number of Floquet vectors to span subspace
 *
 *  @note subsp does not stores the indices of the subspace cut. 
 */
MatrixXd difAngle(const MatrixXd &minDifv, const VectorXi &minIx, const VectorXi &subsp, 
		  const MatrixXd &ve_trunc, const int truncN){
  assert(minDifv.cols() == minIx.size());
  const int N = minDifv.rows();
  const int M = minDifv.cols();
  const int M2 = subsp.size();
  
  MatrixXd angle(M2, M);
  for(size_t i = 0; i < M; i++){
    int ix = minIx(i);
    for(size_t j = 0; j < M2; j++)
      // calculate the angle between the different vector and Floquet subspace.
      angle(j, i) = angleSubspace(ve_trunc.middleCols(truncN*ix, subsp(j)),
      				  minDifv.col(i));
    // angle(j, i) = angleSpaceVector(ve_trunc.middleCols(truncN*ix, subsp(j)),
    // minDifv.col(i));
  }
  return angle;
}



int main(){
  cout.precision(16);
  const int Nks = 64;
  const int N = Nks - 2;
  const int N64 = 64;
  const int N62 = 62;
  const double L = 22;

  switch (4)
    {
    case 1: // small test for angle calculation.
      {
	MatrixXi subspDim(4,3); 
	subspDim << 
	  3, 0, 0,
	  3, 7, 8,
	  4, 8, 9,
	  4, 29, 29; // (0-6,7-29), (0-7,8-29), (0-8,9-29)
	cout << subspDim << endl;
	string fileName("../data/ks22h02t100");
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	string ppType("rpo");	
	int ppId = 1;
	std::pair<MatrixXd, MatrixXi> ang = 
	  anglePO(readks, ppType, ppId, subspDim);
	
	cout << ang.second << endl;
	
	ofstream file;
	file.precision(16);
	file.open("good.txt", ios::trunc);
	file << ang.first << endl;
	file.close();

	break;
      }


    case 2: // calculate the angle, output to files.
	    // This the MAIN experiments I am doing.
      {
	/////////////////////////////////////////////////////////////////
	string fileName("../data/ks22h02t120");
	string ppType("rpo");
	string spType("vector");
	string folder("./case4/");
	/////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////
	// all kinds of IF statements
	int NN;
	if(fileName.compare("../data/ks22h02t120") ==0 ){	  
	  if(ppType.compare("ppo") == 0) NN = 840; // number of ppo
	  else NN = 834; // number of rpo
	}
	else if(fileName.compare("../data/ks22h02t100") ==0 ) {
	  if(ppType.compare("ppo") == 0) NN = 240; // number of ppo
	  else NN = 239; // number of rpo
	}
	else{ 
	  printf("invalid file name !\n");
	}

       	MatrixXi subspDim(4,29);
	if(spType.compare("vector") == 0)
	  for (size_t i = 0; i < 29; i++) subspDim.col(i) << i, i, i+1, i+1;
	else if(spType.compare("space") == 0)
	  for (size_t i = 0; i < 29; i++) subspDim.col(i) << 0, i, i+1, 29;
	else {
	  printf("invalid spType.\n");
	}
	const int M = subspDim.cols();
	ofstream file[M];
	string angName("ang");
	for(size_t i = 0; i < M; i++){
	  file[i].open(folder + angName + to_string(i) + ".txt", ios::trunc);
	  file[i].precision(16);
	}
	/////////////////////////////////////////////////////////////////
	
	/////////////////////////////////////////////////////////////////
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	// get the index of POs which converge.
	MatrixXi status = readks.checkExistEV(ppType, NN);
	for(size_t i = 0; i < NN; i++)
	  {
	    if( 1 == status(i,0) ){
	      int ppId = i + 1;	      
	      printf("========= i = %zd ========\n", i);
	      std::pair<MatrixXd, MatrixXi> tmp =
		anglePO(readks, ppType, ppId, subspDim);
	      MatrixXd &ang = tmp.first;
	      MatrixXi &boundStrict = tmp.second; cout << boundStrict << endl;
	      // check whether there are degeneracy
	      MatrixXi pro = boundStrict.row(0).array() *  boundStrict.row(1).array() *
		boundStrict.row(2).array() * boundStrict.row(3).array();
	      for(size_t i = 0; i < M; i++){
		// only keep the orbits whose 4 bounds are not degenerate
		if(pro(0, i) == 1) file[i] << ang.col(i) << endl;
	      }
	    }
	  }
	for(size_t i = 0; i < M; i++) file[i].close();
	/////////////////////////////////////////////////////////////////
	
	break;
      }
      
    case 3 : // small test of the covariant vector projection process. 
      {
	string fileName("../data/ks22h02t100");
	string ppType("ppo");
	const int ppId = 1;
	const int gTpos = 3;

	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
  	MatrixXd eigVals = readks.readKSe(ppType, ppId);
	MatrixXd eigVecs = readks.readKSve(ppType, ppId);

	KS ks(Nks, T/nstp, L);
	ArrayXXd aa = ks.intg(a, nstp);
	std::pair<MatrixXd, VectorXd> tmp = ks.orbitToSlice(aa); 
	MatrixXd &aaHat = tmp.first; 
	MatrixXd veSlice = ks.veToSliceAll( eigVecs, aa.leftCols(aa.cols()-1) );
	MatrixXd ve_trunc = veTrunc(veSlice, gTpos);
	
	cout << veSlice.middleCols(2,3) << endl << endl;
	cout << veSlice.middleCols(2+30*100,3) << endl << endl;
	cout << ve_trunc.middleCols(2,2) << endl << endl;
	cout << ve_trunc.middleCols(2+29*100,2) << endl << endl;
	
	break;
      }
      
    case 4 : // ergodic orbit approache rpo/ppo
	     // fields need to be changed: ppType ppId, nqr, gTpos, sT, folder
	{
	    ////////////////////////////////////////////////////////////
	    // set up the system
	    const int Nks = 64;
	    const int N = Nks - 2;
	    string fileName("../data/ks22h001t120x64");
	    string ppType("ppo");
	    const int ppId = 4; 
	    const int nqr = 5;
	    const int Trunc = 30;
	    const int gTpos = 3; // position of group tangent marginal vector 
	    VectorXi subsp(7); subsp << 3, 4, 5, 6, 7, 8, 9; // subspace indices.
	    ////////////////////////////////////////////////////////////

	    ////////////////////////////////////////////////////////////
	    // prepare orbit, vectors
	    ReadKS readks(fileName+".h5",
			  fileName+"E.h5", 
			  fileName+"EV.h5", N, Nks);
	    // ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	    std::tuple<ArrayXd, double, double, double, double>
		pp = readks.readKSinit(ppType, ppId);	
	    ArrayXd &a = get<0>(pp); 
	    double T = get<1>(pp);
	    int nstp = (int)get<2>(pp);
	    double r = get<3>(pp);
	    double s = get<4>(pp);
	    MatrixXd eigVals = readks.readKSe(ppType, ppId); 
	    MatrixXd eigVecs = readks.readKSve(ppType, ppId);

	    KS ks(Nks, T/nstp, L);
	    ArrayXXd aa = ks.intg(a, nstp, nqr); 
	    ArrayXXd aaWhole, eigVecsWhole;
	    if(ppType.compare("ppo") == 0) {
		aaWhole = ks.half2whole(aa.leftCols(aa.cols()-1));
		eigVecsWhole = ks.half2whole(eigVecs); // this is correct. Think carefully.
	    } else {
		aaWhole = aa.leftCols(aa.cols()-1); // one less
		eigVecsWhole = eigVecs;
	    }
	    assert(aaWhole.cols() == eigVecsWhole.cols());
	    std::pair<MatrixXd, VectorXd> tmp = ks.orbitToSlice(aaWhole); 
	    MatrixXd &aaHat = tmp.first;
	    // note here aa has one more column the the Floquet vectors
	    MatrixXd veSlice = ks.veToSliceAll( eigVecsWhole, aaWhole, Trunc);
	    MatrixXd ve_trunc = veTrunc(veSlice, gTpos, Trunc);
	    ////////////////////////////////////////////////////////////
	
	    ////////////////////////////////////////////////////////////
	    // choose experiment parameters & do experiment
	    const double h = 0.1;
	    const double sT = 30;
	    const double tolClose = 0.1;
	    const int MaxSteps = floor(2000/h);
	    const int MaxT = 10000;
	    string folder = "./case4ppo4x5sT30/";
	    KS ks2(Nks, h, L); 
	    srand(time(NULL));
	    ArrayXd a0(0.1 * ArrayXd::Random(N));
	
	    const int fileNum = 5;
	    string strf[fileNum] = {"angle", "dis", "difv", "indexPo", "No"};
	    ofstream saveName[fileNum];	
	    for (size_t i = 0; i < fileNum; i++) {
		saveName[i].open(folder + strf[i], ios::trunc);
		saveName[i].precision(16);
	    } 
	
	    int accum = 0;
	    for(size_t i = 0; i < MaxT; i++){
		std::cout << "********** i = " << i << "**********"<< std::endl;
		ArrayXXd ergodic = ks2.intg(a0, MaxSteps); a0 = ergodic.rightCols(1);
		std::pair<MatrixXd, VectorXd> tmp = ks2.orbitToSlice(ergodic);
		MatrixXd &ergodicHat = tmp.first;
		// be careful about the size of aaHat
		std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd> 
		    dis = minDistance(ergodicHat, aaHat, tolClose, (int)(sT/h) );
		MatrixXd &minDifv = std::get<0>(dis); 
		VectorXi &minIndexErgodic = std::get<1>(dis);
		VectorXi &minIndexPo = std::get<2>(dis); 
		VectorXd &minDis = std::get<3>(dis);
		MatrixXd angle = difAngle(minDifv, minIndexPo, subsp, ve_trunc, Trunc-1);
		if(angle.cols() > 0) printf("angle size = %ld x %ld, instance %d \n", 
					    angle.rows(), angle.cols(), ++accum);

		if(angle.cols() != 0) {
		    saveName[0] << angle.transpose() << endl;
		    saveName[1] << minDis << std::endl;
		    saveName[2] << minDifv.transpose() << std::endl;
		    saveName[3] << minIndexPo << std::endl;
		    saveName[4] << angle.cols() << std::endl;
		}
	    }
	    for (size_t i = 0; i < fileNum; i++)  saveName[i].close();
	    ////////////////////////////////////////////////////////////
	    break;
	}
      
    case 5: // test the projection of subspaces.
	    // not using FVs, but OVs. OVs is rotated to slice.
      {
	//////////////////////////////////////////////////
	string fileName("../data/ks22h001t120x64");
	string ppType("ppo");
	const int ppId = 4; 
	VectorXi subsp(10); subsp << 4, 5, 6, 7, 8, 9, 10, 12, 16, 28;

	//////////////////////////////////////////////////
	// prepare orbit, vectors
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(Nks, T/nstp, L);
	pair<ArrayXXd, ArrayXXd> tmp = ks.intgj(a, nstp, 5, 5);
	ArrayXXd aaWhole;
	if(ppType.compare("ppo") == 0)
	  aaWhole = ks.half2whole(tmp.first.leftCols(tmp.first.cols()-1));
	else 
	  aaWhole = tmp.first;
	MatrixXd daa = tmp.second;
	
	std::pair<MatrixXd, VectorXd> tmp2 = ks.orbitToSlice(aaWhole); 
	MatrixXd &aaHat = tmp2.first; 
	VectorXd &theta = tmp2.second;

	PED ped;
	ped.reverseOrderSize(daa); // reverse order.
	if(ppType.compare("ppo") == 0)
	  daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
	else // R*J for rpo
	  daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);
	pair<MatrixXd, vector<int> > psd = ped.PerSchur(daa, 1000, 1e-15, false);
	MatrixXd &Q1 = psd.first;
	int n1 = Q1.rows();
	int m1 = Q1.cols() / n1;
	MatrixXd Q2(n1, n1*m1);
	for(size_t i = 0; i < m1; i++) 
	  Q2.middleCols(i*n1, n1) = Q1.middleCols(n1*((m1-i)%m1), n1);

	MatrixXd Q;
	if(ppType.compare("ppo") == 0)
	  Q= ks.half2whole(Q2);
	else // R*J for rpo
	  Q = Q2;
	
	int n = Q.rows();
	int m = Q.cols() / n;
	MatrixXd rQ(n, m*n);
	for (size_t i = 0; i < m; i++) {
	  rQ.middleCols(i*n, n) = ks.rotate( Q.middleCols(i*n, n),
					       -theta(i) );
	}
  
	////////////////////////////////////////////////////////////
	// choose experiment parameters & do experiment
	const double h = 0.1;
	const double sT = 50;
	const double tolClose = 0.1;
	const int MaxSteps = floor(2000/h);
	const int MaxT = 10000;
	string folder = "./case7/";
	KS ks2(Nks, h, L); 
	srand(time(NULL));
	ArrayXd a0(0.1 * ArrayXd::Random(N));
	
	const int fileNum = 5;
	string strf[fileNum] = {"angle", "dis", "difv", "indexPo", "No"};
	ofstream saveName[fileNum];	
	for (size_t i = 0; i < fileNum; i++) {
	  saveName[i].open(folder + strf[i], ios::trunc);
	  saveName[i].precision(16);
	} 

	for(size_t i = 0; i < MaxT; i++){
	  std::cout << "********** i = " << i << "**********"<< std::endl;
	  ArrayXXd ergodic = ks2.intg(a0, MaxSteps); a0 = ergodic.rightCols(1);
	  std::pair<MatrixXd, VectorXd> tmp = ks2.orbitToSlice(ergodic);
	  MatrixXd &ergodicHat = tmp.first;
	  // be careful about the size of aaHat
	  std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd> 
	    dis = minDistance(ergodicHat, aaHat, tolClose, (int)(sT/h) );
	  MatrixXd &minDifv = std::get<0>(dis); 
	  VectorXi &minIndexErgodic = std::get<1>(dis);
	  VectorXi &minIndexPo = std::get<2>(dis); 
	  VectorXd &minDis = std::get<3>(dis);
	  MatrixXd angle = difAngle(minDifv, minIndexPo, subsp, rQ, N);
	  if(angle.cols() > 0) printf("angle size = %ld x %ld\n", angle.rows(),
				      angle.cols());

	  if(angle.cols() != 0) {
	    saveName[0] << angle.transpose() << endl;
	    saveName[1] << minDis << std::endl;
	    saveName[2] << minDifv.transpose() << std::endl;
	    saveName[3] << minIndexPo << std::endl;
	    saveName[4] << angle.cols() << std::endl;
	  }
	}
	for (size_t i = 0; i < fileNum; i++)  saveName[i].close();
	////////////////////////////////////////////////////////////
	  
	break;
      }

    case 6: // test the projection of subspaces.
	    // not using FVs, but OVs. Slice is not used,
	    // Experiments are conducted on the full state space.
      {
	//////////////////////////////////////////////////
	string fileName("../data/ks22h02t100");
	string ppType("ppo");
	const int ppId = 1; 
	VectorXi subsp(10); subsp << 4, 5, 6, 7, 8, 9, 10, 12, 16, 28;

	//////////////////////////////////////////////////
	// prepare orbit, vectors
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(Nks, T/nstp, L);
	pair<ArrayXXd, ArrayXXd> tmp = ks.intgj(a, nstp);
	ArrayXXd aaWhole;
	if(ppType.compare("ppo") == 0)
	  aaWhole = ks.half2whole(tmp.first.leftCols(tmp.first.cols()-1));
	else 
	  aaWhole = tmp.first;
	MatrixXd daa = tmp.second;
	
	PED ped;
	ped.reverseOrderSize(daa); // reverse order.
	if(ppType.compare("ppo") == 0)
	  daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
	else // R*J for rpo
	  daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);
	pair<MatrixXd, vector<int> > psd = ped.PerSchur(daa, 10000, 1e-15, false);
	MatrixXd &Q1 = psd.first;
	int n1 = Q1.rows();
	int m1 = Q1.cols() / n1;
	MatrixXd Q2(n1, n1*m1);
	for(size_t i = 0; i < m1; i++) 
	  Q2.middleCols(i*n1, n1) = Q1.middleCols(n1*((m1-i)%m1), n1);

	MatrixXd Q;
	if(ppType.compare("ppo") == 0)
	  Q= ks.half2whole(Q2);
	else // R*J for rpo
	  Q = Q2;
  
	////////////////////////////////////////////////////////////
	// choose experiment parameters & do experiment
	const double h = 0.1;
	const double sT = 20;
	const double tolClose = 0.1;
	const int MaxSteps = floor(2000/h);
	const int MaxT = 100000;
	string folder = "./case2/";
	KS ks2(Nks, h, L); 
	srand(time(NULL));
	ArrayXd a0(0.1 * ArrayXd::Random(N));
	
	const int fileNum = 5;
	string strf[fileNum] = {"angle", "dis", "difv", "indexPo", "No"};
	ofstream saveName[fileNum];	
	for (size_t i = 0; i < fileNum; i++) {
	  saveName[i].open(folder + strf[i], ios::trunc);
	  saveName[i].precision(16);
	} 

	for(size_t i = 0; i < MaxT; i++){
	  std::cout << "********** i = " << i << "**********"<< std::endl;
	  ArrayXXd ergodic = ks2.intg(a0, MaxSteps); a0 = ergodic.rightCols(1);
	  // be careful about the size of aaHat
	  std::tuple<MatrixXd, VectorXi, VectorXi, VectorXd> 
	    dis = minDistance(ergodic, aaWhole, tolClose,
			      (int)(sT/h) );
	  MatrixXd &minDifv = std::get<0>(dis); 
	  VectorXi &minIndexErgodic = std::get<1>(dis);
	  VectorXi &minIndexPo = std::get<2>(dis); 
	  VectorXd &minDis = std::get<3>(dis);
	  MatrixXd angle = difAngle(minDifv, minIndexPo, subsp, Q, N);
	  if(angle.cols() > 0) printf("angle size = %ld x %ld\n", angle.rows(),
				      angle.cols());

	  if(angle.cols() != 0) {
	    saveName[0] << angle.transpose() << endl;
	    saveName[1] << minDis << std::endl;
	    saveName[2] << minDifv.transpose() << std::endl;
	    saveName[3] << minIndexPo << std::endl;
	    saveName[4] << angle.cols() << std::endl;
	  }
	}
	for (size_t i = 0; i < fileNum; i++)  saveName[i].close();
	////////////////////////////////////////////////////////////
	  
	break;
      }

    case 7: // test rotated initial condition for N = 64
	    // after rotation, the result looks good.
      {

	string fileName("../data/ks22h001t120x64");
	string ppType("ppo");
	const int ppId = 13; 

	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N62, N64);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);

	const int div = 1;
	KS ks(N64, T/nstp/div, L);
	MatrixXd aa = ks.intg(a, 2*div*nstp);
	MatrixXd aaHat = ks.orbitToSlice(aa).first;
	cout << (aa.rightCols(1) - aa.col(0)).norm() << endl;
	MatrixXd paa = ks.intg(ks.rotate(aa.col(0), 1), 2*div*nstp);
	std::cout << (paa.rightCols(1) - paa.col(0)).norm() << std::endl;

	break;
      }
      
      
    case 8: // test the linear relation of OVs
	    // the result is bad 1e-5. 
      {
	//////////////////////////////////////////////////
#if 0
	string fileName("../data/ks22h02t100");
	string ppType("rpo");
	const int ppId = 3; 
	
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);

	KS ks(Nks, T/nstp, L);
# endif			
	string fileName("../data/ks22h001t120x64");
	string ppType("rpo");
	const int ppId = 8;
	
	ReadKS readks(fileName+".h5", fileName+".h5", fileName+".h5", N62, N64);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(N64, T/nstp, L);
	//////////////////////////////////////////////////
	
	pair<ArrayXXd, ArrayXXd> tmp = ks.intgj(a, nstp, 5, 5);
	MatrixXd aa = tmp.first;
	MatrixXd daa = tmp.second;
	PED ped;
	ped.reverseOrderSize(daa); // reverse order.
	if(ppType.compare("ppo") == 0)
	  daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
	else // R*J for rpo
	  daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);


	switch (2) {
	case 1:
	  {
	    pair<MatrixXd, vector<int> > psd = ped.PerSchur(daa, 3000, 1e-15, true);
	    MatrixXd &Q1 = psd.first;
	    int n1 = Q1.rows();
	    int m1 = Q1.cols() / n1;
	    MatrixXd Q2(n1*n1, m1);
	    for(size_t i = 0; i < m1; i++) {
	      MatrixXd tmp = Q1.middleCols(n1*((m1-i)%m1), n1);
	      tmp.resize(n1*n1,1);
	      Q2.col(i) = tmp;
	    }
	    MatrixXd Q = ks.veToSliceAll( Q2, aa.leftCols(aa.cols()-1) );
	    cout << Q.rows() << 'x' << Q.cols() << endl;

	    ColPivHouseholderQR<MatrixXd> qr(Q.leftCols(5));
	    MatrixXd R = qr.matrixQR().triangularView<Upper>();
	    cout << R.rows() << 'x' << R.cols() << endl;
	    cout << R.topRows<5>() << endl;

	    break;
	  }
	  
	case 2 :
	  {
	    const int N = daa.rows();
	    const int M = daa.cols() / N;
	    MatrixXd J(N, N*M);
	    for (size_t i = 0; i < M; i++) {
	      J.middleCols(i*N, N) = daa.middleCols((M-i-1)*N, N);
	    }
	    
	    HouseholderQR<MatrixXd> qr;
	    MatrixXd Q(MatrixXd::Identity(N,N));
	    MatrixXd Qp(N, N);
	    for (size_t i = 0; i < 3000; i++) {
	      if(i%10 == 0) cout << i << endl;
	      for (size_t i = 0; i < M; i++) {
		Qp = J.middleCols(i*N, N) * Q;
		qr.compute(Qp);
		Q = qr.householderQ();
	      }
	    }
	    Q.resize(N*N,1);
	    MatrixXd rQ = ks.veToSliceAll(Q, aa.col(0));
	    qr.compute(rQ.leftCols(5));
	    MatrixXd R = qr.matrixQR().triangularView<Upper>();
	    cout << R.rows() << 'x' << R.cols() << endl;
	    cout << R.topRows<5>() << endl;
	  }
	}
	
	break;
      }

    case 9 : // test the 32 modes initial condition 
      {
	string fileName("../data/ks22h001t120x64");
	string ppType("ppo");
	const int ppId = 1;
	ReadKS readks(fileName+".h5", fileName+".h5", fileName+".h5", N62, N64);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(N64, T/nstp, L);
	MatrixXd daa = ks.intgj(a, nstp, 10, 10).second;
	
	PED ped ;
	ped.reverseOrderSize(daa);
	daa.leftCols(N) = ks.reflect(daa.leftCols(N));
	MatrixXd eigVals = ped.EigVals(daa, 3000, 1e-15, true);
	
	MatrixXd FloquetE(eigVals.rows(), eigVals.cols());
	FloquetE << eigVals.col(0).array()/T, eigVals.rightCols(2);
	cout << FloquetE << endl;

	break;
      }

    case 10: // test the spacing in 32 modes orbit
      {
	string fileName("../data/ks22h001t50x64");
	string ppType("rpo");
	const int ppId = 8;
	
	ReadKS readks(fileName+".h5", fileName+".h5", fileName+".h5", N62, N64);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(N64, T/nstp, L);
	MatrixXd aa = ks.intg(a, nstp, 10);
	ArrayXXd aaWhole;
	if(ppType.compare("ppo") == 0) {
	  aaWhole = ks.half2whole(aa.leftCols(aa.cols()-1));
	} else {
	  aaWhole = aa.leftCols(aa.cols()-1); // one less
	} 
	MatrixXd aaReduced = ks.orbitToSlice(aaWhole).first;
	// cout << aa.rows() << 'x' << aa.cols() << endl;
	VectorXd dis(aaReduced.cols());
	for (int i = 0; i < dis.size(); i++) {
	  dis(i) = (aaReduced.col( (i+1)%dis.size() )-aaReduced.col(i)).norm();
	}
	cout << dis << endl;
	
	break;
      }
      
    case 11: // to try Predrag's suggestions
      {
	string folder("../data/ErgodicApproch/cases32modes/case4ppo4x10/");
	string ppType("ppo");
	const int ppId = 4;
	const int N = 62;
	const int nqr = 10;

	// read files from disk
	const int fileNum = 4;
	string strf[fileNum] = {"No", "dis", "difv", "indexPo"};	
	ifstream saveName[fileNum];
	for (int i = 0; i < fileNum; i++) saveName[i].open(folder+strf[i]);

	string line;
	vector<int> No;
	while( getline(saveName[0], line) ) No.push_back(stoi(line));
	int M = accumulate(No.begin(), No.end(), 0);
	VectorXd dis(M);
	VectorXi indexPo(M);
	MatrixXd difv(N, M);
	for (int i = 0; i < M; i++) {
	  getline(saveName[1], line);
	  dis(i) = stod(line);
	  
	  getline(saveName[2], line);
	  size_t sz = 0;
	  for (int j = 0; j < N; j++){
	    size_t tmp;
	    difv(j, i) = stod(line.substr(sz), &tmp);
	    sz += tmp;
	  }

	  getline(saveName[3], line);
	  indexPo(i) = stoi(line);
	}
	for (int i = 0; i < fileNum; i++) saveName[i].close();
	
	string fileName("../data/ks22h001t50x64.h5");
	ReadKS readks(fileName, fileName, fileName, N, N+2);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(N+2, T/nstp, L);
	ArrayXXd aa = ks.intg(a, nstp, nqr); 
	ArrayXXd aaWhole;
	if(ppType.compare("ppo") == 0) {
	  aaWhole = ks.half2whole(aa.leftCols(aa.cols()-1));
	} else {
	  aaWhole = aa.leftCols(aa.cols()-1); // one less
	}
	MatrixXd aaHat = ks.orbitToSlice(aaWhole).first;
	MatrixXd ergodicHat(N, M);
	for (int i = 0; i < M; i++) {
	  ergodicHat.col(i) = aaHat.col(indexPo(i)) + difv.col(i);
	}
	//vector<int> filter = interp(ks, ergodicHat, aaHat, indexPo, 0.05);
	//for (int i = 0; i < filter.size(); i++) cout << filter[i] << endl;
	// cout << M << endl;
	cout << aaHat << endl;
	
	break;
      }

    case 12:
      {
	string fileName("../data/ks22h001t120x64");
	string ppType("ppo");
	const int ppId = 1; 
	const int nqr = 5;
	const int Trunc = 30;
	const int gTpos = 3; 
	////////////////////////////////////////////////////////////

	////////////////////////////////////////////////////////////
	// prepare orbit, vectors
	const int Nks = 64;
	const int N = Nks - 2;
	ReadKS readks(fileName+".h5",
		      fileName+"E.h5", 
		      fileName+"EV.h5", N, Nks);
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
  	MatrixXd eigVals = readks.readKSe(ppType, ppId); 
	MatrixXd eigVecs = readks.readKSve(ppType, ppId);
	
	// printf("%ld x %ld\n", eigVecs.rows(), eigVecs.cols());
	assert(N * Trunc == eigVecs.rows());
	const int M = eigVecs.cols();
	VectorXd vol = VectorXd::Zero(Trunc);
	for (int i = 0; i < M; i++) {
	  MatrixXd v = eigVecs.col(i);
	  v.resize(N, Trunc);
	  for (int j = 0; j < Trunc; j++) {
	    double nor = v.col(j).norm();
	    v.col(j) = v.col(j) / nor;
	  }
	  for (int j = 1; j < Trunc+1; j++) {
	    MatrixXd A = v.leftCols(j).transpose();
	    MatrixXd B = v.leftCols(j);
	    double  det = (A*B).determinant();
	    // if(i == 500) cout << sqrt(det) << endl;
	    vol(j-1) = vol(j-1) + sqrt(det);
	  }
	}
	vol = vol.array() / M;
	cout << vol << endl;


	KS ks(Nks, T/nstp, L);
	ArrayXXd aa = ks.intg(a, nstp, nqr); 
	ArrayXXd aaWhole, eigVecsWhole;
	if(ppType.compare("ppo") == 0) {
	  aaWhole = ks.half2whole(aa.leftCols(aa.cols()-1));
	  eigVecsWhole = ks.half2whole(eigVecs); // this is correct. Think carefully.
	} else {
	  aaWhole = aa.leftCols(aa.cols()-1); // one less
	  eigVecsWhole = eigVecs;
	}
	assert(aaWhole.cols() == eigVecsWhole.cols());
	std::pair<MatrixXd, VectorXd> tmp = ks.orbitToSlice(aaWhole); 
	MatrixXd &aaHat = tmp.first;
	// note here aa has one more column the the Floquet vectors
	MatrixXd veSlice = ks.veToSliceAll( eigVecsWhole, aaWhole, Trunc);
	MatrixXd ve_trunc = veTrunc(veSlice, gTpos, Trunc);
	
	break;
      }

    default:
      {
	printf("please indicate the index of problem !\n");
      }
    }
  return 0;

}
 
<file_sep>#ifndef MYBOOSTPYTHON_H
#define MYBOOSTPYTHON_H

#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;

typedef std::complex<double> dcp;

// ============================================================

/* get the dimension of an array */
inline void getDims(bn::ndarray x, int &m, int &n){
    if(x.get_nd() == 1){
	m = 1;
	n = x.shape(0);
    } else {
	m = x.shape(0);
	n = x.shape(1);
    }
}

/*
 * @brief used to copy content in Eigen array to boost.numpy array.
 *
 *  Only work for double array/matrix
 */
template<class MyAry = ArrayXXd, class MyType = double>
bn::ndarray copy2bn(const Ref<const MyAry> &x){
    int m = x.cols();
    int n = x.rows();

    Py_intptr_t dims[2];
    int ndim;
    if(m == 1){
	ndim = 1;
	dims[0] = n;
    }
    else {
	ndim = 2;
	dims[0] = m;
	dims[1] = n;
    }
    bn::ndarray px = bn::empty(ndim, dims, bn::dtype::get_builtin<MyType>());
    memcpy((void*)px.get_data(), (void*)x.data(), sizeof(MyType) * m * n);
	    
    return px;
}

/* non-template function overloading for real matrix */
inline bn::ndarray copy2bn(const Ref<const ArrayXXd> &x) {
    return copy2bn<ArrayXXd, double>(x);
}

/* non-template function overloading for imaginary matrix */
inline bn::ndarray copy2bnc(const Ref<const ArrayXXcd> &x) {
    return copy2bn<ArrayXXcd, dcp>(x);
}


/**
 * @brief std::vector to bp::list
 */
template <class T>
inline bp::list toList(std::vector<T> vector) {
    typename std::vector<T>::iterator iter;
    bp::list list;
    for (iter = vector.begin(); iter != vector.end(); ++iter) {
	list.append(*iter);
    }
    return list;
}


#endif /* MYBOOSTPYTHON_H */
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CQCGL2d.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class pyCQCGL2d : public CQCGL2d {
  
public:

    pyCQCGL2d(int N, int M, double dx, double dy,
	      double Mu, double Dr, double Di,
	      double Br, double Bi, double Gr,
	      double Gi,  
	      int threadNum) :
	CQCGL2d(N, M, dx, dy, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) {}

    pyCQCGL2d(int N, double dx,
	      double Mu, double Dr, double Di,
	      double Br, double Bi, double Gr,
	      double Gi,  
	      int threadNum) :
	CQCGL2d(N, dx, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) {}

    pyCQCGL2d(int N, int M,  double dx, double dy, 
	      double b, double c, double dr, double di, 
	      int threadNum) :
	CQCGL2d(N, M, dx, dy, b, c, dr, di, threadNum) {}

    pyCQCGL2d(int N, double dx,
	      double b, double c, double dr, double di,
	      int threadNum) :
	CQCGL2d(N, dx, b, c, dr, di, threadNum) {}
    
    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }

    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

    /* Kx */
    bn::ndarray PYKx(){
	return copy2bn(Kx);
    }

    /* Ky */
    bn::ndarray PYKy(){
	return copy2bn(Ky);
    }
    
    /* L */
    bn::ndarray PYL(){
	return copy2bnc(L);
    }

   /* wrap the integrator */
    bn::ndarray PYintg(bn::ndarray a0, double h, int Nt, int skip_rate, 
		       bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(intg(tmpa, h, Nt, skip_rate, doSaveDisk, fileName));
    }
    
    bn::ndarray PYaintg(bn::ndarray a0, double h, double tend, int skip_rate,
			bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(aintg(tmpa, h, tend, skip_rate, doSaveDisk, fileName));
    }

    bn::ndarray PYintgv(bn::ndarray a0, bn::ndarray v0, double h, int Nt, int skip_rate,
			bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);
	return copy2bnc(intgv(tmpa, tmpv, h, Nt, skip_rate, doSaveDisk, fileName));
    }    

    bn::ndarray PYaintgv(bn::ndarray a0, bn::ndarray v0, double h, double tend, int skip_rate,
			 bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);
	return copy2bnc(aintgv(tmpa, tmpv, h, tend, skip_rate, doSaveDisk, fileName));
    }

    bn::ndarray PYFourier2Config(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXcd> tmpaa((dcp*)aa.get_data(), n, m);
	return copy2bnc( Fourier2Config(tmpaa) );
    }

    bn::ndarray PYConfig2Fourier(bn::ndarray AA){
	int m, n;
	getDims(AA, m, n);
	Map<ArrayXXcd> tmpAA((dcp*)AA.get_data(), n, m);
	return copy2bnc( Config2Fourier(tmpAA) );
    }
    
    bn::ndarray PYvelocity(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(velocity(tmpa));
    }

    bn::ndarray PYvelocityReq(bn::ndarray a0, double wthx, 
			      double wthy, double wphi){
	int m, n;
	getDims(a0, m, n);	
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(velocityReq(tmpa, wthx, wthy, wphi));
    }
   
    bn::ndarray PYstab(bn::ndarray a0, bn::ndarray v0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);

	return copy2bnc(stab(tmpa, tmpv));
    }

    bn::ndarray PYstabReq(bn::ndarray a0, bn::ndarray v0, double wthx,
			  double wthy, double wphi){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);

	return copy2bnc(stabReq(tmpa, tmpv, wthx, wthy, wphi));
    }

    bn::ndarray PYrotate(bn::ndarray a0, int mode, double th1=0, double th2=0, double th3=0){
	int m, n;
	getDims(a0, m, n);	
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc( rotate(tmpa, mode, th1, th2, th3) );
    }
    
    bn::ndarray PYrotate1(bn::ndarray a0, int mode, double th1, double th2){
	return PYrotate(a0, mode, th1, th2);
    }

    bn::ndarray PYrotate2(bn::ndarray a0, int mode, double th1){
	return PYrotate(a0, mode, th1);
    }

    bn::ndarray PYrotate3(bn::ndarray a0, int mode){
	return PYrotate(a0, mode);
    }

    bn::ndarray PYtangent(bn::ndarray a0, int mode){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc( tangent(tmpa, mode) );
    }

#if 0
    /* reflectVe */
    bn::ndarray PYreflectVe(const bn::ndarray &veHat, const bn::ndarray &xHat){
	int m, n;
	getDims(veHat, m, n);	
	Map<MatrixXd> tmpveHat((double*)veHat.get_data(), n, m);
	int m2, n2;
	getDims(xHat, m2, n2);
	Map<ArrayXd> tmpxHat((double*)xHat.get_data(), n2*m2);
	return copy2bn( reflectVe(tmpveHat, tmpxHat) );
    }

    /* reflectVeAll */
    bn::ndarray PYreflectVeAll(const bn::ndarray &veHat, const bn::ndarray &aaHat,
			       const int trunc){
	int m, n;
	getDims(veHat, m, n);	
	Map<MatrixXd> tmpveHat((double*)veHat.get_data(), n, m);
	int m2, n2;
	getDims(aaHat, m2, n2);
	Map<ArrayXd> tmpaaHat((double*)aaHat.get_data(), n2, m2);
	return copy2bn( reflectVeAll(tmpveHat, tmpaaHat, trunc) );
    }
    
    
    /* ve2slice */
    bn::ndarray PYve2slice(bn::ndarray ve, bn::ndarray x){
	int m, n;
	getDims(ve, m, n);
	int m2, n2;
	getDims(x, m2, n2);
	Map<ArrayXXd> tmpve((double*)ve.get_data(), n, m);
	Map<ArrayXd> tmpx((double*)x.get_data(), n2*m2);
	return copy2bn( ve2slice(tmpve, tmpx) );
    }
    
    /* reduceAllSymmetries */
    bp::tuple PYreduceAllSymmetries(const bn::ndarray &aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	std::tuple<ArrayXXd, ArrayXd, ArrayXd> tmp = 
	    reduceAllSymmetries(tmpaa);
	return bp::make_tuple(copy2bn(std::get<0>(tmp)),
			      copy2bn(std::get<1>(tmp)),
			      copy2bn(std::get<2>(tmp)));
	
    }

    /* reduceVe */
    bn::ndarray PYreduceVe(const bn::ndarray &ve, const bn::ndarray &x){
	int m, n;
	getDims(ve, m, n);
	Map<ArrayXXd> tmpve((double*)ve.get_data(), n, m);
	int m2, n2;
	getDims(x, m2, n2);
	Map<ArrayXd> tmpx((double*)x.get_data(), n2*m2);
	return copy2bn(reduceVe(tmpve, tmpx));
    }
    

    /* rotateOrbit */
    bn::ndarray PYrotateOrbit(bn::ndarray aa, bn::ndarray th, bn::ndarray phi){
	int m, n;
	getDims(aa, m, n);
	int m2, n2;
	getDims(th, m2, n2);
	int m4, n4;
	getDims(phi, m4, n4);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	Map<ArrayXd> tmpth((double*)th.get_data(), n2 * m2);
	Map<ArrayXd> tmpphi((double*)phi.get_data(), n4 * m4);
	return copy2bn( rotateOrbit(tmpaa, tmpth, tmpphi) );
    }
    
#endif
    
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_CQCGL2d) {
    bn::initialize();
    
    // must provide the constructor
    bp::class_<CQCGL2d>("CQCGL2d", bp::init<
			int, double, 
			double, double, double, double, 
			int>())
	;
    
    
    bp::class_<pyCQCGL2d, bp::bases<CQCGL2d> >("pyCQCGL2d", bp::init<
					       int, double, 
					       double, double, double, double,
					       int>())
	.def(bp::init<int, int, double, double,
	     double, double, double,
	     double, double, double,
	     double,
	     int>())
	.def(bp::init<int, double,
	     double, double, double,
	     double, double, double,
	     double,
	     int>())
	.def(bp::init<int, int, double, double,
	     double, double, double, double, 
	     int>())
	.def_readonly("N", &pyCQCGL2d::N)
	.def_readonly("M", &pyCQCGL2d::M)
	.def_readonly("dx", &pyCQCGL2d::dx)
	.def_readonly("dy", &pyCQCGL2d::dy)
	.def_readonly("Mu", &pyCQCGL2d::Mu)
	.def_readonly("Br", &pyCQCGL2d::Br)
	.def_readonly("Bi", &pyCQCGL2d::Bi)
	.def_readonly("Dr", &pyCQCGL2d::Dr)
	.def_readonly("Di", &pyCQCGL2d::Di)
	.def_readonly("Gr", &pyCQCGL2d::Gr)
	.def_readonly("Gi", &pyCQCGL2d::Gi)
	.def_readonly("Ne", &pyCQCGL2d::Ne)
	.def_readonly("Me", &pyCQCGL2d::Me)
	// .def_readonly("b", &pyCQCGL2d::b)
	// .def_readonly("c", &pyCQCGL2d::c)
	// .def_readonly("dr", &pyCQCGL2d::dr)
	// .def_readonly("di", &pyCQCGL2d::di)
	.def_readonly("Omega", &pyCQCGL2d::Omega)
	.def_readwrite("rtol", &pyCQCGL2d::rtol)
	.def_readwrite("nu", &pyCQCGL2d::nu)
	.def_readwrite("mumax", &pyCQCGL2d::mumax)
	.def_readwrite("mumin", &pyCQCGL2d::mumin)
	.def_readwrite("mue", &pyCQCGL2d::mue)
	.def_readwrite("muc", &pyCQCGL2d::muc)
	.def_readwrite("NCalCoe", &pyCQCGL2d::NCalCoe)
	.def_readwrite("NReject", &pyCQCGL2d::NReject)
	.def_readwrite("NCallF", &pyCQCGL2d::NCallF)
	.def_readwrite("NSteps", &pyCQCGL2d::NSteps)
	.def_readwrite("Method", &pyCQCGL2d::Method)
	.def_readwrite("constETDPrint", &pyCQCGL2d::constETDPrint)
	.def("Ts", &pyCQCGL2d::PYTs)
	.def("hs", &pyCQCGL2d::PYhs)
	.def("lte", &pyCQCGL2d::PYlte)
	.def("Kx", &pyCQCGL2d::PYKx)
	.def("Ky", &pyCQCGL2d::PYKy)
	.def("L", &pyCQCGL2d::PYL)

	.def("changeOmega", &pyCQCGL2d::changeOmega)
	.def("intg", &pyCQCGL2d::PYintg)
	.def("aintg", &pyCQCGL2d::PYaintg)
	.def("intgv", &pyCQCGL2d::PYintgv)
	.def("aintgv", &pyCQCGL2d::PYaintgv)
	.def("Fourier2Config", &pyCQCGL2d::PYFourier2Config)
	.def("Config2Fourier", &pyCQCGL2d::PYConfig2Fourier)
	.def("velocity", &pyCQCGL2d::PYvelocity)
	.def("velocityReq", &pyCQCGL2d::PYvelocityReq)
	.def("stab", &pyCQCGL2d::PYstab)
	.def("stabReq", &pyCQCGL2d::PYstabReq)
	.def("rotate", &pyCQCGL2d::PYrotate)
	.def("rotate", &pyCQCGL2d::PYrotate1)
	.def("rotate", &pyCQCGL2d::PYrotate2)
	.def("rotate", &pyCQCGL2d::PYrotate3)
	.def("tangent", &pyCQCGL2d::PYtangent)
#if 0
	.def("velocity", &pyCQCGL2d::PYvelocity)
	.def("velSlice", &pyCQCGL2d::PYvelSlice)
	.def("velPhase", &pyCQCGL2d::PYvelPhase)
	.def("velocityReq", &pyCQCGL2d::PYvelocityReq)
	.def("orbit2sliceWrap", &pyCQCGL2d::PYorbit2sliceWrap)
	.def("orbit2slice", &pyCQCGL2d::PYorbit2slice)
	.def("stab", &pyCQCGL2d::PYstab)
	.def("stabReq", &pyCQCGL2d::PYstabReq)
	.def("reflect", &pyCQCGL2d::PYreflect)
	.def("reduceReflection", &pyCQCGL2d::PYreduceReflection)
	.def("refGradMat", &pyCQCGL2d::PYrefGradMat)
	.def("reflectVe", &pyCQCGL2d::PYreflectVe)
	.def("reflectVeAll", &pyCQCGL2d::PYreflectVeAll)
	.def("ve2slice", &pyCQCGL2d::PYve2slice)
	.def("reduceAllSymmetries", &pyCQCGL2d::PYreduceAllSymmetries)
	.def("reduceVe", &pyCQCGL2d::PYreduceVe)
	.def("transRotate", &pyCQCGL2d::PYtransRotate) 
	.def("transTangent", &pyCQCGL2d::PYtransTangent)
	.def("phaseRotate", &pyCQCGL2d::PYphaseRotate)
	.def("phaseTangent", &pyCQCGL2d::PYphaseTangent)
	.def("Rotate", &pyCQCGL2d::PYRotate)
	.def("rotateOrbit", &pyCQCGL2d::PYrotateOrbit)
#endif
	;

}
<file_sep>import numpy as np
import matplotlib.pyplot as plt
import h5py

N = 256;

f = h5py.File('/usr/local/home/xiong/svn/DOGS/blog/code/data/req.h5', 'r')
a0 = f['/req1/a0']


taa = a0; taa = taa[::2]+1j*taa[1::2];
ia = np.fft.ifft(taa, axis=0)

fig = plt.figure(figsize=(5,5));
ax = fig.add_subplot(111)
ax.plot(np.linspace(0, 50, 256), abs(ia), 'c-', lw = 2.0)
ax.plot(np.linspace(0, 50, 256), ia.real,'r-',lw = 1.0)
ax.plot(np.linspace(0, 50, 256), ia.imag,'b-',lw = 1.0)
ax.locator_params(nbins=5)

plt.tight_layout(pad=0)
plt.show()
f.close()
<file_sep>#include <iostream>
#include "CQCGL2dDislin.hpp"

using namespace denseRoutines;
using namespace Eigen;
using namespace std;

//////////////////////////////////////////////////////////////////////

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = -A + (1 + b*i) (A_{xx}+A_{yy}) + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
 */
CQCGL2dDislin::CQCGL2dDislin(int N, int M, double dx, double dy,
			     double b, double c, double dr, double di,
			     int threadNum)
    : CQCGL2d(N, M, dx, dy, b, c, dr, di, threadNum)
{				
}

CQCGL2dDislin::CQCGL2dDislin(int N, double dx,
		 double b, double c, double dr, double di,
		 int threadNum)
    : CQCGL2d(N, dx, b, c, dr, di, threadNum)
{				
}


CQCGL2dDislin::~CQCGL2dDislin(){}

CQCGL2dDislin & CQCGL2dDislin::operator=(const CQCGL2dDislin &x){
    return *this;
}


//////////////////////////////////////////////////////////////////////
//                              member functions                    //
//////////////////////////////////////////////////////////////////////

/* should resize the field to make it insize the Z-coordinate */
void 
CQCGL2dDislin::initPlot(Dislin &g, const double Lx, const double Ly, 
			const double Lz){
    
    g.scrmod ("revers");	/* background color */
    g.metafl ("cons");		/* file format */
    g.winsiz(600, 425);		/* window size */
    g.clrmod("full");		/* 256 colors */
  
    g.disini ();		/* initialize */

    g.winmod ("none");		/* not holding */
    g.pagera ();		/* border around page */
    g.hwfont ();		/* set hardware font if available */

    g.name   ("X", "x");	/* axis titles */
    g.name   ("Y", "y");
    g.name   ("|A|", "z");

    // g.autres (N, N);		/* number of data points */
    g.axspos (500, 1900);		/* position of axis */
    g.ax3len (1600, 1600, 1600);	/* axis length in plot coordinates */
    g.widbar(50);			/* color bar width */

    // plot 3d axis system
    g.graf3  (0.0, Lx, 0.0, Lx, /* x : lower, upper, 1st label, label step */
	      0.0, Ly, 0.0, Ly,
	      0.0, Lz, 0.0, Lz);

    // g.titlin ("|A|", 4);		/* title up to 4 */
    g.height (50);		/* character height */
    g.title  ();			/* plot title */
}

/**
 * Note, can not use function Fourier2Config() because it will destroy the current state.
 * 
 */
void 
CQCGL2dDislin::plot(Dislin &g, const double t, const double err){
    F[0].ifft();
    ArrayXXd absA = F[0].v2.abs();
    double m = absA.maxCoeff();
    absA = absA / m;

    char buffer[30];
    sprintf(buffer, "%e", err);
    std::string s = "t: " + to_string(t) + "; max|A|: " + std::to_string(m) + 
	"; LTE: " + std::string(buffer);

    g.erase();
    g.titlin(s.c_str(), 4);
    g.title();
    g.pagera ();
    g.crvmat((double *)absA.data(), M, N, 1, 1); 
    g.sendbf();
}

void
CQCGL2dDislin::endPlot(Dislin &g){
    g.disfin();
}

/**
 * @brief Constant time step integrator
 */
void
CQCGL2dDislin::constAnim(const ArrayXXcd &a0, const double h, const int skip_rate){
    F[0].v1 = pad(a0);
    calCoe(h);
    
    Dislin g;
    initPlot(g, dx, dy, 1);
    plot(g, 0, 0);

    double t = 0;
    double du;
    int i = 0;
    while (true){
	oneStep(du, true);
	t += h;
	F[0].v1 = F[4].v1;	// update state
	if ( (i+1)%skip_rate == 0 ) {
	    plot(g, t, du);
	}
	i = (i+1) % skip_rate;
    }	
    
    endPlot(g);
}



/**
 * @brief time step adaptive integrator
 */
void
CQCGL2dDislin::adaptAnim(const ArrayXXcd &a0, const double h0, const int skip_rate){
    double h = h0; 
    calCoe(h);
    F[0].v1 = pad(a0);

    Dislin g;
    initPlot(g, dx, dy, 1);
    plot(g, 0, 0);

    double t = 0;
    double du = 0;
    int i = 0;
    bool doChange, doAccept;

    bool TimeEnds = false;
    while( true ){ 
	
	oneStep(du, true);
	double s = nu * std::pow(rtol/du, 1.0/4);
	double mu = adaptTs(doChange, doAccept, s);
	
	if (doAccept){
	    t += h;
	    F[0].v1 = F[4].v1;
	    if ( (i+1) % skip_rate == 0) plot(g, t, du);
	}
	
	if (doChange) {
	    h *= mu;
	    calCoe(h);
	}

	i = (i+1) % skip_rate;
    }

    endPlot(g);
}
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CqcglETD.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class pyCqcglETD : public CqcglETD {
public :
    pyCqcglETD(int N, double d, double W, double B, double C, double DR, double DI) : 
	CqcglETD(N, d, W, B, C, DR, DI) {}

    bp::tuple PYetd(bn::ndarray a0, double tend, double h, int skip_rate, 
		    int method, bool adapt){
	int m, n;
	getDims(a0, m, n);
	Map<VectorXd> tmpa0((double*)a0.get_data(), n * m);

	auto tmp = etd(tmpa0, tend, h, skip_rate, method, adapt);
	return bp::make_tuple(copy2bn(tmp.first), 
			      copy2bn(tmp.second)
			      );
    }

    bn::ndarray PYhs() {
	return copy2bn(etdrk4->hs);
    }
    
    bn::ndarray PYduu() {
	return copy2bn(etdrk4->duu);
    }

    bp::tuple PYetdParam(){
	return bp::make_tuple(etdrk4->NCalCoe,
			      etdrk4->NReject,
			      etdrk4->NCallF,
			      etdrk4->rtol
			      );
    }
    
    void PYsetRtol(double x){
	etdrk4->rtol = x;
    }

};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_cqcgl1d_threads) {
    bn::initialize();

    bp::class_<CqcglETD>("CqcglETD", bp::init<
			 int, double, double, double, double, double , double
			 >())
	;

    
    bp::class_<pyCqcglETD, bp::bases<CqcglETD> >("pyCqcglETD", bp::init<
						 int, double, double, double, double, double , double
						 >())
	.def_readonly("N", &pyCqcglETD::N)
	.def_readonly("d", &pyCqcglETD::d)
	.def("etdParam", &pyCqcglETD::PYetdParam)
	.def("setRtol", &pyCqcglETD::PYsetRtol)
	.def("etd", &pyCqcglETD::PYetd)
	.def("hs", &pyCqcglETD::PYhs)
	.def("duu", &pyCqcglETD::PYduu)
	; 
    
}
<file_sep>from personalFunctions import *

##################################################
#            1d CQCGL related                    #
##################################################
class CQCGLBase():

    def __init__(self, cgl=None):
        self.cgl = cgl

    def toStr(self, Bi, Gi, index):
        if abs(Bi) < 1e-6:
            Bi = 0
        if abs(Gi) < 1e-6:
            Gi = 0
        return (format(Bi, '013.6f') + '/' + format(Gi, '013.6f') +
                '/' + str(index))

    def checkExist(self, fileName, groupName):
        f = h5py.File(fileName, 'r')
        x = groupName in f
        f.close()
        return x
        
    def scanGroup(self, fileName, level):
        """
        get all group names with a specific level
        """
        f = h5py.File(fileName, 'r')
        gs = []
        def parse(name, obj):
            if isinstance(obj, h5py.Group) and name.count('/') == level:
                gs.append(name)
        f.visititems(parse)
        return gs

    def checkVecSym(self, v):
        """
        check the symmetry of a vector
        symmetric : a_k = a_{-k}
        anti-symmetric : a_k = - a_{-k}
        """
        vr, vi = v.real, v.imag
        vr, vi = vr[::2] + 1j*vr[1::2], vi[::2] + 1j*vi[1::2]
        # pad a_0 at end
        vr, vi = np.append(vr, vr[0]), np.append(vi, vi[0])

        sym_r = norm(vr - vr[::-1]) / norm(vr)
        sym_i = norm(vi - vi[::-1]) / norm(vi)
        anti_r = norm(vr + vr[::-1]) / norm(vr)
        anti_i = norm(vi + vi[::-1]) / norm(vi)

        return np.array([sym_r, sym_i, anti_r, anti_i])
        
    
class CQCGLplot():
    def __init__(self, cgl=None):
        self.cgl = cgl

    def oneConfig(self, A, d=50, isFourier=True, 
                  size=[6, 5], labs=[r'$x$', r'$|A|$'],
                  axisLabelSize=20, tickSize=None,
                  save=False, name='out.png'):
        """
        plot the configuration at one point 
        or plot one eigen vector.
        
        Parameter
        ======
        isFourier : is the input the Fourier modes of A. If it is, then we need back FFT.
        """
        fig, ax = pl2d(size=size, labs=labs, axisLabelSize=axisLabelSize, tickSize=tickSize)
        if isFourier:
            A = self.cgl.Fourier2Config(A)
        Aamp = np.abs(A)
        ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=1.5)
        ax2d(fig, ax, save=save, name=name)
    
    def config(self, AA, ext, isFourier=True, tt=None, yls=None, timeMode=1,
               barTicks=[1, 2, 3], colortype='jet',
               percent='5%', size=[4, 5], labs=[r'$x$', r'$t$'],
               axisLabelSize=20, tickSize=None,
               save=False, name='out.png'):
        """
        plot the color map of the states
        """
        if tt is not None:
            if timeMode == 1:
                n = len(tt)
                ids = [bisect_left(tt, yl) for yl in yls]
                yts = [x / float(n) * ext[3] for x in ids]
                ax.set_yticks(yts)
                ax.set_yticklabels(yls)
            else:
                idx = self.sliceTime(tt)
                AA = AA[idx, :]

        if isFourier:
            AA = self.cgl.Fourier2Config(AA)
        Aamp = np.abs(AA)
        fig, ax = pl2d(size=size, labs=labs, axisLabelSize=axisLabelSize, tickSize=tickSize)
        im = ax.imshow(Aamp, cmap=plt.get_cmap(colortype), extent=ext,
                       aspect='auto', origin='lower')
        ax.grid('on')
        dr = make_axes_locatable(ax)
        cax = dr.append_axes('right', size=percent, pad=0.05)
        plt.colorbar(im, cax=cax, ticks=barTicks)

        ax2d(fig, ax, save=save, name=name)

    def wire(self, AA, ext, isFourier=True, tt=None, skipRate=1,
             size=[8, 6], labs=[r'$x$', r'$t$', r'$|A|$'], c='k',
             axisLabelSize=20, tickSize=None, save=False, name='out.png'):
        """
        plot the fence plot
        """
        if isFourier:
            AA =self.cgl.Fourier2Config(AA)
        Aamp = np.abs(AA)
        Aamp = Aamp[::skipRate, :]
        rows, cols = Aamp.shape
        X = np.linspace(ext[0], ext[1], cols)
        if tt is None:
            Y = np.linspace(ext[2], ext[3], rows)
        else:
            Y = tt[::skipRate]
        fig, ax = pl3d(size=size, labs=labs, axisLabelSize=axisLabelSize, tickSize=tickSize)
        for i in range(Aamp.shape[0]):
            ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c=c, alpha=1)

        ax3d(fig, ax, save=save, name=name)

    def sliceTime(self, t):
        n = len(t)
        hs = t[1:] - t[:-1]
        hmax = np.max(hs)
        idx = [0]
        s = 0
        for i in range(n-1):
            s += hs[i]
            if(s >= hmax):
                idx.append(i)
                s = 0
        return idx

class CQCGLreq(CQCGLBase):
    """
    relative equilibrium related 
    """
    def __init__(self, cgl=None):
        CQCGLBase.__init__(self, cgl)
    
        
    def read(self, fileName, groupName, sub=False, flag=0):
        """
        sub : is subspace ?
        """
        f = h5py.File(fileName, 'r')
        req = '/' + groupName + '/'
        a = f[req+'a'].value
        wth = f[req+'wth'].value if not sub else None
        wphi = f[req+'wphi'].value
        err = f[req+'err'].value
        if flag == 1:
            e = f[req+'er'].value + 1j*f[req+'ei'].value
        if flag == 2:
            e = f[req+'er'].value + 1j*f[req+'ei'].value
            v = f[req+'vr'].value + 1j*f[req+'vi'].value
        f.close()
        
        
        if flag == 0:
            return a, wth, wphi, err
        if flag == 1:
            return a, wth, wphi, err, e
        if flag == 2:
            return a, wth, wphi, err, e, v

    def readDi(self, fileName, di, index, flag=0):
        groupName = format(di, '.6f') + '/' + str(index)
        return self.read(fileName, groupName, flag)
        
    def eigReq(self, a0, wth0, wphi0, sub=False):
        if sub:
            stabMat = self.cgl.stabReq(a0, wphi0).T 
        else:
            stabMat = self.cgl.stabReq(a0, wth0, wphi0).T 
        e, v = LA.eig(stabMat)
        e, v = sortByReal(e, v)
        v = v.T.copy()

        return e, v

    def getAxes(self, fileName, Bi, Gi, index, flag):
        a, wth, wphi, err, e, v = self.read(fileName, self.toStr(Bi, Gi, index), flag=2)
        aH = self.cgl.orbit2slice(a, flag)[0]
        vrH = self.cgl.ve2slice(v.real.copy(), a, flag)
        viH = self.cgl.ve2slice(v.imag.copy(), a, flag)
        
        return e, aH, vrH + 1j*viH
        

class CQCGLrpo(CQCGLBase):

    def __init__(self, cgl=None):
        CQCGLBase.__init__(self, cgl)

    def read(self, fileName, groupName, flag=0):
        """
        read rpo.
        
        flag : = 0 : only load basic initial condition
               = 1 : also load multiplier
               = 2 : load multiplier and eigenvectors

        Example usage:
        >> rpo = CQCGLrpo(cgl)
        >> a0, T, nstp, th0, phi0, err = rpo.read(f, rpo.toStr(Bi, Gi, index), 0)
        """
        f = h5py.File(fileName, 'r')
        req = '/' + groupName + '/'
        x = f[req+'x'].value
        T = f[req+'T'].value
        nstp = f[req+'nstp'].value
        th = f[req+'th'].value
        phi = f[req+'phi'].value
        err = f[req+'err'].value
        if flag == 1:
            e = f[req+'er'].value + 1j*f[req+'ei'].value
        if flag == 2:
            e = f[req+'er'].value + 1j*f[req+'ei'].value
            v = f[req+'v'].value
        f.close()

        if flag == 0:
            return x, T, nstp, th, phi, err
        elif flag == 1:
            return x, T, nstp, th, phi, err, e
        elif flag == 2:
            return x, T, nstp, th, phi, err, e, v
        else :
            print "invalid flag"
    
    def readAll(self, fileName, index, hasEV):
        f = h5py.File(fileName, 'r')
        gs = f.keys()
        f.close()
        xx = []                     # all rpo
        dis = []                    # all di
        for i in gs:
            di = float(i)
            dis.append(di)
            if hasEV:
                x = cqcglReadEVdi(fileName, di, index)
            else:
                x = cqcglReaddi(fileName, di, index)
            xx.append(x)
        return dis, xx

    def save(self, fileName, groupName, x, T, nstp, th, phi, err, e=None, v=None):
        """
        save rpo.
        
        Example usage:
        >> rpo = CQCGLrpo(cgl)
        >> rpo.save(f, rpo.toStr(Bi, Gi, index), x, T, nstp, th, phi, err)
        """
        f = h5py.File(fileName, 'a')
        rpo = f.create_group(groupName)
        rpo.create_dataset("x", data=x)
        rpo.create_dataset("T", data=T)
        rpo.create_dataset("nstp", data=nstp)
        rpo.create_dataset("th", data=th)
        rpo.create_dataset('phi', data=phi)
        rpo.create_dataset('err', data=err)
        if e is not None:
            rpo.create_dataset('er', data=e.real)
            rpo.create_dataset('ei', data=e.imag)
        if v is not None:
            rpo.create_dataset('v', data=v)
        f.close()

    def move(self, inFile, ingroup, outFile, outgroup, flag=0):
        e, v = None, None
        pack = self.read(inFile, ingroup, flag)
        if flag == 0:
            x, T, nstp, th, phi, err = pack
        elif flag == 1:
            x, T, nstp, th, phi, err, e = pack
        elif flag == 2:
            x, T, nstp, th, phi, err, e, v = pack
        else:
            print "error of move"
            
        self.save(outFile, outgroup, x, T, nstp, th, phi, err, e, v)


#===================================================

def plotConfigSurface(AA, ext, barTicks=[2, 4], colortype='jet',
                      percent='5%', size=[7, 5], axisLabelSize=25,
                      save=False, name='out.png'):
    """
    plot the color map of the states
    """
    Aamp = np.abs(AA)
    
    X = np.linspace(ext[0], ext[1], Aamp.shape[1])
    Y = np.linspace(ext[2], ext[3], Aamp.shape[0])
    X, Y = np.meshgrid(X, Y)
    
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111, projection='3d')
    surf = ax.plot_surface(X, Y, Aamp, rstride=1, cstride=1,
                           cmap=plt.get_cmap(colortype),
                           linewidth=0, antialiased=False)

    fig.colorbar(surf, fraction=0.05, shrink=0.6, aspect=20, ticks=barTicks)
    
    ax.set_xlabel(r'$x$', fontsize=axisLabelSize)
    ax.set_ylabel(r'$t$', fontsize=axisLabelSize)
    ax.set_zlabel(r'$|A|$', fontsize=axisLabelSize)

    # dr = make_axes_locatable(ax)
    # cax = dr.append_axes('right', size=percent, pad=0.05)
    # plt.colorbar(surf, cax=cax, ticks=barTicks)
    fig.tight_layout(pad=0)
    if save:
        plt.savefig(name)
        plt.close()
    else:
        plt.show(block=False)


def plotConfigSurfaceFourier(cgl, aa, ext, barTicks=[2, 7],
                             colortype='jet',
                             percent='5%', size=[7, 5],
                             axisLabelSize=25,
                             save=False, name='out.png'):
    plotConfigSurface(cgl.Fourier2Config(aa), ext, barTicks,
                      colortype, percent, size,
                      axisLabelSize,
                      save, name)


def plotConfigWire(AA, ext, barTicks=[2, 7], size=[7, 6], axisLabelSize=25,
                   tickSize=15, c='r',
                   save=False, name='out.png'):
    """
    plot the meshframe plot
    """
    Aamp = abs(AA)
    
    X = np.linspace(ext[0], ext[1], Aamp.shape[1])
    Y = np.linspace(ext[2], ext[3], Aamp.shape[0])
    X, Y = np.meshgrid(X, Y)
    
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111, projection='3d')
    #ax.plot_wireframe(X, Y, Aamp)
    for i in range(Aamp.shape[0]):
        ax.plot(X[i], Y[i], Aamp[i], c=c, alpha=1)
    ax.set_xlabel(r'$x$', fontsize=axisLabelSize)
    ax.set_ylabel(r'$t$', fontsize=axisLabelSize)
    ax.set_zlabel(r'$|A|$', fontsize=axisLabelSize)

    if tickSize is not None:
        ax.tick_params(axis='both', which='major', labelsize=tickSize)

    fig.tight_layout(pad=0)
    if save:
        plt.savefig(name)
        plt.close()
    else:
        plt.show(block=False)
    

def plotConfigWireFourier(cgl, aa, ext, barTicks=[2, 7], size=[7, 6],
                          axisLabelSize=25, tickSize=15, c='r',
                          save=False, name='out.png'):
    plotConfigWire(cgl.Fourier2Config(aa), ext, barTicks, size,
                   axisLabelSize, tickSize, c, save, name)
    


def plotPhase(cgl, aa, ext, barTicks=[-3, 0, 3],
              colortype='jet',
              percent='5%', size=[4, 5],
              save=False, name='out.png'):
    """
    plot phase of filed A in cqcgl
    """
    phi = cgl.Fourier2Phase(aa)
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    im = ax.imshow(phi, cmap=plt.get_cmap(colortype), extent=ext,
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size=percent, pad=0.05)
    bar = plt.colorbar(im, cax=cax, ticks=barTicks)
    fig.tight_layout(pad=0)
    if save:
        plt.savefig(name)
        plt.close()
    else:
        plt.show(block=False)
    

def PoincareLinearInterp(x, getIndex=False):
    """
    x has dimension [N x 3]. The Poincare section is defined
    as x[i, 0] = 0. Linear interpolation is used to obtain
    the intersection points.

    (y - y1) / (0 - x1) = (y2 - y1) / (x2 - x1)
    (z - z1) / (0 - x1) = (z2 - z1) / (x2 - x1)
    """
    N, M = x.shape
    points = np.zeros((0, M-1))
    index = np.zeros((0,), dtype=np.int)
    ratios = np.zeros((0,))
    for i in range(N-1):
        if x[i, 0] < 0 and x[i+1, 0] >= 0:
            ratio = -x[i, 0] / (x[i+1, 0] - x[i, 0])
            y = (x[i+1, 1] - x[i, 1]) * ratio + x[i, 1]
            z = (x[i+1, 2] - x[i, 2]) * ratio + x[i, 2]
            points = np.vstack((points, np.array([y, z])))
            index = np.append(index, i)
            ratios = np.append(ratios, ratio)
    if getIndex:
        return points, index, ratios
    else:
        return points


def getCurveIndex(points):
    """
    Obtain the curvalinear Index of a set of points.
    
    parameter:
    points   :  each row is a point
    """
    n = points.shape[0]         # number of points
    indices = range(n)
    sortedIndices = []

    norms = [np.linalg.norm(points[i]) for i in range(n)]
    start = np.argmin(norms)
    sortedIndices.append(start)
    indices.remove(start)
    
    for i in range(n-1):
        last = sortedIndices[-1]
        norms = [np.linalg.norm(points[i] - points[last]) for i in indices]
        minimal = indices[np.argmin(norms)]  # careful
        sortedIndices.append(minimal)
        indices.remove(minimal)

    return sortedIndices


def getCurveCoor(points):
    """
    Obtain the curvalinear coordinate of a set of points.
    
    parameter:
    points   :  each row is a point
    """
    n = points.shape[0]         # number of points
    indices = getCurveIndex(points)
    dis = np.empty(n)

    dis[0] = np.linalg.norm(points[indices[0]])
    for i in range(1, n):
        dis[i] = np.linalg.norm(points[indices[i]] - points[indices[i-1]])

    return dis
   
##################################################
#            2d CQCGL related                    #
##################################################


class CQCGL2dPlot():

    def __init__(self, dx, dy):
        self.dx = dx
        self.dy = dy

    def load(self, fileName, i, flag=1):
        """
        Load one state in the original storage order

        Parameters
        ==========
        flag : what to return
        """
        f = h5py.File(fileName, 'r')
        ds = '/' + format(i, '06d') + '/'
        if flag == 1 or flag == 0:
            a = f[ds+'ar'].value + 1j*f[ds+'ai'].value
        if flag == 2 or flag == 0:
            v = f[ds+'vr'].value + 1j*f[ds+'vi'].value

        f.close()

        if flag == 0:
            return a, v
        elif flag == 1:
            return a
        elif flag == 2:
            return v

    def loadSeq(self, fileName, x, y, ids):
        """
        load a sequence of points but only at location (x, y)
        Avoid using the whole mesh since it is slow.

        Parameters
        ==========
        x, y : the x and y location of the mesh
        """
        n = len(ids)
        data = np.zeros(n, dtype=np.complex)
        f = h5py.File(fileName, 'r')
        for i in ids:
            ds = '/' + format(i, '06d') + '/'
            data[i] = f[ds+'ar'][x, y] + 1j*f[ds+'ai'][x, y]
        f.close()
        return data

    def oneState(self, cgl, a, save=False, name='out.png',
                     colortype='jet', percent=0.05, size=[7, 5],
                     barTicks=None, axisLabelSize=25,
                     plotType=0):
        """
        Parameters
        ==========
        plotType : 0 => heat plot
                   1 => 3d mesh plot
                   else => both together
        """
        A = cgl.Fourier2Config(a)
        aA = np.abs(A).T

        if plotType == 0:
            fig, ax = pl2d(size=size, labs=[None, None],
                           axisLabelSize=axisLabelSize)
            ax.grid('on')
            im = ax.imshow(aA, cmap=plt.get_cmap(colortype), aspect='equal',
                           origin='lower', extent=[0, self.dx, 0, self.dy])
            dr = make_axes_locatable(ax)
            cax = dr.append_axes('right', size=percent, pad=0.05)
            if barTicks is not None:
                plt.colorbar(im, cax=cax, ticks=barTicks)
            else:
                plt.colorbar(im, cax=cax)
            ax2d(fig, ax, save=save, name=name)
            # plotMat(aA, save=save, name=name)

        else:
            X = np.linspace(0, self.dx, aA.shape[1])
            Y = np.linspace(0, self.dy, aA.shape[0])
            X, Y = np.meshgrid(X, Y)

            if plotType == 1:
                fig, ax = pl3d(size=size, labs=[r'$x$', r'$y$', r'$|A|$'],
                               axisLabelSize=axisLabelSize)
                surf = ax.plot_surface(X, Y, aA, rstride=10, cstride=10,
                                       cmap=plt.get_cmap(colortype),
                                       linewidth=0, antialiased=False)

                if barTicks is not None:
                    fig.colorbar(surf, fraction=percent, shrink=0.6, aspect=20,
                                 ticks=barTicks)
                else:
                    fig.colorbar(surf, fraction=percent, shrink=0.6, aspect=20,
                                 ticks=barTicks)

                ax3d(fig, ax, save=save, name=name)

            else:
                fig = plinit(size)
                ax1 = ax3dinit(fig, 121, labs=[r'$x$', r'$y$', r'$|A|$'],
                               axisLabelSize=axisLabelSize)
                ax2 = ax2dinit(fig, 122, labs=[None, None])
                ax2.grid('on')
                surf = ax1.plot_surface(X, Y, aA, rstride=10, cstride=10,
                                        cmap=plt.get_cmap(colortype),
                                        linewidth=0, antialiased=False)

                im = ax2.imshow(aA, cmap=plt.get_cmap(colortype),
                                aspect='equal', origin='lower',
                                extent=[0, self.dx, 0, self.dy])
                dr = make_axes_locatable(ax2)
                cax = dr.append_axes('right', size=percent, pad=0.05)
                if barTicks is not None:
                    plt.colorbar(im, cax=cax, ticks=barTicks)
                else:
                    plt.colorbar(im, cax=cax)
                ax2d(fig, ax2, save=save, name=name)

    def makeMovie(self, folderName, name='out.mp4'):
        """
        Parameters
        ==========
        folderName : name of the figure folder
        """
        files = "'" + folderName + '/*.png' + "'"
        command = ('ffmpeg -f image2 -r 6 -pattern_type glob -i' +
                   ' ' + files + ' ' + name)
        os.system(command)

    def savePlots(self, cgl, f1, f2, sids=None, plotType=0, size=[7, 5]):
        """
        Parameters
        ==========
        f1 : h5 data file
        f2 : save folder name
        sids : a list which contains the ids of the states
               if it is None, then all states will be loaded
        """
        if os.path.exists(f2):
            print 'folder already exists'
        else:
            os.makedirs(f2)
            if sids == None:
                f = h5py.File(f1, 'r')
                sids = range(len(f.keys()))
                f.close()

            for i in sids:
                name = f2+'/a'+format(i, '06d')
                a = self.load(f1, i)
                self.oneState(cgl, a, save=True, size=size,
                              name=name, plotType=plotType)

    def saveReq(self, fileName, groupName, a, wthx, wthy, wphi, err):
        f = h5py.File(fileName, 'a')
        req = f.create_group(groupName)
        req.create_dataset("ar", data=a.real)
        req.create_dataset("ai", data=a.imag)
        req.create_dataset("wthx", data=wthx)
        req.create_dataset("wthy", data=wthy)
        req.create_dataset('wphi', data=wphi)
        req.create_dataset('err', data=err)
        f.close()

    def toStr(self, Bi, Gi, index):
        if abs(Bi) < 1e-6:
            Bi = 0
        if abs(Gi) < 1e-6:
            Gi = 0
        return (format(Bi, '013.6f') + '/' + format(Gi, '013.6f') +
                '/' + str(index))

    def loadReq(self, fileName, groupName):
        f = h5py.File(fileName, 'r')
        req = '/' + groupName + '/'
        a = f[req+'ar'].value + 1j*f[req+'ai'].value
        wthx = f[req+'wthx'].value
        wthy = f[req+'wthy'].value
        wphi = f[req+'wphi'].value
        err = f[req+'err'].value
        f.close()

        return a, wthx, wthy, wphi, err
<file_sep>// to compile
//
// first use
// mpicxx --showme -O3 test_CQCGL1dRpo_mpi.cc  -L../../lib -I../../include -I$EIGEN -std=c++11 -lCQCGL1dRpo -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm
//
// then change g++ to h5c++
// 
// h5c++ -O3 test_CQCGL1dRpo_mpi.cc -L../../lib -I../../include -I/usr/local/home/xiong/apps/eigen/include/eigen3 -std=c++11 -lCQCGL1dRpo -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -L/usr//lib -L/usr/lib/openmpi/lib -lmpi_cxx -lmpi -ldl -lhwloc 


#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <ctime>
#include <mpi.h>

#include "CQCGL1dReq.hpp"
#include "CQCGL1dRpo.hpp"

using namespace std; 
using namespace Eigen;
using namespace iterMethod;

#define cee(x) (cout << (x) << endl << endl)

#define CASE_10

int main(int argc, char **argv){
    
    cout.precision(15);
    GMRES_IN_PRINT_FREQUENCE = 50;
    HOOK_PRINT_FREQUENCE = 1;
    GMRES_OUT_PRINT = false;
    
#ifdef CASE_10
    //====================================================================== 
    // find limit cycles by varying Bi and Gi
    const int N = 1024;
    const int L = 50;
    double Bi = 2.0;
    double Gi = -5.6;

    int id = 1;
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
	
    string file = "../../data/cgl/rpoBiGi2.h5";
    double stepB = 0.1;
    int NsB = 38;

    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = NsB / num;
    int rem = NsB - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////

    for (int i = p_start; i < p_end; i++){
	cgl.Bi = Bi + i*stepB;
	cgl.findRpoParaSeq(file, 1, 0.1, 55, false);
    }
    

    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////

#endif

    return 0;
}
<file_sep>#include "CQCGL1dRpo.hpp"
#include <functional>   // std::bind
#include "myH5.hpp"

#define cee(x) (cout << (x) << endl << endl)

namespace ph = std::placeholders;

using namespace denseRoutines;
using namespace sparseRoutines;
using namespace iterMethod;
using namespace Eigen;
using namespace std;
using namespace MyH5;


//////////////////////////////////////////////////////////////////////
//                      constructor                                 //
//////////////////////////////////////////////////////////////////////

// A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
CQCGL1dRpo::CQCGL1dRpo(int N, double d,
		       double Mu, double Dr, double Di, double Br, double Bi, 
		       double Gr, double Gi, int dimTan):
    CQCGL1d(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}

// A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
CQCGL1dRpo::CQCGL1dRpo(int N, double d, 
		       double b, double c, double dr, double di, 
		       int dimTan):
    CQCGL1d(N, d, b, c, dr, di, dimTan){}
    
// iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
CQCGL1dRpo::CQCGL1dRpo(int N, double d,
		       double delta, double beta, double D, double epsilon,
		       double mu, double nu, int dimTan) :
    CQCGL1d(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

CQCGL1dRpo::~CQCGL1dRpo(){}

CQCGL1dRpo & CQCGL1dRpo::operator=(const CQCGL1dRpo &x){
    return *this;
}

//////////////////////////////////////////////////////////////////////
//                      member functions                            //
//////////////////////////////////////////////////////////////////////
std::string 
CQCGL1dRpo::toStr(double x){
    //  avoid possibilty that 000000.000000 or -00000.000000
    if (fabs(x) < 1e-6) x = 0; 
    char buffer [20];
    sprintf (buffer, "%013.6f", x);
    return std::string(buffer);
}

std::string
CQCGL1dRpo::toStr(double x, double y, int id){
    return toStr(x) + '/' + toStr(y) + '/' + to_string(id);
}

/**
 * @note group should be a new group
 * [x, T,  nstp, theta, phi, err]
 */
void CQCGL1dRpo::write(const string fileName, const string groupName,
		       const MatrixXd &x, const double T, const int nstp,
		       const double th, const double phi, double err){

    H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";

    writeMatrixXd(file, DS + "x", x);
    writeScalar<double>(file, DS + "T", T);
    writeScalar<int>(file, DS + "nstp", nstp);
    writeScalar<double>(file, DS + "th", th);
    writeScalar<double>(file, DS + "phi", phi);
    writeScalar<double>(file, DS + "err", err);
}

void CQCGL1dRpo::write2(const std::string fileName, const string groupName, 
			const MatrixXd &x, const int nstp, double err){	
    MatrixXd tmp = x.bottomRows(3).rowwise().sum();
    double T = tmp(0);
    double th = tmp(1);
    double phi = tmp(2);
    
    write(fileName, groupName, x, T, nstp, th, phi, err);
}

std::tuple<MatrixXd, double, int, double, double, double>
CQCGL1dRpo::read(const string fileName, const string groupName){
    H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";
    
    return make_tuple(readMatrixXd(file, DS + "x"),
		      readScalar<double>(file, DS + "T"),
		      readScalar<int>(file, DS + "nstp"),
		      readScalar<double>(file, DS + "th"),
		      readScalar<double>(file, DS + "phi"),
		      readScalar<double>(file, DS + "err")
		      );
    
}

/**
 * @brief move rpo from one file, group to another file, group
 */
void
CQCGL1dRpo::move(string infile, string ingroup, 
		    string outfile, string outgroup, int flag){
    MatrixXd x;
    double T, th, phi, err;
    int nstp;

    VectorXcd e;
    MatrixXd v;

    std::tie(x, T, nstp, th, phi, err) = read(infile, ingroup);
    write(outfile, outgroup, x, T, nstp, th, phi, err);
    
    if (flag == 1 || flag == 2){
	e = readE(infile, ingroup);
	writeE(outfile, outgroup, e);
    }
    
    if (flag == 2) {
	v = readV(infile, ingroup);
	writeV(outfile, outgroup, v);
    }
    
}


VectorXcd 
CQCGL1dRpo::readE(std::string fileName, const std::string groupName){
    H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";
    VectorXd er = readMatrixXd(file, DS + "er");
    VectorXd ei = readMatrixXd(file, DS + "ei");
    VectorXcd e(er.size());
    e.real() = er;
    e.imag() = ei;

    return e;
}

MatrixXd 
CQCGL1dRpo::readV(std::string fileName, const std::string groupName){
    H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";
    return readMatrixXd(file, DS + "v");
}

void 
CQCGL1dRpo::writeE(std::string fileName, const std::string groupName, 
		   const VectorXcd &e){
    H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "er", e.real());
    writeMatrixXd(file, DS + "ei", e.imag());
}


void 
CQCGL1dRpo::writeV(std::string fileName, const std::string groupName, 
		   const MatrixXd &v){
    H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "v", v);
}

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


//======================================================================

/* 
 * @brief multishooting form [f(x_0, t) - x_1, ... g*f(x_{M-1},t) - x_0]
 * @param[in] x   [Ndim * M + 3, 1] dimensional vector: (x, t, theta, phi)
 * @return    vector F(x, t) =
 *               |   f(x_0, t) -x_1     |
 *               |   f(x_1, t) -x_2     |
 *               |     ......           |
 *               | g*f(x_{M-1}, t) - x_0|
 *               |       0              |
 *               |       0              |
 *               |       0              |
 *
 */
VectorXd CQCGL1dRpo::MFx(const VectorXd &x, int nstp){
    assert( (x.size() - 3) % Ndim == 0 );
    int m = (x.size() - 3) / Ndim;
	
    Vector3d t = x.tail<3>();	   /* T, theta, phi */
    assert(t(0) > 0);		   /* make sure T > 0 */
    VectorXd F(VectorXd::Zero(Ndim * m + 3));

    for(size_t i = 0; i < m; i++){
	VectorXd fx = intg(x.segment(i*Ndim, Ndim), t(0)/nstp/m, nstp, nstp).rightCols<1>();
	if(i != m-1){		// the first m-1 vectors
	    F.segment(i*Ndim, Ndim) = fx - x.segment((i+1)*Ndim, Ndim);
	}
	else{			// the last vector
	    F.segment(i*Ndim, Ndim) = Rotate(fx, t(1), t(2)).matrix() - x.head(Ndim);
	}
    }
	
    return F;
}
    
/* 
 * @brief get the multishooting product J * dx. Dimension [nstp*m+3, 1]
 * @see MFx()
 */
VectorXd CQCGL1dRpo::MDFx(const VectorXd &x, const VectorXd &dx, int nstp){
    assert( (x.size() - 3) % Ndim == 0 );
    int m = (x.size() - 3) / Ndim;

    Vector3d t = x.tail<3>();
    Vector3d dt = dx.tail<3>();
    assert(t(0) > 0); 		/* make sure T > 0 */
    VectorXd DF(VectorXd::Zero(Ndim * m + 3));
    
    for(size_t i = 0; i < m; i++){
	ArrayXd xt = x.segment(i*Ndim, Ndim);
	ArrayXd dxt = dx.segment(i*Ndim, Ndim);
	ArrayXXd tmp = intgv(xt, dxt, t(0)/nstp/m, nstp); /* f(x, t) and J(x, t)*dx */
	
	VectorXd v1 = velocity(xt); /* v(x) */
	VectorXd v2 = velocity(tmp.col(0));   /* v(f(x, t)) */
	VectorXd t1 = transTangent(xt);
	VectorXd t2 = phaseTangent(xt);

	// update the last 3 elements
	DF(m * Ndim) += v1.dot(dxt.matrix());
	DF(m * Ndim + 1) += t1.dot(dxt.matrix());
	DF(m * Ndim + 2) += t2.dot(dxt.matrix());
	
	if(i != m-1){
	    DF.segment(i*Ndim, Ndim) = tmp.col(1).matrix()
		- dx.segment((i+1)*Ndim , Ndim)
		+ 1.0 / m * v2 * dt(0);
	}
	else{
	    ArrayXd gfx = Rotate(tmp.col(0), t(1), t(2)); /* g(theta, phi)*f(x, t) */
	    VectorXd gJx = Rotate(tmp.col(1), t(1), t(2)); /* g(theta, phi)*J(x,t)*dx */
	    DF.segment(i*Ndim, Ndim) = gJx
		- dx.segment(0, Ndim)
		+ 1.0/m * Rotate(v2, t(1), t(2)).matrix() * dt(0)
		+ transTangent(gfx).matrix() * dt(1)
		+ phaseTangent(gfx).matrix() * dt(2)
		;
	}
    }
    
    return DF;
    
}

/**
 * @brief         form [g*f(x,t) - x, ...]
 *
 * Form the difference vector, which consists of m pieces, each piece
 * correspond to (x, t, theta, phi). If m = 1, then it reduces to single
 * shooting.
 * 
 * @param[in] x   [(Ndim + 3)*m, 1] dimensional vector. 
 * @return        vector F_i(x, t) =
 *                  | g*f(x, t) - x|
 *                  |       0      |
 *                  |       0      |
 *                  |       0      |
 *                for i = 1, 2, ..., m
 */
VectorXd CQCGL1dRpo::MFx2(const VectorXd &x, int nstp){
    int n = Ndim + 3;
    assert( x.size() % n == 0 );
    int m = x.size() / n;

    VectorXd F(VectorXd::Zero(n*m));
	
    for(int i = 0; i < m; i++){
	VectorXd xi = x.segment(n*i, n);
	int j = (i+1) % m;
	VectorXd xn = x.segment(n*j, n);
	
	double t = xi(Ndim);
	double th = xi(Ndim+1);
	double phi = xi(Ndim+2);	
	assert(t > 0);
	
	VectorXd fx = intg(xi.head(Ndim), t/nstp, nstp, nstp).rightCols<1>();
	
	F.segment(i*n, Ndim) = Rotate(fx, th, phi).matrix() - xn.head(Ndim);
    }
	
    return F;
}

/**
 * @brief get the product J * dx
 *
 * If m = 1, then it reduces to single shooting
 *
 * Here J_i  = | g*J(x, t),      g*v(f(x,t)),  g*t1(f(x,t)),  g*t2(f(x,t))| 
 *             |     v(x),          0             0                  0    |
 *             |     t1(x),         0             0                  0    |
 *             |     t2(x),         0             0                  0    |
 */
VectorXd CQCGL1dRpo::MDFx2(const VectorXd &x, const VectorXd &dx, int nstp){
    int n = Ndim + 3;
    assert( x.size() % n == 0 );
    int m = x.size() / n;
	
    VectorXd DF(VectorXd::Zero(n*m));

    for (int i = 0; i < m; i++) {
	VectorXd xi = x.segment(i*n, n);
	VectorXd dxi = dx.segment(i*n, n);
	int j = (i+1) % m;
	VectorXd dxn = dx.segment(j*n, n);
	
	double t = xi(Ndim);
	double th = xi(Ndim+1);
	double phi = xi(Ndim+2);
	assert( t > 0 );
	double dt = dxi(Ndim);
	double dth = dxi(Ndim+1);
	double dphi = dxi(Ndim+2);
	
	MatrixXd tmp = intgv(xi.head(Ndim), dxi.head(Ndim), t/nstp, nstp);

	VectorXd gfx = Rotate(tmp.col(0), th, phi);
	VectorXd gJx = Rotate(tmp.col(1), th, phi);
	
	VectorXd v = velocity(xi.head(Ndim));
	VectorXd vgf = velocity(gfx); 

	VectorXd t1 = transTangent(xi.head(Ndim));
	VectorXd tgf1 = transTangent(gfx);

	VectorXd t2 = phaseTangent(xi.head(Ndim));
	VectorXd tgf2 = phaseTangent(gfx);
	
	DF.segment(i*n, Ndim) = gJx + vgf*dt + tgf1*dth + tgf2*dphi - dxn.head(Ndim);
	DF(i*n+Ndim) = v.dot(dxi.head(Ndim));
	DF(i*n+Ndim+1) = t1.dot(dxi.head(Ndim));
	DF(i*n+Ndim+2) = t2.dot(dxi.head(Ndim));
	
    }
    
    return DF;

}

//======================================================================
#if 0

/**
 * @brief find rpo in cqcgl 1d system
 *
 * @return [x, T, theta, phi, err]
 */
std::tuple<VectorXd, double, double, double, double>
CQCGL1dRpo::findRPO(const VectorXd &x0, const double T,
		    const double th0, const double phi0,
		    const double tol,
		    const int btMaxIt,
		    const int maxit,
		    const double eta0,
		    const double t,
		    const double theta_min,
		    const double theta_max,
		    const int GmresRestart,
		    const int GmresMaxit){
    assert(x0.size() == Ndim);
    auto fx = std::bind(&CQCGL1dRpo::Fx, this, ph::_1);
    auto dfx = std::bind(&CQCGL1dRpo::DFx, this, ph::_1, ph::_2);
    VectorXd x(Ndim+3);
    x << x0, T, th0, phi0;
    auto result = InexactNewtonBacktrack(fx, dfx, x, tol, btMaxIt, maxit, eta0,
					 t, theta_min, theta_max, GmresRestart, GmresMaxit);
    if(std::get<2>(result) != 0){
	fprintf(stderr, "RPO not converged ! \n");
    }
    return std::make_tuple(std::get<0>(result).head(Ndim), /* x */
			   std::get<0>(result)(Ndim),	   /* T */
			   std::get<0>(result)(Ndim+1),	   /* theta */
			   std::get<0>(result)(Ndim+2),	   /* phi */
			   std::get<1>(result).back()	   /* err */
			   );
}

/**
 * @brief find rpo in cqcgl 1d system
 *
 * @return [x, T, theta, phi, err]
 */
std::tuple<MatrixXd, double, double, double, double>
CQCGL1dRpo::findRPOM(const MatrixXd &x0, const double T,
		     const double th0, const double phi0,
		     const double tol,
		     const int btMaxIt,
		     const int maxit,
		     const double eta0,
		     const double t,
		     const double theta_min,
		     const double theta_max,
		     const int GmresRestart,
		     const int GmresMaxit){
    assert(x0.cols() == M && x0.rows() == Ndim);
    auto fx = std::bind(&CQCGL1dRpo::MFx, this, ph::_1);
    auto dfx = std::bind(&CQCGL1dRpo::MDFx, this, ph::_1, ph::_2);
    
    // initialize input 
    VectorXd x(M * Ndim + 3);
    MatrixXd tmp(x0);
    tmp.resize(M * Ndim, 1);
    x << tmp, T, th0, phi0;
    
    auto result = InexactNewtonBacktrack(fx, dfx, x, tol, btMaxIt, maxit, eta0,
					 t, theta_min, theta_max, GmresRestart, GmresMaxit);
    if(std::get<2>(result) != 0){
	fprintf(stderr, "RPO not converged ! \n");
    }

    MatrixXd tmp2(std::get<0>(result).head(M*Ndim));
    tmp2.resize(Ndim, M);
    return std::make_tuple(tmp2, /* x */
			   std::get<0>(result)(M*Ndim),	  /* T */
			   std::get<0>(result)(M*Ndim+1), /* theta */
			   std::get<0>(result)(M*Ndim+2), /* phi */
			   std::get<1>(result).back()	  /* err */
			   );
}

/**
 * @brief single shooting to find rpo with GMRES HOOK algorithm 
 *
 * @param[in]  x0            initial guess state
 * @param[in]  T             initial guess period
 * @param[in]  th0           initial guess of translation angle
 * @param[in]  phi0          initial guess of phase angle
 * @param[in]  tol           tolerance of the orbit ||x(0)-X(T)||
 * @param[in]  minRD         mininal relative descrease at each step
 * @param[in]  maxit         maximal number of iterations for Newton steps
 * @param[in]  maxInnIt      maximal number of iterations for Hook steps
 * @param[in]  GmresRtol     relative tolerence of GMRES
 * @param[in]  GmresRestart  maximal Krylov subspace dimension => inner loop size
 * @param[in]  GmresMaxit    maximal outer iteration number
 * @return     [x, T, theta, phi, err]
 *
 * @see  findRPOM_hook() for multishooting method
 */
std::tuple<VectorXd, double, double, double, double>
CQCGL1dRpo::findRPO_hook(const VectorXd &x0, const double T,
			 const double th0, const double phi0,
			 const double tol,
			 const double minRD,
			 const int maxit,
			 const int maxInnIt,
			 const double GmresRtol,
			 const int GmresRestart,
			 const int GmresMaxit){
    assert(x0.size() == Ndim);
    auto fx = std::bind(&CQCGL1dRpo::Fx, this, ph::_1);
    auto dfx = std::bind(&CQCGL1dRpo::DFx, this, ph::_1, ph::_2);
    VectorXd x(Ndim + 3);
    x << x0, T, th0, phi0;
    
    auto result = Gmres0Hook(fx, dfx, x, tol, minRD, maxit, maxInnIt,
			     GmresRtol, GmresRestart, GmresMaxit,
			     true, 3);
    if(std::get<2>(result) != 0){
	fprintf(stderr, "RPO not converged ! \n");
    }

    return std::make_tuple(std::get<0>(result).head(Ndim), /* x */
			   std::get<0>(result)(Ndim),	   /* T */
			   std::get<0>(result)(Ndim+1),	   /* theta */
			   std::get<0>(result)(Ndim+2),	   /* phi */
			   std::get<1>(result).back()	   /* err */
			   );
}



/**
 * @brief find rpo in cqcgl 1d system
 *
 * @return [x, T, theta, phi, err]
 * @see findRPO_hook() for single shooting method
 */
std::tuple<MatrixXd, double, double, double, double>
CQCGL1dRpo::findRPOM_hook(const MatrixXd &x0, const double T,
			  const double th0, const double phi0,
			  const double tol,
			  const double minRD,
			  const int maxit,
			  const int maxInnIt,
			  const double GmresRtol,
			  const int GmresRestart,
			  const int GmresMaxit){
    assert(x0.cols() == M && x0.rows() == Ndim);
    auto fx = std::bind(&CQCGL1dRpo::MFx, this, ph::_1);
    auto dfx = std::bind(&CQCGL1dRpo::MDFx, this, ph::_1, ph::_2);
    
    // initialize input 
    VectorXd x(M * Ndim + 3);
    MatrixXd tmp(x0);
    tmp.resize(M * Ndim, 1);
    x << tmp, T, th0, phi0;
    
    auto result = Gmres0Hook(fx, dfx, x, tol, minRD, maxit, maxInnIt,
			     GmresRtol, GmresRestart, GmresMaxit,
			     true, 3);
    if(std::get<2>(result) != 0){
	fprintf(stderr, "RPO not converged ! \n");
    }

    MatrixXd tmp2(std::get<0>(result).head(M*Ndim));
    tmp2.resize(Ndim, M);
    return std::make_tuple(tmp2, /* x */
			   std::get<0>(result)(M*Ndim),	  /* T */
			   std::get<0>(result)(M*Ndim+1), /* theta */
			   std::get<0>(result)(M*Ndim+2), /* phi */
			   std::get<1>(result).back()	  /* err */
			   );
}

#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// new version of F and DF, This version use a full multishooting method

VectorXd CQCGL1dRpo::calPre(const VectorXd &x, const VectorXd &dx){
    int n = Ndim + 3;
    assert( x.size() % n == 0 );
    int m = x.size() / n;

    VectorXd DF(VectorXd::Zero(n*m));
    
    for (int i = 0; i < m; i++) {
	VectorXd xi = x.segment(i*n, n);
	VectorXd dxi = dx.segment(i*n, n);

	double th = xi(Ndim+1);
	double phi = xi(Ndim+2);

	DF.segment(i*n, n) << 
	    Rotate(dxi.head(Ndim), -th, -phi),
	    dxi.tail(3);
    }

    return DF;
}

/// @return [ (x, T, th, phi), err, flag ]
std::tuple<MatrixXd, double, int>
CQCGL1dRpo::findRPOM_hook2(const MatrixXd &x0, 
			   const int nstp,
			   const double tol,
			   const double minRD,
			   const int maxit,
			   const int maxInnIt,
			   const double GmresRtol,
			   const int GmresRestart,
			   const int GmresMaxit){
    int n = Ndim + 3; 
    int m = x0.cols();
    assert( x0.rows() == n);

    auto fx = [this, nstp](const VectorXd &x){ return MFx2(x, nstp); };
    auto dfx = [this, nstp](const VectorXd &x, const VectorXd &dx){ return MDFx2(x, dx, nstp); };
    
    // initialize input 
    MatrixXd x(x0);
    x.resize(m * n, 1);
    

    // auto Pre = [this](const VectorXd &x, const VectorXd &dx){VectorXd p = calPre(x, dx); return p; };
    auto Pre = [this](const VectorXd &x, const VectorXd &dx){ return dx; };
    VectorXd xnew;
    std::vector<double> errs;
    int flag;
    std::tie(xnew, errs, flag) = Gmres0HookPre(fx, dfx, Pre, x, tol, minRD, maxit, maxInnIt,
    					       GmresRtol, GmresRestart, GmresMaxit,
    					       true, 3);
    // std::tie(xnew, errs, flag) = Gmres0Hook(fx, dfx, x, tol, minRD, maxit, maxInnIt,
    // 					    GmresRtol, GmresRestart, GmresMaxit,
    // 					    true, 3);
    if(flag != 0) fprintf(stderr, "RPO not converged ! \n");

    MatrixXd tmp(xnew);
    tmp.resize(n, m);
    return std::make_tuple(tmp,	errs.back(), flag );
}

/**
 * @brief find req with a sequence of Bi or Gi
 */ 
void 
CQCGL1dRpo::findRpoParaSeq(const std::string file, int id, double step, int Ns, bool isBi,
			   int nstpFlag, int paraNstp){
    double Bi0 = Bi;
    double Gi0 = Gi;
    
    MatrixXd x0;
    double T0, th0, phi0, err0;
    int nstp0;
    std::tie(x0, T0, nstp0, th0, phi0, err0) = read(file, toStr(Bi, Gi, id));
    
    MatrixXd x;
    double T, th, phi, err;
    int nstp, flag;

    int Nfail = 0;
    
    for (int i = 0; i < Ns; i++){
	if (isBi) Bi += step;
	else Gi += step;
	
	// if exist, use it as seed, otherwise find req
	if ( checkGroup(file, toStr(Bi, Gi, id), false) ){ 
	    std::tie(x0, T0, nstp0, th0, phi0, err0) = read(file, toStr(Bi, Gi, id));
	}
	else {
	    switch(nstpFlag){
	    case 1 : nstp = static_cast<int>( T0 / (1e-3*10) ) * 10; break; 
	    case 2 : nstp = nstp0 - paraNstp ; break; // change the same amount 
	    case 3 : nstp = paraNstp; break; // use a specific value
	    default : nstp = nstp0; // use previous nstp
	    }

	    fprintf(stderr, "Bi = %g Gi = %g nstp = %d T0 = %g\n", Bi, Gi, nstp, T0);

	    std::tie(x, err, flag) = findRPOM_hook2(x0, nstp, 8e-10, 1e-3, 50, 30, 1e-6, 300, 1);
	    if (flag == 0){
		write2(file, toStr(Bi, Gi, id), x, nstp, err);
		std::tie(x0, T0, nstp0, th0, phi0, err0) = read(file, toStr(Bi, Gi, id));
	    }
	    else {
		if(++Nfail == 3) break;		
	    }
	}
    }
    
    Bi = Bi0; 			// restore Bi, Gi
    Gi = Gi0;
}


#if 0

////////////////////////////////////////////////////////////////////////////////////////////////////
// use LM algorithm to find RPO

std::tuple<SpMat, SpMat, VectorXd> 
CQCGL1dRpo::calJJF(const VectorXd &x){
    int N = Ndim + 3;
    SpMat JJ(N*M, N*M);
    SpMat D(N*M, N*M);
    VectorXd df(VectorXd::Zero(N*M));
    
    MatrixXd F(MatrixXd::Zero(N, N));
    MatrixXd FF(N, N);
    MatrixXd FK(MatrixXd::Zero(N, N));
    MatrixXd KF(MatrixXd::Zero(N, N));

    std::vector<Tri> nzjj, nzd;
    nzjj.reserve(3*M*N*N);
    nzd.reserve(M*N);
    
    /////////////////////////////////////////
    // construct the JJ, Diag(JJ), JF
    for(int i = 0; i < M; i++){
	fprintf(stderr, "%d ", i);
	
	VectorXd xi = x.segment(i*N, N);
	int j = (i+1) % M;
	VectorXd xn = x.segment(j*N, N);
	
	double t = xi(Ndim);
	double th = xi(Ndim + 1);
	double phi = xi(Ndim + 2);
	assert( t > 0);

	cgl3.changeh( t/nstp ); 
	auto tmp = cgl3.intgj(xi.head(Ndim), nstp, nstp, nstp);
	ArrayXd fx = tmp.first.col(1);
	ArrayXXd &J = tmp.second;

	VectorXd gfx = cgl3.Rotate(fx, th, phi);
	
	df.segment(i*N, Ndim) = gfx - xn.head(Ndim);
	
	F.topLeftCorner(Ndim, Ndim) = cgl3.Rotate(J, th, phi);

	F.col(Ndim).head(Ndim) = cgl3.velocity(gfx);
	F.col(Ndim+1).head(Ndim) = cgl3.transTangent(gfx);
	F.col(Ndim+2).head(Ndim) = cgl3.phaseTangent(gfx); 
	
	F.row(Ndim).head(Ndim) = cgl3.velocity(xi.head(Ndim));
	F.row(Ndim+1).head(Ndim) = cgl3.transTangent(xi.head(Ndim)).transpose();
	F.row(Ndim+2).head(Ndim) = cgl3.phaseTangent(xi.head(Ndim)).transpose();
	
	FF = F.transpose() * F; 
	for(int i = 0; i < Ndim; i++) FF(i, i) += 1;
	
	FK.leftCols(Ndim) = -F.transpose().leftCols(Ndim);
	KF.topRows(Ndim) = -F.topRows(Ndim);
	
	std::vector<Tri> triFF = triMat(FF, i*N, i*N);
	std::vector<Tri> triFK = triMat(FK, i*N, j*N);
	std::vector<Tri> triKF = triMat(KF, j*N, i*N);
	std::vector<Tri> triD = triDiag(FF.diagonal(), i*N, i*N);
	    
	nzjj.insert(nzjj.end(), triFF.begin(), triFF.end());
	nzjj.insert(nzjj.end(), triFK.begin(), triFK.end());
	nzjj.insert(nzjj.end(), triKF.begin(), triKF.end());

	nzd.insert(nzd.end(), triD.begin(), triD.end());
    }

    JJ.setFromTriplets(nzjj.begin(), nzjj.end());
    D.setFromTriplets(nzd.begin(), nzd.end());

    return std::make_tuple(JJ, D, df);
    
}

std::tuple<MatrixXd, double>
CQCGL1dRpo::findRPOM_LM(const MatrixXd &x0, 
			const double tol,
			const int maxit,
			const int innerMaxit){
    int N = Ndim + 3;
    assert(x0.cols() == M && x0.rows() == N);
    auto fx = std::bind(&CQCGL1dRpo::MFx2, this, ph::_1);
    
    MatrixXd x(x0);
    x.resize(M * N, 1); 
    
    // SparseLU<SpMat> solver;
    SimplicialLDLT<SpMat> solver; 
    cqcglJJF<SpMat> jj(*this);
    auto result = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    
    if(std::get<2>(result) != 0) fprintf(stderr, "RPO not converged ! \n");
    
    MatrixXd tmp2(std::get<0>(result));
    tmp2.resize(N, M);
    return std::make_pair( tmp2, std::get<1>(result).back() );
}


#endif
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' MEXksint.cpp ksint.cc ksintM1.cc
 * -I../../include -I/usr/include/eigen3 
 * */
#include "ksintM1.hpp"
#include "mex.h"
#include "matrix.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>
using Eigen::ArrayXXd;
using Eigen::ArrayXd;
using Eigen::Map;

const int N = 32; 

/* ks full state space integrator without Jacobian */
static ArrayXXd ksf(double *a0, double d,  double h, int nstp, int np){
  KS ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  //ArrayXd v0(N-2); for(int i = 0 ; i < N-2; i++) v0(i) = a0[i];
  ArrayXXd aa = ks.intg(v0, nstp, np);
  return aa;
}

/* ks full state space integrator with Jacobian */
static std::pair<ArrayXXd, ArrayXXd>
ksfj(double *a0, double d,  double h, int nstp, int np, int nqr){
  KS ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  return ks.intgj(v0, nstp, np, nqr);
}

static std::tuple<ArrayXXd, VectorXd, VectorXd>
ksfDP(double *a0, double d, double h, int nstp, int np){
  KS ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  return ks.intgDP(v0, nstp, np);
}

static std::pair<ArrayXXd, ArrayXd>
ksfM1(double *a0, double d,  double h, int nstp, int np){
  KSM1 ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  //ArrayXd v0(N-2); for(int i = 0 ; i < N-2; i++) v0(i) = a0[i];
  return ks.intg(v0, nstp, np);
}

static std::pair<ArrayXXd, ArrayXd>
ksf2M1(double *a0, double d,  double h, double T, int np){
  KSM1 ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  //ArrayXd v0(N-2); for(int i = 0 ; i < N-2; i++) v0(i) = a0[i];
  return ks.intg2(v0, T, np);
}


void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
  double *a0 = mxGetPr(prhs[0]);
  double d = mxGetScalar(prhs[1]);
  double h = mxGetScalar(prhs[2]);
  int nstp = mxGetScalar(prhs[3]);
  int np = mxGetScalar(prhs[4]);
  int nqr = mxGetScalar(prhs[5]);
  mwSize isM1 = mxGetScalar(prhs[6]); /* isM1 =1: integration on the 1st
					 mode slice. */
  mwSize isT = mxGetScalar(prhs[7]); /* isT = 1: integration time on full
					state space. */
  double T = mxGetScalar(prhs[8]);
  mwSize isDP = mxGetScalar(prhs[9]); /* isDp = 1: integrate D and P too */
  mwSize Jacob = mxGetScalar(prhs[10]); /* Jacob = 1: integrate with Jacobian */

  if(isM1 == 0){
      if(isDP == 0){
	  if(Jacob == 0){
	      plhs[0] = mxCreateDoubleMatrix(N-2, nstp/np + 1, mxREAL);
	      //Map<ArrayXXd> aa(mxGetPr(plhs[0]), N-2, nstp/np + 1);
	      //aa = ksf(a0, d, h, nstp, np);
	      ArrayXXd aa = ksf(a0, d, h, nstp, np);
	      memcpy(mxGetPr(plhs[0]), &aa(0,0), (nstp/np+1)*(N-2)*sizeof(double));
	  }
	  else{ // integration with Jacobian
	      plhs[0] = mxCreateDoubleMatrix(N-2, nstp/np + 1, mxREAL);
	      plhs[1] = mxCreateDoubleMatrix((N-2)*(N-2), nstp/np, mxREAL);
	      std::pair<ArrayXXd, ArrayXXd> aada = ksfj(a0, d, h, nstp, np, nqr);
	      memcpy(mxGetPr(plhs[0]), &(aada.first(0, 0)), (nstp/np+1)*(N-2)*sizeof(double));
	      memcpy(mxGetPr(plhs[1]), &(aada.second(0, 0)), (nstp/np)*(N-2)*(N-2)*sizeof(double));
	  }
      }
    else{			/* dispation integration */
      plhs[0] = mxCreateDoubleMatrix(N-2, nstp/np + 1, mxREAL);
      plhs[1] = mxCreateDoubleMatrix(nstp/np+1, 1, mxREAL);
      plhs[2] = mxCreateDoubleMatrix(nstp/np+1, 1, mxREAL);
      std::tuple<ArrayXXd, VectorXd, VectorXd> tmp = ksfDP(a0, d, h, nstp, np);
      memcpy(mxGetPr(plhs[0]), &(std::get<0>(tmp)(0,0)), (nstp/np+1)*(N-2)*sizeof(double));
      memcpy(mxGetPr(plhs[1]), &(std::get<1>(tmp)(0)), (nstp/np+1)*sizeof(double));
      memcpy(mxGetPr(plhs[2]), &(std::get<2>(tmp)(0)), (nstp/np+1)*sizeof(double));
    }
  }
  else{
    if(isT == 0){
      plhs[0] = mxCreateDoubleMatrix( nstp/np + 1 , 1, mxREAL);
      plhs[1] = mxCreateDoubleMatrix(N-2, nstp/np + 1, mxREAL);
      std::pair<ArrayXXd, ArrayXd> at = ksfM1(a0, d, h, nstp, np);
      memcpy(mxGetPr(plhs[0]), &(std::get<1>(at)(0,0)), (nstp/np+1)*sizeof(double));
      memcpy(mxGetPr(plhs[1]), &(std::get<0>(at)(0)), (nstp/np+1)*(N-2)*sizeof(double));
      //Map<ArrayXXd> (at.aa)(mxGetPr(plhs[1]), N-2, nstp/np+1);
      //Map<ArrayXd> (at.tt)(mxGetPr(plhs[0]), nstp/np+1);
    }
    else{
      std::pair<ArrayXXd, ArrayXd> at = ksf2M1(a0, d, h, T, np);
      int m = (std::get<0>(at)).cols();
      plhs[0] = mxCreateDoubleMatrix( m , 1, mxREAL);
      plhs[1] = mxCreateDoubleMatrix(N-2, m, mxREAL);
      memcpy(mxGetPr(plhs[0]), &(std::get<1>(at)(0,0)), m*sizeof(double));
      memcpy(mxGetPr(plhs[1]), &(std::get<0>(at)(0)), m*(N-2)*sizeof(double));
    }
  }
}
<file_sep>CC = h5c++
GCC = g++
AR = ar

OPTIM = -O3 -msse2 -msse4 -march=corei7
INCLUDE = ../../include
EIGEN = /usr/local/home/xiong/apps/eigen/include/eigen3
CFLAGS = -std=c++11
LIB = ../../lib
hdf5 = /usr/lib/x86_64-linux-gnu


# for pace cluster 
ifdef pace
OPTIM = -O3
EIGEN = /nv/hp16/xding35/data/apps/eigen/include/eigen3
hdf5 = /nv/hp16/xding35/data/apps/hdf5/lib
endif
####

H5FLAGS = -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_BSD_SOURCE -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security

H5LIB = $(hdf5)/libhdf5_hl_cpp.so $(hdf5)/libhdf5_cpp.so $(hdf5)/libhdf5_hl.so $(hdf5)/libhdf5.so -Wl,-Bsymbolic-functions -Wl,-z,relro -lpthread -lz -ldl -lm -Wl,-rpath -Wl,


# H5FLAGS = -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_BSD_SOURCE -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security

# H5LIB = -L/usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/libhdf5_hl_cpp.so /usr/lib/x86_64-linux-gnu/libhdf5_cpp.so /usr/lib/x86_64-linux-gnu/libhdf5_hl.so /usr/lib/x86_64-linux-gnu/libhdf5.so -Wl,-Bsymbolic-functions -Wl,-z,relro -lpthread -lz -ldl -lm -Wl,-rpath -Wl,/usr/lib/x86_64-linux-gnu


SOURCE = myH5.cc
SHARED = $(addprefix lib, $(addsuffix .so, $(basename $(SOURCE))))
STATIC = $(addprefix lib, $(addsuffix .a, $(basename $(SOURCE))))

# use flag -show to h5c++ to find out what library it uses
all : $(STATIC) $(SHARED)

$(SHARED): $(SOURCE)
	$(GCC) $(H5FLAGS) -c -shared -fPIC $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
	$(GCC) $(H5FLAGS) $(SOURCE:.cc=.o) -shared -fPIC $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) -o $@ $(H5LIB)
$(SOURCE:.cc=.o) : $(SOURCE)
	$(CC) -c $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
$(STATIC): $(SOURCE:.cc=.o)
	$(AR) crs $@ $^


clean:
	rm -f *.so *.o *.a
move:
	mv *.so *.a $(LIB)
<file_sep>/* to comiple:
 * h5c++ -O3 test_CQCGL1dSubReq.cc  -L../../lib -I../../include -I$EIGEN -std=c++11 -lCQCGL1dSubReq -lCQCGL1dSub -lCQCGL1dReq -lCQCGL1d -ldenseRoutines -literMethod -lmyH5 -lfftw3 -lm
 */
#include "CQCGL1dSubReq.hpp"			
#include "CQCGL1dReq.hpp"
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <H5Cpp.h>

using namespace std;
using namespace Eigen;
using namespace denseRoutines;
using namespace MyH5;

typedef std::complex<double> dcp;


#define N50

int main(int argc, char **argv){

#ifdef N10
    //======================================================================
    // use the full-space req as initial condition to find req in the
    // symmetric subspace.
    const int N = 1024;
    const double L = 50;
    double Bi = 0.8, Gi = -0.6;
    CQCGL1dReq cgl0(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    CQCGL1dSubReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	
    string fileName = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    H5File file(fileName, H5F_ACC_RDWR);
    ArrayXd a0;
    double wth0, wphi0, err0;
    std::tie(a0, wth0, wphi0, err0) = cgl0.read(file, cgl.toStr(Bi, Gi, 2));
    a0 = a0.head(cgl.Ndim);

    ArrayXd a;
    double wphi, err;
    int flag;
    std::tie(a, wphi, err, flag) = cgl.findReq_LM(a0, wphi0, 1e-10, 100, 1000);
    fprintf(stderr, "%g %g\n", wphi, err);
    H5File fout("sub.h5", H5F_ACC_TRUNC);
    if (flag == 0) cgl.write(fout, cgl.toStr(Bi, Gi, 1), a, wphi, err);    
#endif
#ifdef N20
    //======================================================================
    // the same as N10, but navigate in the parameter plane.
    const int N = 1024;
    const double L = 50;
	
    string finName = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    H5File file(finName, H5F_ACC_RDWR);
    string foutName = "sub.h5";
    H5File fout(foutName, H5F_ACC_TRUNC);
    
    ArrayXd a0;
    double wth0, wphi0, err0;
    ArrayXd a;
    double wphi, err;
    int flag;
    auto gs = scanGroup(finName);
    for(auto entry : gs) {
	double Bi = stod(entry[0]), Gi = stod(entry[1]);
	int id = stoi(entry[2]);
	fprintf(stderr, "\n %d %g %g \n", id, Bi, Gi);
	
	CQCGL1dReq cgl0(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	CQCGL1dSubReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	std::tie(a0, wth0, wphi0, err0) = cgl0.read(file, cgl.toStr(Bi, Gi, id));
	a0 = a0.head(cgl.Ndim);
	std::tie(a, wphi, err, flag) = cgl.findReq_LM(a0, wphi0, 1e-10, 100, 1000);
	fprintf(stderr, "%g %g\n", wphi, err);
	if (flag == 0) cgl.write(fout, cgl.toStr(Bi, Gi, id), a, wphi, err);    
    }
    
#endif
#ifdef N40
    //======================================================================
    // try to calculate the eigenvalue and eigenvector of one req
    const int N = 1024;
    const double L = 50;
    double Bi = 0.8, Gi = -0.6;
    CQCGL1dSubReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    
    string fileName = "/usr/local/home/xiong/00git/research/data/cgl/reqsubBiGi.h5";
    H5File file(fileName, H5F_ACC_RDWR);
    int id = 1;

    ArrayXd a0;
    double wphi0, err0;
    std::tie(a0, wphi0, err0) = cgl.read(file, cgl.toStr(Bi, Gi, id));
    VectorXcd e;
    MatrixXcd v;
    std::tie(e, v) = cgl.evReq(a0, wphi0); 
    
    cout << e.head(10) << endl;
    cout << endl;
    cout << v.cols() << ' ' << v.rows() << endl;

#endif
#ifdef N50
    //======================================================================
    // calculate E/V
    const int N = 1024;
    const double L = 50;
    
    string s = "/usr/local/home/xiong/00git/research/data/cgl/reqsubBiGi";
    auto gs = scanGroup(s + ".h5");
    // H5File fin(s + ".h5", H5F_ACC_RDWR);
    H5File fout(s + "EV.h5", H5F_ACC_RDWR);
    
    ArrayXd a0;
    double wphi0, err0;
    VectorXcd e;
    MatrixXcd v;
    
    int i = 0;
    for (auto entry : gs){
	double Bi = stod(entry[0]), Gi = stod(entry[1]);
	int id = stoi(entry[2]);
	if( !checkGroup(fout, CQCGL1dSubReq::toStr(Bi, Gi, id) + "/er", false) ){
	    fprintf(stderr, "%d/%d : %d %g %g \n", ++i, (int)gs.size(), id, Bi, Gi);
	    CQCGL1dSubReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	    std::tie(a0, wphi0, err0) = cgl.read(fout, cgl.toStr(Bi, Gi, id));
	    std::tie(e, v) = cgl.evReq(a0, wphi0); 
	    cgl.writeE(fout, cgl.toStr(Bi, Gi, id), e);
	    cgl.writeV(fout, cgl.toStr(Bi, Gi, id), v.leftCols(10));
	}
    }

#endif
    return 0;
}
<file_sep>from py_CQCGL_threads import pyCQCGL
from personalFunctions import *

case = 65

if case == 1:
    """
    test the accuracy of the soliton solution
    """
    N = 1024
    d = 30
    h = 0.0002
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    vReq = cgl.velocityReq(a0, wth0, wphi0)
    nstp = abs(int(2 * np.pi / h / wphi0))
    print norm(vReq)
    aaE = cgl.intg(a0, nstp, 1)
    aaEH, th, phi = cgl.orbit2slice(aaE)
    

if case == 10:
    """
    plot unstable manifold of the exploding soliton solution
    only continuous symmetries are reduced
    """
    N = 1024
    d = 30
    h = 0.000001
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    veHat = cgl.ve2slice(eigvectors, a0)

    nstp = 120000
    a0Erg = a0 + eigvectors[0]*1e-7
    aaErg = cgl.intg(a0Erg, nstp, 10)
    aaErgHat, th, phi = cgl.orbit2slice(aaErg)
    aaErgHat -= a0Hat

    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[10])
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ix1 = 000
    ix2 = 10000
    ixs = ix1 + 1400
    ax.plot(aaErgHatProj[ix1:ix2, 0], aaErgHatProj[ix1:ix2, 1],
            aaErgHatProj[ix1:ix2, 2], c='r', lw=1)
    # ax.scatter([0], [0], [0], s=120)
    # ax.scatter(aaErgHatProj[ixs, 0], aaErgHatProj[ixs, 1],
    #            aaErgHatProj[ixs, 2], s=120, c='k')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 11:
    """
    view a sing unstable manifold orbit
    but with full symmetry reduction
    """
    N = 1024
    d = 30
    h = 0.0002
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    a0Tilde = cgl.reduceReflection(a0Hat)
    veHat = cgl.ve2slice(eigvectors, a0)
    veTilde = cgl.reflectVe(veHat, a0Hat)

    a0Reflected = cgl.reflect(a0)
    a0ReflectedHat = cgl.orbit2slice(a0Reflected)[0].squeeze()

    nstp = 5500
    a0Erg = a0 + eigvectors[0]*1e-4
    aaErg = cgl.intg(a0Erg, nstp, 1)
    aaErgHat, th, phi = cgl.orbit2slice(aaErg)
    aaErgTilde = cgl.reduceReflection(aaErgHat)
    aaErgTilde -= a0Tilde

    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[10])
    aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)

    # plot3dfig(aaErgHatProj[1000:, 0], aaErgHatProj[1000:, 1], aaErgHatProj[1000:, 2])
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ix1 = 0
    ix2 = 3300
    ax.plot(aaErgTildeProj[ix1:ix2, 0], aaErgTildeProj[ix1:ix2, 1],
            aaErgTildeProj[ix1:ix2, 2], c='r', lw=1)
    ax.scatter([0], [0], [0], s=100)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 13:
    N = 1024
    d = 30
    h = 0.0002
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

    def vel(x, t):
        return cgl.velocity(x)
    
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    a0Tilde = cgl.reduceReflection(a0Hat)
    veHat = cgl.ve2slice(eigvectors, a0)
    veTilde = cgl.reflectVe(veHat, a0Hat)

    a0Reflected = cgl.reflect(a0)
    a0ReflectedHat = cgl.orbit2slice(a0Reflected)[0].squeeze()

    nstp = 5500
    a0Erg = a0 + eigvectors[0]*1e-4
    aaErg = cgl.intg(a0Erg, nstp, 1)
    aaErgHat, th, phi = cgl.orbit2slice(aaErg)
    aaErgTilde = cgl.reduceReflection(aaErgHat)
    aaErgTilde -= a0Tilde

    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[10])
    aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)

    # plot3dfig(aaErgHatProj[1000:, 0], aaErgHatProj[1000:, 1], aaErgHatProj[1000:, 2])
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ix1 = 0
    ix2 = 3300
    ax.plot(aaErgTildeProj[ix1:ix2, 0], aaErgTildeProj[ix1:ix2, 1],
            aaErgTildeProj[ix1:ix2, 2], c='r', lw=1)
    ax.scatter([0], [0], [0], s=100)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
  

if case == 15:
    """
    view a single unstable manifold orbit using Jacobian not the
    system integrator.
    """
    N = 1024
    d = 30
    h = 0.0002
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    veHat = cgl.ve2slice(eigvectors, a0)

    cgl1 = pyCqcgl1d(N, d, h, True, 1, 4.0, 0.8, 0.01, di, 4)
    nstp = 3000
    v0 = eigvectors[0]*1e-7
    aaErg, vErg = cgl1.intgvs(a0, v0, nstp, 1, 1)
    aaErgHat, th, phi = cgl1.orbit2slice(aaErg)
    vErgHat = cgl1.ve2slice(vErg, a0)
    aaErgHat -= a0Hat

    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[10])
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2, e3)).T)
    vErgHatProj = np.dot(vErgHat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ix1 = 000
    ix2 = nstp
    ixs = ix1 + 1400
    # ax.plot(aaErgHatProj[ix1:ix2, 0], aaErgHatProj[ix1:ix2, 1],
    #         aaErgHatProj[ix1:ix2, 2], c='r', lw=1)
    ax.plot(vErgHatProj[ix1:ix2, 0], vErgHatProj[ix1:ix2, 1],
            vErgHatProj[ix1:ix2, 2], c='r', lw=1)
    # ax.scatter([0], [0], [0], s=120)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 20:
    """
    plot unstable manifold
    of the exploding soliton solution from a
    line of states
    """
    N = 1024
    d = 30
    h = 1e-5
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    a0R = cgl.reflect(a0)
    a0RH = cgl.orbit2slice(a0R)[0]

    nstp = np.int(1e5)
    Er = eigvalues[0].real
    Ei = eigvalues[0].imag
    Vr, Vi = orthAxes2(eigvectors[0], eigvectors[1])
    n = 10
    aaE = []
    aaEHat = []
    for i in range(n):
        print i
        # ang = 2 * i * np.pi / n
        e = np.exp(2*np.pi * Er / Ei / n * i*10)
        a0Erg = a0 + Vr * e * 1e-6
        aaErg = cgl.intg(a0Erg, nstp, 100)
        aaErgHat, th, phi = cgl.orbit2slice(aaErg)
        # aaE.append(aaErg)
        aaEHat.append(aaErgHat - a0Hat)

    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[10])
    aaEHatP = []
    for i in range(n):
        aaErgHatProj = np.dot(aaEHat[i], np.vstack((e1, e2, e3)).T)
        aaEHatP.append(aaErgHatProj)

    ix1 = 0
    ix2 = nstp
    ixs = ix1 + 1400

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    for i in range(1):
        ax.plot(aaEHatP[i][ix1:ix2, 0], aaEHatP[i][ix1:ix2, 1],
                aaEHatP[i][ix1:ix2, 2], c='r', lw=1)
    # ax.scatter([0], [0], [0], s=50)
    # ax.scatter(aaErgHatProj[ixs, 0], aaErgHatProj[ixs, 1],
    #            aaErgHatProj[ixs, 2], s=120, c='k')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 21:
    """
    plot unstable manifold
    of the exploding soliton solution from a
    circular states
    """
    N = 1024
    d = 30
    h = 0.0002
    di = 0.05

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    veHat = cgl.ve2slice(eigvectors, a0)

    nstp = 3000
    Er = eigvalues[0].real
    Ei = eigvalues[0].imag
    Vr, Vi = orthAxes2(eigvectors[0], eigvectors[1])
    n = 30
    aaE = []
    aaEHat = []
    for i in range(n):
        print i
        ang = 2 * i * np.pi / n
        a0Erg = a0 + (Vr * np.cos(ang) + Vi * np.sin(ang)) * 1e-4
        aaErg = cgl.intg(a0Erg, nstp, 1)
        aaErgHat, th, phi = cgl.orbit2slice(aaErg)
        # aaE.append(aaErg)
        aaEHat.append(aaErgHat - a0Hat)

    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[10])
    aaEHatP = []
    for i in range(n):
        aaErgHatProj = np.dot(aaEHat[i], np.vstack((e1, e2, e3)).T)
        aaEHatP.append(aaErgHatProj)

    ix1 = 00000
    ix2 = 03000
    ixs = ix1 + 1400

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    for i in range(n):
        ax.plot(aaEHatP[i][ix1:ix2, 0], aaEHatP[i][ix1:ix2, 1],
                aaEHatP[i][ix1:ix2, 2], c='r', lw=1)
    # ax.scatter([0], [0], [0], s=120)
    # ax.scatter(aaErgHatProj[ixs, 0], aaErgHatProj[ixs, 1],
    #            aaErgHatProj[ixs, 2], s=120, c='k')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    
if case == 30:
    """
    try to obtain the Poincare intersection points
    """
    N = 1024
    d = 50
    h = 0.0001
    
    cgl = pyCqcgl1d(N, d, h, True, 0,
                    -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
                    4)
    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN1024.h5', '1')
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = realve(eigvectors)
    eigvectors = Tcopy(eigvectors)
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    a0Tilde = cgl.reduceReflection(a0Hat)
    veHat = cgl.ve2slice(eigvectors, a0)
    veTilde = cgl.reflectVe(veHat, a0Hat)
    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[6])

    nstp = 60000

    M = 10
    a0Erg = np.empty((M, cgl.Ndim))
    for i in range(M):
        a0Erg[i] = a0 + (i+1) * eigvectors[0]*1e-4
    PointsProj = np.zeros((0, 2))
    PointsFull = np.zeros((0, cgl.Ndim))
    for i in range(30):
        for j in range(M):
            aaErg = cgl.intg(a0Erg[j], nstp, 1)
            aaErgHat, th, phi = cgl.orbit2slice(aaErg)
            aaErgTilde = cgl.reduceReflection(aaErgHat)
            aaErgTilde -= a0Tilde
            aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)

            # plotConfigSpace(cgl.Fourier2Config(aaErg),
            #                 [0, d, nstp*h*i, nstp*h*(i+1)])
            points, index, ratios = PoincareLinearInterp(aaErgTildeProj, getIndex=True)
            PointsProj = np.vstack((PointsProj, points))
            for i in range(len(index)):
                dif = aaErgTilde[index[i]+1] - aaErgTilde[index[i]]
                p = dif * ratios[i] + aaErgTilde[index[i]]
                PointsFull = np.vstack((PointsFull, p))
            a0Erg[j] = aaErg[-1]

    upTo = PointsProj.shape[0]
    scatter2dfig(PointsProj[:upTo, 0], PointsProj[:upTo, 1], s=10,
                 labs=[r'$e_2$', r'$e_3$'])
    dis = getCurveCoor(PointsFull)
    # np.savez_compressed('PoincarePoints', totalPoints=totalPoints)

if case == 40:
    """
    plot the Poincare intersection points
    """
    totalPoints = np.load('PoincarePoints.npz')['totalPoints']
    multiScatter2dfig([totalPoints[:280, 0], totalPoints[280:350, 0]],
                      [totalPoints[:280, 1], totalPoints[280:350, 1]],
                      s=[15, 15], marker=['o', 'o'], fc=['r', 'b'],
                      labs=[r'$e_2$', r'$e_3$'])
    
    scatter2dfig(totalPoints[:, 0], totalPoints[:, 1], s=10,
                 labs=[r'$e_2$', r'$e_3$'])

if case == 50:
    """
    use the new constructor of cqcgl
    try to obtain the Poincare intersection points
    """
    N = 1024
    d = 40
    h = 0.0005

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, -0.01, -0.04, 4)
    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN1024.h5', '1')
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = realve(eigvectors)
    eigvectors = Tcopy(eigvectors)
    a0Hat = cgl.orbit2slice(a0)[0].squeeze()
    a0Tilde = cgl.reduceReflection(a0Hat)
    veHat = cgl.ve2slice(eigvectors, a0)
    veTilde = cgl.reflectVe(veHat, a0Hat)
    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[6])

    nstp = 60000

    M = 10
    a0Erg = np.empty((M, cgl.Ndim))
    for i in range(M):
        a0Erg[i] = a0 + (i+1) * eigvectors[0]*1e-4
    PointsProj = np.zeros((0, 2))
    PointsFull = np.zeros((0, cgl.Ndim))
    for i in range(30):
        for j in range(M):
            aaErg = cgl.intg(a0Erg[j], nstp, 1)
            aaErgHat, th, phi = cgl.orbit2slice(aaErg)
            aaErgTilde = cgl.reduceReflection(aaErgHat)
            aaErgTilde -= a0Tilde
            aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)

            # plotConfigSpace(cgl.Fourier2Config(aaErg),
            #                 [0, d, nstp*h*i, nstp*h*(i+1)])
            points, index, ratios = PoincareLinearInterp(aaErgTildeProj, getIndex=True)
            PointsProj = np.vstack((PointsProj, points))
            for i in range(len(index)):
                dif = aaErgTilde[index[i]+1] - aaErgTilde[index[i]]
                p = dif * ratios[i] + aaErgTilde[index[i]]
                PointsFull = np.vstack((PointsFull, p))
            a0Erg[j] = aaErg[-1]

    upTo = PointsProj.shape[0]
    scatter2dfig(PointsProj[:upTo, 0], PointsProj[:upTo, 1], s=10,
                 labs=[r'$e_2$', r'$e_3$'])
    dis = getCurveCoor(PointsFull)
    # np.savez_compressed('PoincarePoints', totalPoints=totalPoints)

if case == 60:
    """
    change parameter of b, see how the soliton changes
    """
    N = 1024
    d = 30
    di = 0.06
    b = 4
    T = 3

    cgl = pyCQCGL(N, d, b, 0.8, 0.01, di, 0, 4)
    cgl.changeOmega(-176.67504941219335)

    Ndim = cgl.Ndim
    A0 = 5*centerRand(N, 0.1, True)
    a0 = cgl.Config2Fourier(A0)

    aa = cgl.aintg(a0, 0.001, T, 1)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])
    t1 = cgl.Ts()
    plot2dfig(t1, aa[:, 0], labs=['t', r'$Re(a_0)$'])
<file_sep>#ifndef KSEIDR_H
#define KSEIDR_H

#include "EIDr.hpp"
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>

////////////////////////////////////////////////////////////////////////////////
class KSEIDr {
    
public:
    typedef std::complex<double> dcp;
    
    const int N;
    const double d;
    ArrayXd L;
    ArrayXd K;
    ArrayXcd G;
    
    FFT<double> fft;

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 500;

    struct NL {
	FFT<double> *fft;
	ArrayXcd *G;

	NL(){}
	NL(FFT<double> &fft, ArrayXcd &G) : fft(&fft), G(&G) {}
	~NL(){}

	void init(FFT<double> &fft, ArrayXcd &G){
	    this->G = &G;
	    this->fft = &fft;
	}

	VectorXd u;
	void operator()(ArrayXcd &x, ArrayXcd &dxdt, double t){
	    Map<VectorXcd> xv(x.data(), x.size());
	    Map<VectorXcd> dxdtv(dxdt.data(), dxdt.size());
	    fft->inv(u, xv);
	    u = u.array().square();
	    fft->fwd(dxdtv, u);
	    dxdt *=  (*G);
	}
    };
    
    NL nl;
    
    ArrayXcd Yv[10], Nv[10];
    EIDr eidr;

    /* ============================================================ */
    KSEIDr(int N, double d) :  N(N), d(d) {
	K = ArrayXd::LinSpaced(N/2+1, 0, N/2) * 2 * M_PI / d;
	K(N/2) = 0;
	L = K*K - K*K*K*K;
	G = 0.5 * dcp(0,1) * K * N; 

	fft.SetFlag(fft.HalfSpectrum);
	nl.init(fft, G);
	
	int nYN0 = eidr.nYNs[eidr.scheme];
	for(int i = 0; i < nYN0; i++){
	    Yv[i].resize(N/2+1);
	    Nv[i].resize(N/2+1);
	}
	eidr.init(&L, Yv, Nv);
	
    }
    
    ~KSEIDr(){};

    /* ============================================================ */
    inline void 
    setScheme(std::string x){
	int nYN0 = eidr.nYNs[eidr.scheme];	
	eidr.scheme = eidr.names[x];
	int nYN1 = eidr.nYNs[eidr.scheme];
	for (int i = nYN0; i < nYN1; i++) {
	    Yv[i].resize(N/2+1);
	    Nv[i].resize(N/2+1);
	}
    }

    inline 
    ArrayXXd
    intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
	assert( N-2 == a0.size());
	
	ArrayXcd u0 = R2C(a0); 
	const int Nt = (int)round(tend/h);
	const int M = (Nt+skip_rate-1)/skip_rate;
	ArrayXXcd aa(N/2+1, M);
	lte.resize(M);
	int ks = 0;
	auto ss = [this, &ks, &aa](ArrayXcd &x, double t, double h, double err){
	    aa.col(ks) = x;
	    lte(ks++) = err;
	};
	
        eidr.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
	
	return C2R(aa);
    }

    inline 
    ArrayXXd
    intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
	assert( N-2 == a0.size());

	ArrayXcd u0 = R2C(a0); 
	const int Nt = (int)round(tend/h);
	const int M = (Nt+skip_rate-1)/skip_rate;
	ArrayXXcd aa(N/2+1, M);
	Ts.resize(M);
	hs.resize(M);
	lte.resize(M);
	int ks = 0;
	auto ss = [this, &ks, &aa](ArrayXcd &x, double t, double h, double err){
	    int m = Ts.size();
	    if (ks >= m ) {
		Ts.conservativeResize(m+cellSize);
		aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
		hs.conservativeResize(m+cellSize);
		lte.conservativeResize(m+cellSize);
	    }
	    hs(ks) = h;
	    lte(ks) = err;
	    aa.col(ks) = x;
	    Ts(ks++) = t;
	};
	
	eidr.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
	hs.conservativeResize(ks);
	lte.conservativeResize(ks);
	Ts.conservativeResize(ks);
	aa.conservativeResize(Eigen::NoChange, ks);

	return C2R(aa);
    }



    inline
    ArrayXXd C2R(const ArrayXXcd &v){
	int n = v.rows();
	int m = v.cols();
	ArrayXXcd vt = v.middleRows(1, n-2);
	ArrayXXd vp(2*(n-2), m);
	vp = Map<ArrayXXd>((double*)&vt(0,0), 2*(n-2), m);

	return vp;
    }
    
    inline
    ArrayXXcd R2C(const ArrayXXd &v){
	int n = v.rows();
	int m = v.cols();
	assert( 0 == n%2);
	
	ArrayXXcd vp = ArrayXXcd::Zero(n/2+2, m);
	vp.middleRows(1, n/2) = Map<ArrayXXcd>((dcp*)&v(0,0), n/2, m);
	
	return vp;
    }

};


#endif	/* KSEIDR_H */
<file_sep>#ifndef MYH5_H
#define MYH5_H

#include <Eigen/Dense>
#include <iostream>
#include <cstdio>
#include <unordered_set>
#include "H5Cpp.h"

/**
 * Note,
 * scalars have dimension 0,
 * vectors have dimension 1
 */
namespace MyH5 {
    using namespace H5;
    using namespace std;
    using namespace Eigen;

    template<typename Scalar>
    PredType getPredType();

    template <typename Scalar>
    Scalar readScalar(H5File &file, string DSitem);

    template <typename Scalar>
    void 
    writeScalar(H5File &file, string DSitem, Scalar value);
    
    void 
    writeMatrixXd(H5File &file, string DSitem, const MatrixXd &mat);
    void 
    writeVectorXd(H5File &file, string DSitem, const VectorXd &vec);
    MatrixXd 
    readMatrixXd(H5File &file, string DSitem);
    VectorXd 
    readVectorXd(H5File &file, string DSitem);
    bool 
    checkGroup(H5File &file, const std::string groupName, const bool doCreate);
    bool 
    checkGroup(std::string fileName, const std::string groupName, const bool doCreate);
    vector<vector<string>> 
    scanGroup(std::string fileName);
    void 
    scanGroupHelp(hid_t gid, vector<vector<string>> &result, unordered_set<string> &record,
		  vector<string> &curt) ;
    
    //////////////////////////////////////////////////////////////////////
    /* KS related */
    std::pair<VectorXd, double>
    KSreadEq(const std::string fileName, const int Id);
    std::tuple<VectorXd, double, double>
    KSreadReq(const std::string fileName, const int Id);
}

//////////////////////////////////////////////////
//              Implementation                  //
//////////////////////////////////////////////////

namespace MyH5 {

    /**
     * @brief obtain the data type in HDF5
     */
    template<typename Scalar>
    PredType getPredType(){
	if(typeid(Scalar) == typeid(double)){
	    return PredType::NATIVE_DOUBLE;
	}
	else if (typeid(Scalar) == typeid(int)){
	    return PredType::NATIVE_INT;
	}
	else{
	    fprintf(stderr, "getPredType received undetermined type !\n");
	    exit(1);
	}
    }

    /**
     * @brief read a scaler from a HDF5 file
     *
     * @param[in] file    H5File object. shold open as H5F_ACC_RDWR
     * @param[in] DSitem  the pass to the dataset
     * @return            the scalar
     */
    template <typename Scalar>
    Scalar readScalar(H5File &file, string DSitem){
	DataSet item = file.openDataSet(DSitem);
	DataSpace dsp = item.getSpace();
	assert(dsp.getSimpleExtentNdims() == 0);
	hsize_t dims[1];
	int ndims = dsp.getSimpleExtentDims(dims, NULL);
	Scalar value(0);
	PredType type = getPredType<Scalar>();
	item.read(&value, type);
	return value;
    }

    /**
     * @brief write a scaler to a HDf5 file
     *
     * @param[in] file    H5File object. shold open as H5F_ACC_RDWR
     * @param[in] value   the scalar need to be wrote
     */
    template <typename Scalar>
    void writeScalar(H5File &file, string DSitem, Scalar value){
	hsize_t dim[0];
	DataSpace dsp(0, dim);
	PredType type = getPredType<Scalar>();
	DataSet item = file.createDataSet(DSitem, type, dsp);
	item.write(&value, type);
    }

}


#endif	/* MYH5_H */

<file_sep>#include "CQCGL1dSub.hpp"

using namespace denseRoutines;

// implementation notes
// 1) not use fft.fwd(MatrixBase, MatrixBase) but use
//    fft.fwd(Complex * dst, const Complex * src, Index nfft)
//    becuase the former cannot work with Map<VectorXcd> type.
// 2) In C++, initialization list will be evaluated in the order they were
//    declared in the class definition

//////////////////////////////////////////////////////////////////////
//                     Inner Class CQCGL1dSub                          //
//////////////////////////////////////////////////////////////////////
CQCGL1dSub::NL::NL(){}
CQCGL1dSub::NL::NL(CQCGL1dSub *cgl, int cols) : 
    cgl(cgl), N(cgl->N), Ne(cgl->Ne), B(cgl->Br, cgl->Bi), G(cgl->Gr, cgl->Gi) 
{
    modes.resize(cgl->N, cols);
    field.resize(cgl->N, cols);
}
CQCGL1dSub::NL::~NL(){}

// the dimension should be [Ne, DimTan+1]
void CQCGL1dSub::NL::operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t){
    int cs = x.cols();
    assert(cs == dxdt.cols() && Ne == x.rows() && Ne == dxdt.rows());
    
    modes << x, ArrayXXcd::Zero(N-2*Ne+1, cs), x.bottomRows(Ne-1).colwise().reverse();    
    for(int i = 0; i < cs; i++)
	cgl->fft.inv(field.data() + i*N, modes.data() + i*N, N);
    ArrayXXcd AA = field.topRows(N/2 + 1); // [A_0, A_1..., A_N/2, A_N/2-1,,. A_1]

    ArrayXcd A = AA.col(0); 
    ArrayXcd aA2 = A * A.conjugate();

    if (cgl->IsQintic)
	AA.col(0) = B * A * aA2 + G * A * aA2.square();
    else 
	AA.col(0) = B * A * aA2;

    if(cs > 1){
	int M = cs - 1;
	ArrayXcd A2 = A.square();
	if (cgl->IsQintic)
	    AA.rightCols(M) = AA.rightCols(M).conjugate().colwise() *  ((B+G*2.0*aA2) * A2) +
		AA.rightCols(M).colwise() * ((2.0*B+3.0*G*aA2)*aA2);
	else
	    AA.rightCols(M) = AA.rightCols(M).conjugate().colwise() *  (B * A2) +
		AA.rightCols(M).colwise() * (2.0*B*aA2);	
    }
    
    field << AA, AA.middleRows(1, N/2-1).colwise().reverse();
    for(int i = 0; i < cs; i++)
	cgl->fft.fwd(modes.data() + i*N, field.data() + i*N, N);
    
    dxdt = modes.topRows(Ne);
}

//////////////////////////////////////////////////////////////////////
//                        Class CQCGL1dSub                             //
//////////////////////////////////////////////////////////////////////

/* ------------------------------------------------------ */
/* ----                constructor/destructor     ------- */
/* ------------------------------------------------------ */

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
 *
 * @param[in] N            the number of Fourier modes
 * @param[in] d            the spacial period, size
 * @param[in] dimTan       the dimension of tangent space
 *                         dimTan > 0 => dimTan
 *                         dimTan = 0 => Ndim
 *                         dimTan < 0 => 0
 *              
 * Dealiasing is the method to calculate correct convolution term. For centralized
 * FFT, it works as set Fourier modes a_k = 0 for wave number |k| > 2/3 * N.
 * More specifically, in this code, the middle part of modes
 * is set to zero.
 *
 *    |<---------------------------------------------------------->|
 *                             FFT length: N
 *               
 *    |<--------------->|<--------------------->|<---------------->|
 *        Ne                    N - 2*Ne + 1           Ne - 1
 */
CQCGL1dSub::CQCGL1dSub(int N, double d,
		       double Mu, double Dr, double Di, double Br, double Bi,
		       double Gr, double Gi, int dimTan)
    : N(N), d(d), Mu(Mu), Dr(Dr), Di(Di), Br(Br), Bi(Bi), Gr(Gr), Gi(Gi),
      Ne(N/3),	
      Ndim(2 * Ne),
      DimTan(dimTan == 0 ? Ndim : (dimTan > 0 ? dimTan : 0)),
      nl(this, 1), nl2(this, DimTan+1)
{
    // calculate the Linear part
    K = ArrayXd::LinSpaced(Ne, 0, Ne-1);      
    QK = 2*M_PI/d * K; 
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square(); 

    int nYN0 = eidc.names.at(eidc.scheme).nYN; // do not call setScheme here. Different.
    for(int i = 0; i < nYN0; i++){
	Yv[i].resize(Ne, 1);
	Nv[i].resize(Ne, 1);
	Yv2[i].resize(Ne, DimTan+1);
	Nv2[i].resize(Ne, DimTan+1);
    }
    eidc.init(&L, Yv, Nv);
    eidc2.init(&L, Yv2, Nv2);
}

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
 */
CQCGL1dSub::CQCGL1dSub(int N, double d, 
		       double b, double c, double dr, double di, 
		       int dimTan)
    : CQCGL1dSub::CQCGL1dSub(N, d, -1, 1, b, 1, c, -dr, -di, dimTan) {}


CQCGL1dSub::CQCGL1dSub(int N, double d,
		       double delta, double beta, double D, double epsilon,
		       double mu, double nu, int dimTan)
    : CQCGL1dSub::CQCGL1dSub(N, d, delta, beta, D/2, epsilon, 1, mu, nu) {}

CQCGL1dSub::~CQCGL1dSub(){}

CQCGL1dSub & CQCGL1dSub::operator=(const CQCGL1dSub &x){
    return *this;
}

/* ------------------------------------------------------ */
/* ----                 Integrator                ------- */
/* ------------------------------------------------------ */

void CQCGL1dSub::setScheme(std::string x){
    int nYN0 = eidc.names.at(eidc.scheme).nYN;
    eidc.scheme = x;
    int nYN1 = eidc.names.at(eidc.scheme).nYN;
    for (int i = nYN0; i < nYN1; i++) {
	Yv[i].resize(Ne, 1);
	Nv[i].resize(Ne, 1);
	Yv2[i].resize(Ne, DimTan+1);
	Nv2[i].resize(Ne, DimTan+1);
    }
}

void CQCGL1dSub::changeOmega(double w){
    Omega = w;
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square();
}

/** @brief Integrator of 1d cqCGL equation.
 *
 *  The intial condition a0 should be coefficients of the intial state:
 *  [b0, c0 ,b1, c1,...] where bi, ci the real and imaginary parts of Fourier modes.
 *  
 * @param[in] a0 initial condition of Fourier coefficents. Size : [2*Ne,1]
 * @return state trajectory. Each column is the state followed the previous column. 
 */
ArrayXXd 
CQCGL1dSub::intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert( Ndim == a0.size());
    
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(Ne, M);
    lte.resize(M);
    int ks = 0; 
    auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	aa.col(ks) = x;
	lte(ks++) = err;
    }; 
	
    eidc.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
	
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
CQCGL1dSub::intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(v0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(Ne, M), daa(Ne, Ndim*M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	aa.col(ks) = x.col(0);
	daa.middleCols(ks*Ndim, Ndim) = x.rightCols(Ndim);
	lte(ks++) = err;
	x.rightCols(Ndim) = R2C(MatrixXd::Identity(Ndim, Ndim));
    };
    
    eidc2.intgC(nl2, ss, 0, u0, tend, h, skip_rate);
    
    return std::make_pair(C2R(aa), C2R(daa));
}

/**
 * @brief integrate the state and a subspace in tangent space
 */
ArrayXXd
CQCGL1dSub::intgvC(const ArrayXd &a0, const ArrayXXd &v, const double h,
		const double tend){
    assert( Ndim == a0.size() && Ndim == v.rows() && DimTan == v.cols());
    ArrayXXd v0(Ndim, DimTan+1);
    v0 << a0, v;
    ArrayXXcd u0 = R2C(v0);

    const int Nt = (int)round(tend/h);
    ArrayXXcd aa(Ne, DimTan+1);
    auto ss = [this, &aa](ArrayXXcd &x, double t, double h, double err){
	aa = x;
    };
    
    eidc2.intgC(nl2, ss, 0, u0, tend, h, Nt);
    
    return C2R(aa);	   //both the final orbit and the perturbation
}

ArrayXXd
CQCGL1dSub::intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert( Ndim == a0.size());
    
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt+skip_rate-1)/skip_rate;
    ArrayXXcd aa(Ne, M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (ks >= m ) {
	    Ts.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	}
	hs(ks) = h;
	lte(ks) = err;
	aa.col(ks) = x;
	Ts(ks++) = t;
    };
    
    eidc.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
    hs.conservativeResize(ks);
    lte.conservativeResize(ks);
    Ts.conservativeResize(ks);
    aa.conservativeResize(Eigen::NoChange, ks);
    
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
CQCGL1dSub::intgj(const ArrayXd &a0, const double h, const double tend, 
	       const int skip_rate){
    
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(a0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(Ne, M), daa(Ne, Ndim*M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (ks >= m ) {
	    Ts.conservativeResize(m+cellSize);	    
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
	    daa.conservativeResize(Eigen::NoChange, (m+cellSize)*Ndim);
	}
	hs(ks) = h;
	lte(ks) = err;
	Ts(ks) = t;
	aa.col(ks) = x.col(0);
	daa.middleCols(ks*Ndim, Ndim) = x.rightCols(Ndim);
	x.rightCols(Ndim) = R2C(MatrixXd::Identity(Ndim, Ndim));
	ks++;
    };

    eidc2.intg(nl2, ss, 0, u0, tend, h, skip_rate);
    return std::make_pair(C2R(aa), C2R(daa));
}
 

ArrayXXd 
CQCGL1dSub::intgv(const ArrayXXd &a0, const ArrayXXd &v, const double h,
		  const double tend){
    assert( Ndim == a0.size() && Ndim == v.rows() && DimTan == v.cols());
    ArrayXXd v0(Ndim, DimTan+1);
    v0 << a0, v;
    ArrayXXcd u0 = R2C(v0);

    ArrayXXcd aa(Ne, DimTan+1); 
    auto ss = [this, &aa](ArrayXXcd &x, double t, double h, double err){
	aa = x;
    };

    eidc2.intg(nl2, ss, 0, u0, tend, h, 1000000);
    return C2R(aa);
}


ArrayXXd CQCGL1dSub::C2R(const ArrayXXcd &v){
    return Map<ArrayXXd>((double*)&v(0,0), 2*v.rows(), v.cols());
}

ArrayXXcd CQCGL1dSub::R2C(const ArrayXXd &v){
    assert( 0 == v.rows() % 2);
    return Map<ArrayXXcd>((dcp*)&v(0,0), v.rows()/2, v.cols());
}


/* -------------------------------------------------- */
/* -------  Fourier/Configure transformation -------- */
/* -------------------------------------------------- */

/**
 * @brief back Fourier transform of the states. 
 */
ArrayXXcd CQCGL1dSub::Fourier2Config(const Ref<const ArrayXXd> &aa){
    int cs = aa.cols(), rs = aa.rows();
    assert(Ndim == rs);
    ArrayXXcd aac = R2C(aa);
    ArrayXXcd modes(N, cs);
    modes << aac, ArrayXXcd::Zero(N-2*Ne+1, cs), aac.bottomRows(Ne-1).colwise().reverse();
    ArrayXXcd field(N, cs);
    
    for(size_t i = 0; i < cs; i++)
	fft.inv(field.data() + i*N, modes.data() + i*N, N);
    
    return field;
}


/**
 * @brief Fourier transform of the states. Input and output are both real.
 */
ArrayXXd CQCGL1dSub::Config2Fourier(const Ref<const ArrayXXcd> &field){
    int cs = field.cols(), rs = field.rows();
    assert(N == rs);
    ArrayXXcd modes(N, cs);
    
    for(size_t i = 0; i < cs; i++)
	fft.fwd(modes.data() + i*N, field.data() + i*N, N);
    
    return C2R(modes.topRows(Ne));
}


ArrayXXd CQCGL1dSub::calPhase(const Ref<const ArrayXXcd> &AA){
    int m = AA.cols();
    int n = AA.rows();
    assert(N == n);
    ArrayXXd phase(n, m);
    for(size_t i = 0; i < m; i++)
	for(size_t j =0; j < n; j++)
	    phase(j, i) = atan2(AA(j, i).imag(), AA(j, i).real());

    return phase;
}


/**
 * @brief calculate the mean energy density
 * \frac{\int |A|^2  dx}{\int dx} = 1/N \sum |A_i|^2 = 1/N^2 \sum |a_i|^2
 * = 1/N^2 \sum (a_r^2 + a_i^2)
 */
VectorXd 
CQCGL1dSub::calQ(const Ref<const ArrayXXd> &aa){
    const int n = aa.cols();
    VectorXd Q(n);
    for (int i = 0; i < n; i++){
	Q(i) = aa.col(i).matrix().squaredNorm() / (N*N);
    }

    return Q;
}

VectorXd
CQCGL1dSub::calMoment(const Ref<const ArrayXXd> &aa, const int p){
    const int n = aa.cols();
    VectorXd mom(n);
    
    ArrayXd x = ArrayXd::LinSpaced(N, 0, N-1) * d / N;
    ArrayXd xp = x;
    for(int i = 0; i < p-1; i++) xp *= x;

    ArrayXXcd AA = Fourier2Config(aa);
    for (int i = 0; i < n; i++){
	ArrayXd A2 = (AA.col(i) * AA.col(i).conjugate()).real();
	mom(i) = (A2 * xp).sum() / A2.sum();
    }

    return mom;
}

/* -------------------------------------------------- */
/* --------            velocity field     ----------- */
/* -------------------------------------------------- */

/**
 * @brief velocity field
 */
ArrayXd CQCGL1dSub::velocity(const ArrayXd &a0){
    assert( Ndim == a0.rows() );
    ArrayXXcd A = R2C(a0);
    ArrayXXcd v(Ne, 1);
    nl(A, v, 0);
    return C2R(L*A + v);
}

/**
 * @brief the generalized velociyt for relative equilibrium
 *
 *   v(x) + \omega_\tau * t_\tau(x) + \omega_\rho * t_\rho(x)
 */
ArrayXd CQCGL1dSub::velocityReq(const ArrayXd &a0, const double wphi){
    return velocity(a0) + wphi*phaseTangent(a0);    
}

/* -------------------------------------------------- */
/* --------          stability matrix     ----------- */
/* -------------------------------------------------- */
MatrixXd CQCGL1dSub::stab(const ArrayXd &a0){
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(v0);
    
    ArrayXXcd v(Ne, Ndim+1);
    nl2(u0, v, 0);
	
    ArrayXXcd j0 = R2C(MatrixXd::Identity(Ndim, Ndim));
    MatrixXcd Z = j0.colwise() * L + v.rightCols(Ndim);
    
    return C2R(Z);
}

/**
 * @brief stability for relative equilbrium
 */
MatrixXd CQCGL1dSub::stabReq(const ArrayXd &a0, double wphi){
    return stab(a0) + wphi*phaseGenerator();
}

/**
 * @brief stability exponents of req
 */
VectorXcd CQCGL1dSub::eReq(const ArrayXd &a0, double wphi){
    return eEig(stabReq(a0, wphi), 1);
}

/**
 * @brief stability vectors of req
 */
MatrixXcd CQCGL1dSub::vReq(const ArrayXd &a0, double wphi){
    return vEig(stabReq(a0, wphi), 1);
}

/**
 * @brief stability exponents and vectors of req
 */
std::pair<VectorXcd, MatrixXcd>
CQCGL1dSub::evReq(const ArrayXd &a0, double wphi){
    return evEig(stabReq(a0, wphi), 1);
}


/* -------------------------------------------------- */
/* ------           symmetry related           ------ */
/* -------------------------------------------------- */

ArrayXXd CQCGL1dSub::phaseRotate(const Ref<const ArrayXXd> &aa, const double phi){
    return C2R( R2C(aa) * exp(dcp(0,1)*phi) ); // a0*e^{i\phi}
}

ArrayXXd CQCGL1dSub::phaseTangent(const Ref<const ArrayXXd> &modes){
    return C2R( R2C(modes) * dcp(0,1) );
}

/** @brief group generator  */
MatrixXd CQCGL1dSub::phaseGenerator(){
    MatrixXd T = MatrixXd::Zero(Ndim, Ndim);
    for(size_t i = 0; i < Ne; i++){
	T(2*i, 2*i+1) = -1;
	T(2*i+1, 2*i) = 1;
    }
    return T;
}
<file_sep>from personalFunctions import *

class KSplot():
    """
    KS help class.
    Its main funciton is to load data and plot figures.
    
    """
    
    def __init__(self, ks=None):
        """
        initialization with 
        >> ksp = KSplot(ks)
        or
        >> ksp = KSplot()
        """
        self.ks = ks
        self.N = ks.N if ks is not None else None
        self.L = ks.d if ks is not None else None
        # pass

    def F2C(self, aa):
        """
        Fourier modes a_k(t) to physical state u(x,t)

        Parameter
        ======
        aa : real and imaignary part of the Fourier modes. Can be 1d or 2d 

        Return
        ======
        AA : the physical space states (real).
        """
        if aa.ndim == 1:
            half1 = aa[0::2] + 1j*aa[1::2]
            half2 = aa[0::2] - 1j*aa[1::2]
            aaWhole = np.hstack(([0], half1, [0], half2[::-1]))
            AA = np.fft.ifft(aaWhole).real  # only the real part
        else:
            half1 = aa[:, 0::2] + 1j*aa[:, 1::2]
            half2 = aa[:, 0::2] - 1j*aa[:, 1::2]
            M = half1.shape[0]
            aaWhole = np.hstack((np.zeros((M, 1)), half1,
                                 np.zeros((M, 1)), half2[:, ::-1]))
            AA = np.fft.ifftn(aaWhole, axes=(1,)).real  # only the real part

        # because we have a different normalization conversion for FFT,
        # we need to multiply the result with N.
        return self.N * AA     

    def readEq(self, fileName, idx):
        f = h5py.File(fileName, 'r')
        req = '/' + 'E' + '/' + str(idx) + '/'
        a = f[req+'a'].value
        err = f[req+'err'].value
        f.close()

        return a, err

    def readReq(self, fileName, idx):
        f = h5py.File(fileName, 'r')
        req = '/' + 'tw' + '/' + str(idx) + '/'
        a = f[req+'a'].value
        w = f[req+'w'].value
        err = f[req+'err'].value
        f.close()

        return a, w, err
    
    def stabEig(self, a0):
        stab = self.ks.stab(a0).T
        eigvalue, eigvector = LA.eig(stab)
        eigvalue, eigvector = sortByReal(eigvalue, eigvector)
        return eigvalue, eigvector


    def stabReqEig(self, a0, w):
        stab = self.ks.stabReq(a0, w).T
        eigvalue, eigvector = LA.eig(stab)
        eigvalue, eigvector = sortByReal(eigvalue, eigvector)
        return eigvalue, eigvector

    def toStr(self, poType, idx, L=22, flag=0):
        if flag == 0:
            return poType + '/' + format(idx, '06d')
        else:
            return format(L, '010.6f') + '/' + poType + '/' + format(idx, '06d')

    def checkExist(self, fileName, groupName):
        f = h5py.File(fileName, 'r')
        x = groupName in f
        f.close()
        return x

    def readPO(self, fileName, groupName, isRPO, hasNstp=True, flag=0):
        f = h5py.File(fileName, 'r')
        DS = '/' + groupName + '/'
        a = f[DS+'a'].value
        T = f[DS+'T'].value
        nstp = f[DS+'nstp'].value if hasNstp else 0
        err = f[DS+'err'].value
        theta = f[DS+'theta'].value if isRPO else 0
        e = f[DS+'e'].value if flag > 0 else None
        v = f[DS+'v'].value if flag > 1 else None
        f.close()
        return a, T, nstp, theta, err, e, v


    def copyTo(self, inFile, outFile, poType, r):
        inF = h5py.File(inFile, 'r')
        outF = h5py.File(outFile, 'a')
        if not ('/' + poType in outF):
            outF.create_group('/' + poType)
        for i in r:
            print i
            ds = '/' + poType + '/' + str(i)
            h5py.h5o.copy(inF.id, ds, outF.id, ds)

        inF.close()
        outF.close()


    def oneConfig(self, A, isFourier=True, 
                  size=[6, 5], labs=[r'$x$', r'$u$'],
                  xlim=[0, 22],
                  axisLabelSize=20, tickSize=None,
                  save=False, name='out.png'):
        """
        plot the configuration at one point 
        or plot one eigen vector.
        
        Parameter
        ======
        isFourier : is the input the Fourier modes of A. If it is, then we need back FFT.
        """
        fig, ax = pl2d(size=size, labs=labs, xlim=xlim, 
                       axisLabelSize=axisLabelSize, tickSize=tickSize)
        if isFourier:
            A = self.F2C(A)
        ax.plot(np.linspace(0, self.L, A.shape[0]), A, lw=1.5)
        ax2d(fig, ax, save=save, name=name)

    def config(self, A, ext, isFourier=True, barOn=True,
               barTicks=[-3, -2, -1, 0, 1, 2, 3], colortype='jet',
               percent='5%', size=[3, 6], labs=[r'$x$', r'$t$'],
               axisLabelSize=20, tickSize=None,
               save=False, name='out.png'):
        """
        plot the color map of the states
        """
        if isFourier:
            A = self.F2C(A)

        fig, ax = pl2d(size=size, labs=labs, axisLabelSize=axisLabelSize, tickSize=tickSize)
        im = ax.imshow(A, cmap=plt.get_cmap(colortype), extent=ext,
                       aspect='auto', origin='lower')
        ax.grid('on')
        if barOn:
            dr = make_axes_locatable(ax)
            cax = dr.append_axes('right', size=percent, pad=0.05)
            bar = plt.colorbar(im, cax=cax, ticks=barTicks)

        ax2d(fig, ax, save=save, name=name)


    def poHeat(self, fileName, poType, poId, NT=1, Ts=100, fixT=False):
        """
        plot the heat map of ppo/rpo.
        Sometimes, a few periods make it easy to observe the state space.
        Also, fixing an integration time makes it easy to see the transition

        NT : the number of periods need to be ploted
        """
        a0, T, nstp, r, s = self.readPO(fileName, poType, poId)
        h = T / nstp
        if fixT:
            aa = self.ks.intg(a0, h, np.int(Ts/h), 5)
            self.config(aa, [0, ks.d, 0, Ts])
        else:
            aa = self.ks.intg(a0, h, nstp*NT, 5)
            self.config(aa, [0, ks.d, 0, T*NT])

<file_sep>import os
from py_ks import *
from personalFunctions import *

##################################################


def add_subplot_axes(ax, rect, axisbg='w'):
    """
    function to add embedded plot
    rect = [ x of left corner, y of left corner, width, height ] in
    percentage
    """
    fig = plt.gcf()
    box = ax.get_position()
    width = box.width
    height = box.height
    inax_position = ax.transAxes.transform(rect[0:2])
    transFigure = fig.transFigure.inverted()
    infig_position = transFigure.transform(inax_position)
    x = infig_position[0]
    y = infig_position[1]
    width *= rect[2]
    height *= rect[3]  # <= Typo was here
    subax = fig.add_axes([x, y, width, height], axisbg=axisbg)
    x_labelsize = subax.get_xticklabels()[0].get_size()
    y_labelsize = subax.get_yticklabels()[0].get_size()
    x_labelsize *= rect[2]**0.5
    y_labelsize *= rect[3]**0.5
    subax.xaxis.set_tick_params(labelsize=x_labelsize)
    subax.yaxis.set_tick_params(labelsize=y_labelsize)
    return subax


def setAxis(ax):
    # ax.set_xlabel(r'$\theta$', fontsize=20, labelpad=-40)
    ax.set_xticks([0., .125*pi, 0.25*pi, 0.375*pi, 0.5*pi])
    ax.set_xticklabels(["$0$", r"$\frac{1}{8}\pi$", r"$\frac{1}{4}\pi$",
                        r"$\frac{3}{8}\pi$", r"$\frac{1}{2}\pi$"],
                       fontsize=15)
    # ax.legend(loc='best', fontsize=12)
    ax.set_yscale('log')
    # ax.set_ylim([0.01, 100])
    # ax.text(0.02, 20, r'$\rho(\theta)$', fontsize=20)
    # ax.set_ylabel(r'$\rho(\theta)$', fontsize=20, labelpad=-55)


def filterAng(a, ns, angSpan, angNum):
    """
    filter the bad statistic points
    because a very small fraction of Floquet vectors corresponding
    to high Fourier modes are not well told apart, so there are
    a small fraction of misleading close to zeros angles for
    non-physical space.
    """
    for i in range(29):
        n = a[0].shape[0]
        for j in range(n):
            y = a[i][j]*ns/(angSpan[i]*angNum[i])
            if y < 2e-2:
                a[i][j] = 0


situation = 2

if situation == 1:
    ##################################################
    # load data
    ixRange = range(0, 29)
    N = len(ixRange)

    folder = './anglePOs64/ppo/space/'
    folder2 = './anglePOs64/rpo/space/'
    ns = 1000

    # collect the data with rpo, ppo combined
    angs = []
    for i in range(N):
        print i
        as1 = np.empty(0)
        as2 = np.empty(0)
        for j in range(1, 201):
            f1 = folder + str(j) + '/ang' + str(i) + '.dat'
            if os.stat(f1).st_size > 0:
                ang = np.arccos(np.loadtxt(f1))
                as1 = np.append(as1, ang)

            f2 = folder2 + str(j) + '/ang' + str(i) + '.dat'
            if os.stat(f2).st_size > 0:
                ang2 = np.arccos(np.loadtxt(f2))
                as2 = np.append(as2, ang2)

        angs.append(np.append(as1, as2))
        # angs.append(as2)
        # angs.append(as1)

    ##################################################

    case = 2

    if case == 1:
        """
        angle distribution in ppo and rpo
        """
        a = []
        b = []
        angNum = []
        angSpan = []
        for i in range(N):
            print i
            angNum.append(angs[i].shape[0])
            angSpan.append(max(angs[i])-min(angs[i]))
            at, bt = histogram(angs[i], ns)
            a.append(at)
            b.append(bt)

        labs = ['k='+str(i+1) for i in ixRange]

        np.savez_compressed('ab', a=a, b=b, ns=ns, angSpan=angSpan,
                            angNum=angNum)

        fig = plt.figure(figsize=(4, 1.5))
        ax = fig.add_subplot(111)
        for i in range(7):
            ax.plot(b[i][:-1], a[i]*ns/(angSpan[i]*angNum[i]), label=labs[i],
                    lw=1.5)
        setAxis(ax)
        plt.tight_layout(pad=0)
        plt.show(block=False)

        fig = plt.figure(figsize=(4, 1.5))
        ax = fig.add_subplot(111)
        colors = cm.rainbow(linspace(0, 1, 11))
        for ix in range(11):
            i = 7 + 2*ix
            ax.plot(b[i][:-1], a[i]*ns/(angSpan[i]*angNum[i]), c=colors[ix], lw=1.5)
        setAxis(ax)
        plt.tight_layout(pad=0)
        plt.show(block=False)

    if case == 2:
        """
        try to locate the resource of bad distribution at the bottom
        """
        a = []
        b = []
        angNum = []
        angSpan = []

        for i in range(N):
            if angs[i].shape[0] > 0:
                angNum.append(angs[i].shape[0])
                angSpan.append(max(angs[i])-min(angs[i]))
                at, bt = histogram(angs[i], ns)
                a.append(at)
                b.append(bt)

        labs = ['k='+str(i+1) for i in ixRange]

        fig = plt.figure(figsize=(4, 1.5))
        ax = fig.add_subplot(111)
        for i in range(len(a)):
            ax.plot(b[i][:-1], a[i]*ns/(angSpan[i]*angNum[i]), label=labs[i],
                    lw=1.5)
        setAxis(ax)
        plt.tight_layout(pad=0)
        plt.show(block=False)

    if case == 20:
        a = []
        b = []
        angNum = []
        angSpan = []
        for i in range(N):
            print i
            angNum.append(angs[i].shape[0])
            angSpan.append(max(angs[i])-min(angs[i]))
            at, bt = histogram(log(angs[i]), ns)
            a.append(at)
            b.append(bt)

        fig = plt.figure(figsize=(7, 5))
        ax = fig.add_subplot(111)

        colors = cm.rainbow(linspace(0, 1, N))
        #labs = ['(1-' + str(i+1) + ',' + str(i+2) + '-30)' for i in ixRange]
        labs = ['(' + str(i+1) + ',' + str(i+2) + ')' for i in ixRange]
        labx = [pi/16, pi/8*1.1, pi/8*0.9, pi/8*3*0.9, pi/2*0.8]
        laby = [0.9, 0.02, 0.1, 0.05, 0.005]

        ax.set_xlabel(r'$\theta$', size='large')
        ax.set_xticks([0., .125*pi, 0.25*pi, 0.375*pi])
        ax.set_xticklabels(["$0$", r"$\frac{1}{8}\pi$", r"$\frac{2}{8}\pi$",
                            r"$\frac{3}{8}\pi$"])

        for i in range(9):
            ax.scatter(b[i][:-1], a[i]*ns/(angSpan[i]*angNum[i]), s=7,
                       c=colors[i], edgecolor='none', label=labs[i])

        ax.legend(fontsize='small', loc='upper center', ncol=1,
                  bbox_to_anchor=(1.1, 1), fancybox=True)
        ax.set_yscale('log')
        ax.set_ylim([0.001, 1000])
        ax.set_ylabel(r'$\rho(\theta)$', size='large')

        plt.tight_layout(pad=0)
        plt.show()

    if case == 30:
        nstps = []
        for i in range(200):
            a, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', 'rpo', i+1)
            nstps.append(nstp)
        nstps = np.array(nstps)


if situation == 2:
    """
    pick out the orbit with smallest angle
    """
    ixRange = range(0, 29)
    N = len(ixRange)

    folder = './anglePOs64/ppo/space/'
    folder2 = './anglePOs64/rpo/space/'
    ns = 1000

    # collect the data with rpo, ppo combined
    as1 = []
    as2 = []
    n1 = []
    n2 = []
    i = 1
    for j in range(1, 201):
        f1 = folder + str(j) + '/ang' + str(i) + '.dat'
        if os.stat(f1).st_size > 0:
            ang = np.arccos(np.loadtxt(f1))
            as1 = np.append(as1, ang)
            n1.append(ang.shape[0])
        else:
            n1.append(0)

        f2 = folder2 + str(j) + '/ang' + str(i) + '.dat'
        if os.stat(f2).st_size > 0:
            ang2 = np.arccos(np.loadtxt(f2))
            as2 = np.append(as2, ang2)
            n2.append(ang2.shape[0])
        else:
            n2.append(0)

    ma1 = np.min(as1)
    ma2 = np.min(as2)
    ix1 = np.argmin(as1)
    ix2 = np.argmin(as2)
    print ma1, ma2, ix1, ix2
    
    s = 0
    for i in range(len(n1)):
        s += n1[i]
        if s >= ix1:
            print i, s
            break

    mix = i + 1
    i1 = np.sum(n1[:i])
    i2 = np.sum(n1[:i+1])
    fig = plt.figure(figsize=(6, 4))
    ax = fig.add_subplot(111)
    ax.plot(as1[i1:i2], lw=1.5)
    ax.set_yscale('log')
    ax.set_ylabel(r'$\theta$')
    plt.tight_layout(pad=0)
    plt.show(block=False)

if situation == 3:
    """
    After we pick out the smallest angle orbit, let us
    plot the distribution
    """
    ixRange = range(0, 29)
    N = len(ixRange)

    folder = './anglePOs64/ppo/space/147'
    ns = 1000

    # collect the data with rpo, ppo combined
    as1 = []

    for i in range(N):
        f1 = folder + '/ang' + str(i) + '.dat'
        if os.stat(f1).st_size > 0:
            ang = arccos(loadtxt(f1))
            as1.append(ang)
        else:
            as1.append(np.array([]))
            
    a = []
    b = []
    for i in range(N):
        at, bt = histogram(as1[i], ns)
        # print as1[i].shape, at.shape, bt.shape
        a.append(at)
        b.append(bt)
    
    labs = ['k='+str(i+1) for i in ixRange]
    fig = plt.figure(figsize=(4, 1.5))
    ax = fig.add_subplot(111)
    for i in range(7):
        ax.plot(b[i][:-1], a[i], label=labs[i],
                lw=1.5)
    setAxis(ax)
    plt.tight_layout(pad=0)
    plt.show(block=False)

    fig = plt.figure(figsize=(4, 1.5))
    ax = fig.add_subplot(111)
    colors = cm.rainbow(linspace(0, 1, 11))
    for ix in range(11):
        i = 7 + 2*ix
        ax.plot(b[i][:-1], a[i], c=colors[ix], lw=1.5)
    setAxis(ax)
    plt.tight_layout(pad=0)
    plt.show(block=False)

    
if situation == 4:
    """
    There seems periodic peaks on top of the angle
    for ppo 147, we want to find out the reason
    """
    poType = 'ppo'
    poId = 147
    a0, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', poType, poId)
    h = T / nstp
    ks = pyKS(64, h, 22)
    aa = ks.intg(a0, nstp, 5)
    # aa = ks.reduceReflection(ks.orbitToSlice(aa)[0])

    peaks = [180, 1485, 3701, 6243, 8980, 11262, 13869, 16541]
    colors = plt.cm.winter(np.linspace(0, 1, len(peaks)))
    i1 = 0
    i2 = 2
    i3 = 3
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa[:, i1], aa[:, i2], aa[:, i3], c='r', lw=2)
    for i, c in zip(peaks, colors):
        ax.scatter(aa[i, i1], aa[i, i2], aa[i, i3], marker='o', c=c,
                   edgecolor='none', s=50)
    ax.set_xlabel(r'$b_1$', fontsize=30)
    ax.set_ylabel(r'$b_2$', fontsize=30)
    ax.set_zlabel(r'$c_2$', fontsize=30)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def getDet(poType, poId, k=30):
    fv = KSreadFV('../ks22h001t120x64EV.h5', poType, poId)
    n, m = fv.shape

    ds = np.zeros(n)
    for i in range(n):
        x = np.reshape(fv[i], (30, m/30))
        x = x[:k, :k]
        ds[i] = LA.det(x)

    return ds


def getDetK(poType, poId):
    dss = []
    for k in range(1, 8) + range(8, 31, 2):
        # print k
        ds = getDet(poType, poId, k)
        dss.append(ds)

    return np.array(dss)


if situation == 5:
    """
    try to see whether the determiant of Floquet vector matrix change sign
    for a specific orbit
    """
    poType = 'ppo'
    for i in range(146, 147):
        poId = i+1
        ds = getDet(poType, poId, 4)
        print poId, np.sign(np.max(ds)) * np.sign(np.min(ds))

    plot1dfig(abs(ds), yscale='log')

if situation == 6:
    """
    try to plot the determinant of the leading k block.
    """
    poType = 'ppo'
    poId = 147
    dss = getDetK(poType, poId)
    m, n = dss.shape
    ers = np.zeros(m-1)
    for i in range(m-1):
        ers[i] = norm(dss[i]-dss[-1])

    plot1dfig(ers, yscale='log')
    plot1dfig(abs(dss[3]), yscale='log', labs=[None, '|det|'],
              axisLabelSize=15, size=[6, 4])

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    ax.plot(abs(dss[2]), lw=1, label=r'$k=3$')
    ax.plot(abs(dss[5]), lw=2, ls='--', label=r'$k=6$')
    ax.plot(abs(dss[6]), lw=2, ls='-.', label=r'$k=7$')
    # ax.plot(abs(dss[7]), lw=1, label=r'$k=8$')
    # ax.plot(abs(dss[12]), lw=2, ls='--', label=r'$k=18$')
    # ax.plot(abs(dss[18]), lw=2, ls='-.', label=r'$k=30$')
    ax.set_ylabel('|det|', fontsize=15)
    ax.set_yscale('log')
    fig.tight_layout(pad=0)
    plt.legend(loc='best')
    plt.show(block=False)

if situation == 7:
    """
    """
    N = 64
    h = 0.001
    L = 22

    ks = pyKS(N, h, L)

    a0, w, err = KSreadReq('../ks22Reqx64.h5', 1)
    es, vs = KSstabReqEig(ks, a0, w)

    a0, err = KSreadEq('../ks22Reqx64.h5', 1)
    es, vs = KSstabEig(ks, a0)

    a0H = ks.orbitToSlice(a0)[0]

if situation == 8:
    """
    There seems periodic peaks on top of the angle
    for ppo 147, we want to find out the reason. Here
    I use covariant axis to visulzie ppo
    """
    poType = 'ppo'
    poId = 147
    a0, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', poType, poId)
    h = T / nstp
    ks = pyKS(64, h, 22)
    aa = ks.intg(a0, nstp, 5)
    # aa = ks.reduceReflection(ks.orbitToSlice(aa)[0])

    peaks = [180, 1485, 3701, 6243, 8980, 11262, 13869, 16541]
    colors = plt.cm.winter(np.linspace(0, 1, len(peaks)))
    i1 = 0
    i2 = 2
    i3 = 3
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa[:, i1], aa[:, i2], aa[:, i3], c='r', lw=2)
    for i, c in zip(peaks, colors):
        ax.scatter(aa[i, i1], aa[i, i2], aa[i, i3], marker='o', c=c,
                   edgecolor='none', s=50)
    ax.set_xlabel(r'$b_1$', fontsize=30)
    ax.set_ylabel(r'$b_2$', fontsize=30)
    ax.set_zlabel(r'$c_2$', fontsize=30)
    fig.tight_layout(pad=0)
    plt.show(block=False)

<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' orbitToSlice.cc ../ksint.cc  -I../../../include -I$XDAPPS/eigen/include/eigen3 -lfftw3
 * */
#include "ksint.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>
using Eigen::ArrayXXd;
using Eigen::ArrayXd;
using Eigen::Map;

/* transform trajectory into 1st mode slice */
static std::pair<MatrixXd, VectorXd>
orbitToSlice(double *aa, const int N, const int M){
    KS ks(N+2);
    Map<MatrixXd> aa2(aa, N, M);
    return ks.orbitToSlice(aa2);
}


void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    // get the pointer and the size of input 
    double *aa = mxGetPr(prhs[0]);
    mwSize N = mxGetM(prhs[0]);
    mwSize M = mxGetN(prhs[0]);
    plhs[0] = mxCreateDoubleMatrix(N, M, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(M, 1, mxREAL);

    std::pair<MatrixXd, VectorXd> tmp = orbitToSlice(aa, N, M);
    memcpy(mxGetPr(plhs[0]), &tmp.first(0,0), N*M*sizeof(double));
    memcpy(mxGetPr(plhs[1]), &tmp.second(0), M*sizeof(double));
}
<file_sep>from personalFunctions import *
from py_ks import *

case = 10

N, L = 64, 22
eqFile =  '../../data/ks22Reqx64.h5'
poFile = '../../data/ks22h001t120x64EV.h5'

if case == 10:
    """
    print the exponents of ppo/rpo
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    fe = ksp.readFE(poFile, 'rpo', 3)
    np.set_printoptions(formatter={'float': '{: 15.6f}'.format})
    print fe[:, np.r_[0:10, -4:0]].T  # print formated 10 first and 4 last
    np.set_printoptions()
    print 
    print fe[0, :4].T                   # print the marginal ones

<file_sep>/* How to compile:
 * mpicxx test_ksrefine.cc -cxx=h5c++ -O3  -L ../../lib -I ../../include
 * -I $XDAPPS/eigen/include/eigen3 -std=c++0x
 * -lreadks -lksrefine -lped -lksint -lfftw3 -lm -std=c++0x
 * */
#include "ksrefine.hpp"
#include "ksint.hpp"
#include "readks.hpp"
#include <iostream>
#include <cmath>
#include <mpi.h>
using namespace std;
using namespace Eigen;

int main(int argc, char **argv)
{
  cout.precision(16);
  switch (3) 
    {
    case 1: // test multiF(). For rpo, the shift should be reversed.
      {
	string fileName("../../data/ks22h02t100");
	string ppType("ppo");
	const int ppId = 1;

	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5");
	std::tuple<ArrayXd, double, double, double, double>
	  pp = readks.readKSinit(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	int nstp = (int)get<2>(pp);
	double r = get<3>(pp);
	double s = get<4>(pp);
	
	KS ks(32, T/nstp, 22);
	ArrayXXd aa = ks.intg(a, nstp, nstp/10);
	KSrefine ksrefine(32, 22);
	VectorXd F = ksrefine.multiF(ks, aa.leftCols(aa.cols()-1),
				     nstp/10, ppType, -s/22*2*M_PI);
	cout << F.norm() << endl;
	
	break;
      }
    
    case 2: // test findPO() 
      {
	const int Nks = 64;
	const int N = Nks - 2;
	const double L = 22;
	string fileName("../../data/ks22h1t120x64");
	string ppType("rpo");
	const int ppId = 23;

	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks, L);
	std::tuple<ArrayXd, double, double>
	  pp = readks.readKSorigin(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	double s = get<2>(pp); cout << s << endl;

	const int nstp = ceil(ceil(T/0.001)/10)*10; cout << nstp << endl;
	KSrefine ksrefine(Nks, L);
	tuple<MatrixXd, double, double, double> 
	  p = ksrefine.findPOmulti(a, T, nstp, 10, ppType,
				   0.1, -s/L*2*M_PI, 20, 1e-14, true, false);
	cout << get<0>(p).cols() << endl;
	cout << get<1>(p) * nstp << endl;
	cout << get<2>(p) << endl;
	cout << get<3>(p) << endl;

	KS ks(Nks, get<1>(p), L);
	VectorXd df = ksrefine.multiF(ks, get<0>(p), nstp/10, ppType, get<2>(p));
	VectorXd df2 = ksrefine.multiF(ks, get<0>(p).col(0), nstp, ppType, get<2>(p));
	cout << df.norm() << endl;
	cout << df2.norm() << endl;
	break;
	  
      }

    case 3: // distiguish rpo5 and rpo6
      {
	const int Nks = 32;
	const int N = Nks - 2;
	const double L = 22;
	string fileName("../../data/ks22h1t120");
	string ppType("rpo");
	const int ppId = 17;

	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks, L);
	std::tuple<ArrayXd, double, double>
	  pp = readks.readKSorigin(ppType, ppId);	
	ArrayXd &a = get<0>(pp); 
	double T = get<1>(pp);
	double s = get<2>(pp); cout << s << endl;

	const int nstp = ceil(ceil(T/0.02)/10)*10; cout << nstp << endl;
	KSrefine ksrefine(Nks, L);
	tuple<MatrixXd, double, double, double> 
	  p = ksrefine.findPOmulti(a, T, nstp, 10, ppType,
				   0.25, -s/L*2*M_PI, 100, 1e-15, true, false);
	double th = get<2>(p); cout << th << endl;
	double Tnew = get<1>(p) * nstp; std::cout << Tnew << std::endl;
	cout << get<0>(p).cols() << endl;
	cout << get<3>(p) << endl;

	// calculate the Flqouet exponents 
	KS ks(Nks, get<1>(p), L);
	MatrixXd daa = ks.intgjMulti(get<0>(p), nstp/10, 1, 1).second;
	PED ped;
	ped.reverseOrderSize(daa); // reverse order.
	if(ppType.compare("ppo") == 0)
	    daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
	else // R*J for rpo
	    daa.leftCols(N) = ks.rotate(daa.leftCols(N), th);
	//MatrixXd eigvals = ped.EigVals(daa, 1000, 1e-15, true);
	//eigvals.col(0) = eigvals.col(0).array()/Tnew;

	//cout << eigvals << endl;
	
	// write data
	/*
	fileName = "../../data/ks22h02t100";
	ReadKS readks2(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks, L);
	readks2.writeKSinit("../../data/ks22h1t120.h5",  ppType, ppId,
			   make_tuple(get<0>(p).col(0), get<1>(p)*nstp, nstp, 
				      get<3>(p), -L/(2*M_PI)*get<2>(p))
			   );
	readks2.calKSOneOrbit(ppType, ppId, 1000, 1e-15, false);
	*/
	break;
	  
      }

    case 4: // refine the inital condition for N=32
      {
	const int Nks = 64;
	const int N = Nks - 2;
	const double L = 22;
	string fileName("../../data/ks22h1t120x64");
	string ppType("ppo");
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks, L);
	
	int NN(0);
	if(ppType.compare("ppo") == 0) NN = 840;
	else NN = 834;

	const int MaxN = 30;
	const double tol = 1e-14;
	const int M = 10;

	////////////////////////////////////////////////////////////
	// mpi part 
	int left = 0;
	int right = NN;
	
	MPI_Init(&argc, &argv);
	int rank, num;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &num);
	int inc = ceil( (double)(right - left) / num);
	int istart = left + rank * inc;
	int iend = min( left + (rank+1) * inc, right);
	printf("MPI : %d / %d; range : %d - %d \n", rank, num, istart, iend);
	////////////////////////////////////////////////////////////

	for(int i = istart; i < iend; i++){
	  const int ppId = i+1; 
	  std::tuple<ArrayXd, double, double>
	    pp = readks.readKSorigin(ppType, ppId);	
	  ArrayXd &a = get<0>(pp); 
	  double T = get<1>(pp);
	  double s = get<2>(pp); 

	  const int nstp = ceil(ceil(T/0.001)/10)*10;
	  KSrefine ksrefine(Nks, L);
	  tuple<MatrixXd, double, double, double> 
	    p = ksrefine.findPOmulti(a, T, nstp, M, ppType,
				     0.1, -s/L*2*M_PI, MaxN, tol, false, false);
	  
	  printf("r = %g for %s ppId = %d \n", get<3>(p), ppType.c_str(), ppId);
	  readks.writeKSinitMulti("../../data/tmp.h5", ppType, ppId, 
				  make_tuple(get<0>(p), get<1>(p)*nstp, nstp, 
					     get<3>(p), -L/(2*M_PI)*get<2>(p))
				  );
	}

	////////////////////////////////////////////////////////////
	MPI_Finalize();
	////////////////////////////////////////////////////////////
	
	break;
      }
      
    case 5 : // refine step by step
      {
	const int Nks = 64;
	const int N = Nks - 2;
	const double L = 22;
	string fileName("../../data/ks22h001t120x64");
	string ppType("rpo");
	ReadKS readks(fileName+".h5", fileName+"E.h5", fileName+"EV.h5", N, Nks, L);
	
	int NN(0);
	if(ppType.compare("ppo") == 0) NN = 840;
	else NN = 834;

	const int MaxN = 100;
	const double tol = 1e-14;
	const int M = 10;

	////////////////////////////////////////////////////////////
	// mpi part 
	int left = 0;
	int right = NN;
	
	MPI_Init(&argc, &argv);
	int rank, num;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &num);
	int inc = ceil( (double)(right - left) / num);
	int istart = left + rank * inc;
	int iend = min( left + (rank+1) * inc, right);
	printf("MPI : %d / %d; range : %d - %d \n", rank, num, istart, iend);
	////////////////////////////////////////////////////////////

	for(int i = istart; i < iend; i++){
	  const int ppId = i+1; 
	  // printf("\n****  ppId = %d   ****** \n", ppId); 
	  std::tuple<ArrayXd, double, double, double, double>
	    pp = readks.readKSinit(ppType, ppId);	
	  ArrayXd &a = get<0>(pp); 
	  double T = get<1>(pp);
	  int nstp = (int) get<2>(pp);
	  double r = get<3>(pp);  // printf("r = %g\n", r);
	  double s = get<4>(pp); 

	  double hinit = T / nstp;
	  // nstp *= 5;
	  KSrefine ksrefine(Nks, L);
	  tuple<MatrixXd, double, double, double> 
	    p = ksrefine.findPOmulti(a, T, nstp, M, ppType,
				     hinit, -s/L*2*M_PI, MaxN, tol, false, true);
	  
	  printf("r = %g for %s ppId = %d \n", get<3>(p), ppType.c_str(), ppId);
	  readks.writeKSinitMulti("../../data/tmp.h5", ppType, ppId, 
				  make_tuple(get<0>(p), get<1>(p)*nstp, nstp, 
					     get<3>(p), -L/(2*M_PI)*get<2>(p))
				  );

	  
	}
	
	////////////////////////////////////////////////////////////
	MPI_Finalize();
	////////////////////////////////////////////////////////////

	break;
      }
      
    }
  return 0;
}


<file_sep>#!/bin/bash

# usage:
# ./createAll 0 => compile all cases
# ./createAll 1 => single thread caes

rm -rf bin pylib
b2 && mv pylib/py_CQCGL1dSub.so /usr/local/home/xiong/00git/research/lib/boostPython/
rm -rf bin pylib

<file_sep>/* g++ test_myfft.cc -lmyfft -lfftw3 -lfftw3_threads -ldenseRoutines -std=c++11  -I ../../include/ -L ../../lib/ -I $XDAPPS/eigen/include/eigen3 -O3
 */
#include "myfft.hpp"
#include "denseRoutines.hpp"
#include <iostream>
#include <time.h>

#define CE(x) cout << (x) << endl << endl

using namespace std;
using namespace MyFFT;
using namespace Eigen;
using namespace denseRoutines;

int main(){

    switch (2) {

    case 1 :{
	RFFT F(64, 1);
	ArrayXcd x(ArrayXcd::Random(33));

	F.vc1 = x;
	F.ifft();

	break;
    }
       
    case 2 : {			/* test FFT2d */
	/* for large 2d matrix
	   The c++ version is 2 times slower than
	   Matlab FFT
	*/
	
	clock_t t;
	FFT2d F(8, 4);
	ArrayXXcd x = loadComplex("re.dat", "im.dat");	
	CE(x);
	F.v1 = x;
	
	t = clock();
	for (int i = 0; i < 100; i++) F.ifft();
	t = clock() - t;
	cout << "ifft time: " << ((float)t)/CLOCKS_PER_SEC << endl;
	
	savetxt("f1.dat", F.v2.real());
	savetxt("f2.dat", F.v2.imag());
	CE(F.v2);

	F.fft();
	// CE(F.v3);

	break;
    }

    default : {
	cout << "please indicate the correct number" << cout;
	break;
    }
	
    }

    return 0;

}
<file_sep>// g++ randWalk.cc -O3 -std=c++11 -I$EIGEN -I$RESH/include -L$RESH/lib -ldenseRoutines
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <Eigen/Dense>
#include "denseRoutines.hpp"

using namespace std;
using namespace Eigen;
using namespace denseRoutines;

typedef std::complex<double> dcp;

VectorXd 
walk2d(const int Np, const int Ns, const double tol){
    std::srand(std::time(0));
    double max = static_cast<double>(RAND_MAX);

    VectorXd a(Np), s(Ns);
    VectorXcd z(Np);
    a.setZero();
    z.setZero();
    for (int i = 0; i < Ns; i++){
	for(int j = 0; j < Np; j++){
	    double t, m;
	    do {
		t = std::rand() / max;
		Vector3d d;
		d << fabs(t-a(j)), fabs(t-a(j)+1), fabs(t-a(j)-1) ;
		m = d.minCoeff();
	    } while (m < tol);

	    a(j) = t;
	    z(j) += exp(t*2*M_PI*dcp(0,1));
	}
	
	s(i) = (z.array() * z.array().conjugate()).real().mean();
    }
    
    return s;
}

int main(){

    
    const int Np = 10000;
    const int Ns = 1000;
    
    int n = 4;
    MatrixXd ss(Ns, n);
    for (int i = 0; i < n; i++){
	ss.col(i) = walk2d(Np, Ns, 0.1*i);
    }
    
    savetxt("ss.dat", ss);

    return 0;
}
<file_sep>/* to comiple:
 *
 * h5c++ test_CQCGL1dRpo.cc -std=c++11 -O3 -march=corei7 -msse4 -msse2 -I$EIGEN -I$RESH/include  -L$RESH/lib -lCQCGL1dRpo -lCQCGL1dReq -lCQCGL1d -lmyfft -lfftw3 -lm -lsparseRoutines -ldenseRoutines -literMethod -lmyH5
 *
 */

#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <ctime>

#include "CQCGL1dReq.hpp"
#include "CQCGL1dRpo.hpp"

using namespace std; 
using namespace Eigen;
using namespace iterMethod;
using namespace MyH5;

#define cee(x) (cout << (x) << endl << endl)

#define CASE_70

int main(){
    
    cout.precision(15);
    GMRES_IN_PRINT_FREQUENCE = 50;
    HOOK_PRINT_FREQUENCE = 1;
    GMRES_OUT_PRINT = false;
    

#ifdef CASE_10
    //======================================================================
    // to visulize the limit cycle first 
    const int N = 1024;
    const double L = 50;
    double Bi = 0.8;
    double Gi = -3.6;
    
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    string file = "/usr/local/home/xiong/00git/research/data/cgl/rpoT2X1.h5";
    ArrayXd a0;
    double T, th, phi, err;
    int nstp; 
    std::tie(a0, T, nstp, th, phi, err) = CQCGL1dRpo::read(file, "0.360000/1");
    a0 *= 0.316;

    ArrayXXd aa = cgl.intg(a0, 1e-3, 20000, 10);
    savetxt("aa.dat", aa);
    savetxt("lte.dat", cgl.lte);
    
#endif
#ifdef CASE_20
    //======================================================================
    // find one limit cycle using previous data
    const int N = 1024;
    const double L = 50;
    double Bi = 1.9;
    double Gi = -4.1;
    
    int id = 1;
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoBiGi2.h5";
    ArrayXd a0;
    double T0, th0, phi0, err0;
    int nstp0; 
    std::tie(a0, T0, nstp0, th0, phi0, err0) = CQCGL1dRpo::read(file, CQCGL1dRpo::toStr(Bi, Gi, id));
    
    cgl.Bi = 1.5;
    cgl.Gi -= 3.9;
    
    double T, th, phi, err;
    MatrixXd x;
    int nstp = nstp0;
    int flag;
    
    std::tie(x, err, flag) = cgl.findRPOM_hook2(a0, nstp, 8e-10, 1e-3, 50, 30, 1e-6, 300, 1);
    if (flag == 0) 
	CQCGL1dRpo::write2("../../data/cgl/rpoBiGi2.h5", cgl.toStr(cgl.Bi, cgl.Gi, 1), x, nstp, err);   

#endif
#ifdef CASE_50
    //====================================================================== 
    // find limit cycles by varying Bi and Gi but using propagated initial
    // condition
    const int N = 1024;
    const int L = 50;
    double Bi = 4.8;
    double Gi = -4.8;

    int id = 1;
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
	
    string file = "../../data/cgl/rpoBiGi2.h5";
    ArrayXd x0;
    double T0, th0, phi0, err0;
    int nstp0;
    std::tie(x0, T0, nstp0, th0, phi0, err0) = CQCGL1dRpo::read(file, CQCGL1dRpo::toStr(Bi, Gi, id));

    ArrayXd a0 = x0.head(cgl.Ndim);
    ArrayXXd aa = cgl.intg(a0, T0/nstp0, nstp0, 1);
    ArrayXd x1(cgl.Ndim+3);
    x1 << aa.col(3000), T0, th0, phi0;

    double T, th, phi, err;
    ArrayXd x;
    int flag, nstp;
    nstp = nstp0;
    
    cgl.Gi -= 0.1;
    if (!checkGroup(file, CQCGL1dRpo::toStr(cgl.Bi, cgl.Gi, id), false)){
	fprintf(stderr, "Bi = %g Gi = %g nstp = %d T0 = %g\n", cgl.Bi, cgl.Gi, nstp, T0);
	std::tie(x, err, flag) = cgl.findRPOM_hook2(x1, nstp, 8e-10, 1e-3, 50, 30, 1e-6, 300, 1);
	if(flag == 0) CQCGL1dRpo::write2(file, cgl.toStr(cgl.Bi, cgl.Gi, id), x, nstp, err);
    }
    
#endif
#ifdef CASE_60
    //======================================================================
    // find rpo of next one in Bi-Gi plane but using multishooting
    const int N = 1024;
    const double L = 50;
    double Bi = 5.5;
    double Gi = -5.2;
    
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoBiGi2.h5";

    ArrayXd x0;
    double T0, th0, phi0, err0;
    int nstp0; 

    std::tie(x0, T0, nstp0, th0, phi0, err0) = CQCGL1dRpo::read(file, CQCGL1dRpo::toStr(Bi, Gi, 1));
    ArrayXd a0 = x0.head(cgl.Ndim);
    ArrayXXd aa = cgl.intg(a0, T0/nstp0, nstp0, nstp0/4);
    MatrixXd x1(cgl.Ndim+3, 4);
    x1.col(0) << aa.col(0), T0/4, 0, 0;
    x1.col(1) << aa.col(1), T0/4, 0, 0;
    x1.col(2) << aa.col(2), T0/4, 0, 0;
    x1.col(3) << aa.col(3), T0/4, th0, phi0;
	
    double T, th, phi, err;
    MatrixXd x;
    int nstp = 1000;
    int flag;

    cgl.Gi += 0.1;
    cout << cgl.Bi << ' ' << cgl.Gi << endl;
    std::tie(x, err, flag) = cgl.findRPOM_hook2(x1, nstp, 8e-10, 1e-3, 50, 30, 1e-6, 300, 1);
    if (flag == 0) CQCGL1dRpo::write2("rpoBiGi2.h5", cgl.toStr(Bi, Gi, 1), x, nstp, err);    

#endif
#ifdef CASE_70
    //======================================================================
    // use saved guess directively
    const int N = 1024;
    const double L = 50;
    double Bi = 1.4;
    double Gi = -3.9;
    
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/p.h5";
    ArrayXd a0;
    double T0, th0, phi0, err0;
    int nstp0; 
    std::tie(a0, T0, nstp0, th0, phi0, err0) = CQCGL1dRpo::read(file, cgl.toStr(Bi, Gi, 1));
    VectorXd x0(cgl.Ndim+3);
    x0 << a0, T0, th0, phi0;
    // x0 << a0, 3, th0, -7.3;
    
    double T, th, phi, err;
    MatrixXd x;
    int nstp = nstp0;
    int flag;

    std::tie(x, err, flag) = cgl.findRPOM_hook2(x0, nstp, 8e-10, 1e-3, 50, 30, 1e-6, 300, 1);
    if (flag == 0) CQCGL1dRpo::write2("../../data/cgl/rpoBiGi2.h5", cgl.toStr(Bi, Gi, 1), x, nstp, err);   

#endif
#ifdef CASE_80
    //====================================================================== 
    // test the accuracy of a limit cycle
    const int N = 1024;
    const double L = 50;
    double Bi = 1.4;
    double Gi = -3.9;
    
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoBiGi2.h5";
    ArrayXd a0;
    double T0, th0, phi0, err0;
    int nstp0; 
    std::tie(a0, T0, nstp0, th0, phi0, err0) = CQCGL1dRpo::read(file, cgl.toStr(Bi, Gi, 1));
    printf("%g %g %g %g %d\n", T0, th0, phi0, err0, nstp0);

    double e = cgl.MFx2(a0, nstp0).norm();
    cee(e);

#endif
#ifdef CASE_100
    //====================================================================== 
    // find limit cycles by varying Bi and Gi
    const int N = 1024;
    const int L = 50;
    double Bi = 4.9;
    double Gi = -4.9;

    int id = 1;
    CQCGL1dRpo cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
	
    string file = "../../data/cgl/rpoBiGi2.h5";
    double step = -0.02;
    int Ns = 20;
    cgl.findRpoParaSeq(file, id, step, Ns, true, 1, 0);

    // for (int i = 1; i < NsB+1; i++){
    // 	cgl.Bi = Bi+i*stepB;
    // 	cgl.findRpoParaSeq(file, id, -0.1, 50, false);
    // }


#endif
#ifdef CASE_120
    //====================================================================== 
    // move rpo from one file to another file
    std::string fin = "../../data/cgl/rpoBiGiEV.h5";
    std::string fout = "../../data/cgl/rpoBiGiEV2.h5";
    
    for( int i = 0; i < 39; i++){
	double Bi = 1.9 + 0.1*i;
	for(int j = 0; j < 55; j++){
	    double Gi = -5.6 + 0.1*j;
	    string g = CQCGL1dRpo::toStr(Bi, Gi, 1);
	    if (checkGroup(fin, g, false) && !checkGroup(fout, g, false)){
		fprintf(stderr, "%d %g %g\n", 1, Bi, Gi);
		CQCGL1dRpo::move(fin, g, fout, g, 2);
	    }
	}
    }
    

#endif

    return 0;
    

}
<file_sep>#ifndef EIDC_H
#define EIDC_H

#include "EID.hpp"

////////////////////////////////////////////////////////////////////////////////
//   Exponential Integrator with complex data type
////////////////////////////////////////////////////////////////////////////////

class EIDc : public EID<std::complex<double>> {
    
 public:
    
    EIDc(){}
    EIDc(ArrayXcd *L, ArrayXXcd *Y, ArrayXXcd *N) : EID<std::complex<double>>(L, Y, N){}
    EIDc & operator=(const EIDc &x){
	return *this;
    }
    ~EIDc(){}
    
    inline ArrayXXcd MUL(const ArrayXcd &C, const ArrayXXcd &Y){ 
	return Y.colwise() * C;
    }
    
    inline ArrayXcd mean(const Ref<const ArrayXXcd> &x){
	return x.rowwise().mean();
    }
    
    inline ArrayXXcd ZR(ArrayXcd &z){
	int M1 = z.size();
	ArrayXd K = ArrayXd::LinSpaced(M, 1, M);
	ArrayXXcd r = R * (K/M * dcp(0,2*M_PI)).exp().transpose(); // row array.
	return z.replicate(1, M) + r.replicate(M1, 1);
    }
};

#endif /* EIDC_H */
<file_sep>#include "CQCGL1dRpo_arpack.hpp"
#include <arsnsym.h>
#include "myH5.hpp"

#define cee(x) (cout << (x) << endl << endl)

using namespace denseRoutines;
using namespace iterMethod;
using namespace Eigen;
using namespace std;
using namespace MyH5;


//////////////////////////////////////////////////////////////////////
//                      constructor                                 //
//////////////////////////////////////////////////////////////////////

// A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
CQCGL1dRpo_arpack::CQCGL1dRpo_arpack(int N, double d,
				     double Mu, double Dr, double Di, double Br, double Bi, 
				     double Gr, double Gi, int dimTan):
    CQCGL1dRpo(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}

// A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
CQCGL1dRpo_arpack::CQCGL1dRpo_arpack(int N, double d, 
				     double b, double c, double dr, double di, 
				     int dimTan):
    CQCGL1dRpo(N, d, b, c, dr, di, dimTan){}
    
// iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
CQCGL1dRpo_arpack::CQCGL1dRpo_arpack(int N, double d,
				     double delta, double beta, double D, double epsilon,
				     double mu, double nu, int dimTan) :
    CQCGL1dRpo(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

CQCGL1dRpo_arpack::~CQCGL1dRpo_arpack(){}

CQCGL1dRpo_arpack & CQCGL1dRpo_arpack::operator=(const CQCGL1dRpo_arpack &x){
    return *this;
}

/////////////////////////////////////////////////////////////////////////
//                     member functions                                //
/////////////////////////////////////////////////////////////////////////

/// @param[in] ne  number of eigenvalues wanted
std::pair<VectorXcd, MatrixXd>
CQCGL1dRpo_arpack::evRpo(const ArrayXd &a0, double h, int nstp, 
			 double th, double phi, int ne){
    int n = Ndim;
    
    VectorXd er(ne+1), ei(ne+1);
    MatrixXd v((ne+1)*n, 1);
    double *p_er = er.data();
    double *p_ei = ei.data();
    double *p_v = v.data();

    Jdotx jdotx(this, a0, h, nstp, th, phi);
    ARNonSymStdEig<double, Jdotx> dprob(n, ne, &jdotx, &Jdotx::mul, "LM");
    dprob.ChangeTol(1e-9);

    int nconv = dprob.EigenValVectors(p_v, p_er, p_ei);
    if (nconv < ne) fprintf(stderr, "arpack not converged. nconv = %d\n", nconv);

    // truncate if necessary
    VectorXcd e(nconv);
    e.real() = er.head(nconv);
    e.imag() = ei.head(nconv);
    v.resize(n, ne+1);
    MatrixXcd vc = vr2vc(e, v.leftCols(nconv));
    
    // sort the eigenvalues by their magnitude
    std::vector<int> id = csort(e, 2);
    VectorXcd e2(nconv);
    MatrixXcd vc2(n, nconv);
    for (int i = 0; i < nconv; i++ ){
	e2(i) = e(id[i]);
	vc2.col(i) = vc.col(id[i]);
    }
    MatrixXd vr = vc2vr(vc2);
    
    return std::make_pair(e2, vr);
}

/**
 * Bis and Gis have the same size. Bis[i] and Gis[i] give the pair.
 */ 
void 
CQCGL1dRpo_arpack::calEVParaSeq(std::string file, std::vector<double> Bis, 
				std::vector<double> Gis, int ne, bool saveV){
    double Bi0 = Bi;
    double Gi0 = Gi;

    ArrayXd x, a0;
    double T, th, phi, err;
    int nstp;
    VectorXcd e;
    MatrixXd v;

    assert(Bis.size() == Gis.size());

    for (int i = 0; i < Bis.size(); i++) {
	Bi = Bis[i];
	Gi = Gis[i];
	std::string g = toStr(Bi, Gi, 1);
	if( checkGroup(file, g, false) && !checkGroup(file, g + "/er", false) ) {
	    fprintf(stderr, "%4d/%4zd : %4g %4g\n", i, Bis.size(), Bi, Gi);
	    std::tie(x, T, nstp, th, phi, err) = read(file, g);
	    a0 = x.head(Ndim);
	    std::tie(e, v) = evRpo(a0, T/nstp, nstp, th, phi, ne);
	    writeE(file, g, e);
	    if (saveV) writeV(file, g, v);
	}
    }
    
    Bi = Bi0;
    Gi = Gi0;
}

/// @brief obtain the the remaing set that needs computing E and V. 
std::pair< std::vector<double>, std::vector<double> >
CQCGL1dRpo_arpack::getMissIds(std::string file, double Bi0, double Gi0, 
			      double incB, double incG, int nB, int nG){
    std::vector<double> Bis, Gis;
    for(int i = 0; i < nB; i++){
	double Bi = Bi0 + incB*i;
	for(int j = 0; j < nG; j++) {
	    double Gi = Gi0 + incG*j;
	    std::string g = toStr(Bi, Gi, 1);
	    if (checkGroup(file, g, false) && !checkGroup(file, g+"/er", false)){
		Bis.push_back(Bi);
		Gis.push_back(Gi);
	    }
	}
    }
    
    return std::make_pair(Bis, Gis);
}
<file_sep>#!/bin/bash

# usage:
# ./createAll

rm -rf bin pylib
b2 && mv pylib/py_ks.*so /usr/local/home/xiong/00git/research/lib/boostPython/ && rm -rf bin pylib


<file_sep>from py_cqcgl1d_threads import pyCqcgl1d
from personalFunctions import *


def plotcgl(Aamp, ext, barTicks=[0, 3], colortype='jet',
            percent='5%', size=[4, 5],
            axisLabelSize=20,
            save=False, name='out.png'):
    """
    plot the color map of the states
    """
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    ax.set_xlabel('x', fontsize=axisLabelSize)
    ax.set_ylabel('t', fontsize=axisLabelSize)
    im = ax.imshow(Aamp, cmap=plt.get_cmap(colortype), extent=ext,
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size=percent, pad=0.05)
    plt.colorbar(im, cax=cax, ticks=barTicks)
    fig.tight_layout(pad=0)
    if save:
        plt.savefig(name)
    else:
        plt.show(block=False)


case = 1

if case == 1:
    N = 1024
    d = 30
    h = 0.0002
    di = 0.06
    
    Y = loadtxt('Y.dat')
    plotcgl(Y, [0, 30, 0, 3])
<file_sep>
#ifndef CGL1D_H
#define CGL1D_H

#include "myfft.hpp"
#include "cqcgl1d.hpp"
#include "denseRoutines.hpp"

class Cgl1d : public Cqcgl1d {
    
public:
    Cgl1d(int N, double d, double h,
	  bool enableJacv, int Njacv,
	  double b, double c,
	  int threadNum);
protected:
    void NL(FFT &f);
    void jNL(FFT &f);
};

#endif CGL1D_H
<file_sep>#ifndef LORENZ_H
#define LORENZ_H

#include <Eigen/Dense>
#include <utility>
#include <algorithm>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>

#include "denseRoutines.hpp"


/**
 *        | sigma * (y -x)     |
 * v(x) = | rho * x - y - x*z  |
 *        | x*y - b*z          |
 */
class Lorenz {
    
public:
    
    double Sigma = 10;
    double B = 8.0 / 3;		/* caution: use float  */
    double Rho = 28;
    
    /* ============================================================ */
    Lorenz();
    ~Lorenz();
    Lorenz & operator=(const Lorenz &x);
    
    /* ============================================================ */
    
    Eigen::Vector3d vel(const Eigen::Ref<const Eigen::Vector3d> &x);
    Eigen::Matrix3d stab(const Eigen::Ref<const Eigen::Vector3d> &x);
    Eigen::MatrixXd velJ(const Eigen::Ref<const Eigen::MatrixXd> &x);
    Eigen::MatrixXd intg(const Eigen::Ref<const Eigen::Vector3d> &x0, const double h, 
			 const int nstp, const int nq);
    std::pair<Eigen::MatrixXd, Eigen::MatrixXd>
    intgj(const Eigen::Ref<const Eigen::Vector3d> &x0, const double h, 
	  const int hstp, const int xs, const int js);
    
    Eigen::Matrix3d equilibria();
    Eigen::Matrix3d equilibriaStab(const int i);
    std::pair<Eigen::VectorXcd, Eigen::MatrixXcd>
    equilibriaEV(const int i);
    Eigen::MatrixXd
    equilibriaIntg(const int i, const int j, const double eps,
		   const double h, const int nstp, 
		   const int nq);
};


#endif	/* LORENZ_H */
<file_sep>from cglHelp import *
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Times']})  # I love Times
rc('text', usetex=True)


case = 45

labels = ["IF4(3)", "IF5(4)",
          "ERK4(3)2(2)", "ERK4(3)3(3)", "ERK4(3)4(3)", "ERK5(4)5(4)",
          "SS4(3)"]
mks = ['o', 's', '+', '^', 'x', 'v', 'p']
Nscheme = len(labels)
lss = ['--', '-.', ':', '-', '-', '-', '-']

if case == 45:
    """
    plot fence instead of heat
    """
    N, d = 1024, 50
    fig = plt.figure(figsize=[15, 4])
    
    # 1st
    ax = ax3dinit(fig, num=131, labs=[r'$x$', r'$t$', None], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(a)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    # cgl = pyCQCGL1d(N, d, -0.1, 0.08, 0.5, 0.782, 1, -0.1, -0.08, -1)
    skipRate = 1
    pulsate = np.load('data/pulsatingSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp = Aamp[::skipRate, :]
    Aamp2 = Aamp2[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_yticks([0, 30, 60])
    ax.set_zticks([0, 3])
    ax.view_init(75, -50)
    
    # 2nd
    ax = ax3dinit(fig, num=132, labs=[r'$x$', r'$t$', None], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(b)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    # Bi, Gi = 3.5, -5.0
    # cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    skipRate = 1
    pulsate = np.load('data/extremeSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp = Aamp[::skipRate, :]
    Aamp2 = Aamp2[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_ylim([0, 13])
    ax.set_yticks([0, 5, 10])
    ax.set_zticks([0, 1])
    ax.view_init(60, -40)

    # 3rd
    ax = ax3dinit(fig, num=133, labs=[r'$x$', r'$t$', r'$|A|$'], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(c)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    # Bi, Gi = 0.8, -0.6
    # cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    skipRate = 5
    pulsate = np.load('data/explodingSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp = Aamp[::skipRate, :]
    Aamp2 = Aamp2[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_ylim([0, 20])
    ax.set_yticks([0, 10, 20])
    ax.set_zticks([0, 3])
    ax.view_init(75, -80)
    
    ############
    ax3d(fig, ax)


if case == 46:
    """
    plot fence instead of heat same as case 45
    but for time adaptive in constant frame
    """
    N, d = 1024, 50
    fig = plt.figure(figsize=[15, 4])
    
    # 1st
    ax = ax3dinit(fig, num=131, labs=[r'$x$', r'$t$', None], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(a)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    skipRate = 3
    pulsate = np.load('data/pulsatingSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp2 = Aamp2[::skipRate, :]
    Ts = Ts[::skipRate]
    rows, cols = Aamp2.shape
    X = np.linspace(0, d, cols)
    for i in range(rows):
        ax.plot(X, np.ones(cols) * Ts[i], Aamp2[i], c='k', alpha=1)
    
    ax.set_yticks([0, 30, 60])
    ax.set_zticks([0, 3])
    ax.view_init(75, -50)
    
    # 2nd
    ax = ax3dinit(fig, num=132, labs=[r'$x$', r'$t$', None], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(b)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    # Bi, Gi = 3.5, -5.0
    # cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    skipRate = 2
    pulsate = np.load('data/extremeSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp2 = Aamp2[::skipRate, :]
    Ts = Ts[::skipRate]
    rows, cols = Aamp2.shape
    X = np.linspace(0, d, cols)
    for i in range(rows):
        ax.plot(X, np.ones(cols) * Ts[i], Aamp2[i], c='k', alpha=1)
    
    # ax.set_ylim([0, 13])
    ax.set_yticks([0, 5, 10])
    ax.set_zticks([0, 1])
    ax.view_init(60, -40)

    # 3rd
    ax = ax3dinit(fig, num=133, labs=[r'$x$', r'$t$', r'$|A|$'], axisLabelSize=20, tickSize=15)
    ax.text2D(0.3, 0.9, '(c)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=22)
    skipRate = 5
    pulsate = np.load('data/explodingSolitonAmp.npz')
    Aamp, Aamp2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    Aamp2 = Aamp2[::skipRate, :]
    Ts = Ts[::skipRate]
    rows, cols = Aamp2.shape
    X = np.linspace(0, d, cols)
    for i in range(rows):
        ax.plot(X, np.ones(cols) * Ts[i], Aamp2[i], c='k', alpha=1)
    
    # ax.set_ylim([0, 20])
    ax.set_yticks([0, 10, 20])
    ax.set_zticks([0, 3])
    ax.view_init(75, -80)
    
    ############
    ax3d(fig, ax)
<file_sep>CC = g++
AR = ar

OPTIM = -O3 -msse2 -msse4 -march=corei7
INCLUDE = ../../include
EIGEN = /usr/local/home/xiong/apps/eigen/include/eigen3

CFLAGS = -std=c++11

SOURCE = lorenz.cc
SHARED = liblorenz.so
STATIC = liblorenz.a

# for RPO code
CFLAGS2 = -std=c++11

all : int 
int : $(SHARED) $(STATIC)

$(SHARED): $(SOURCE)
	$(CC) -shared -fpic $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^ -o $@
$(SOURCE:.cc=.o) : $(SOURCE)
	$(CC) -c $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
$(STATIC): $(SOURCE:.cc=.o)
	$(AR) crs $@ $^

clean:
	rm -f *.so *.o *.a
move:
	mv *.so *.a /usr/local/home/xiong/00git/research/lib
<file_sep>/*
 * g++ test_FFT.cc -std=c++11 -I$EIGEN -DEIGEN_FFTW_DEFAULT -lfftw3 -O3 && ./a.out
 */
#include <iostream>
#include <sstream>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include <ctime>
#define cee(x) (cout << (x) << endl << endl )

using namespace std;
using namespace Eigen;


int main(){
    
    switch (10){
	
    case 1 : {
	FFT<double> fft;
	fft.SetFlag(fft.HalfSpectrum);
	FFT<double> fft2;
	fft2.SetFlag(fft2.HalfSpectrum);

	int N = 16;
	VectorXd A(VectorXd::LinSpaced(N, 0, 1));
	VectorXcd B(VectorXd::LinSpaced(N/2+1, 0, 1).cast<std::complex<double>>());
	cee(A.data()); cee(B.data());
    
	clock_t t = clock();
	for(int i = 0; i < 1000; i++){
	    fft.fwd(B, A);
	    fft.inv(A, B);
	}
	t = clock()-t;
	cee( (double)t / CLOCKS_PER_SEC);

	t = clock();
	for(int i = 0; i < 1000; i++){
	    fft.fwd(B, A);
	    fft2.inv(A, B);
	}
	t = clock()-t;
	cee( (double)t / CLOCKS_PER_SEC);

	cee(A); cee(B); 
	cee(A.data()); cee(B.data());
	break;
    }

    case 10: {			/* does not work */
	FFT<double> fft;
	fft.SetFlag(fft.HalfSpectrum);
	int N = 16;
	VectorXcd A(N);
	VectorXcd B(N);
	A.setRandom();
	
	fft.fwd(B, A);
	cee(A); cee(B);
	
	break;

    }

	////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef N20
    case 20: {			/* does not work */
	FFT<double> fft;
	fft.SetFlag(fft.HalfSpectrum);
	int N = 16;
	MatrixXd A(16, 2);
	MatrixXcd B(16, 2);
	
	A.col(1) = VectorXd::LinSpaced(N, 0, 1);
	fft.fwd(B.col(0), A.col(1));
	cee(A); cee(B);
	
	break;

    }
#endif

    case 2: {			/* simple test 2d */
	FFT<double> fft;
	fft.SetFlag(fft.HalfSpectrum);
	int N0 = 8;
	int N1 = 4;
	MatrixXcd A(MatrixXd::Random(N0,N1).cast<std::complex<double>>());
	MatrixXcd B(MatrixXd::Random(N0,N1).cast<std::complex<double>>());
	clock_t t = clock();
	fft.inv2(B, A);
	t = clock()-t;
	cee( (double)t / CLOCKS_PER_SEC);

	cee(A); cee(B); 
	//cee(A.real());

	break;
    }

    case 3: {			/* 2d performance */
	FFT<double> fft;
	fft.SetFlag(fft.HalfSpectrum);
	int N0 = 1024;
	int N1 = 1024;
	MatrixXcd A(MatrixXd::Random(N0,N1).cast<std::complex<double>>());
	MatrixXcd B(MatrixXd::Random(N0,N1).cast<std::complex<double>>());
	cee(A.data()); cee(B.data());

	clock_t t = clock();
	for (int i = 0; i < 200; i++){
	    fft.fwd2(B, A);
	}
	t = clock()-t;
	cee( (double)t / CLOCKS_PER_SEC);

	cee(A.data()); cee(B.data());
	//cee(A); cee(B); 
	//cee(A.real());

	break;
    }
    }
    return 0;
}
<file_sep>from personalFunctions import *
from py_CQCGL1d import *

case = 10

# complex Ginzburg Landau equation
# A_t = A + (1 + alpha*i) A_{xx} - (1 + beta*i) |A|^2 A 
# The constructor siginature is
# A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A

if case == 10:
    """
    alpha = 1.5, beta = -1.4
    L = 100
    """
    N, d = 256, 100
    alpha, beta = 2, -2
    
    cgl = pyCQCGL1d(N, d, 1, 1, alpha, -1, -beta, 0, 0, -1)
    cgl.IsQintic = False
    cp = CQCGLplot(cgl)
    h = 0.02
    T = 100.0
    nstp = np.int(T/h)
    # cgl = pyCgl1d(N, d, h, False, 0, 1.5, -1.4, 4)

    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    aa = cgl.intg(a0, T/nstp, 1000, 1000000)
    a0 = aa[-1]
    aa = cgl.intg(a0, T/nstp, nstp, 10)
    
    cp.config(aa, [0, d, 0, T], size=[3.6, 6], percent='3%', barTicks=[0, 0.5, 1],
              axisLabelSize=25, tickSize=15)

if case == 20:
    """
    complex Ginzburg Landau equation
    A_t = A + (1 + alpha*i) A_{xx} - (1 + beta*i) |A|^2 A 
    alpha = 1.5, beta = -1.4
    The constructor siginature is
    A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    """
    N, d = 256, 200
    alpha, beta = 2, -2
    
    cgl = pyCQCGL1d(N, d, 1, 1, alpha, -1, -beta, 0, 0, -1)
    cgl.IsQintic = False
    cp = CQCGLplot(cgl)
    h = 0.02
    T = 100.0
    nstp = np.int(T/h)
    # cgl = pyCgl1d(N, d, h, False, 0, 1.5, -1.4, 4)

    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    aa = cgl.intg(a0, T/nstp, 1000, 1000000)
    a0 = aa[-1]
    aa = cgl.intg(a0, T/nstp, nstp, 10)
    
    cp.config(aa, [0, d, 0, T], size=[6, 6], percent='3%', barTicks=[0, 0.5, 1],
              axisLabelSize=25, tickSize=15)
<file_sep>import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.ticker import ScalarFormatter
from personalFunctions import *


case = 1

if case == 1:
    """
    plot Floquet exponents for N = 64 with a insert plot
    """
    FE = KSreadFE('../../data/ks22h001t120x64E.h5', 'ppo', 1)[0]

    N = 32
    d = 22
    x = np.arange(1, N, 0.01)
    qk = 2 * np.pi / d * x
    L = qk**2 - qk**4

    fig = plt.figure(figsize=(3, 2))
    ax = fig.add_subplot(111)
    ax.plot(x, L, 'g--', lw=1.8)
    ax.scatter(np.arange(1, N), FE[::2], c='r',
               marker='o', s=22, edgecolors='none')
    ax.scatter(np.arange(1, N), FE[1::2], c='r',
               marker='s', s=30, facecolors='none',
               edgecolors='k')
    yfmt = ScalarFormatter()
    yfmt.set_powerlimits((0, 1))
    ax.yaxis.set_major_formatter(yfmt)

    ax.set_yticks((-7e3, -3e3, 0, 1e3))
    ax.set_xlim((0, 35))
    ax.set_ylim((-7e3, 1e3))
    ax.grid('on')

    axin = inset_axes(ax, width="45%", height="50%", loc=3)
    axin.scatter(np.arange(1, N), FE[::2], c='r',
                 marker='o', s=22, edgecolors='none')
    axin.scatter(np.arange(1, N), FE[1::2], c='r',
                 marker='s', s=30, facecolors='none',
                 edgecolors='k')
    axin.set_xlim(0.5, 4.5)
    axin.set_ylim(-0.4, 0.1)
    axin.yaxis.set_ticks_position('right')
    axin.xaxis.set_ticks_position('top')
    axin.set_xticks((1, 2, 3, 4))
    axin.set_yticks((-0.4, -0.2, 0))
    axin.grid('on')

    mark_inset(ax, axin, loc1=1, loc2=2, fc="none")

    fig.tight_layout(pad=0)
    plt.show()
    # plt.savefig('pprpfigure.eps',format='eps', dpi=30)
<file_sep>from py_CQCGL_threads import *
from personalFunctions import *

case = 4

if case == 1:
    """
    use poincare section to find rpos
    """
    N = 512
    d = 50
    h = 0.001
    cgl = pyCqcgl1d(N, d, h, True, 0,
                    -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
                    4)
    Ndim = cgl.Ndim

    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN512.h5', '1')
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    ve = Tcopy(realve(eigvectors))
    a0Tilde = cgl.reduceAllSymmetries(a0)[0]
    veTilde = cgl.reduceVe(ve, a0)
    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[6])

    nstp = 50000
    a0Erg = a0 + ve[0]*1e-2
    totalPoints = np.zeros((0, 2))
    globalIndex = np.zeros((0,), dtype=np.int)
    originalPoints = np.zeros((0, Ndim))
    for i in range(2):
        aaErg = cgl.intg(a0Erg, nstp, 1)
        aaErgTilde = cgl.reduceAllSymmetries(aaErg)[0] - a0Tilde
        aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)

        plotConfigSpace(cgl.Fourier2Config(aaErg),
                        [0, d, nstp*h*i, nstp*h*(i+1)])
        points, index = PoincareLinearInterp(aaErgTildeProj, getIndex=True)
        totalPoints = np.vstack((totalPoints, points))
        globalIndex = np.append(globalIndex, index+i*nstp)
        originalPoints = np.vstack((originalPoints, aaErg[index]))
        a0Erg = aaErg[-1]

    scatter2dfig(totalPoints[:, 0], totalPoints[:, 1])

    Nsteps = (globalIndex[180] - globalIndex[0])/10
    Nps = Nsteps * 10
    aa = cgl.intg(originalPoints[0], Nps, 1)
    aaTilde, th, phi = cgl.reduceAllSymmetries(aa)
    print norm(aaTilde[0] - aaTilde[-1]), th[0] - th[-1], phi[0] - phi[-1]

    savez_compressed('rpoGuess', x=aa[:-1:Nsteps], h=h, Nsteps=Nsteps,
                     th=th[0]-th[-1], phi=phi[0]-phi[-1])

if case == 2:
    """
    single shooting
    """
    N = 512
    d = 50
    h = 0.001

    rpoGuess = np.load('rpoGuess.npz')
    nstp = rpoGuess['Nsteps'] * 10
    x0 = rpoGuess['x'][0]
    th0 = rpoGuess['th'].take(0)
    phi0 = rpoGuess['phi'].take(0)
    
    # cglrpo = pyCqcglRPO(nstp, 1, N, d, h,  -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6, 4)
    # rpo = cglrpo.findRPO(x0, nstp*h, th0, phi0, 1e-12, 20, 100, 1e-4, 1e-4, 0.1, 0.5, 30, 100)

if case == 3:
    """
    multi shooting
    """
    N = 512
    d = 50
    h = 0.001

    M = 10
    S = 1
    rpoGuess = np.load('rpoGuess.npz')
    nstp = rpoGuess['Nsteps'].take(0) * S
    x0 = rpoGuess['x'][::S, :].copy()
    th0 = rpoGuess['th'].take(0)
    phi0 = rpoGuess['phi'].take(0)

    cqcglSaveRPO('rpo.h5', '1', x0, nstp*h*M, nstp, th0, phi0, 1000.0)
    # cglrpo = pyCqcglRPO(nstp, M, N, d, h,  -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6, 4)
    # rpo = cglrpo.findRPOM(x0, nstp*h*M, th0, phi0, 1e-12, 20, 100, 1e-4, 1e-4, 0.1, 0.5, 80, 10)

    # cgl = pyCqcgl1d(N, d, h, False, 1,
    #                 -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
    #                 4)
    # Ndim = cgl.Ndim
    # xx = cgl.intg(rpoGuess['x'][0], rpoGuess['Nsteps']*10, 1)
    # plotConfigSpaceFromFourier(cgl, xx, [0, 50, 0, rpoGuess['Nsteps']*10*h])

 
    # cglrpo = pyCqcglRPO(N, d, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)
    # rpo = cglrpo.findPO(rpoGuess['x'], rpoGuess['h'].take(0),
    #                     rpoGuess['Nsteps'].take(0),
    #                     rpoGuess['th'].take(0), rpoGuess['phi'].take(0),
    #                     100, 1e-12, True, True)

if case == 4:
    """
    use the new form of cqcgl with larger di to find
    candidate of periodic orbit initial conditon
    """
    N = 1024
    d = 30
    di = 0.06
    T = 3

    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, -1, 4)
    cgl.changeOmega(-176.67504941219335)
    cgl.rtol = 1e-10
    
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    a1 = cgl.aintg(a0, 0.001, T, 10000)
    aa = cgl.aintg(a1[-1], 0.001, T, 1)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])

    S = aa.shape[0]
    aaHat, ths, phis = cgl.orbit2sliceWrap(aa)
    i1 = 99
    i2 = 28307
    th = ths[i1] - ths[i2]
    phi = phis[i1] - phis[i2]
    err = norm(aaHat[i1]-aaHat[i2])
    print err, th, phi

    M = 10
    sp = (i2-i1) / M
    ids = np.arange(i1, i2, sp)
    ids[-1] = i2
    x = aa[ids[:M]]
    Ts = cgl.Ts()[ids]
    T = np.zeros(M)
    for i in range(M):
        T[i] = Ts[i+1]-Ts[i]
    
    xs = np.zeros((x.shape[0], x.shape[1]+3))
    xs[:, :-3] = x
    xs[:, -3] = T
    xs[-1, -2] = th
    xs[-1, -1] = phi
    cqcglSaveRPO('rpo2.h5', '1', xs, sum(T), 1000, th, phi, err)

    aa2 = cgl.intg(x[0], nstp*M, 20)
    plotConfigSpaceFromFourier(cgl, aa2, [0, d, 0, nstp*M*h])
    aa3 = cgl.intg(x[0]*(1+0.00001*rand(cgl.Ndim)), nstp*M, 20)
    plotConfigSpaceFromFourier(cgl, aa3, [0, d, 0, nstp*M*h])
    dif = aa3-aa2
    plot1dfig(norm(dif, axis=1))
    plot1dfig(norm(dif, axis=1) / norm(aa2, axis=1), yscale='log')

if case == 5:
    """
    find good candidate to homoclinic orbits
    """
    N = 1024
    d = 30
    h = 1e-5
    s = 20

    di = 0.05
    
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    A0 = 5*centerRand(2*N, 0.2)
    a0 = cgl.Config2Fourier(A0)
    nstp = 150000
    aa = cgl.intg(a0, nstp, s)
    for i in range(1):
        aa = cgl.intg(aa[-1], nstp, s)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])

    aaHat, ths, phis = cgl.orbit2sliceWrap(aa)
    
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5', di, 1)
    a0H = cgl.orbit2sliceWrap(a0)[0]
    dif = aaHat - a0H
    no = norm(dif, axis=1)
    plot1dfig(no)
    print np.min(no)
    """
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    ve = Tcopy(realve(eigvectors))

    veTilde = cgl.reduceVe(ve, a0)
    e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[6])
    """
<file_sep>from py_CQCGL1dSub import *
from cglHelp import *

################################################################################
#   view the reqs in the symmetric subspace
################################################################################

case = 70

if case == 10:
    """
    use the new data to calculate tyhe stability exponents of req
    """
    N, d = 1024, 50
    Bi, Gi = 2, -5
    index = 1

    cgl = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    
    a0, wth0, wphi0, err0 = req.read('../../data/cgl/reqsubBiGi.h5',
                                     req.toStr(Bi, Gi, index),
                                     sub=True)
    e, v = req.eigReq(a0, wth0, wphi0, sub=True)
    print e[:10]


if case == 20:
    """
    visualize the eigenvectors
    """
    N, d = 1024, 50
    Bi, Gi = 2, -2
    index = 1

    cgl = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)
    
    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqsubBiGiEV.h5',
                                           req.toStr(Bi, Gi, index),
                                           sub=True,flag=2)
    print e[:10]
    cp.oneConfig(v[0].real * cgl.N)
    cp.oneConfig(v[0].imag * cgl.N)

if case == 30:
    """
    check the accuracy of all req in symmetric subspace
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6
    index = 1

    cgl = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)
    fin = '../../data/cgl/reqsubBiGi.h5'
    
    gs = req.scanGroup(fin, 2)
    errs = []
    for item in gs:
        a0, wth0, wphi0, err0 = req.read(fin, item, sub=True)
        errs.append(err0)

    print np.max(np.abs(errs))

if case == 40:
    """
    save the data
    """
    req = CQCGLreq()
    fin = '../../data/cgl/reqsubBiGiEV.h5'
    index = 1
    
    gs = req.scanGroup(fin, 2)
    saveData = np.zeros([0, 3])

    for item in gs:
        param = item.split('/')
        Bi, Gi, index = np.double(param[0]), np.double(param[1]), np.int(param[2])
        if index == 1:
            a0, wth0, wphi0, err0, e, v = req.read(fin, item, sub=True, flag=2)
            m, ep, accu = numStab(e)
            saveData = np.vstack((saveData, np.array([Gi, Bi, m])))

    np.savetxt("BiGiReqSubStab.dat", saveData)

if case == 50:
    """
    plot the Bi - Gi req stability plot using the saved date from running viewReq.py
    data format : {Gi, Bi, #unstable}
    #unstalbe is 0, 2, 4, 6 ...
    """
    saveData = np.loadtxt("BiGiReqSubStab.dat")
    cs = {0: 'c', 1: 'm', 2: 'g', 3: 'r', 4: 'b'}#, 8: 'y', 56: 'r', 14: 'grey'}
    ms = {0: '^', 1: '^', 2: 'x', 3: 'o', 4: 'D'}#, 8: '8', 56: '4', 14: 'v'}
    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30,
                   tickSize=20, ylim=[-6, 0], xlim=[-4, 6])
    for item in saveData:
        Gi, Bi, m = item
        ax.scatter(Bi, Gi, s=18 if m > 0 else 18, edgecolors='none',
                   marker=ms.get(m, 'v'), c=cs.get(m, 'k'))
    ax2d(fig, ax)



if case == 70:
    """
    same as case 10, bu plot contourf plot
    Note: the problem of contourf() is that whenever there is a jump
    in the levels, say from lv1 to lv2 but lv2 = lv1 + 2, then it will
    interpolate these two levels, thus a line for lv1 + 1 is plotted
    between these two regions.
    I need to draw each region indivisually. 
    """
    saveData = np.loadtxt("BiGiReqSubStab.dat")
    BiRange = [-3.2, 4]
    GiRange = [-5.6, -0.9]
    inc = 0.1

    nx = np.int(np.rint( (BiRange[1] - BiRange[0])/inc ) + 1)
    ny = np.int(np.rint( (GiRange[1] - GiRange[0])/inc ) + 1)

    x = np.linspace(BiRange[0], BiRange[1], nx)
    y = np.linspace(GiRange[0], GiRange[1], ny)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros([ny, nx]) - 1  # initialized with -1

    for item in saveData:
        Gi, Bi, m = item
        idx = np.int(np.rint((Bi - BiRange[0]) / inc))
        idy = np.int(np.rint((Gi - GiRange[0]) / inc))
        if idx >= 0 and idx < nx and idy >= 0 and idy < ny:
            Z[idy, idx] = m if m < 6 else 6

    levels = [-1, 0, 2, 4, 6]
    cs = ['w', 'm', 'c', 'r', 'y']
    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30,
                   tickSize=20)
    for i in range(len(levels)):
        vfunc = np.vectorize(lambda t : 0 if t == levels[i] else 1)
        Z2 = vfunc(Z)
        ax.contourf(X, Y, Z2, levels=[-0.1, 0.9], colors=cs[i])
    ax.text(0, -2, r'$S$', fontsize=30)
    ax.text(0, -4.5, r'$U_1$', fontsize=30)
    ax.text(2., -4.8, r'$U_2$', fontsize=30)
    ax.text(3., -3, r'$U_{\geq 3}$', fontsize=30)
    ax.scatter(2.0,-5, c='k', s=100, edgecolor='none')
    ax.scatter(2.7,-5, c='k', s=100, edgecolor='none')
    ax.scatter(1.4,-3.9, c='k', marker='*', s=200, edgecolor='none')
    ax.set_xlim(BiRange)
    ax.set_ylim(GiRange)
    ax2d(fig, ax)
<file_sep>/** \mainpage iterative methods to solve linear problems
 *
 *  \section sec_intro Introduction
 *  This file contains the iterative methods to solve linear problems. It
 *  mainly contains the congugate gradient method w/wo preconditioning and
 *  provide SSOR as one choice of precondition method, which is thought to
 *  perform better than Jacobi and G-S. The reason that I insist writing
 *  these routines by myself is that the corresponding libraries in Eigen
 *  seem not to give the desired accuracy when I use them to refine POs for
 *  KS system. I suggest you using the libraries shipped with Eigen, but if
 *  you want to use my routines, I welcome !
 *
 *  \section sec_use usage
 *  This file is assembly of template functions, which means that all function
 *  implementations are in this header file, and there is no .cc file.
 *  You only need to include this file when compiling your code.
 *  Example:
 *  \code
 *  g++ yourfile.cc -I/path/to/iterMethod.hpp -I/path/to/eigen -std=c++0x
 *  \endcode
 */

#ifndef ITERMETHOD_H
#define ITERMETHOD_H

#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>
#include <tuple>
#include <iostream>
#include <fstream>
#include "denseRoutines.hpp"

//////////////////////////////////////////////////
//              Interface                       //
//////////////////////////////////////////////////
namespace iterMethod {
  
    using namespace std;
    using namespace Eigen;
    using namespace denseRoutines;
    
    typedef Eigen::SparseMatrix<double> SpMat;

    /* -------------------------------------------------- */
    extern bool CG_PRINT;
    extern int CG_PRINT_FREQUENCE;
    
    extern bool GMRES_OUT_PRINT;
    extern int GMRES_OUT_PRINT_FREQUENCE;

    extern bool GMRES_IN_PRINT;
    extern int GMRES_IN_PRINT_FREQUENCE;

    extern bool HOOK_PRINT;
    extern int HOOK_PRINT_FREQUENCE;

    extern bool INB_OUT_PRINT;
    extern int INB_OUT_PRINT_FREQUENCE;

    extern bool INB_IN_PRINT;
    extern int INB_IN_PRINT_FREQUENCE;

    extern bool LM_OUT_PRINT;
    extern int LM_OUT_PRINT_FREQUENCE;

    extern bool LM_IN_PRINT;
    extern int LM_IN_PRINT_FREQUENCE;

    extern double LM_LAMBDA_INCREASE_FACTOR; 
    extern double LM_LAMBDA_DECREASE_FACTOR;
    extern double LM_MAX_LAMBDA;
    /* -------------------------------------------------- */

    template <typename Mat>
    std::pair<Eigen::VectorXd, std::vector<double> >
    ConjGrad(const Mat &A, const Eigen::VectorXd &b, 
	     const Eigen::VectorXd &x0,
	     const int jmax, const double rtol);


    template <typename Mat, typename LinearSolver>
    std::pair<VectorXd, vector<double> >
    ConjGradPre(const Mat &A, const VectorXd &b, const Mat &M, 
		LinearSolver &solver, 
		const VectorXd &x0, const int jmax, const double rtol);

    template <typename Mat>
    Mat preSSOR(const Mat &A);

    template < typename Mat, typename LinearSolver>
    std::pair<VectorXd, vector<double> >
    ConjGradSSOR(const Mat &A, const VectorXd &b,
		 LinearSolver &solver, 
		 const VectorXd &x0, const int jmax, const double rtol);
    
    /* -------------------------------------------------- */
    void rotmat(const double &x, const double &y,
		double *c, double *s);

    template <class Adotx>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0(Adotx Ax , const VectorXd &b, const VectorXd &x0,
	   const int restart,
	   const int maxit, const double rtol);
    
    template <typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres(const Mat &A, const VectorXd &b, const VectorXd &x0, 
	  const int restart,
	  const int maxit, const double rtol);
    
    ArrayXd calz(const ArrayXd &D, const ArrayXd &p, const double mu);
    
    std::tuple<double, std::vector<double>, int>
    findTrustRegion(const ArrayXd &D, const ArrayXd &p, double delta,
		    const double tol = 1e-12,
		    const int maxit = 100,
		    const double mu0 = 0);

    /* -------------------------------------------------- */
    template <class Adotx>
    std::tuple<VectorXd, VectorXd, VectorXd, ArrayXd, MatrixXd, MatrixXd, std::vector<double>, int>
    Gmres0SVD(Adotx Ax , const VectorXd &b, const VectorXd &x0,
	      const int restart,
	      const int maxit, const double rtol);

    template<class Fx, class Jacv>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0Hook( Fx fx, Jacv jacv,
		const VectorXd &x0,
		const double tol,
		const double minRD,
		const int maxit,
		const int maxInnIt,
		const double GmresRtol,
		const int GmresRestart,
		const int GmresMaxit,
		const bool testT,
		const int Tindex);
    
    template<class Fx, class Jacv, class Precondition>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0HookPre( Fx fx, Jacv jacv, Precondition Pre,
		   const VectorXd &x0,
		   const double tol,
		   const double minRD,
		   const int maxit,
		   const int maxInnIt,
		   const double GmresRtol,
		   const int GmresRestart,
		   const int GmresMaxit,
		   const bool testT,
		   const int Tindex);

    template<typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    GmresHook( const Mat &A, const VectorXd &b,
	       const VectorXd &x0,
	       const double tol,
	       const double minRD,
	       const int maxit,
	       const int maxInnIt,
	       const double GmresRtol,
	       const int GmresRestart,
	       const int GmresMaxit,
	       const bool testT,
	       const int Tindex);

    template<typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    GmresHookPre( const Mat &A, const VectorXd &b,
		  const VectorXd &x0,
		  const double tol,
		  const double minRD,
		  const int maxit,
		  const int maxInnIt,
		  const double GmresRtol,
		  const int GmresRestart,
		  const int GmresMaxit,
		  const bool testT,
		  const int Tindex);
    /* -------------------------------------------------- */
    double chooseTheta(const double g0, const double g1, const double gp0,
		       const double theta_min, const double theta_max);

    template<class Fx, class Jacv>
    std::tuple<VectorXd, std::vector<double>, int>
    InexactNewtonBacktrack(Fx &fx, Jacv &jacv,
			   const VectorXd &x0,
			   const double tol = 1e-12,
			   const int btMaxIt = 20,
			   const int maxit = 100,
			   const double eta0 = 1e-4,
			   const double t = 1e-4,
			   const double theta_min = 0.1,
			   const double theta_max = 0.5,
			   const int GmresRestart = 30,
			   const int GmresMaxit = 100);
    

    /* --------------------------  LM  ------------------------ */

    template<class Fx, template<class> class CalJJ, class LinearSolver, class Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    LM0( Fx & fx, CalJJ<Mat> &JJF, LinearSolver &solver, 
	 const VectorXd &x0, const double tol,
	 const int maxit, const int innerMaxit);
    
    std::tuple<VectorXd, std::vector<double>, int>
    LM( const MatrixXd &A, const VectorXd &b,
	const VectorXd &x0, const double tol,
	const int maxit, const int innerMaxit);

}


///////////////////////////////////////////////////              Implementation                  ////////////////////////

namespace iterMethod {

    //////////////////////////////////////////////////////////////////////
    //                        CG related                                //
    //////////////////////////////////////////////////////////////////////
    
    /** @brief perform conjugate gradient method on symmetry matrix A
     *         to solve Ax=b.
     *         Here the type of A is a template. permitted types are
     *         MatrixXd and SparseMatrix<double>.
     *
     *  @param[in] A symmetric (sparse) matrix
     *  @param[in] b vector
     *  @param[in] x0 initial guess of solution x
     *  @param[in] jmax maximal iteration number. This method is guranteed
     *                  to converge at most A's size iteration, so
     *                  jmax should be smaller than A.rows().
     *  @param[in] rtol relative tolerance for convergence
     */
    template <typename Mat>
    pair<VectorXd, vector<double> >
    ConjGrad(const Mat &A, const VectorXd &b, 
	     const VectorXd &x0, const int jmax,
	     const double rtol){
	assert( A.rows() == A.cols() );
	const int n = A.rows();
	VectorXd r1(b);
	VectorXd r0(b);
	VectorXd p(VectorXd::Zero(n));
	VectorXd x(x0);
	vector<double> res;
	res.reserve(jmax);
	double errInit = b.norm();
	res.push_back(errInit);
	
	for (size_t i = 0; i < jmax; i++) {

	    if(CG_PRINT && i % CG_PRINT_FREQUENCE == 0)
		fprintf(stderr, "CG : i= %zd/%d , r= %g\n", i, jmax, res.back());

	    double r1snorm = r1.squaredNorm(); 
	    double mu = r1snorm / r0.squaredNorm(); 
	    p = mu * p + r1;
	    VectorXd ap = A * p;
	    double sigma = r1snorm / (p.transpose() * ap);
	    x = x + sigma * p;
	    r0 = r1;
	    r1 -= sigma * ap;
	    double err = r1.norm();
	    res.push_back(err);
	    if(err <= rtol*errInit) break;
	}

	return make_pair(x, res);

    }

    /** @brief conjugate gradient with perconditioning
     *
     * Example usage:
     * 
     * for sparse matrix :
     * \code
     * typedef Eigen::SparseMatrix<double> SpMat;
     * // construction of A, M
     * // ...
     * SparseLU<SpMat> solver;
     * pair<VectorXd, vector<double> > cg = iterMethod::ConjGradPre<SpMat, SparseLU<SpMat> >
     * (A, b, M, solver, VectorXd::Zero(N), 100, 1e-6);
     * \endcode
     *
     * for dense matrix :
     * \code
     * PartialPivLU<MatrixXd> solver;
     * pair<VectorXd, vector<double> >
     * cg = iterMethod::ConjGradPre<MatrixXd, PartialPivLU<MatrixXd> >
     * (A, b, M, solver, VectorXd::Zero(N), 100, 1e-16);
     * \endcode
     * 
     * @param[in] M preconditioning matrix
     * @param[in] solver the linear solver
     * @see ConjGrad()
     * 
     */
    template <typename Mat, typename LinearSolver>
    std::pair<VectorXd, vector<double> >
    ConjGradPre(const Mat &A, const VectorXd &b, const Mat &M, 
		LinearSolver &solver, 
		const VectorXd &x0, const int jmax, const double rtol){

	assert( A.rows() == A.cols() );
	const int n = A.rows();
	VectorXd r1(b);
	VectorXd r0(b);
	VectorXd p(VectorXd::Zero(n));
	VectorXd x(x0); 
	solver.compute(M);
	VectorXd z0 = solver.solve(r0);
	vector<double> res;
	res.reserve(jmax);
	double errInit = b.norm();
	res.push_back(errInit);
	
	for (size_t i = 0; i < jmax; i++) {

	    if(CG_PRINT && i % CG_PRINT_FREQUENCE == 0)
		fprintf(stderr, "CG : i= %zd/%d , r= %g\n", i, jmax, res.back());

	    VectorXd z1 = solver.solve(r1);
	    double r1z1 = r1.dot(z1);
	    double mu = r1z1 / r0.dot(z0); 
	    z0 = z1;
	    p = mu * p + z1;
	    VectorXd ap = A * p;
	    double sigma = r1z1 / p.dot(ap);
	    x = x + sigma * p;
	    r0 = r1;
	    r1 -= sigma * ap;
	    double err = r1.norm();
	    res.push_back(err);
	    if(err <= rtol*errInit) break;
	}

	return make_pair(x, res);
    }
  
    /** @brief find the SSOR precondition matrix for CG method
     *  This works for both dense and sparse matrix.
     */
    template<typename Mat>
    Mat preSSOR(const Mat &A){
	Mat LD = A.template triangularView<Lower>();
	Mat UD = A.template triangularView<Upper>();

	return LD * ( A.diagonal().asDiagonal().inverse()) * UD;
    }
    

    /** @brief CG method with SSOR preconditioning
     *
     *  @see preSSOR
     *  @see ConjGradPre()
     */
    template < typename Mat, typename LinearSolver>
    std::pair<VectorXd, vector<double> >
    ConjGradSSOR(const Mat &A, const VectorXd &b,
		 LinearSolver &solver, 
		 const VectorXd &x0, const int jmax, const double rtol){
	Mat M = preSSOR<Mat> (A);
	return ConjGradPre<Mat, LinearSolver>(A, b, M, solver, x0, jmax, rtol);
    }


    //////////////////////////////////////////////////////////////////////
    //                        GMRES                                     //
    //////////////////////////////////////////////////////////////////////
    

    /**
     * @brief GMRES method to solve A*x = b.
     *
     *  This algorithm is described in
     *  "
     *  <NAME>, <NAME> 
     *  GMRES: A Generalized Minimal Residual Algorithm for Solving Nonsymmetric Linear Systems
     *  SIAM Journal on Scientific and Statistical Computing, 1986
     *  "
     *  The implementation follows the free netlib implementation
     *  http://www.netlib.org/templates/matlab/gmres.m
     *  with some modifications. Also, preconditioning is not implemented right now.
     *
     * @param[in]  Ax      : a function take one argument and return Krylov vector:  Ax(x) = A*x
     * @param[in]  b       : right side of linear equation A*x = b
     * @param[in]  x0      : initial guess
     * @param[in]  restart : restart number
     * @param[in]  maxit   : maximum iteration number
     * @param[in]  rtol    : relative error tolerance 
     * @return [x, errVec, flag]
     *          x       : the sotion of Ax=b
     *          errVec  : errors in each iteration step
     *          flag    : 0 => converged, 1 => not
     *          
     * @note this routine does not require the explicit form of matrix A, but only a function
     *       which can return A*x.
     * @see  Gmres()
     */
    template <class Adotx>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0(Adotx Ax , const VectorXd &b, const VectorXd &x0,
	   const int restart,
	   const int maxit, const double rtol){

	/* initial setup */
	const int N = b.size();
	int M = restart;
	VectorXd x = x0;
	double bnrm2 = b.norm();
	if ( bnrm2 == 0.0 ) bnrm2 = 1.0;
	std::vector<double> errVec;	/* error at each iteration */

	/* initialize workspace */
	MatrixXd V(MatrixXd::Zero(N, M+1)); // orthogonal vectors in Arnoldi iteration
	MatrixXd H(MatrixXd::Zero(M+1, M)); // Hessenberg matrix in Arnoldi iteration
	
	ArrayXd C(ArrayXd::Zero(M+1));  // cos of Givens rotation
	ArrayXd S(ArrayXd::Zero(M+1));  // sin of Givens rotation
    
	/* outer iteration */
	for(size_t iter = 0; iter < maxit; iter++){
	    /* obtain residule */
	    VectorXd r = b - Ax(x); 
	    double rnorm = r.norm();
	    double err = rnorm / bnrm2;
	    
	    if(GMRES_OUT_PRINT && iter % GMRES_OUT_PRINT_FREQUENCE == 0)
		fprintf(stderr, "GMRES : out loop: i= %zd/%d , r= %g\n", iter, maxit, err);

	    if(err < rtol) return std::make_tuple(x, errVec, 0);
	
	    V.col(0) = r / rnorm;	// obtain V_1
	
	    VectorXd g(VectorXd::Zero(M+1));// vector g = ||r|| * e1
	    g(0) = rnorm;		

	    /* inner iteration : Arnoldi Iteration */
	    for(size_t i = 0; i < M; i++){
		// form the V_{i+1} and H(:, i)
		V.col(i+1) = Ax( V.col(i) );
		for(size_t j = 0; j <= i; j++){
		    H(j, i) = V.col(i+1).dot( V.col(j) );
		    V.col(i+1) -= H(j, i) * V.col(j);
		}
		H(i+1, i) = V.col(i+1).norm();
		if(H(i+1, i) != 0) V.col(i+1) /= H(i+1, i);
	    
		/* Givens Rotation
		 *  | c, s| * |x| = |r|
		 *  |-s, c|   |y|   |0|
		 */
		for(size_t j = 0; j < i; j++) {
		    double tmp = C(j) * H(j, i) + S(j) * H(j+1, i);
		    H(j+1, i) = -S(j) * H(j, i) + C(j) * H(j+1, i);
		    H(j, i) = tmp;
		}
	    
		/* rotate the last element */
		rotmat(H(i, i), H(i+1, i), &C(i), &S(i));
		H(i ,i) = C(i) * H(i, i) + S(i) * H(i+1, i);
		H(i+1, i) = 0;

		/* rotate g(i) and g(i+1)
		 *  | c, s| * |g_i| = |c * g_i |
		 *  |-s, c|   | 0 |   |-s * g_i|
		 */
		g(i+1) = -S(i) * g(i); // be careful about the order
		g(i) = C(i) * g(i);

		/* after all above operations, we obtain dimensions
		 *  H : [i+2, i+1]
		 *  V : [N,   i+2]
		 *  g : [i+2,   1]
		 *
		 * Here, it is better denote H as R since it is transfored
		 * into upper triangular form.
		 * residual = || \beta * e_1 - H * y|| = ||g - R*y||
		 * since the last row of R is zero, then residual =
		 * last element of g, namely g(i+1)
		 */
		double err = fabs(g(i+1)) / bnrm2 ; 
		errVec.push_back(err);

		if(GMRES_IN_PRINT && i % GMRES_IN_PRINT_FREQUENCE == 0)
		    fprintf(stderr, "GMRES : inner loop: i= %zd/%d , r= %g\n", i, M, err);

		if (err < rtol){
		    VectorXd y = H.topLeftCorner(i+1, i+1).lu().solve(g.head(i+1));
		    x += V.leftCols(i+1) * y; 
		    return std::make_tuple(x, errVec, 0);
		}
	    }

	    // the inner loop finishes => has not converged
	    // so need to update x, and go to outer loop
	    VectorXd y = H.topLeftCorner(M, M).lu().solve(g.head(M));
	    x += V.leftCols(M) * y; 
	}

	// if the outer loop finished => not converged
	return std::make_tuple(x, errVec, 1);
    
    }

    /**
     * @brief a wrapper of Gmres0.
     *
     * This function uses an explicit form of matrix A.
     */
    template <typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres(const Mat &A , const VectorXd &b, const VectorXd &x0,
	  const int restart,
	  const int maxit, const double rtol){

	return Gmres0([&A](const VectorXd &x){return A * x;}, b, x0, restart, maxit, rtol);
    }

    //////////////////////////////////////////////////////////////////////
    //                        GMRES Hook                                //
    //////////////////////////////////////////////////////////////////////

    /**
     * @brief GMRES method to solve A*x = b  w. r. t  ||x|| < delta
     *
     * This GMRES method adds a hook step to the original GMRES to restrict the update to
     * a trust region.
     * 
     * The implementation follows paper 
     * "Simple invariant solutions embedded in 2D Kolmogorov turbulence " by
     *             <NAME> AND <NAME>
     * and online reference
     * http://channelflow.org/dokuwiki/doku.php?id=docs:math:newton_krylov_hookstep
     *
     * @param[in]  Ax            : a function take one argument and return Krylov vector:  Ax(x) = A*x
     * @param[in]  b             : right side of linear equation A*x = b
     * @param[in]  x0            : initial guess
     * @param[in]  restart       : restart number
     * @param[in]  maxit         : maximum iteration number
     * @param[in]  rtol          : relative error tolerance
     * @param[in]  delta         : radius of ball constriant
     * @param[in]  innerMaxit    : maximal inner iteration number 
     * @return [x, xold, p, D, V2, V, errVec, flag]
     *          x         the sotion of Ax=b
     *          xold      the old value just before the last update
     *          p         the residule vector without the last element
     *          D         SVD diagonal array
     *          V2        SVD right hand side orthogonal matrix
     *          V         the orthogonal matrix in the Arnolds iteration
     *          errVec    errors in each iteration step
     *          flag      0 => converged, 1 => not
     *          
     * @note this routine does not require the explicit form of matrix A, but only a function
     *       which can return A*x.
     *       The return values: p, D, V2, V can be used to reconstruct the update vector.
     * @see  Gmres0(), Gmres0Hook()
     */
    template <class Adotx>
    std::tuple<VectorXd, VectorXd, VectorXd, ArrayXd, MatrixXd, MatrixXd, std::vector<double>, int>
    Gmres0SVD(Adotx Ax , const VectorXd &b, const VectorXd &x0,
	      const int restart,
	      const int maxit, const double rtol){
	
	/* initial setup */
	const int N = b.size();
	int M = restart;
	VectorXd x = x0;
	double bnrm2 = b.norm();
	if ( bnrm2 == 0.0 ) bnrm2 = 1.0;
	std::vector<double> errVec;	/* error at each iteration */

	/* initialize workspace */
	MatrixXd V(MatrixXd::Zero(N, M+1)); // orthogonal vectors in Arnoldi iteration
	MatrixXd H(MatrixXd::Zero(M+1, M)); // Hessenberg matrix in Arnoldi iteration
    
	/* outer iteration */
	for(size_t iter = 0; iter < maxit; iter++){
	    /* obtain residule */
	    VectorXd r = b - Ax(x);
	    double rnorm = r.norm();
	    double err = rnorm / bnrm2;

	    if(GMRES_OUT_PRINT && (iter+1) % GMRES_OUT_PRINT_FREQUENCE == 0)
		fprintf(stderr, "**** GMRES : out loop: i= %zd/%d, r= %g\n", iter+1, maxit, err);

	    // if(err < rtol) return std::make_tuple(x, errVec, 0);
	
	    V.col(0) = r / rnorm;	// obtain V_1
	    
	    /* inner iteration : Arnoldi Iteration */
	    for(size_t i = 0; i < M; i++){
		// form the V_{i+1} and H(:, i)
		V.col(i+1) = Ax( V.col(i) );
		for(size_t j = 0; j <= i; j++){
		    H(j, i) = V.col(i+1).dot( V.col(j) );
		    V.col(i+1) -= H(j, i) * V.col(j);
		}
		H(i+1, i) = V.col(i+1).norm(); // cout << H.col(i).head(i+2) << endl;
		if(H(i+1, i) != 0) V.col(i+1) /= H(i+1, i);
		else fprintf(stderr, "H(i+i, i) = 0, Boss, what should I do ? \n");
		
		// conduct SVD decomposition
		// Here we must use the full matrix U
		// the residul is |p(i+1)|
		JacobiSVD<MatrixXd> svd(H.topLeftCorner(i+2, i+1), ComputeFullU | ComputeThinV);
	        ArrayXd D ( svd.singularValues() );
		MatrixXd U ( svd.matrixU() ); 
		MatrixXd V2 ( svd.matrixV() ); 
		VectorXd p = rnorm * U.row(0);
		double err = fabs(p(i+1)) / bnrm2;
		errVec.push_back(err); 

		if(GMRES_IN_PRINT && (i+1)%GMRES_IN_PRINT_FREQUENCE == 0)
		    fprintf(stderr, "** GMRES : inner loop: i= %zd/%d, r= %g\n", i+1, M, err);

		if (err < rtol){
		    VectorXd xold = x; 
 		    ArrayXd z = p.head(i+1).array() / D;
		    VectorXd y = V2 * z.matrix();
		    x += V.leftCols(i+1) * y;
		    return std::make_tuple(x, xold, p.head(i+1), D, V2, V.leftCols(i+1), errVec, 0);
		}
		if (i == M -1){ /* last one but has not converged */
		    VectorXd xold = x; 
		    ArrayXd z = p.head(i+1).array() / D;
		    VectorXd y = V2 * z.matrix();
		    x += V.leftCols(i+1) * y;
		    if (iter == maxit - 1){ // if the outer loop finished => not converged
			return std::make_tuple(x, xold, p.head(i+1), D, V2, V.leftCols(i+1), errVec, 1);
		    }
		}
	    }
	}
	
    }
        
    /**
     * @brief use GMRES HOOK method to fin the solution of A x = b
     *
     * @param[in] testT     whether test the updated period T is postive
     * @param[in] Tindex    the index of T in the state vector counting from the tail
     * @param[in] minRD      minimal relative descrease at each step
     */
    template<class Fx, class Jacv>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0Hook( Fx fx, Jacv jacv,
		const VectorXd &x0,
		const double tol,
		const double minRD,
		const int maxit,
		const int maxInnIt,
		const double GmresRtol,
		const int GmresRestart,
		const int GmresMaxit,
		const bool testT,
		const int Tindex){

	const int N = x0.size(); 
	VectorXd x(x0);
	std::vector<double> errVec;

	bool fail = false;
	for(size_t i = 0; i < maxit; i++){
	    VectorXd F = fx(x);
	    double Fnorm = F.norm();
	    
	    if(HOOK_PRINT && i % HOOK_PRINT_FREQUENCE == 0)
		fprintf(stderr, "\n+++++++++++ GHOOK: i = %zd/%d, r = %g ++++++++++ \n", i, maxit, Fnorm);

	    errVec.push_back(Fnorm);
	    if(Fnorm < tol) return std::make_tuple(x, errVec, 0);

	    // use GmresRPO to solve F' dx = -F
	    auto Ax = [&x, &jacv](const VectorXd &t){return jacv(x, t); };
	    auto tmp = Gmres0SVD(Ax, -F, VectorXd::Zero(N), GmresRestart, GmresMaxit, GmresRtol); 
	    if(std::get<7>(tmp) != 0) fprintf(stderr, "GMRES SVD not converged !\n");
	    VectorXd &s = std::get<0>(tmp); // update vector
	    VectorXd &sold = std::get<1>(tmp); // old update vector just before last change
	    VectorXd &p = std::get<2>(tmp);
	    ArrayXd &D = std::get<3>(tmp);
	    MatrixXd &V2 = std::get<4>(tmp);
	    MatrixXd &V = std::get<5>(tmp); 
	    
	    ArrayXd D2 = D * D;
	    ArrayXd pd = p.array() * D;
	    // ArrayXd mu = ArrayXd::Ones(p.size()) * 0.1; 
	    ArrayXd mu = ArrayXd::Ones(p.size()) * 0.1 * D2.minCoeff(); 
	    for(size_t j = 0; j < maxInnIt; j++){ 
		VectorXd newx = x + s; 
		double newT = newx(N - Tindex); 

		if(HOOK_PRINT && i % HOOK_PRINT_FREQUENCE == 0)	    
		    fprintf(stderr, " %zd, %g |", j, newT);

		if(!testT || newT > 0){
		    VectorXd newF = fx(newx);
		    if(newF.norm() < (1 - minRD)*Fnorm){
			x = newx;
			break;
		    }
		}
		ArrayXd z = pd / (D2 + mu);
		VectorXd y = V2 * z.matrix();
		s = sold + V * y;
		mu *= 2;
		
		if(j == maxInnIt-1) fail = true;
	    }
	    
	    if(fail) break; // if all inner loop finish, it means state not changed
			    // then no need to iterate more.
	}

	return std::make_tuple(x, errVec, 1);
	    
    }


    /**
     * Preconditioning version of GMRES.
     *
     * GMRES will converge in fewer steps if the eigenvalues are clustered. A 
     * matrix P^{-1} which makes AP^{-1} close to identiy is the goal of right
     * side preconditioning. The equation then becomes AP^{-1} (Px) = b. If the
     * solution is AP^{-1} y = b. then x = P^{-1} y. So only need a function
     * to calculate P^{-1} y.
     * See discussions in
     * ----------------------------------------------------------------------
     * "How Fast are Nonsymmetric Matrix Iterations?" by
     * <NAME>; <NAME>.; and <NAME>.
     * ----------------------------------------------------------------------
     *
     * @parame[in] Pre    the precondition funcion which return product P^{-1}x
     * @see Gmres0SVD
     * 
     */
    template<class Fx, class Jacv, class Precondition>
    std::tuple<VectorXd, std::vector<double>, int>
    Gmres0HookPre( Fx fx, Jacv jacv, Precondition Pre,
		   const VectorXd &x0,
		   const double tol,
		   const double minRD,
		   const int maxit,
		   const int maxInnIt,
		   const double GmresRtol,
		   const int GmresRestart,
		   const int GmresMaxit,
		   const bool testT,
		   const int Tindex) {
	
	const int N = x0.size(); 
	VectorXd x(x0);
	std::vector<double> errVec;

	bool fail = false;
	for(size_t i = 0; i < maxit; i++){
	    VectorXd F = fx(x);
	    double Fnorm = F.norm();
	    
	    if(HOOK_PRINT && (i+1) % HOOK_PRINT_FREQUENCE == 0)
		fprintf(stderr, "+++++++++++ GHOOK: i = %zd/%d, r = %g ++++++++++ \n", i+1, maxit, Fnorm);

	    errVec.push_back(Fnorm);
	    if(Fnorm < tol) return std::make_tuple(x, errVec, 0);

	    // use GmresRPO to solve F' dx = -F
	    VectorXd s, sold, p;
	    ArrayXd D;
	    MatrixXd V, V2;
	    std::vector<double> e;
	    int flag;
	    auto Ax = [&x, &jacv, &Pre](const VectorXd &t){ VectorXd y = Pre(x, t); 
							    VectorXd z = jacv(x, y);
							    return z; };
	    std::tie(s, sold, p, D, V2, V, e, flag) = 
		Gmres0SVD(Ax, -F, VectorXd::Zero(N), GmresRestart, GmresMaxit, GmresRtol); 
	    if(flag != 0) fprintf(stderr, "GMRES SVD not converged !\n");
	    
	    ArrayXd D2 = D * D;
	    ArrayXd pd = p.array() * D;
	    ArrayXd mu = ArrayXd::Ones(p.size()) * 0.1 * D2.minCoeff(); 
	    for(size_t j = 0; j < maxInnIt; j++){ 
		VectorXd newx = x + Pre(x, s);

		double newT = newx(N - Tindex); 

		if(HOOK_PRINT && (j+1) % HOOK_PRINT_FREQUENCE == 0)	    
		    fprintf(stderr, " %zd, %g |", j+1, newT);

		if(!testT || newT > 0){
		    VectorXd newF = fx(newx); 
		    if(newF.norm() < (1 - minRD)*Fnorm){
			x = newx;
			break;
		    }
		}
		ArrayXd z = pd / (D2 + mu);
		VectorXd y = V2 * z.matrix();
		s = sold + V * y;
		mu *= 2;
		
		if(j == maxInnIt-1) fail = true;
	    }
	    if(HOOK_PRINT) fprintf(stderr, "\n");
	    

	    if(fail) break; // if all inner loop finish, it means state not changed
			    // then no need to iterate more.
	}

	return std::make_tuple(x, errVec, 1);
	    
    }

    template<typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    GmresHook( const Mat &A, const VectorXd &b,
	       const VectorXd &x0,
	       const double tol,
	       const double minRD,
	       const int maxit,
	       const int maxInnIt,
	       const double GmresRtol,
	       const int GmresRestart,
	       const int GmresMaxit,
	       const bool testT,
	       const int Tindex){
	return Gmres0Hook([&A, &b](const VectorXd &x){return A * x - b;},
			  [&A](const VectorXd &x, const VectorXd &t){return A * t;},
			  x0, tol, minRD, maxit, maxInnIt, GmresRtol,
			  GmresRestart, GmresMaxit, testT, Tindex);
    }

    /* use inverse of diagonal matrix as preconditioner */
    template<typename Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    GmresHookPre( const Mat &A, const VectorXd &b,
		  const VectorXd &x0,
		  const double tol,
		  const double minRD,
		  const int maxit,
		  const int maxInnIt,
		  const double GmresRtol,
		  const int GmresRestart,
		  const int GmresMaxit,
		  const bool testT,
		  const int Tindex){
	int n = A.cols();
	ArrayXd D(n);
	for(int i = 0; i < n; i++) D(i) = abs(A(i, i)) > 1 ? 1 / A(i,i) : 1;
	//for(int i = 0; i < n; i++) D(i) = 2;
	// cout << D << endl << endl;

	auto fx = [&A, &b](const VectorXd &x){return A * x - b;};
	auto jacv = [&A](const VectorXd &x, const VectorXd &t){return A * t;};
	auto Pre = [&D](const VectorXd &x){VectorXd t = D*x.array(); return t; };
	return Gmres0HookPre(fx, jacv, Pre,			     
			     x0, tol, minRD, maxit, maxInnIt, GmresRtol,
			     GmresRestart, GmresMaxit, testT, Tindex);
    }
    
    //////////////////////////////////////////////////////////////////////
    //                    Netwon methods related                        //
    //////////////////////////////////////////////////////////////////////

    
    /**
     * @brief Inexact Newton Backtracking method
     *
     *   try to solve problem F(x) = 0 
     *--------------------------------------------------------------------- 
     *        "Inexact Newton Methods Applied to Under–Determined Systems
     *                    by. <NAME>. "
     *
     * Algorithm BINMU: 
     *     Let x0 and t in (0,1), eta_max in [0,1), and
     *         0 < theta_min< theta_max < 1 be given.
     *         
     *     For k = 0, 1, 2, ...; do
     *
     *         Find some bar_eta_k in [0, eta_max] and bar_s_k that satisfy
     *            || F(x_k) + F′(x_k) * bar_s_k ||  ≤ bar_eta_k * ||F(x_k)||,
     * 
     *         Evaluate F(x_k+ s_k). Set eta_k = bar_eta_k,  s_k = bar_s_k.
     *         While || F(x_k+ s_k) || > [1 − t(1 − eta_k)] * ||F(x_k)||, do
     *               Choose theta in [theta_min, theta_max].
     *               Update s_k = theta * s_k and eta_k = 1 − theta(1 − eta_k).
     *               Evaluate F(x_k+ s_k)
     *               
     *         Set x_{k+1}= x_k+ s_k.
     *----------------------------------------------------------------------
     *
     * In the above, we use GMRES to find s_k :
     *   F'(x_k) * s_k = - F(x_k) with relative tolerance bar_eta_k.
     * Also, for simplicity, we choose bar_eta_k to be constant.
     *
     * @param[in] fx             evaluate f(x)
     * @param[in] jacv           perform J(x)*dx. Symtex is jacv(x, dx)
     * @param[in] x0             initial guess
     * @param[in] btMaxIt        maximal backtracking iteration number
     *                           theta_max ^ btMaxIt => least shrink if fails
     * @param[in] tol            convergence tollerance
     * @param[in] eta0           initial value of eta
     * @param[in] theta_min      minimal value of forcing parameter
     * @param[in] theta_max      maximal value of forcing parameter
     *                           set 0.5 => at least shrink 1/2
     * @param[in] GmresRestart   gmres restart number
     * @param[in] GmresMaxit     gmres maximal iteration number 
     */
    template<class Fx, class Jacv>
    std::tuple<VectorXd, std::vector<double>, int>
    InexactNewtonBacktrack( Fx &fx, Jacv &jacv,
			    const VectorXd &x0,
			    const double tol,
			    const int btMaxIt,
			    const int maxit,
			    const double eta0,
			    const double t,
			    const double theta_min,
			    const double theta_max,
			    const int GmresRestart,
			    const int GmresMaxit){
	const int N = x0.size();
	VectorXd x(x0);
	std::vector<double> errVec; // errors
	
	for (size_t i = 0; i < maxit; i++){

	    ////////////////////////////////////////////////
	    // test convergence first
	    VectorXd F = fx(x); 
	    double Fnorm = F.norm(); 

	    if(INB_OUT_PRINT && i % INB_OUT_PRINT_FREQUENCE == 0)
		fprintf(stderr, "\n+++++++++++ INB: i = %zd, r = %g ++++++++++ \n", i, Fnorm);

	    errVec.push_back(Fnorm);
	    if( Fnorm < tol) return std::make_tuple(x, errVec, 0);

	    ////////////////////////////////////////////////
	    //solve ||F + F's|| < eta * ||F||
	    double eta = eta0; 
	    std::tuple<VectorXd, std::vector<double>, int>
		tmp = Gmres0([&x, &jacv](const VectorXd &t){ return jacv(x, t); },
			     -F, VectorXd::Zero(N), GmresRestart, GmresMaxit, eta);
	    if(std::get<2>(tmp) != 0) {
		fprintf(stderr, "GMRES not converged ! \n");
	    }
	    VectorXd &s = std::get<0>(tmp); // update vector 
	    printf("GMRES : %lu  %g | resdiual %g  %g\n",
		   std::get<1>(tmp).size(), std::get<1>(tmp).back(),
		   (fx(x) + jacv(x, s)).norm()/Fnorm, fx(x+s).norm());
	    
	    ////////////////////////////////////////////////
	    // use back tracking method to find appropariate scale
	    double initgp0 = 2 * F.dot(jacv(x, s));
	    double theta = 1;
	    for(size_t j = 0; j < btMaxIt; j++){
		VectorXd F1 = fx(x + s);
		double F1norm = F1.norm();

		if(INB_IN_PRINT && j % INB_IN_PRINT_FREQUENCE == 0)
		    fprintf(stderr, "INB(inner): j = %zd, r = %g \n", j, F1norm);

		if(F1norm < (1 - t * (1 - eta)) * Fnorm ) break;
		double gp0 = theta * initgp0;
		theta = chooseTheta(Fnorm, F1norm, gp0, theta_min, theta_max);
		s *= theta;
		eta = 1 - theta * (1 - eta);
		
		if(j == btMaxIt - 1) fprintf(stderr, "INB backtrack not converged !\n");
	    }
	    x += s; 		// update x
	}

	// if finish the outer loop => not converged
	fprintf(stderr, "INB not converged !\n");
	return std::make_tuple(x, errVec, 1); 
    }
    
    
    //////////////////////////////////////////////////////////////////////
    //            Levenberg-Marquardt related                           //
    //////////////////////////////////////////////////////////////////////

    /**
     * @brief Levenberg-Marquardt algorithm to minimize ||f(x)||
     *
     * @param[in]  Fx          VectorXd (*)(VectorXd x) to evaluate f(x)
     * @param[in] JJF          std::tuple<Mat, Mat, VectorXd> (*)(VectorXd x) function to
     *                         evaulate J^T*J, diag(diag(J^T*J)), J^T*f(x)
     * @param[in] solver       a linear solver to solve Ax = b
     * @param[in] x0           initial guess
     * @param[in] tol          tolerance
     * @param[in] mxit         maximal number of iterations
     * @param[in] innerMaxit   maximal number of inner iteration number
     */
    template<class Fx, template<class> class CalJJ, class LinearSolver, class Mat>
    std::tuple<VectorXd, std::vector<double>, int>
    LM0( Fx & fx, CalJJ<Mat> &JJF, LinearSolver &solver, 
	 const VectorXd &x0, const double tol,
	 const int maxit, const int innerMaxit){

	double lam = 1;
	VectorXd x(x0);
	std::vector<double> res;

	for(int i = 0; i < maxit; i++){
	    if (lam > LM_MAX_LAMBDA) return std::make_tuple(x, res, 0);
	    
	    /////////////////////////////////////////////////
	    // judge stop or not 
	    VectorXd F = fx(x); 
	    double err = F.norm();
	    res.push_back(err);
	    if(err < tol){
		fprintf(stderr, "stops at error = %g\n", err);
		return std::make_tuple(x, res, 0);
	    }	    
	    if (LM_OUT_PRINT && i % LM_OUT_PRINT_FREQUENCE == 0)
		fprintf(stderr,  "+++ LM : out loop: i = %d/%d, err=%g +++ \n", i, maxit, err);
	 
	    ////////////////////////////////////////////////
	    // construct JJ and JF
	    std::tuple<Mat, Mat, VectorXd> tmp = JJF(x);
	    Mat &jj = std::get<0>(tmp); 
	    Mat &d = std::get<1>(tmp);
	    VectorXd &jf = std::get<2>(tmp);
	    
	    for(int j = 0; j < innerMaxit; j++){
		
		Mat H = jj + lam * d; 
		int N = H.rows();

		// solve H x = -jf
		auto cg = ConjGradSSOR(H, -jf, solver, VectorXd::Zero(N), N, 1e-6);
		VectorXd &dx = cg.first;
		std::vector<double> &r = cg.second;
		if (LM_IN_PRINT)
		    printf("CG error %g, iteration number %zd\n", r.back(), r.size());
		
		// update the state or keep unchanged
		VectorXd xnew = x + dx;
		VectorXd Fnew = fx(xnew);
		double errnew = Fnew.norm();
		
		if (LM_IN_PRINT && i % LM_IN_PRINT_FREQUENCE == 0)
		    fprintf(stderr,  "LM : inner loop: j = %d/%d, err=%g\n", j, innerMaxit, errnew);
		
		if (errnew < err){
		    x = xnew;
		    lam /= LM_LAMBDA_DECREASE_FACTOR;
		    break;
		} 
		else {
		    lam *= LM_LAMBDA_INCREASE_FACTOR;
		    if (lam > LM_MAX_LAMBDA) {
			fprintf(stderr, "lambda = %g too large \n", lam);
			break;
		    }
		}
		
	    }
	    
	    
	}
	
	// run out of loop, which means it does not converge
	return std::make_tuple(x, res, 1);
    }

    /**
     * @brief JJF template function for LM() to solve Ax=b
     */
    template<class Mat>
    struct JJF {
	const Mat &J;
	const VectorXd &b;
	
	JJF(const Mat &tJ, const VectorXd &tb) : J(tJ), b(tb) {}
	
	std::tuple<MatrixXd, MatrixXd, VectorXd>
        operator()(const VectorXd &x) {
	    MatrixXd JJ = J.transpose() * J;
	    MatrixXd d = JJ.diagonal().asDiagonal();
	    return std::make_tuple(JJ, d, J.transpose()*(J*x-b));
	}
    };

}

#endif	/* ITERMETHOD_H */

<file_sep>from personalFunctions import *


def setAxis(ax, xr, xlabel=r'$t$', ylabel=r'$\lambda_k(t)$'):
    # ax.get_yaxis().set_tick_params(which='both', direction='in', pad = -20)
    # ax.get_xaxis().set_tick_params(which='both', direction='in', pad = -20)

    # ax.set_xlabel(xlabel, fontsize=20)
    # ax.set_ylabel(ylabel, fontsize=20)
    ax.set_xlim([0, xr])
    ax.set_xticks([0, xr-1])
    ax.set_xticklabels([0, r'$T_p$'], fontsize=13)


if __name__ == '__main__':

    case = 1

    if case == 1:
        """
        plot the local Flouqet exponents of ppo1
        """
        # load data
        expand = np.loadtxt('./ppo/FVexpand1.dat')
        
        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ax.plot(expand[0], lw=1.5, ls='-')
        # ax.plot(expand[1], lw=1.5, ls='-')
        ax.plot(expand[2], lw=1.5, ls='-')
        ax.plot(expand[3], lw=1.5, ls='-')
        ax.plot(expand[4], lw=1.5, ls='-')
        ax.plot(expand[5], lw=1.5, ls='-')
        ax.plot(expand[7], lw=1.5, ls='-')

        ax.plot(expand[8], lw=1.5, ls='-')
        ax.plot(expand[9], lw=1.5, ls='-')

        ax.text(expand.shape[1]/50, 0.4, r'$\lambda_k(t)$', fontsize=18)
        ax.text(expand.shape[1]/3, -0.8, r'$k=1, 3, 4, 5, 6, 8$', fontsize=18)
        ax.text(expand.shape[1]/2, -1.8, r'$k=9, 10$', fontsize=18)
        
        setAxis(ax, expand.shape[1])
        ax.set_ylim([-2.5, 1])
        ax.set_yticks([-2, -1, 0, 1])
        fig.tight_layout(pad=0)
        plt.show()

    if case == 2:
        """
        plot $\lambda_i(t) -\lambda$ for a small subset
        """
        expand = np.loadtxt('./ppo/FVexpand1.dat')
        fe = KSreadFE('../ks22h001t120x64EV.h5', 'ppo', 1)[0]

        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ix = [8, 9, 10, 11]
        for i in ix:
            ax.plot(expand[i]-fe[i], lw=1.5, ls='-', label='k='+str(i+1))

        setAxis(ax, expand.shape[1], ylabel=r'$\lambda_k(t) - \lambda_k$')
        ax.set_yticks([-0.03, 0, 0.03, 0.06])
        ax.legend(loc='best', fontsize=13, frameon=False)
        fig.tight_layout(pad=0)
        plt.show()

        # savez_compressed('ppo1', T=T, nstp=nstp, fe=fe)

    if case == 3:
        """
        plot $\lambda_i(t) -\lambda$ for the remaining set
        """
        expand = np.loadtxt('./ppo/FVexpand1.dat')
        fe = KSreadFE('../ks22h001t120x64EV.h5', 'ppo', 1)[0]

        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ix = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
        for i in ix:
            ax.plot(expand[i]-fe[i], lw=1.5, ls='-')

        ax.arrow(expand.shape[1]/20, 0.009, 0, -0.003,
                 width=20, head_length=0.001, head_width=80,
                 fc='k')
        setAxis(ax, expand.shape[1], ylabel=r'$\lambda_k(t) - \lambda_k$')
        ax.set_yticks([-0.008, -0.002, 0.004, 0.01])
        fig.tight_layout(pad=0)
        plt.show()
   
<file_sep>#ifndef CQCGL1dREQ_H		
#define CQCGL1dREQ_H

#include <type_traits>
#include "CQCGL1d.hpp"
#include "myH5.hpp"


using namespace H5;

class CQCGL1dReq : public CQCGL1d {
    
public :
    
    ////////////////////////////////////////////////////////////
    // A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    CQCGL1dReq(int N, double d,
	       double Mu, double Dr, double Di, double Br, double Bi, 
	       double Gr, double Gi, int dimTan);
    
    // A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
    CQCGL1dReq(int N, double d, 
	       double b, double c, double dr, double di, 
	       int dimTan);
    
    // iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
    CQCGL1dReq(int N, double d,
	       double delta, double beta, double D, double epsilon,
	       double mu, double nu, int dimTan);
    ~CQCGL1dReq();
    CQCGL1dReq & operator=(const CQCGL1dReq &x);

    ////////////////////////////////////////////////////////////
    static
    std::string 
    toStr(double Bi, double Gi, int index);

    static
    std::tuple<VectorXd, double, double ,double>
    read(H5File &file, const std::string groupName); 
    
    static
    void 
    write(H5File &file, const std::string groupName,
	  const ArrayXd &a, const double wth, 
	  const double wphi, const double err);
    static
    VectorXcd 
    readE(H5File &file, const std::string groupName);

    static
    MatrixXcd 
    readV(H5File &file, const std::string groupName);
    
    static
    void 
    writeE(H5File &file, const std::string groupName, 
	   const VectorXcd e);
    
    static
    void 
    writeV(H5File &file, const std::string groupName, 
	   const MatrixXcd v);
    
    static
    void 
    move(H5File &fin, std::string gin, H5File &fout, std::string gout,
	 int flag = 0);
    
    ////////////////////////////////////////////////////////////
    VectorXd Fx(const VectorXd &x);
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    calJJF(const VectorXd &x);
    std::tuple<VectorXd, double, double, double, int>
    findReq_LM(const ArrayXd &a0, const double wth0, const double wphi0, 
	       const double tol,
	       const int maxit,
	       const int innerMaxit);
    std::vector<double>
    optThPhi(const ArrayXd &a0);
    void 
    findReqParaSeq(H5File &file, int id, double step, int Ns, bool isBi);
    void 
    calEVParaSeq(H5File &file, std::vector<int> ids, std::vector<double> Bis,
		 std::vector<double> Gis, bool saveV);
    
    
};

template<class Mat>
struct CQCGL1dReqJJF {
    
    CQCGL1dReq *req;
    
    CQCGL1dReqJJF(CQCGL1dReq *req) : req(req){}
    
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    operator()(const VectorXd &x) {
	return req->calJJF(x);
    }	
};

#endif	/* CQCGL1dREQ_H */
<file_sep>/* to compile the class
 *  
 *  compile with Mutithreads FFT support:
 *  g++ cqcgl2d.cc  -shared -fpic -march=corei7 -O3 -msse2 -msse4 -lfftw3_threads -lfftw3 -lm -fopenmp -DTFFT  -I $XDAPPS/eigen/include/eigen3 -I../include -std=c++0x
 *
 *  complile with only one thread:
 *  g++ cqcgl2d.cc -shared -fpic -lfftw3 -lm -fopenmp  -march=corei7 -O3 -msse2 -msse4 -I/usr/include/eigen3 -I../../include -std=c++0x
 *
 *  */
#ifndef CQCGL2D_H
#define CQCGL2D_H

// #include <fftw3.h>
#include <complex>
#include <utility>
#include <algorithm>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>
#include "denseRoutines.hpp"
#include "myH5.hpp"
#include "myfft.hpp"
using std::pair; using std::make_pair; 
using Eigen::MatrixXd; using Eigen::VectorXd;
using Eigen::MatrixXcd; using Eigen::VectorXcd;
using Eigen::ArrayXXcd; using Eigen::ArrayXcd;
using Eigen::ArrayXXd; using Eigen::ArrayXd;
using Eigen::ConjugateGradient;
using Eigen::PartialPivLU;
using Eigen::Map; using Eigen::Ref;

//////////////////////////////////////////////////////////////////////
//                       class CQCGLgeneral                         //
//////////////////////////////////////////////////////////////////////

/**
 * @brief two dimensional cubic quintic complex Ginzburg-Landau equation
 *
 * The dimension of the mesh is [M x N] corresponding to actual simulation
 * domain [dy x dx]. Therefore, the x direction is discretized to N points,
 * and y direction is divided to M points. Memory is contiguous in the
 * y direction.
 */
class CQCGL2d {
  
public:
    typedef std::complex<double> dcp;
    typedef Eigen::SparseMatrix<double> SpMat;
    typedef Eigen::Triplet<double> Tri;
    
    const int N, M;		/* dimension of FFT */
    const double dx, dy;	/* system domain size */
    
    int Ne, Me;			/* effective number of modes */
    int Nplus, Nminus, Nalias;
    int Mplus, Mminus, Malias;
    
    double Br, Bi, Gr, Gi, Dr, Di, Mu;
    double Omega = 0;		/* used for comoving frame */
    ArrayXd Kx, Kx2, Ky, Ky2, QKx, QKy;

    ArrayXXcd L, E, E2, a21, a31, a32, a41, a43, b1, b2, b4;

    MyFFT::FFT2d F[5], JF[5];
    
    /* for time step adaptive ETDRK4 and Krogstad  */
    ////////////////////////////////////////////////////////////
    // time adaptive method related parameters
    double rtol = 1e-10;
    double nu = 0.9;		/* safe factor */
    double mumax = 2.5;		/* maximal time step increase factor */
    double mumin = 0.4;		/* minimal time step decrease factor */
    double mue = 1.25;		/* upper lazy threshold */
    double muc = 0.85;		/* lower lazy threshold */

    int NCalCoe = 0;	      /* times to evaluate coefficient */
    int NReject = 0;	      /* times that new state is rejected */
    int NCallF = 0;	      /* times to call velocity function f */
    int NSteps = 0;	      /* total number of integrations steps */
    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    
    int cellSize = 500;	/* size of cell when resize output container */
    int MC = 64;	/* number of sample points */
    int R = 1;		/* radius for evaluating phi(z) */

    int Method = 1;
    int constETDPrint = 0;
    ////////////////////////////////////////////////////////////


    ////////////////////////////////////////////////////////////
    //         constructor, destructor, copy assignment.      //
    ////////////////////////////////////////////////////////////
    CQCGL2d(int N, int M, double dx, double dy,
	    double Mu, double Dr, double Di,
	    double Br, double Bi, double Gr,
	    double Gi,  
	    int threadNum);
    CQCGL2d(int N, double dx,
	    double Mu, double Dr, double Di,
	    double Br, double Bi, double Gr,
	    double Gi,  
	    int threadNum);
    CQCGL2d(int N, int M,  double dx, double dy, 
	    double b, double c, double dr, double di, 
	    int threadNum);
    CQCGL2d(int N, double dx,
	    double b, double c, double dr, double di, 
	    int threadNum);
    ~CQCGL2d();
    CQCGL2d & operator=(const CQCGL2d &x);
    
    ////////////////////////////////////////////////////////////
    //                    member functions.                   //
    ////////////////////////////////////////////////////////////

    //============================================================    
    inline int calNe(const double N);
    void CGLInit();
    void changeOmega(double w);
    void calCoe(const double h);
    void oneStep(double &du, const bool onlyOrbit);
    ArrayXXcd ZR(const Ref<const ArrayXcd> &z);
    double adaptTs(bool &doChange, bool &doAccept, const double s);


    void saveState(H5::H5File &file, int id, const ArrayXXcd &a, 
		   const ArrayXXcd &v, const int flag);
    ArrayXXcd 
    constETD(const ArrayXXcd &a0, const ArrayXXcd &v0, 
	     const double h, const int Nt, 
	     const int skip_rate, const bool onlyOrbit,
	     const bool doSaveDisk, const std::string fileName);
    ArrayXXcd
    adaptETD(const ArrayXXcd &a0, const ArrayXXcd &v0, 
	     const double h0, const double tend, 
	     const int skip_rate, const bool onlyOrbit,
	     const bool doSaveDisk, const std::string fileName);
    ArrayXXcd 
    intg(const ArrayXXcd &a0, const double h, const int Nt, const int skip_rate,
	 const bool doSaveDisk, const std::string fileName);
    ArrayXXcd
    aintg(const ArrayXXcd &a0, const double h, const double tend, 
	  const int skip_rate, const bool doSaveDisk, const std::string fileName);
    ArrayXXcd
    intgv(const ArrayXXcd &a0, const ArrayXXcd &v0, const double h,
	  const int Nt, const int skip_rate,
	  const bool doSaveDisk, const std::string fileName);
    ArrayXXcd 
    aintgv(const ArrayXXcd &a0, const ArrayXXcd &v0, const double h,
	   const double tend, const int skip_rate,
	   const bool doSaveDisk, const std::string fileName);
    
    void dealias(const int k, const bool onlyOrbit);
    void NL(const int k, const bool onlyOrbit);
    ArrayXXcd unpad(const ArrayXXcd &v);
    ArrayXXcd pad(const ArrayXXcd &v);
    ArrayXd c2r(const ArrayXXcd &v);
    ArrayXXcd r2c(const ArrayXd &v);
    
    //============================================================  

    ArrayXXcd Fourier2Config(const Ref<const ArrayXXcd> &aa);
    ArrayXXcd Config2Fourier(const Ref<const ArrayXXcd> &AA);
    
    ArrayXXcd velocity(const ArrayXXcd &a0);
    ArrayXXcd velocityReq(const ArrayXXcd &a0, const double wthx,
			  const double wthy, const double wphi);
    ArrayXXcd stab(const ArrayXXcd &a0, const ArrayXXcd &v0);
    ArrayXXcd stabReq(const ArrayXXcd &a0, const ArrayXXcd &v0,
		      const double wthx, const double wthy,
		      const double wphi);
    
    ArrayXXcd rotate(const Ref<const ArrayXXcd> &a0, const int mode, const double th1 = 0,
		     const double th2 = 0, const double th3 = 0);
    ArrayXXcd tangent(const Ref<const ArrayXXcd> &a0, const int mode);


    std::tuple<ArrayXXcd, double, double, double, double>
    readReq(const std::string fileName, const std::string groupName);
    
    
    std::tuple<ArrayXXd, ArrayXd, ArrayXd>
    orbit2sliceWrap(const Ref<const ArrayXXd> &aa);
    std::tuple<ArrayXXd, ArrayXd, ArrayXd>
    orbit2slice(const Ref<const ArrayXXd> &aa);
    ArrayXXd orbit2sliceSimple(const Ref<const ArrayXXd> &aa);
    MatrixXd ve2slice(const ArrayXXd &ve, const Ref<const ArrayXd> &x);

};



#endif  /* CQCGL2D_H */
<file_sep>from ctypes import *
from numpy import *

class AT(Structure):
    _fields_ = [("aa", POINTER(c_double)),
                ("tt", POINTER(c_double))]



def ksint(a0, h, nstp, np = 1, d = 22):
    """
    % integrate KS system.
    % input:
    %      a0 : initial condition (must be 30x1)
    %      h : time step
    %      nstp: number of integration steps
    %      d : size of system. Default = 22
    %      np : saving spacing. Default = 1
    % output:
    %      aa : the orbit.  size [30, nstp/np+1]
    % exmple usage:
    %   aa = ksint(a0, 0.25, 1000);
    """
    ks, N, ch, cnstp, cnp, cd, pa0, aa, paa = init(a0, h, nstp, np, d)
    ks.ksf(paa, pa0, cd, ch, cnstp, cnp)
    aa = aa.reshape((nstp/np+1, N-2))
    # aa = aa.reshape((N-2, nstp/np+1), order='F')
    
    return aa

def ksintM1(a0, h, nstp, np = 1, d = 22):
    """
    % integrate KS system on the 1st mode slice.
    % input:
    %      a0 : initial condition (must be 30x1, a0(2) = 0)
    %      h : time step
    %      nstp: number of integration steps
    %      d : size of system. Default = 22
    %      np : saving spacing. Default = 1
    % output:
    %    tt : time sequence in the full state space [nstp/np+1]
    %    aa : trajectory in the 1st mode slice [30, nstp/np+1]
    % exmple usage:
    %   tt, aa = ksintM1(a0, 0.25, 1000);

    """
    ks, N, ch, cnstp, cnp,cd, pa0, aa, paa = init(a0, h, nstp, np, d)
    tt = empty(nstp/np+1)
    ptt = tt.ctypes.data_as(POINTER(c_double))
    
    ks.ksfM1(paa, ptt, pa0, cd, ch, cnstp, cnp)
    aa = aa.reshape((nstp/np+1, N-2))
    
    return tt, aa

def ksint2M1(a0, h, T, np = 1, d = 22):
    """
    % integrate KS system on the 1st mode slice.
    % input:
    %      a0 : initial condition (must be 30x1, a0(2) = 0)
    %      h : time step
    %      nstp: number of integration steps
    %      d : size of system. Default = 22
    %      np : saving spacing. Default = 1
    % output:
    %      tt : time in the full state space 
    %      aa : trajectory on the 1st mode slice
    % exmple usage:
    %   [tt,aa] = ksint2M1(a0, 0.25, 1000);
    """
    ks = cdll.LoadLibrary('./libks2py.so')
    ks.ksf2M1.argtypes = [POINTER(AT), POINTER(c_double), 
                          c_double, c_double, c_double, c_int]
    ks.ksf2M1.restype = c_int
    ks.freeks.argtypes = [POINTER(AT)]

    N = len(a0) + 2
    
    ch = c_double(h)
    cT = c_double(T)
    cnp = c_int(np)
    cd = c_double(d)
    
    pa0 = a0.ctypes.data_as(POINTER(c_double))
    at = AT()
    M = ks.ksf2M1(byref(at), pa0, cd, ch, cT, cnp)
    aa = fromiter(at.aa, dtype=double, count=M*(N-2))
    aa = aa.reshape((M, N-2))
    tt = fromiter(at.tt, dtype=double, count=M)
    ks.freeks(at) # free the allocated memory. Just once

    return tt, aa
    
def init(a0, h, nstp, np, d):
    
    ks = cdll.LoadLibrary('./libks2py.so')
    
    N = len(a0) + 2
    
    ch = c_double(h)
    cnstp = c_int(nstp)
    cnp = c_int(np)
    cd = c_double(d)
    
    pa0 = a0.ctypes.data_as(POINTER(c_double))
    aa = empty((nstp/np+1)*(N-2)) 
    paa = aa.ctypes.data_as(POINTER(c_double))

    return ks, N, ch, cnstp, cnp, cd, pa0, aa, paa

<file_sep>// to compile
//
// add -I$XDAPPS/arpackpp/include -llapack -larpack -lsuperlu -lopenblas
//
// first use
// mpicxx --showme -O3 test_CQCGL1dRpo_mpi.cc  -L../../lib -I../../include -I$EIGEN -std=c++11 -lCQCGL1dRpo -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm
//
// then change g++ to h5c++
// 
// h5c++ -O3 test_CQCGL1dRpo_arpack_mpi.cc -std=c++11 -L../../lib -I$RESH/include -I$EIGEN  -I$XDAPPS/arpackpp/include -lCQCGL1dRpo_arpack -lCQCGL1dRpo -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -L/usr//lib -L/usr/lib/openmpi/lib -lmpi_cxx -lmpi -ldl -lhwloc -llapack -larpack -lsuperlu -lopenblas


#include <iostream>
#include <arsnsym.h>
#include <Eigen/Dense>
#include "CQCGL1dRpo_arpack.hpp"
#include "myH5.hpp"
#include <mpi.h>

using namespace std;
using namespace Eigen;
using namespace denseRoutines;
using namespace MyH5;

#define cee(x) (cout << (x) << endl << endl)

#define CASE_10


int main(int argc, char **argv){

#ifdef CASE_10
    //======================================================================
    // calculate E and V 
    const int N = 1024;
    const double L = 50;
    double Bi = 1.9;
    double Gi = -5.6;
    
    CQCGL1dRpo_arpack cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoBiGiEV.h5";
    
    std::vector<double> Bis, Gis;
    std::tie(Bis, Gis) =  CQCGL1dRpo_arpack::getMissIds(file, Bi, Gi, 0.1, 0.1, 39, 55);
    int Ns = Bis.size();
    cout << Ns << endl;

    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = Ns / num;
    int rem = Ns - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    std::vector<double> p_Bis, p_Gis;
    for(int i = p_start; i < p_end; i++){
	p_Bis.push_back(Bis[i]);
	p_Gis.push_back(Gis[i]);
    }
    
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////

    cgl.calEVParaSeq(file, p_Bis, p_Gis, 30, true);
    

    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////


#endif
#ifdef CASE_20
    //======================================================================
    // Calculate E and V along one Gi line for a specific Bi
    const int N = 1024;
    const int L = 50;
    double Bi = 2.3;
    double Gi = -5.6;

    CQCGL1dRpo_arpack cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 1);
    string file = "../../data/cgl/rpoBiGiEV.h5";    
    std::vector<double> Bis, Gis;
    Bis.push_back(Bi);
    
    int NsG = 16;
    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = NsG / num;
    int rem = NsG - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    for (int i = p_start; i < p_end; i++) Gis.push_back(Gi+0.1*i);
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////

    cgl.calEVParaSeq(file, Bis, Gis, 10, true);

    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////


#endif

    return 0;
}

<file_sep>/*
 * g++ rossler.cc -O3 -std=c++11 -I $XDAPPS/sources/boost_1_57_0 -I $XDAPPS/eigen/include/eigen3 -I $RESH/include -L $RESH/lib -literMethod
 */
#include <iostream>
#include <vector>
#include <boost/numeric/odeint.hpp>
#include <Eigen/Dense>
#include <functional>
#include "iterMethod.hpp"

using namespace std;
using namespace Eigen;
using namespace boost::numeric::odeint;
using namespace iterMethod;
namespace ph = std::placeholders;

class Rossler {
    
protected:
    //////////////////////////////////////////////////////////////////////
    //                              Inner classes                       //
    //////////////////////////////////////////////////////////////////////

    /**
     * @brief velocity of Rossler system
     *
     *   dx/dt = - y - z
     *   dy/dt = x + a * y
     *   dz/dt = b + z * (x - c)
     */
    struct Velocity{
	const double a, b, c;
	Velocity (double a = 0.2, double b=0.2, double c = 5.7) : a(a), b(b), c(c) {}
	void operator()(const std::vector<double> &x, std::vector<double> &dxdt,
			const double /* t */){
	    dxdt[0] = -x[1] - x[2];
	    dxdt[1] = x[0] + a * x[1];
	    dxdt[2] = b + x[2] * (x[0] - c);
	}
    };
    
    /**
     * @brief calculate J * dx for Rossler
     *
     *               | 0, -1, -1  |
     *  stability =  | 1,  a,  0  |
     *               | z,  0, x-c |
     *
     */
    struct Jacv{
	const double a, b, c;
	Jacv (double a = 0.2, double b = 0.2, double c = 5.7) : a(a), b(b), c(c) {}
	void operator()(const std::vector<double> &x, std::vector<double> &dxdt,
			const double /* t */){
	    dxdt[0] = -x[1] - x[2];
	    dxdt[1] = x[0] + a * x[1];
	    dxdt[2] = b + x[2] * (x[0] - c);
	    
	    dxdt[3] = -x[4] - x[5];
	    dxdt[4] = x[3] + a*x[4];
	    dxdt[5] = x[2]*x[3] + (x[0]-c)*x[5];
	}
	
    };


public:
    
    const double a, b, c;
    Velocity velocity;
    Jacv jacv;
    double odeAtol, odeRtol;


    Rossler(double odeAtol = 1e-16, double odeRtol = 1e-12,
	    double a = 0.2, double b=0.2, double c=5.7) :
	a(a), b(b), c(c),
	velocity(a, b, c),
	jacv(a, b, c),
	odeAtol(odeAtol), odeRtol(odeRtol)
    {}

    Vector3d getVelocity(Array3d x0){
	std::vector<double> x(&x0[0], &x0[0] + x0.size());
	std::vector<double> v(3);
	velocity(x, v, 0);
	Vector3d vel = Map<Vector3d>(&v[0]);
	return vel; 
    }
    
    /**
     * @brief integrator : each column is a state vector
     */
    template< typename Vel>
    std::pair<ArrayXXd, ArrayXd>
    intg0(const ArrayXd &x0, const double h, const int nstp, Vel vel, int blockSize = 100){
	ArrayXXd xx(x0.size(), blockSize);
	ArrayXd tt(blockSize);
	int totalNum = 0;
	std::vector<double> x(&x0[0], &x0[0] + x0.size());
	//integrate_adaptive(make_controlled< runge_kutta_cash_karp54<std::vector<double>> >( odeAtol , odeRtol ) ,
	integrate_const( runge_kutta4< std::vector<double> >() , 
			 // integrate(
			 vel, x, 0.0, nstp*h, h,
			 [&xx, &tt, &totalNum, &blockSize](const std::vector<double> &x, double t){		      
			     if(totalNum >= tt.size()){
				 xx.conservativeResize(NoChange, xx.cols() + blockSize);
				 tt.conservativeResize(tt.size() + blockSize);
			     }
			     xx.col(totalNum) = ArrayXd::Map(&x[0], x.size());
			     tt(totalNum++) = t;
			 });
       
	return make_pair(xx.leftCols(totalNum), tt.head(totalNum));
    }

    std::pair<ArrayXXd, ArrayXd>
    intg(const ArrayXd &x0, const double h, const int nstp, int blockSize = 100){
	return intg0(x0, h, nstp, velocity, blockSize);
    }

    std::tuple<ArrayXXd, ArrayXXd, ArrayXd>
    intgv(const ArrayXd &x0, const ArrayXd &dx0, const double h,
	  const int nstp, int blockSize = 100){
	ArrayXd xdx(x0.size() + dx0.size());
	xdx << x0, dx0;
	auto tmp = intg0(xdx, h, nstp, jacv, blockSize);
	return std::make_tuple(tmp.first.topRows(3),
			       tmp.first.bottomRows(3),
			       tmp.second);
    }

    /**
     * @brief form f(x,t) - x
     * @param[in] x   4-element vector: (x, t)
     * @return    4-element vector
     *               | f(x, t) - x|
     *               |     0      |
     */
    Vector4d Fx(Vector4d x){
	int nstp =  (int)(x(3) / 0.01); 
	Array3d fx = intg(x.head(3), x(3)/nstp, nstp).first.rightCols(1);
	Vector4d F; 
	F << fx, x(3);
	return F - x;
    }

    /**
     * @brief get the product J * dx
     *
     * Here J = | J(x, t) - I,  v(f(x,t)) | 
     *          |     v(x),          0    |
     */

    Vector4d DFx(Vector4d x, Vector4d dx){
	int nstp = (int)(x(3) / 0.01);
	auto tmp = intgv(x.head(3), dx.head(3), x(3)/nstp, nstp);
	VectorXd v1 = getVelocity(x.head(3));
	VectorXd v2 = getVelocity(std::get<0>(tmp).rightCols(1));
	Vector4d DF;
	DF << std::get<1>(tmp).rightCols(1).matrix() - dx.head(3) + v2 * dx(3),
	    v1.dot(dx.head(3));
	return DF;
    }

#if 0
    VectorXd DFx(Vector4d x, Vector4d dx){
	int nstp = (int)(x(3) / 0.01);
	auto tmp = intg(x.head(3), x(3)/nstp, nstp);
	double norm = dx.head(3).norm();
	auto tmp2 = intg(x.head(3) + 1e-7*dx.head(3)/norm, x(3)/nstp, nstp);
	Vector3d Jx = (tmp2.first.rightCols(1) - tmp.first.rightCols(1)) / 1e-7 * norm;
	VectorXd v1 = getVelocity(x.head(3));
	VectorXd v2 = getVelocity(tmp.first.rightCols(1));
	Vector4d DF;
	DF << Jx - dx.head(3) + v2 * dx(3),
	    v1.dot(dx.head(3));
	return DF;
    }

    #endif
};


int main(){
    
    switch (1){
	
    case 1 :{
	Rossler ros;
	Array3d x0;
	// x0 << 1, 6.0918, 1.2997;
	// x0 << -3.36773  ,  5.08498  ,  0.0491195;
	// T = 18
	// x0 << -3.36788  ,  5.08677  ,  0.0240049;
	// double T = 17.5959;
	x0 << 0.511787,  5.99344,  1.85836;
	double T = 5.88109;

	
	int nstp = int(T/0.01);
	    
	Array3d dx0;
	dx0 << 0.2, 0.2, 0.2;
	auto tmp = ros.intgv(x0, dx0, T/nstp, nstp);
	cout << std::get<0>(tmp) << endl;
	break;
    }

    case 2 : {
	Rossler ros;
	Array3d x0;
	//x0 << 1, 6.0918, 1.2997;
	x0 << -3.36773  ,  5.08498  ,  0.0491195;   
	Array3d dx0;
	dx0 << 0.1, 0.1, 0.1;
	auto tmp = ros.intg(x0, 0.01, 1800);
	cout << std::get<1>(tmp) << endl;
	break;
	
    }
	
    case 3 : {
	Rossler ros;
	Vector4d x0;
	//x0 << 1, 6.0918, 1.2997, 5.88;
	x0  <<  -3.36773  ,  5.08498  ,  0.0491195, 18;   
	auto tmp = ros.Fx(x0);
	//cout << tmp << endl;
	
	/* Vector4d dx0; */
	/* dx0 << 0.1, 0.1, 0.1, 0.1; */
	/* tmp = ros.DFx(x0, dx0); */
	/* cout << tmp << endl; */
	break;
    }
	
    case 4: {			// find POs
	Rossler ros;
	Vector4d x0;
	x0 << 1, 6.0918, 1.2997, 5.88;
	//x0  <<  -3.36773  ,  5.08498  ,  0.0491195, 18;
	
	auto f = std::bind(&Rossler::Fx, ros, ph::_1);
	auto df = std::bind(&Rossler::DFx, ros, ph::_1, ph::_2);
	auto result = InexactNewtonBacktrack(f, df, x0, 1e-12, 10, 10);
	cout << std::get<0>(result) << endl;
	break;
    }
	
    }
    return 0;
}
<file_sep>from ksHelp import *

case = 10

if case == 10:
    ksp = KSplot()
    fileName = '../../data/Ruslan/ks22h1t120.h5'
    a, T, nstp, theta, err = ksp.readPO(fileName, ksp.toStr('ppo', 1), False, hasNstp=False)
    
    
<file_sep>/* to comiple:
 * g++ ksrefine.cc std=c++0x -O3 -march=corei7 -msse2 -msse4
 * -L ../../lib -I ../../include -I $XDAPPS/eigen/include/eigen3
 * -lksint -lfftw3 -lm
 */

#ifndef KSREFINE_H
#define KSREFINE_H

#include "ksint.hpp"
#include <vector>
#include <tuple>
#include <Eigen/Dense>
#include <Eigen/Sparse>

class KSrefine {

public:
  //////////////////////////////////////////////////
  // variables
  const int N;			/* N = 32 */
  const double L;		/* L = 22 */

  //////////////////////////////////////////////////
  std::tuple<VectorXd, double, double>
  findPO(const Eigen::ArrayXd &a0, const double T, const int Norbit, 
	 const int M, const std::string ppType,
	 const double hinit = 0.1,
	 const double th0 = 0, 
	 const int MaxN = 100, 
	 const double tol = 1e-14, 
	 const bool Print = false,
	 const bool isSingle = false);
  std::tuple<MatrixXd, double, double, double>
  findPOmulti(const Eigen::ArrayXd &a0, const double T, const int Norbit, 
	      const int M, const std::string ppType,
	      const double hinit = 0.1,
	      const double th0 = 0, 
	      const int MaxN = 100, 
	      const double tol = 1e-14, 
	      const bool Print = false,
	      const bool isSingle = false);
  Eigen::VectorXd 
  multiF(KS &ks, const Eigen::ArrayXXd &x, const int nstp, 
	 const std::string ppType, const double th = 0.0);
  std::pair<Eigen::SparseMatrix<double>, Eigen::VectorXd> 
  multishoot(KS &ks, const Eigen::ArrayXXd &x, const int nstp, 
	     const std::string ppType, const double th = 0.0, 
	     const bool Print = false);

  //////////////////////////////////////////////////
  KSrefine(int N = 32, double L = 22);
  explicit KSrefine(const KSrefine &x);
  KSrefine & operator=(const KSrefine &x);
  ~KSrefine();

protected:
  
  std::vector<Eigen::Triplet<double> >
  triMat(const MatrixXd &A, const size_t M = 0, const size_t N = 0);
  std::vector<Eigen::Triplet<double> >
  triDiag(const size_t n, const double x, const size_t M = 0, 
	  const size_t N = 0 );
  int
  calColSizeDF(const int &rows, const int &cols, const std::string ppType);
  
};
#endif	/* KSREFINE_H */
<file_sep>#include <iostream>
#include <fstream>
#include "KSPO.hpp"
#include "iterMethod.hpp"
#include "sparseRoutines.hpp"

using namespace std; 
using namespace Eigen;
using namespace sparseRoutines;
using namespace iterMethod;
using namespace MyH5;

////////////////////////////////////////////////////////////
//                     class KSPO                     //
////////////////////////////////////////////////////////////

/*------------          constructor        ---------------*/
KSPO::KSPO(int N, double d) : KS(N, d) {
}
KSPO & KSPO::operator=(const KSPO &x){ 
    return *this; 
}
KSPO::~KSPO(){}

////////////////////////////////////////////////////////////////////////////////
std::string 
KSPO::toStr(string ppType, int id){
    char g[20];
    sprintf(g, "%06d", id);
    return ppType + '/' + string(g);    
}

std::string
KSPO::toStr(double domainSize, string ppType, int id){
    char g1[20], g2[20];
    sprintf(g1, "%010.6f", domainSize);
    sprintf(g2, "%06d", id);
    return string(g1) + '/' + ppType + '/' + string(g2);
}

// [a, T, nstp, theta, err]
std::tuple<VectorXd, double, int, double, double>
KSPO::read(H5File &file, const std::string groupName, const bool isRPO){
    // H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";
    
    // Ruslan's orignal data does not have nstp
    int nstp = checkGroup(file, groupName + "/nstp", false) ? 
	readScalar<int>(file, DS + "nstp") : 0;
    
    double theta = isRPO ? readScalar<double>(file, DS + "theta") : 0;
    
    return make_tuple(readMatrixXd(file, DS + "a").col(0),
		      readScalar<double>(file, DS + "T"),
		      nstp, 
		      theta,
		      readScalar<double>(file, DS + "err")
		      );
}

/** [a, T, nstp, theta, err]
 * @note group should be a new group
 */
void 
KSPO::write(H5File &file, const std::string groupName, const bool isRPO,
	    const ArrayXd &a, const double T, const int nstp,
	    const double theta, const double err){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "a", a);
    writeScalar<double>(file, DS + "T", T);
    if(nstp > 0)	   // Ruslan's orignal data does not have nstp
	writeScalar<int>(file, DS + "nstp", nstp);
    if(isRPO)
	writeScalar<double>(file, DS + "theta", theta);
    writeScalar<double>(file, DS + "err", err);
}

MatrixXd 
KSPO::readE(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    MatrixXd e = readMatrixXd(file, DS + "e");
    return e;
}

MatrixXd 
KSPO::readV(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    MatrixXd v = readMatrixXd(file, DS + "ve");
    return v;
}

void 
KSPO::writeE(H5File &file, const std::string groupName, 
	     const MatrixXd &e){
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    writeMatrixXd(file, DS + "e", e);
}

void 
KSPO::writeV(H5File &file, const std::string groupName, 
	     const MatrixXd &v){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    writeMatrixXd(file, DS + "v", v);
}

void 
KSPO::move(H5File &fin, std::string gin, H5File &fout, std::string gout,
	   int flag){
    // VectorXd a;
    // VectorXcd e;
    // MatrixXcd v;
    // double wth, wphi, err;

    // std::tie(a, wth, wphi, err) = read(fin, gin);
    // if (flag == 1 || flag == 2) e = readE(fin, gin);
    // if (flag == 2) v = readV(fin, gin);
    
    // write(fout, gout, a, wth, wphi, err);
    // if (flag == 1 || flag == 2) writeE(fout, gout, e);
    // if (flag == 2) writeV(fout, gout, v);
}

////////////////////////////////////////////////////////////////////////////////

/**
 * @brief         form [g*f(x,t) - x, ...]
 *
 * Form the difference vector, which consists of m pieces, each piece
 * correspond to (x, t, theta) for RPO and (x, t) for PPO.
 * If m = 1, then it reduces to single
 * shooting.
 * 
 * @param[in] x   [N*m, 1] dimensional vector for RPO and [(N-1)*m] for PPO
 * @return        vector F_i(x, t) =
 *                  | g*f(x, t) - x|
 *                  |       0      |
 *                  |       0      |
 *                for i = 1, 2, ..., m
 */
VectorXd
KSPO::MFx(const VectorXd &x, const int nstp, const bool isRPO){
    int n = isRPO ? N : N - 1;
    assert( x.size() % n == 0 );
    int m = x.size() / n;
    VectorXd F(n*m); F.setZero();
    
    for(int i = 0; i < m; i++){
	VectorXd xi = x.segment(n*i, n);
	int j = (i+1) % m;
	VectorXd xn = x.segment(n*j, n);
	
	double t = xi(N-2);
	double th = isRPO ? xi(N-1) : 0;
	assert(t > 0);
	
	VectorXd fx = intgC(xi.head(N-2), t/nstp, t, nstp); // single state
	VectorXd gfx = isRPO ? (VectorXd)rotate(fx, th) : (i == m-1 ? (VectorXd)reflect(fx) : fx);
	F.segment(i*n, N-2) = gfx - xn.head(N-2);
    }
    return F;
}

/**
 * @brief multishooting
 *
 * For RPO 
 * Here J_i  = | g*J(x, t),      g*v(f(x,t)),  g*t(f(x,t))  | 
 *             |     v(x),          0             0         |
 *             |     t(x),          0             0         |
 * For PPO
 * i = 1, ..., m-1
 * Here J_i  = | J(x, t),      v(f(x,t))  | 
 *             |    v(x),          0      |
 * i = m
 * Here J_i  = | g*J(x, t),      g*v(f(x,t)) | 
 *             |     v(x),          0        |
 *
 * If m = 1, then it reduces to single shooting
 *
 * @note I do not enforce the constraints              
 */
std::tuple<SpMat, SpMat, VectorXd>
KSPO::multiCalJJF(const VectorXd &x, int nstp, const bool isRPO){
    int n = isRPO ? N : N - 1;
    assert( x.size() % n == 0 );
    int m = x.size() / n;
    
    SpMat DF(m*n, m*n);    
    vector<Tri> nz;
    VectorXd F(m*n);
    
    for (int i = 0; i < m; i++) {
	VectorXd xi = x.segment(i*n, n);
	int j = (i+1) % m;
	VectorXd xn = x.segment(n*j, n);
	
	double t = xi(N-2);
	double th = isRPO ? xi(N-1) : 0;
	assert( t > 0 );
	
	auto tmp = intgjC(xi.head(N-2), t/nstp, t, nstp);
	ArrayXXd &fx = tmp.first;
	ArrayXXd &J = tmp.second;

	VectorXd gfx = isRPO ? rotate(fx, th) : (i == m-1 ? reflect(fx) : fx);
	F.segment(i*n, N-2) = gfx - xn.head(N-2);	

	ArrayXXd gJ = isRPO ? rotate(J, th) : (i == m-1 ? reflect(J) : J);
	VectorXd vgfx = velocity(gfx);
	
	vector<Tri> triJ = triMat(gJ, i*n, i*n);
	nz.insert(nz.end(), triJ.begin(), triJ.end());
	vector<Tri> triv = triMat(vgfx, i*n, i*n+N-2);
	nz.insert(nz.end(), triv.begin(), triv.end());
	
	if(isRPO){
	    VectorXd tgfx = gTangent(gfx); 
	    vector<Tri> tritx = triMat(tgfx, i*n, i*n+N-1);
	    nz.insert(nz.end(), tritx.begin(), tritx.end());
	}
	
	// // constraint
	// ArrayXXd v = velocity(xi.head(N-2)).transpose();
	// triv = triMat(v, i*n+N-2, i*n);
	// nz.insert(nz.end(), triv.begin(), triv.end());
	// if(isRPO){
	//     ArrayXXd t = gTangent(xi.head(N-2)).transpose();
	//     vector<Tri> tritx = triMat(t, i*n+N-1, i*n);
	//     nz.insert(nz.end(), tritx.begin(), tritx.end());
	// }

	// -I on the subdiagonal
	vector<Tri> triI = triDiag(N-2, -1, i*n, j*n);
	nz.insert(nz.end(), triI.begin(), triI.end());
    }
    
    DF.setFromTriplets(nz.begin(), nz.end());
    
    SpMat JJ = DF.transpose() * DF;
    SpMat D  = JJ;
    auto keepDiag = [](const int& row, const int& col, const double&){ return row == col; };
    D.prune(keepDiag);
    VectorXd df = DF.transpose() * F; 

    return std::make_tuple(JJ, D, df);
}

// single shooting
// Here   J  = | g*J(x, t) - I,  g*v(f(x,t)),  g*t(f(x,t))  | 
//             |     v(x),          0             0         |
//             |     t(x),          0             0         |
std::tuple<MatrixXd, MatrixXd, VectorXd>
KSPO::calJJF(const VectorXd &x, int nstp, const bool isRPO){
    int n = isRPO ? N : N - 1;
    assert(x.size() == n);
    
    MatrixXd DF(n, n); DF.setZero();
    VectorXd F(n); F.setZero();
    
    double t = x(N-2);
    double th = isRPO ? x(N-1) : 0;
    assert( t > 0 );
    
    auto tmp = intgjC(x.head(N-2), t/nstp, t, nstp);
    ArrayXXd &fx = tmp.first;
    ArrayXXd &J = tmp.second;

    VectorXd gfx = isRPO ? rotate(fx, th) :  reflect(fx);
    F.head(N-2) = gfx - x.head(N-2);	
    
    DF.topLeftCorner(N-2, N-2) = (isRPO ? rotate(J, th) : reflect(J)).matrix() - MatrixXd::Identity(N-2, N-2) ;
    DF.col(N-2).head(N-2) = velocity(gfx);    
    if(isRPO) DF.col(N-1).head(N-2) = gTangent(gfx); 
    
    // DF.row(N-2).head(N-2) = velocity(x.head(N-2)).transpose();
    // if(isRPO) DF.row(N-1).head(N-2) = gTangent(x.head(N-2)).transpose();
    
    
    MatrixXd JJ = DF.transpose() * DF;
    MatrixXd D  = JJ.diagonal().asDiagonal();
    VectorXd df = DF.transpose() * F; 

    return std::make_tuple(JJ, D, df);
}


/// @return [ (x, T, th), err, flag ]
std::tuple<ArrayXXd, double, int>
KSPO::findPO_LM(const ArrayXXd &a0, const bool isRPO, const int nstp,		      
		const double tol, const int maxit, const int innerMaxit){
    int cols = a0.cols(), rows = a0.rows();
    assert (rows == isRPO ? N : N - 1);
    
    Map<const VectorXd> x(a0.data(), cols * rows);
    auto fx = [this, &isRPO, &nstp](const VectorXd &x){ return MFx(x, nstp, isRPO); };
    
    VectorXd xe;
    std::vector<double> res;
    int flag;

    if(cols == 1){
	KSPO_JJF<MatrixXd> jj(this, nstp, isRPO);
	PartialPivLU<MatrixXd> solver;
	std::tie(xe, res, flag) = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    }
    else {
	KSPO_MULTIJJF<SpMat> jj(this, nstp, isRPO);
	SparseLU<SpMat> solver; 	
	std::tie(xe, res, flag) = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    }
    if(flag != 0) fprintf(stderr, "PO not converged ! \n");
    
    ArrayXXd states(xe);
    states.resize(rows, cols);
    return std::make_tuple( states, res.back(), flag );
}


std::pair<MatrixXd, MatrixXd>
KSPO::calEV(const bool isRPO, const ArrayXd &a0,  const double T, const int nstp, const double theta,
	    const double tol, const int MaxN, const int trunc){
    auto tmp = intgjC(a0, T/nstp, T, 1);
    MatrixXd Js = tmp.second; // need to make it MatrixXd.
    
    PED ped;
    ped.reverseOrder(Js);
    Js.leftCols(N-2) = isRPO ? rotate(Js.leftCols(N-2), theta) : reflect(Js.leftCols(N-2));
    
    pair<MatrixXd, MatrixXd> ev = ped.EigVecs(Js, MaxN, tol, false, trunc);
    MatrixXd &e = ev.first, &v = ev.second;
    e.col(0) /= T;
    return make_pair(e, v);    
}
<file_sep>from py_CQCGL1d import *
from cglHelp import *

case = 60

if case == 1:
    """
    view an ergodic instance
    full state space => reduce continuous symmetry =>
    reduce reflection symmetry
    """
    N = 256
    d = 50
    h = 0.005
    cgl = pyCqcgl1d(N, d, h,  True, 0, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6, 4)
    Ndim = cgl.Ndim

    A0 = centerRand(2*N, 0.2)
    a0 = cgl.Config2Fourier(A0)
    nstp = 15000
    aa = cgl.intg(a0, nstp, 1)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])

    aaHat, th, phi = cgl.orbit2sliceWrap(aa)
    aaHat2, th2, phi2 = cgl.orbit2slice(aa)
    plotConfigSpace(cgl.Fourier2Config(aaHat), [0, d, 0, nstp*h])
    plotConfigSpace(cgl.Fourier2Config(aaHat2), [0, d, 0, nstp*h])
    aaTilde = cgl.reduceReflection(aaHat)
    plotConfigSpace(cgl.Fourier2Config(aaTilde), [0, d, 0, nstp*h])

    # rely on numpy's unwrap function
    th3 = unwrap(th*2.0)/2.0
    phi3 = unwrap(phi*2.0)/2.0
    aaHat3 = cgl.rotateOrbit(aa, -th3, -phi3)
    plotConfigSpace(cgl.Fourier2Config(aaHat3), [0, d, 0, nstp*h])

    # rotate by g(pi, pi)
    aaHat4 = cgl.Rotate(aaHat2, pi, pi)
    plotConfigSpace(cgl.Fourier2Config(aaHat4), [0, d, 0, nstp*h])
    aaTilde4 = cgl.reduceReflection(aaHat4)
    plotConfigSpace(cgl.Fourier2Config(aaTilde4), [0, d, 0, nstp*h])

    # reflection
    aa2 = cgl.reflect(aa)
    plotConfigSpace(cgl.Fourier2Config(aa2), [0, d, 0, nstp*h])
    aaHat5, th5, phi5 = cgl.orbit2slice(aa2)
    plotConfigSpaceFromFourier(cgl, aaHat5, [0, d, 0, nstp*h])
    aaTilde5 = cgl.reduceReflection(aaHat5)
    plotConfigSpace(cgl.Fourier2Config(aaTilde5), [0, d, 0, nstp*h])


if case == 2:
    # view relative equlibria
    N = 1024
    d = 30
    di = 0.06

    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, -1, 4)
    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN512.h5', '1')

    vReq = cgl.velocityReq(a0, wth0, wphi0)
    print norm(vReq)

    # check the reflected state
    a0Reflected = cgl.reflect(a0)
    vReqReflected = cgl.velocityReq(a0Reflected, -wth0, wphi0)
    print norm(vReqReflected)
    # plotOneConfigFromFourier(cgl, a0)
    # plotOneConfigFromFourier(cgl, a0Reflected)

    # obtain the stability exponents/vectors
    # eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvalues, eigvectors = eigReq(cgl, a0Reflected, -wth0, wphi0)
    print eigvalues[:10]

    # make sure you make a copy because Fourier2Config takes contigous memory
    tmpr = eigvectors[:, 0].real.copy()
    tmprc = cgl.Fourier2Config(tmpr)
    tmpi = eigvectors[:, 0].imag.copy()
    tmpic = cgl.Fourier2Config(tmpi)
    plotOneConfig(tmprc, size=[6, 4])
    plotOneConfig(tmpic, size=[6, 4])

    nstp = 2000
    aa = cgl.intg(a0Reflected, nstp, 1)
    plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h], [0, 2])
    raa, th, phi = cgl.orbit2slice(aa)
    plotConfigSpace(cgl.Fourier2Config(raa), [0, d, 0, nstp*h], [0, 2])
    plotOneFourier(aa[-1])

# test the ve2slice function
if case == 3:
    N = 512
    d = 50
    h = 0.01

    cgl = pyCqcgl1d(N, d, h, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)
    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN512.h5', '1')
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)

    # plot the last vector to see whether Tcopy works
    eigvectors = realve(eigvectors)
    eigvectors = Tcopy(eigvectors)
    plotOneConfigFromFourier(cgl, eigvectors[-1])

    veHat = cgl.ve2slice(eigvectors, a0)
    print veHat[:4, :8]
    # plotOneConfigFromFourier(cgl, eigvectors[0])
    # print out the norm of two marginal vectors. They should valish
    print norm(veHat[4]), norm(veHat[5])

    # test the angle between each eigenvector
    v1 = veHat[0]
    v2 = veHat[1]
    print np.dot(v1, v2) / norm(v1) / norm(v2)
    plotOneFourier(v1)
    plotOneFourier(v2)

if case == 4:
    """
    test the reflectVe function
    """
    N = 512
    d = 50
    h = 0.01

    cgl = pyCqcgl1d(N, d, h, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)
    Ndim = cgl.Ndim
    a0, wth0, wphi0, err = cqcglReadReq('../../data/cgl/reqN512.h5', '1')
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = realve(eigvectors)
    eigvectors = Tcopy(eigvectors)

    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)
    veTilde = cgl.reflectVe(veHat, a0Hat)

    a0Ref = cgl.reflect(a0)
    veRef = cgl.reflect(eigvectors)
    a0RefHat = cgl.orbit2slice(a0Ref)[0]
    veRefHat = cgl.ve2slice(veRef, a0Ref)
    veRefTilde = cgl.reflectVe(veRefHat, a0RefHat)
    # why the hell is veHat the same as veRefHat ?

if case == 50:
    """
    use the new form of cqcgl
    test the transition with respect to di
    """
    N = 1024
    d = 30
    h = 1e-4
    di = 0.05

    cgl = pyCQCGL1d(N, d, 4.0, 0.8, 0.01, di, -1)
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    nstp = 20000
    x = []
    for i in range(3):
        aa = cgl.intg(a0, h, nstp, 10)
        a0 = aa[-1]
        plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])
        # plotPhase(cgl, aa, [0, d, 0, nstp*h])
        # plotOneConfigFromFourier(cgl, aa[-1], d)
        # plotOnePhase(cgl, aa[-1], d)
        # plot1dfig(aa[:, 0])
        x.append(aa)

if case == 55:
    """
    reproduce the pulstating soliton with L = 50
    """
    N, d = 1024 , 50
    h = 1e-2
    cgl = pyCQCGL1d(N, d, -0.1, 0.08, 0.5, 0.782, 1, -0.1, -0.08, -1)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    a0 = cgl.intgC(a0, h, 100, 1000000)

    T = 70
    aa = cgl.intgC(a0, h, T, 100)
    aa2 = cgl.intg(a0, h, T, 100)
    cp.config(aa, [0, d, 0, T])
    np.savez_compressed('pulsatingSoliton', states=aa, statesAdapt=aa2, Ts=cgl.Ts(), T=T)


if case == 56:
    """
    produce profile with extremete solition
    """
    N, d = 1024 , 50
    Bi, Gi = 3.5, -5.0

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5',
                                              rpo.toStr(Bi, Gi, 1), flag=2)
    a0 = x[:cgl.Ndim]
    print e[:10]

    #a0 += 0.1*norm(a0)*v[0]
    aa = cgl.intgC(a0, T/nstp, 3*T, 600)
    aa2 = cgl.intg(a0, T/nstp, 3*T, 50)
    cp.config(aa, [0, d, 0, 3*T])

    np.savez_compressed('extremeSoliton', states=aa, statesAdapt=aa2, Ts=cgl.Ts(), T=3*T)

if case == 57:
    """
    produce profile with composite soliton
    """
    N, d = 1024 , 50
    h = 2e-3
    Bi, Gi = 3, -5.0

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)
    a0, wth0, wphi0, err = req.read('../../data/cgl/reqBiGi.h5', 
                                    req.toStr(Bi, Gi, 1))
    T = 10
    aa = cgl.intgC(a0, h, T, 100)
    aa2 = cgl.intg(a0, h, T, 50)
    cp.config(aa, [0, d, 0, T])

    np.savez_compressed('compositeSoliton', states=aa, statesAdapt=aa2, Ts=cgl.Ts(), T=T)

if case == 58:
    """
    produce 
    """
    N, d = 1024, 120
    h = 2e-3

    Dr = 0.883
    
    cgl = pyCQCGL1d(N, d, -0.1, Dr, -1.1, 3, 1, -2.75, 1, -1)
    cp = CQCGLplot(cgl)

    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.1, True)
    a0 = cgl.Config2Fourier(A0)
    a0 = cgl.intg(a0, h, 100, 1000000)

    T = 30
    aa = cgl.intgC(a0, h, T, 50)
    aa2 = cgl.intg(a0, h, T, 50)
    cp.config(aa, [0, d, 0, T])
        
###############################################################################
if case == 60:
    """
    Try to reproduce the result of  Descalzi.
    =======
    <NAME> and <NAME>, "Transition from modulated to exploding
    dissipative solitons: Hysteresis, dynamics, and analytic aspects", Phys.
    Rev. E 82, 026203 (2010)
    ======
    But I failed to get the f1 and f1-f2 region and their hysteretic
    transition.
    """
    N = 1024
    d = 50
    h = 2e-3

    Mu = -1
    cgl = pyCQCGL1d(N, d, Mu, 0.125, 0.5, 1, 1, -0.1, -0.6, -1)
    cp = CQCGLplot(cgl)

    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    a0 = cgl.intg(a0, h, 50, 1000000)

    # stable soliton
    T = 50
    aa = cgl.intg(a0, h, T, 100)
    cp.config(aa, [0, d, 0, T])

    # oscillating soltion with one frequency
    Mu = -0.21
    cgl = pyCQCGL1d(N, d, Mu, 0.125, 0.5, 1, 0.8, -0.1, -0.6, -1)
    T = 50
    a0 = cgl.intg(aa[-1], h, 5, 1000000)
    aa = cgl.intg(a0, h, T, 100)
    cp.config(aa, [0, d, 0, T])

    # oscillating soltion with two frequency
    Mu = -0.21
    cgl = pyCQCGL1d(N, d, Mu, 0.125, 0.5, 1, 1, -0.1, -0.6, -1)
    T = 80
    a0 = cgl.intg(aa[-1], h, 5, 1000000)
    aa = cgl.intg(a0, h, T, 100)
    cp.config(aa, [0, d, 0, T])

    # aa = cgl.intg(a0, 0.01, np.int(50/0.01), 10)
    # plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])

if case == 70:
    """
    Try to reproduce AKhmediev's paper
    ======
    Strongly asymmetric soliton explosions
    <NAME>, <NAME> - Physical Review E, 2004 - APS
    =====
    """
    N = 1024
    d = 30
    h = 1e-4

    nu = -0.4
    cgl = pyCQCGL1d(N, d, -0.8, 0.15, 1, 1.4, -0.1, nu, -1)
      
    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    a0 = cgl.intg(a0, h, np.int(50/h), np.int(50/h))[-1]

    T = 500
    aa = cgl.intg(a0, h, np.int(T/h), 100)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])

if case == 80:
    """
    Try to reproduce results of Deissler and Brand
    ======
    "Periodic, quasiperiodic, and chaotic localized solutions of the quintic
    complex Ginzburg-Landau equation"
    <NAME>, HR Brand - Physical review letters, 1994 - APS
    ======
    """
    N = 1024
    d = 120
    h = 1e-3

    Dr = 0.9
    
    cgl = pyCQCGL1d(N, d, -0.1, Dr, -1.1, 3, 1, -2.75, 1, -1)

    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.1, True)
    a0 = cgl.Config2Fourier(A0)
    a0 = cgl.intg(a0, h, np.int(100/h), np.int(100/h))[-1]

    T = 250
    aa = cgl.intg(a0, h, np.int(T/h), 20)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])

if case == 90:
    """
    Try to reproduce results in
    ======
    Creeping solitons in dissipative systems and their bifurcations
    <NAME>, <NAME>, <NAME>, and <NAME>
    Phys. Rev. E 76, 016607 - Published 26 July 2007
    ======
    """
    N = 1024
    d = 60
    h = 1e-2

    epsilon = 0.844
    cgl = pyCQCGL1d(N, d, -0.1, 0.08, 1, epsilon, -0.11, -0.08, -1)
    cp = CQCGLplot(cgl)
      
    if True:
        Ndim = cgl.Ndim
        A0 = 3*centerRand(N, 0.2, True)
        a0 = cgl.Config2Fourier(A0)
        a0 = cgl.intgC(a0, h, 100, 1000000)

        T = 300
        aa = cgl.intgC(a0, h, T, 100)
        Q = cgl.calQ(aa)
        cp.config(aa, [0, d, 0, T])
        plot1dfig(Q)
        np.save('a0', aa[-1])

    if False:
        cgl.Br = 0.844
        a0 = load('a0.npy')
        a0 = cgl.intg(a0, h, np.int(100/h), np.int(100/h))[-1]
        T = 300
        aa = cgl.intg(a0, h, np.int(T/h), 100)
        plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T])
        np.save('a1', aa[-1])

    cgl.Br = 0.844
    a0 = np.load('a0.npy')
    a0 = cgl.intgC(a0, h, 100, 1000000)
    T = 100
    aa = cgl.intg(a0, h, T, 20)
    Q = cgl.calQ(aa)
    cp.config(aa, [0, d, 0, T])
    plot1dfig(Q)
    
    
    
    
    
    
<file_sep>#include <iostream>
#include "cgl1d.hpp"

/**
 * The constructor of complex Ginzburg-Landau equation
 * A_t = A + (1 + b*i) A_{xx} - (1 + c*i) |A|^2 A
 *
 * @see Cqcgl1d()
 */
Cgl1d::Cgl1d(int N, double d, double h,
	     bool enableJacv, int Njacv,
	     double b, double c,
	     int threadNum)
    : Cqcgl1d::Cqcgl1d(N, d, h, enableJacv, Njacv, 1, -1, -c, 1, b, 0, 0, threadNum)
{ }


/** 
 * Nonlinear term without the quintic term
 */
void Cgl1d::NL(FFT &f){
    f.ifft();
    ArrayXcd A2 = f.v2 * f.v2.conjugate(); /* |A|^2 */
    f.v2 =  dcp(Br, Bi) * f.v2 * A2;
    f.fft();
}

/** 
 * Nonlinear term without the quintic term
 */
void Cgl1d::jNL(FFT &f){
    f.ifft(); 
    ArrayXcd A = f.v2.col(0);
    ArrayXcd aA2 = A * A.conjugate(); /* |A|^2 */
    ArrayXcd A2 = A.square();	      /* A^2 */
    dcp B(Br, Bi);
    dcp G(Gr, Gi);
    f.v2.col(0) = dcp(Br, Bi) * A * aA2;

    const int M = f.v2.cols() - 1;
    f.v2.rightCols(M) = f.v2.rightCols(M).conjugate().colwise() *  (B * A2) +
    	f.v2.rightCols(M).colwise() * (2.0*B*aA2);
    
    f.fft();
}
<file_sep>/* to compile the class
 *  
 *  compile with Mutithreads FFT support:
 *  g++ cqcgl1d.cc  -shared -fpic -march=corei7 -O3 -msse2 -msse4 -lfftw3_threads -lfftw3 -lm -fopenmp -DTFFT  -I $XDAPPS/eigen/include/eigen3 -I../include -std=c++0x
 *
 *  complile with only one thread:
 *  g++ cqcgl1d.cc -shared -fpic -lfftw3 -lm -fopenmp  -march=corei7 -O3 -msse2 -msse4 -I/usr/include/eigen3 -I../../include -std=c++0x
 *
 *  */
#ifndef CQCGL1D_H
#define CQCGL1D_H

#include <complex>
#include <utility>
#include <algorithm>
#include <vector>
#include <unsupported/Eigen/FFT>
#include "denseRoutines.hpp"
#include "EIDc.hpp"

//////////////////////////////////////////////////////////////////////
//                       class CQCGL1d                              //
//////////////////////////////////////////////////////////////////////
class CQCGL1d {
  
public:
    typedef std::complex<double> dcp;
    
    const int N;		/* dimension of FFT */
    const double d;		/* system domain size */
    
    const int Ne;		/* effective number of modes */
    const int Ndim;		/* dimension of state space */
    const int Nplus, Nminus, Nalias;
    const int DimTan;		// the dimension of tangent space
    
    bool IsQintic = true;	//  False => cubic equation
    
    double Mu, Dr, Di, Br, Bi, Gr, Gi;
    double Omega = 0;		/* used for comoving frame */
    ArrayXd K, K2, QK;

    ArrayXcd L;

    FFT<double> fft;

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 500;	/* size of cell when resize output container */

    struct NL {
	CQCGL1d *cgl;
	int N;
	dcp B, G;
	ArrayXXcd AA;
	
	NL();
	NL(CQCGL1d *cgl, int cols);
	~NL();
	void operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t);
    };
    
    NL nl, nl2;
    
    ArrayXXcd Yv[10], Nv[10], Yv2[10], Nv2[10];
    EIDc eidc, eidc2;
    
    ////////////////////////////////////////////////////////////
    //         constructor, destructor, copy assignment.      //
    ////////////////////////////////////////////////////////////

    // A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    CQCGL1d(int N, double d,
	    double Mu, double Dr, double Di, double Br, double Bi, 
	    double Gr, double Gi, int dimTan);
    
    // A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
    CQCGL1d(int N, double d, 
	    double b, double c, double dr, double di, 
	    int dimTan);
    
    // iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
    CQCGL1d(int N, double d,
	    double delta, double beta, double D, double epsilon,
	    double mu, double nu, int dimTan);
    ~CQCGL1d();
    CQCGL1d & operator=(const CQCGL1d &x);

    ////////////////////////////////////////////////////////////
    //                    member functions.                   //
    ////////////////////////////////////////////////////////////

    //============================================================    
    void setScheme(std::string x);
    void changeOmega(double w);

    ArrayXXd 
    intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd
    intgvC(const ArrayXd &a0, const ArrayXXd &v, const double h, const double tend);
    ArrayXXd
    intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgj(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd 
    intgv(const ArrayXXd &a0, const ArrayXXd &v, const double h, const double tend);
    
    ArrayXXd C2R(const ArrayXXcd &v);
    ArrayXXcd R2C(const ArrayXXd &v);
    ArrayXXd c2r(const ArrayXXcd &v);
    ArrayXXcd r2c(const ArrayXXd &v);
    
    //============================================================  

    ArrayXXcd Fourier2Config(const Ref<const ArrayXXd> &aa);
    ArrayXXd Config2Fourier(const Ref<const ArrayXXcd> &AA);
    ArrayXXd Fourier2ConfigMag(const Ref<const ArrayXXd> &aa);
    ArrayXXd calPhase(const Ref<const ArrayXXcd> &AA);
    ArrayXXd Fourier2Phase(const Ref<const ArrayXXd> &aa);
    VectorXd calQ(const Ref<const ArrayXXd> &aa);
    VectorXd calMoment(const Ref<const ArrayXXd> &aa, const int p = 1);
    
    ArrayXd velocity(const ArrayXd &a0);
    ArrayXd velocityReq(const ArrayXd &a0, const double th,
			const double phi);
    VectorXd velSlice(const Ref<const VectorXd> &aH);
    VectorXd velPhase(const Ref<const VectorXd> &aH);
    MatrixXd rk4(const VectorXd &a0, const double dt, const int nstp, const int nq);
    MatrixXd velJ(const MatrixXd &xj);
    std::pair<MatrixXd, MatrixXd>
    rk4j(const VectorXd &a0, const double dt, const int nstp, const int nq, const int nqr);
    
    ArrayXcd
    Lyap(const Ref<const ArrayXXd> &aa);
    ArrayXd
    LyapVel(const Ref<const ArrayXXd> &aa);
    MatrixXd stab(const ArrayXd &a0);
    MatrixXd stabReq(const ArrayXd &a0, double th, double phi);
    VectorXcd eReq(const ArrayXd &a0, double wth, double wphi);
    MatrixXcd vReq(const ArrayXd &a0, double wth, double wphi);
    std::pair<VectorXcd, MatrixXcd>
    evReq(const ArrayXd &a0, double wth, double wphi);

    ArrayXXd reflect(const Ref<const ArrayXXd> &aa);
    inline ArrayXd rcos2th(const ArrayXd &x, const ArrayXd &y);
    inline ArrayXd rsin2th(const ArrayXd &x, const ArrayXd &y);
    inline double rcos2thGrad(const double x, const double y);
    inline double rsin2thGrad(const double x, const double y);
    ArrayXXd reduceRef1(const Ref<const ArrayXXd> &aaHat);
    ArrayXXd reduceRef2(const Ref<const ArrayXXd> &step1);
    std::vector<int> refIndex3();
    ArrayXXd reduceRef3(const Ref<const ArrayXXd> &aa);
    ArrayXXd reduceReflection(const Ref<const ArrayXXd> &aaHat);
    MatrixXd refGrad1();
    MatrixXd refGrad2(const ArrayXd &x);
    MatrixXd refGrad3(const ArrayXd &x);
    MatrixXd refGradMat(const ArrayXd &x);
    MatrixXd reflectVe(const MatrixXd &veHat, const Ref<const ArrayXd> &xHat);
    MatrixXd reflectVeAll(const MatrixXd &veHat, const MatrixXd &aaHat,
			  const int trunc = 0);
    
    ArrayXXd transRotate(const Ref<const ArrayXXd> &aa, const double th);
    ArrayXXd transTangent(const Ref<const ArrayXXd> &aa);
    MatrixXd transGenerator();

    ArrayXXd phaseRotate(const Ref<const ArrayXXd> &aa, const double phi);
    ArrayXXd phaseTangent(const Ref<const ArrayXXd> &aa);
    MatrixXd phaseGenerator();

    ArrayXXd Rotate(const Ref<const ArrayXXd> &aa, const double th, const double phi);
    ArrayXXd rotateOrbit(const Ref<const ArrayXXd> &aa, const ArrayXd &th,
			 const ArrayXd &phi);
    std::tuple<ArrayXXd, ArrayXd, ArrayXd>
    orbit2slice(const Ref<const ArrayXXd> &aa, const int method);
    MatrixXd ve2slice(const ArrayXXd &ve, const Ref<const ArrayXd> &x, int flag);
    std::tuple<ArrayXXd, ArrayXd, ArrayXd>
    reduceAllSymmetries(const Ref<const ArrayXXd> &aa, int flag);
    MatrixXd reduceVe(const ArrayXXd &ve, const Ref<const ArrayXd> &x, int flag);

    std::tuple<ArrayXd, double, double>
    planeWave(int k, bool isPositve);
    VectorXcd planeWaveStabE(int k, bool isPositve);
    std::pair<VectorXcd, MatrixXcd>
    planeWaveStabEV(int k, bool isPositve);
};



#endif  /* CQCGL1D_H */
<file_sep>from personalFunctions import *
from scipy.spatial.distance import pdist

if False:
    Np = 10000                      # number of points
    Ns = 1000                       # number of steps

    z = np.zeros(Np, dtype=np.complex)
    s = np.zeros(Ns)
    for i in range(Ns):
        z += np.exp(rand(Np)*2j*np.pi)
        s[i] = np.mean(np.abs(z)**2)

    a2 = np.zeros(Np)
    z2 = np.zeros(Np, dtype=np.complex)
    s2 = np.zeros(Ns)
    for i in range(Ns):
        for j in range(Np):
            t = rand()
            d = min([abs(t-a2[j]), abs(t-a2[j]+1), abs(t-a2[j]-1)])
            while d < 0.1:
                t = rand()
                d = [abs(t - a2[j]), abs(t-a2[j]+1), abs(t-a2[j]-1)]
            a2[j] = t
            z2[j] += np.exp(t*2j*np.pi)
        s2[i] = np.mean(np.abs(z2)**2)


ss = np.loadtxt('ss.dat')
fig, ax = pl2d(size=[8, 6], labs=[r'$N$', r'$<r^2>$'], axisLabelSize=25,
               xlim=[0, 1000], ylim=[0, 1000], tickSize=None)
for i in range(ss.shape[1]):
    ax.plot(ss[:, i], lw=2)
ax2d(fig, ax)
<file_sep>#ifndef KSSOLVE_H
#define KSSOLVE_H

#include <complex>
#include <fftw3.h>
#include <new>

class Ks {

public:
  /*****    structure definition.        ******/
  typedef std::complex<double> dcomp;
  
  typedef struct{
    double *E, *E2;
    double *k, *L;
    double *Q, *f1, *f2, *f3;
    dcomp *g;
  } KsCoe;
  
  // member variables.
  const int N;
  const double d;
  const double h;
  KsCoe coe;
  
  // constructors, destructor, copy assignment.
  Ks(int N = 32, double d = 22, double h = 0.25);
  explicit Ks(const Ks &x);
  ~Ks();
  Ks & operator=(const Ks &x);

  // member function
  /* @brief KS solver without calculating Jacobian matrix.
   * 
   * @param[in] a0 initial condition, size N-2 array
   * @param[in] h time step
   * @param[in] nstp number of steps to be integrated
   * @param[in] np state saving spacing.
   * @param[out] aa saved state vector size = (nstp/np)*(N-2)
   * eg. if state column vector is v0, v1, ... vn-1, then
   * aa is a row vector [ v0^{T}, v1^{T}, ... vn-1^{T}]. */
  void kssolve(double *a0, int nstp, int np, double *aa);

  /* @brief KS solver with calculating Jacobian (size (N-2)*(N-2)).
   * 
   * @param[in] nqr Jacobian saving spacing spacing
   * @param[out] daa saved Jacobian matrix. size = (nstp/nqr)*(N-2)*(N-2).
   * eg. If Jacobian matrix is J=[v1, v2,..., vn] each vi is a
   * column vector,  then 
   * daa is a row vector [vec(J1), vec(J2), vec(Jn)], where
   * vec(J)= [v1^{T}, v2^{T},...,vn^{T}] with each element
   * visted column-wise. */
  void kssolve(double *a0, int nstp, int np, int nqr, double *aa, double *daa);

protected:   
  /****    global variable definition.   *****/
  static constexpr double PI=3.14159265358979323;

  /** @brief Structure for convenience of rfft.
   * For forward real Fourier transform, 'in' is real
   * and 'out' is complex.
   * For inverse real Fourier transform, the situation reverses. */  
  typedef struct{
    fftw_plan p;
    fftw_complex *c; // complex array.
    double *r; // real array
  } FFT;



  /* member function */
  virtual void initKs(double *a0, dcomp *v, double *aa, FFT &rp, FFT &p);
  virtual void initKs(double *a0, dcomp *v, double *aa, FFT *rp, FFT *p);
  virtual void initJ(dcomp *v);
  void cleanKs(FFT &rp, FFT &p);
  void cleanKs(FFT *rp, FFT *p);
  void calcoe(const int M = 16);
  void onestep(dcomp *v, FFT &p, FFT &rp);
  void onestep(dcomp *v, FFT *p, FFT *rp);
  virtual void calNL(dcomp *u, dcomp *Nv, const FFT &p, const FFT &rp);
  virtual void calNL(dcomp *u, dcomp *Nv, const FFT *p, const FFT *rp );
  void irfft(const dcomp *u, const FFT &rp);
  void rfft(double *u, const FFT &p);
  void initFFT(FFT &p,  int a);
  void freeFFT(FFT &p);
  
};



#endif /* KSSOLVE_H */
<file_sep>#include <iostream>
#include <functional>
#include "CQCGL1dSubReq.hpp"
#include "iterMethod.hpp"


#define cee(x) (cout << (x) << endl << endl)

namespace ph = std::placeholders;

using namespace std;
using namespace Eigen;
using namespace iterMethod;
using namespace denseRoutines;
using namespace MyH5;

//////////////////////////////////////////////////////////////////////
//                      constructor                                 //
//////////////////////////////////////////////////////////////////////

// A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
CQCGL1dSubReq::CQCGL1dSubReq(int N, double d,
			     double Mu, double Dr, double Di, double Br, double Bi, 
			     double Gr, double Gi, int dimTan):
    CQCGL1dSub(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}

// A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
CQCGL1dSubReq::CQCGL1dSubReq(int N, double d, 
			     double b, double c, double dr, double di, 
			     int dimTan):
    CQCGL1dSub(N, d, b, c, dr, di, dimTan){}
    
// iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
CQCGL1dSubReq::CQCGL1dSubReq(int N, double d,
			     double delta, double beta, double D, double epsilon,
			     double mu, double nu, int dimTan) :
    CQCGL1dSub(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

CQCGL1dSubReq::~CQCGL1dSubReq(){}

CQCGL1dSubReq & CQCGL1dSubReq::operator=(const CQCGL1dSubReq &x){
    return *this;
}


//////////////////////////////////////////////////////////////////////
//                      member functions                            //
//////////////////////////////////////////////////////////////////////

std::string 
CQCGL1dSubReq::toStr(double Bi, double Gi, int id){
    //  avoid possibilty that 000000.000000 or -00000.000000
    if (fabs(Bi) < 1e-6) Bi = 0; 
    if (fabs(Gi) < 1e-6) Gi = 0;

    char g1[20], g2[20];
    sprintf(g1, "%013.6f", Bi);
    sprintf(g2, "%013.6f", Gi);
    
    string s1(g1);
    string s2(g2);
    string s = s1 + '/' + s2 + '/' + to_string(id);
    
    return s;
}

/**
 * @brief read req (relative equibrium) info from hdf5 file
 *
 */
std::tuple<VectorXd, double, double>
CQCGL1dSubReq::read(H5File &file, const std::string groupName){
    // H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";

    return make_tuple(readMatrixXd(file, DS + "a").col(0),
		      readScalar<double>(file, DS + "wphi"),
		      readScalar<double>(file, DS + "err")
		      );
}



/**
 * @brief write [a, wth, wphi, err] of Req of cqcgl into a group
 * 
 * @note group should be a new group
 */
void 
CQCGL1dSubReq::write(H5File &file, const std::string groupName,
		     const ArrayXd &a, const double wphi, 
		     const double err){
    
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
	
    writeMatrixXd(file, DS + "a", a);
    writeScalar<double>(file, DS + "wphi", wphi);
    writeScalar<double>(file, DS + "err", err);
}

VectorXcd 
CQCGL1dSubReq::readE(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    VectorXd er = readMatrixXd(file, DS + "er");
    VectorXd ei = readMatrixXd(file, DS + "ei");
    VectorXcd e(er.size());
    e.real() = er;
    e.imag() = ei;

    return e;
}

MatrixXcd 
CQCGL1dSubReq::readV(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    MatrixXd vr = readMatrixXd(file, DS + "vr");
    MatrixXd vi = readMatrixXd(file, DS + "vi");
    MatrixXcd v(vr.rows(), vr.cols());
    v.real() = vr;
    v.imag() = vi;

    return v;
}

void 
CQCGL1dSubReq::writeE(H5File &file, const std::string groupName, 
		      const VectorXcd e){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "er", e.real());
    writeMatrixXd(file, DS + "ei", e.imag());
}


void 
CQCGL1dSubReq::writeV(H5File &file, const std::string groupName, 
		      const MatrixXcd v){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "vr", v.real());
    writeMatrixXd(file, DS + "vi", v.imag());
}

void 
CQCGL1dSubReq::move(H5File &fin, std::string gin, H5File &fout, std::string gout,
		    int flag){
    VectorXd a;
    VectorXcd e;
    MatrixXcd v;
    double wphi, err;

    std::tie(a, wphi, err) = read(fin, gin);
    if (flag == 1 || flag == 2) e = readE(fin, gin);
    if (flag == 2) v = readV(fin, gin);
    
    write(fout, gout, a, wphi, err);
    if (flag == 1 || flag == 2) writeE(fout, gout, e);
    if (flag == 2) writeV(fout, gout, v);
}

//====================================================================================================

VectorXd
CQCGL1dSubReq::Fx(const VectorXd &x){
    assert(x.size() == Ndim + 1);

    double wphi = x(Ndim); 
    VectorXd a = x.head(Ndim);	// use matrix type for resizing

    VectorXd F(Ndim+1);
    F << velocityReq(a, wphi), 0;
    
    return F;
}

std::tuple<MatrixXd, MatrixXd, VectorXd>
CQCGL1dSubReq::calJJF(const VectorXd &x){
    assert(x.size() == Ndim + 1);
    
    double wphi = x(Ndim); 
    VectorXd a0 = x.head(Ndim);
  
    MatrixXd DF(Ndim, Ndim+1); 
    ArrayXd tx_phase = phaseTangent(a0); 
    DF.topLeftCorner(Ndim, Ndim) = stabReq(a0, wphi); 
    DF.col(Ndim) = tx_phase;
    VectorXd F = velocity(a0) + wphi*tx_phase;


    MatrixXd JJ = DF.transpose() * DF;
    MatrixXd D  = JJ.diagonal().asDiagonal();
    VectorXd df = DF.transpose() * F; 

    return std::make_tuple(JJ, D, df);
}

std::tuple<VectorXd, double, double, int>
CQCGL1dSubReq::findReq_LM(const ArrayXd &a0, const double wphi0, 
			  const double tol,
			  const int maxit,
			  const int innerMaxit){
    
    VectorXd x(Ndim+1);
    x << a0, wphi0;
    
    auto fx = std::bind(&CQCGL1dSubReq::Fx, this, ph::_1);    
    CQCGL1dSubReqJJF<MatrixXd> jj(this);
    PartialPivLU<MatrixXd> solver;
    
    VectorXd xe;
    std::vector<double> res;
    int flag;
    std::tie(xe, res, flag) = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    if(flag != 0) fprintf(stderr, "Sub Req not converged ! \n");
    
    VectorXd a = xe.head(Ndim);
    double wphi = xe(Ndim);
    return std::make_tuple( a, wphi, res.back(), flag );
}


/** @brief find the optimal guess of wphi for a candidate req
 *  @return    [wth, wphi, err] such that velocityReq(a0, wth, wphi) minimal
 */
std::vector<double>
CQCGL1dSubReq::optThPhi(const ArrayXd &a0){ 
    VectorXd t = phaseTangent(a0);
    VectorXd v = velocity(a0);
    double c = t.dot(v) / t.dot(t);
    
    double err = (v - c * t).norm();
    
    std::vector<double> x{-c, err};
    return x;
}

#if 0
/**
 * @brief find req with a sequence of Bi or Gi
 */ 
void 
CQCGL1dSubReq::findReqParaSeq(H5File &file, int id, double step, int Ns, bool isBi){
    double Bi0 = Bi;
    double Gi0 = Gi;
    
    ArrayXd a0;
    double wth0, wphi0, err0;
    std::tie(a0, wth0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
    
    ArrayXd a;
    double wth, wphi, err;
    int flag;
    
    int Nfail = 0;

    for (int i = 0; i < Ns; i++){
	if (isBi) Bi += step;
	else Gi += step;
	
	// if exist, use it as seed, otherwise find req
	if ( checkGroup(file, toStr(Bi, Gi, id), false) ){ 
	    std::tie(a0, wth0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
	}
	else {
	    fprintf(stderr, "%d %g %g \n", id, Bi, Gi);
	    std::tie(a, wth, wphi, err, flag) = findReq_LM(a0, wth0, wphi0, 1e-10, 100, 1000);
	    if (flag == 0){
		write(file, toStr(Bi, Gi, id), a, wth, wphi, err);
		a0 = a;
		wth0 = wth;
		wphi0 = wphi;
	    }
	    else {
		if(++Nfail == 3) break;
	    }
	}
    }
    
    Bi = Bi0; 			// restore Bi, Gi
    Gi = Gi0;
}
#endif

/// @brief calculate the eigenvalues and eigenvectors of req in certain range
/// gs is obtained by scanGroup()
void 
CQCGL1dSubReq::calEVParaSeq(H5File &file, vector<vector<string>> gs, bool saveV){
    double Bi0 = Bi;
    double Gi0 = Gi;
    int id;

    ArrayXd a0;
    double wth0, wphi0, err0;
    VectorXcd e;
    MatrixXcd v;
    
    for (auto entry : gs){
	Bi = stod(entry[0]);
	Gi = stod(entry[1]);
	id = stoi(entry[2]);
	if( !checkGroup(file, toStr(Bi, Gi, id) + "/er", false) ){
	    fprintf(stderr, "%d %g %g \n", id, Bi, Gi);
	    std::tie(a0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
	    std::tie(e, v) = evReq(a0, wphi0); 
	    writeE(file, toStr(Bi, Gi, id), e);
	    if(saveV) writeV(file, toStr(Bi, Gi, id), v.leftCols(10));
	}
    }

    Bi = Bi0; 			// restore Bi, Gi
    Gi = Gi0;
}

<file_sep>#ifndef KSINT_H
#define KSINT_H

#include <fftw3.h>
#include <complex>
#include <tuple>
#include <utility>
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include "EIDr.hpp"

/*============================================================
 *                       Class : KS integrator
 *============================================================*/
class KS{
  
public:
    typedef std::complex<double> dcp;

    //////////////////////////////////////////////////////////////////////
    /* member variables */
    const int N;
    const double d;

    ArrayXd K, L;
    ArrayXcd G;
    FFT<double> fft;

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 500;	/* size of cell when resize output container */
    
    struct NL {
	KS *ks;
	int N;
	ArrayXXd u;
	NL();
	NL(KS *ks, int cols);
	~NL();
	void operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t);
    };
    
    NL nl, nl2;
    ArrayXXcd Yv[10], Nv[10], Yv2[10], Nv2[10];
    EIDr eidr, eidr2;;
    ////////////////////////////////////////////////////////////
    

    //////////////////////////////////////////////////////////////////////
    /* constructor, destructor, copy assignment */
    KS(int N, double d);
    KS & operator=(const KS &x);
    ~KS();
  
    /* ------------------------------------------------------------ */
    void 
    setScheme(std::string x);
    ArrayXXd 
    intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd
    intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgj(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd 
    C2R(const ArrayXXcd &v);
    ArrayXXcd 
    R2C(const ArrayXXd &v);
    /* ------------------------------------------------------------ */
    
    ArrayXd
    velocity(const Ref<const ArrayXd> &a0);
    ArrayXd
    velReq(const Ref<const VectorXd> &a0, const double c);
    MatrixXd 
    stab(const Ref<const ArrayXd> &a0);
    MatrixXd 
    stabReq(const Ref<const VectorXd> &a0, const double theta);
    std::pair<VectorXcd, Eigen::MatrixXcd>
    evEq(const Ref<const VectorXd> &a0);
    std::pair<VectorXcd, Eigen::MatrixXcd>
    evReq(const Ref<const VectorXd> &a0, const double theta);    
    double 
    pump(const ArrayXcd &vc);
    double 
    disspation(const ArrayXcd &vc);

    ArrayXXd 
    reflect(const Ref<const ArrayXXd> &aa);
    ArrayXXd 
    half2whole(const Ref<const ArrayXXd> &aa);
    ArrayXXd 
    rotate(const Ref<const ArrayXXd> &aa, const double th);
    ArrayXXd
    gTangent(const Ref<const ArrayXXd> &x);
    MatrixXd 
    gGenerator();
    std::pair<MatrixXd, VectorXd>
    redSO2(const Ref<const MatrixXd> &aa, const int p, const bool toY);
    std::pair<MatrixXd, VectorXi>
    fundDomain(const Ref<const MatrixXd> &aa, const int pSlice, const int pFund);
    std::tuple<MatrixXd, VectorXi, VectorXd>
    redO2f(const Ref<const MatrixXd> &aa, const int pSlice, const int pFund);
    MatrixXd
    redV(const Ref<const MatrixXd> &v, const Ref<const VectorXd> &a,
	 const int p, const bool toY);
    MatrixXd 
    veToSliceAll(const MatrixXd &eigVecs, const MatrixXd &aa,
		 const int trunc = 0);
    std::pair<ArrayXXd, ArrayXXd>
    orbitAndFvWhole(const ArrayXd &a0, const ArrayXXd &ve,
		    const double h,
		    const size_t nstp, const std::string ppType
		    );
    MatrixXd veTrunc(const MatrixXd ve, const int pos, const int trunc = 0);
    std::pair<ArrayXXd, ArrayXXd>
    orbitAndFvWholeSlice(const ArrayXd &a0, const ArrayXXd &ve,
			 const double h,
			 const size_t nstp, const std::string ppType,
			 const int pos
			 );

    MatrixXd calMag(const Ref<const MatrixXd> &aa);
    std::pair<MatrixXd, MatrixXd>
    toPole(const Ref<const MatrixXd> &aa);


};


#endif	/* KSINT_H */
<file_sep>## All numerical experiments 
* **EID**   time-step adaptive exponential integrator 

<file_sep>from py_CQCGL2d import *
from personalFunctions import *

case = 40

if case == 10:
    """
    test the plot function
    """
    N = 1024
    d = 30
    di = 0.05

    cgl = pyCQCGL2d(N, d, 4.0, 0.8, 0.01, di, 4)
    Ns = 15000
    skip = 20
    cgl.constETDPrint = 200
    fileName = 'ex.h5'

    A0 = 3*centerRand2d(N, N, 0.2, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    # aa = cgl.intg(a0, 0.001, Ns, skip, True, fileName)
    c2dp = CQCGL2dPlot(d, d)
    # c2dp.plotOneState(cgl, fileName, 100)
    c2dp.savePlots(cgl, fileName, range(Ns/skip+1), 'fig3',
                   plotType=2, onlyMovie=True, size=[12, 6])

if case == 20:
    """
    integrate using current data
    """
    N = 1024
    d = 30
    di = 0.05
    
    cgl = pyCQCGL2d(N, d, 4.0, 0.8, 0.01, di, 4)
    Ns = 2000
    skip = 2
    cgl.constETDPrint = 100
    fileName = 'ex2.h5'

    c2dp = CQCGL2dPlot(d, d)
    a0 = c2dp.load('ex.h5', 750)
    aa = cgl.intg(a0, 0.001, Ns, skip, True, fileName)
    
if case == 30:
    """
    test plotting a sequence
    """
    N = 1024
    d = 30
    di = 0.05

    cgl = pyCQCGL2d(N, d, 4.0, 0.8, 0.01, di, 4)
    fileName = 'ex2.h5'
    c2dp = CQCGL2dPlot(d, d)
    x = c2dp.loadSeq(fileName, 0, 0, range(1000))
    plot1dfig(x.real)
    plot1dfig(x.imag)

if case == 40:
    """
    test stabReq
    """
    N = 1024
    d = 30
    di = 0.05

    cgl = pyCQCGL2d(N, d, 4.0, 0.8, 0.01, di, 4)
    fileName = 'ex2.h5'
    c2dp = CQCGL2dPlot(d, d)
    x = c2dp.load('ex.h5', 500)
    v = rand(cgl.Me, cgl.Ne)
    ax = cgl.stab(x, v)
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "ksintM1.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

class pyKSM1 : public KSM1 {
public :
    pyKSM1(int N, double h, double d) : KSM1(N, h, d) {}
    
    /* wrap the integrator */
    bp::tuple PYintg(bn::ndarray a0, size_t nstp, size_t np){
	Map<ArrayXd> tmpa((double*)a0.get_data(), N-2);
	std::pair<ArrayXXd, ArrayXd> tmp = intg(tmpa, nstp, np);
	
	Py_intptr_t dims[2] = { nstp/np+1, N-2 };
	bn::ndarray aa = 
	    bn::empty(2, dims, bn::dtype::get_builtin<double>());
	bn::ndarray tt = 
	    bn::empty(1, dims, bn::dtype::get_builtin<double>());
	memcpy((void*)aa.get_data(), (void*)(&tmp.first(0, 0)), 
	       sizeof(double) * (N-2) * (nstp/np+1) );
	memcpy((void*)tt.get_data(), (void*)(&tmp.second(0)), 
	       sizeof(double) * (nstp/np+1) );

	return bp::make_tuple(aa, tt);
    }

    /* wrap the second integrator */
    bp::tuple PYintg2(bn::ndarray a0, double T, size_t np){
	Map<ArrayXd> tmpa((double*)a0.get_data(), N-2);
	std::pair<ArrayXXd, ArrayXd> tmp = intg2(tmpa, T, np);
	
	int n = tmp.first.rows();
	int m = tmp.first.cols();
		
	Py_intptr_t dims[2] = { m , n };
	bn::ndarray aa = 
	    bn::empty(2, dims, bn::dtype::get_builtin<double>());
	bn::ndarray tt = 
	    bn::empty(1, dims, bn::dtype::get_builtin<double>());
	memcpy((void*)aa.get_data(), (void*)(&tmp.first(0, 0)), 
	       sizeof(double) * n * m );
	memcpy((void*)tt.get_data(), (void*)(&tmp.second(0)), 
	       sizeof(double) * m );

	return bp::make_tuple(aa, tt);
    }
};

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

BOOST_PYTHON_MODULE(py_ks) {
    bn::initialize();    
    bp::class_<KSM1>("KSM1") ;



    bp::class_<pyKSM1, bp::bases<KSM1> >("pyKSM1", bp::init<int, double, double>())
	.def_readonly("N", &pyKSM1::N)
	.def_readonly("d", &pyKSM1::d)
	.def_readonly("h", &pyKSM1::h)
	.def("intg", &pyKSM1::PYintg)
	.def("intg2", &pyKSM1::PYintg2)
	;
}
<file_sep>#include "sparseRoutines.hpp"

using namespace std;
using namespace Eigen;

typedef Eigen::SparseMatrix<double> SpMat;
typedef Eigen::Triplet<double> Tri;

namespace sparseRoutines {
    
    /* -----------        functions    -------------- */

    /* @brief transform a dense matrix into Triplet form, which should be used to
     *        initialize a spase matrix subblock.
     *
     * @param[in] M row position of the subblock
     * @param[in] N col position of the sbublock
     * @return the triplet representation of the dense matrix
     *
     */
    vector<Tri> 
    triMat(const MatrixXd &A, const size_t M /* = 0 */, 
	   const size_t N /* = 0 */){
	vector<Tri> tri; 
	size_t rows = A.rows(), cols = A.cols();
	tri.reserve(rows*cols);
	// for efficience, loop in the row wise.
	for(size_t j = 0; j < cols; j++)
	    for(size_t i = 0; i < rows; i++)
		tri.push_back( Tri(M+i, N+j, A(i,j) ));

	return tri;
    }


    /* @brief transform a diagoal matrix (diagonal elements are the same) into Triplet
     *        form
     *        
     * @param[in] n size of the diagonal matrix
     * @param[in] x the diagonal elements
     * @param[in] M row position of the subblock
     * @param[in] N col position of the sbublock
     * @see triMat()
     */
    vector<Tri> 
    triDiag(const size_t n, const double x, const size_t M /* = 0 */, 
	    const size_t N /* = 0 */ ){
	vector<Tri> tri;
	tri.reserve(n);
	for(size_t i = 0; i < n; i++) tri.push_back( Tri(M+i, N+i, x) );
	return tri;
    }

    std::vector<Tri>
    triDiag(const VectorXd &D, const size_t M, const size_t N){
	int n = D.size();
	
	vector<Tri> tri;
	tri.reserve(n);
	for(int i = 0; i < n; i++) tri.push_back( Tri(M+i, N+1, D(i)) );

	return tri;

    }
}

<file_sep>from py_ks import *
from personalFunctions import *

case = 10

N, L = 64, 22
eqFile =  '../../data/ks22Reqx64.h5'
poFile = '../../data/ks22h001t120x64EV.h5'

if case == 10:
    """
    plot the FV of ppo1
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    
    fv = ksp.readFV(poFile, 'ppo', 1)
    fvt0 = fv[0].reshape(30, N-2)
    name = 'ksppo1fvt0'
    ksp.oneConfig(fvt0[0], labs=[r'$x$', r'$v$'], axisLabelSize=25, tickSize=18, save=True, name=name+'v1r')
    ksp.oneConfig(fvt0[1], labs=[r'$x$', r'$v$'], axisLabelSize=25, tickSize=18, save=True, name=name+'v1i')
    ksp.oneConfig(fvt0[4], labs=[r'$x$', r'$v$'], axisLabelSize=25, tickSize=18, save=True, name=name+'v5')
    ksp.oneConfig(fvt0[9], labs=[r'$x$', r'$v$'], axisLabelSize=25, tickSize=18, save=True, name=name+'v10')
    ksp.oneConfig(fvt0[-1], labs=[r'$x$', r'$v$'], axisLabelSize=25, tickSize=18, save=True, name=name+'v30')
<file_sep>from py_CQCGL1d import *
from cglHelp import *
from scipy.integrate import odeint

case = 41

if case == 1:
    """
    view the rpo I found
    view its color map, error, Fourier modes and symmetry reduced Fourier modes
    """
    N = 1024
    d = 30
    di = 0.36
    x, T, nstp, th, phi, err = cqcglReadRPOdi('../../data/cgl/rpoT2X1.h5',
                                              di, 1)
    h = T / nstp
    nstp = np.int(nstp)
    cgl = pyCQCGL1d(N, d, 4.0, 0.8, 0.01, di, -1)
    aa = cgl.intg(x, h, nstp, 1)
    aaHat, thAll, phiAll = cgl.orbit2slice(aa)
    
    # print the errors and plot the color map
    print norm(cgl.Rotate(aa[-1], th, phi) - aa[0])
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])

    # Fourier trajectory in the full state space
    i1 = 0
    i2 = 1
    i3 = 2
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa[:, i1], aa[:, i2], aa[:, i3], c='r', lw=1)
    ax.scatter(aa[0, i1], aa[0, i2], aa[0, i3], s=50, marker='o',
               facecolor='b', edgecolors='none')
    ax.scatter(aa[-1, i1], aa[-1, i2], aa[-1, i3], s=50, marker='o',
               facecolor='b', edgecolors='none')
    ax.set_xlabel('x', fontsize=25)
    ax.set_ylabel('y', fontsize=25)
    ax.set_zlabel('z', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    #  Fourier trajectory in the continous symmetry reduced space
    i1 = 0
    i2 = 1
    i3 = 2
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aaHat[:, i1], aaHat[:, i2], aaHat[:, i3], c='r', lw=1)
    ax.scatter(aaHat[0, i1], aaHat[0, i2], aaHat[0, i3], s=50, marker='o',
               facecolor='b', edgecolors='none')
    ax.scatter(aaHat[-1, i1], aaHat[-1, i2], aaHat[-1, i3], s=50, marker='o',
               facecolor='b', edgecolors='none')
    ax.set_xlabel('x', fontsize=25)
    ax.set_ylabel('y', fontsize=25)
    ax.set_zlabel('z', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    
    # plot 4 periods
    M = 6
    aa2 = cgl.intg(x, h, nstp*M, 1)
    plotConfigSpaceFromFourier(cgl, aa2, [0, d, 0, nstp*h*M])

if case == 20:
    """
    view the rpo torus
    """
    N = 1024
    d = 30
    di = 0.39
    x, T, nstp, th, phi, err = cqcglReadRPOdi('../../data/cgl/rpoT2X1.h5',
                                              di, 1)
    h = T / nstp
    cgl = pyCqcgl1d(N, d, h, False, 0, 4.0, 0.8, 0.01, di, 4)
    aa0 = cgl.intg(x[0], nstp, 1)

    # Fourier trajectory in the full state space
    i1 = 4
    i2 = 7
    i3 = 2
    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111, projection='3d')
    for i in range(10):
        ang = i / 10.0 * 2 * np.pi
        aa = cgl.Rotate(aa0, ang, 0)
        ax.plot(aa[:, i1], aa[:, i2], aa[:, i3], c='r', lw=1)
        ax.scatter(aa[0, i1], aa[0, i2], aa[0, i3], s=50, marker='o',
                   facecolor='b', edgecolors='none')
        ax.scatter(aa[-1, i1], aa[-1, i2], aa[-1, i3], s=50, marker='o',
                   facecolor='k', edgecolors='none')
    ax.set_xlabel('x', fontsize=25)
    ax.set_ylabel('y', fontsize=25)
    ax.set_zlabel('z', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 21:
    """
    check whether the velocity is conserved
    """
    N = 1024
    d = 30
    di = 0.39
    x, T, nstp, th, phi, err = cqcglReadRPOdi('../../data/cgl/rpoT2X1.h5',
                                              di, 1)
    h = T / nstp
    cgl = pyCqcgl1d(N, d, h, True, 1, 4.0, 0.8, 0.01, di, 4)
    v0 = cgl.velocity(x[0])
    av = cgl.intgv(x[0], v0, nstp)
    v1 = av[1]
    
    print norm(v1)

if case == 40:
    """
    use L = 50 to obtain the guess initial conditon
    for rpo
    """
    N = 1024
    d = 50
    Bi = 0.8
    Gi = -3.6

    rpo = CQCGLrpo()
    x, T, nstp, th, phi, err = rpo.readRpodi('../../data/cgl/rpoT2X1.h5',
                                             0.36, 1)
    x = x * 0.1**0.5
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    aa = cgl.intg(x, 1e-3, 40000, 50)
    aa = cgl.intg(aa[-1], 1e-3, 10000, 10)
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, 10])

if case == 41:
    """
    use L = 50 to view the rpo
    """
    N, d = 1024, 50
    Bi, Gi = 2, -5.6

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5',
                                              rpo.toStr(Bi, Gi, 1), flag=2)
    a0 = x[:cgl.Ndim]
    print e[:10]

    a0 += 0.1*norm(a0)*v[0]
    numT = 4
    for i in range(1):
        aa = cgl.intg(a0, T/nstp, numT * T, 10)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, T*numT])
        
    
if case == 411:
    """
    use L = 50 to view the rpo and the difference plot
    """
    N = 1024
    d = 50
    Bi, Gi = 4.8, -4.5

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi('../../data/cgl/rpoBiGiEV.h5',
                                                     Bi, Gi, 1, flag=2)
    a0 = x[:cgl.Ndim]
    print e[:10]
    
    aa0 = cgl.intg(a0, T/nstp, nstp, 10)[:-1]

    a0 += 0.1*norm(a0)*v[0]
    numT = 7
    skipRate = 10

    aaBase = aa0
    for i in range(1, numT):
        aaBase = np.vstack((aaBase, cgl.Rotate(aa0, -i*th, -i*phi)))
    
    for i in range(1):
        aa = cgl.intg(a0, T/nstp, numT*nstp, skipRate)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, T*numT])
        dif = aa[:-1] - aaBase
        cellSize = nstp / skipRate
        cp.config(dif[0*cellSize:6*cellSize], [0, d, 0*T, 6*T])

if case == 42:
    """
    L = 50 check the po is not req
    """
    N = 1024
    d = 50

    fileName = '../../data/cgl/rpoBiGi2.h5'
    angs = np.zeros([39, 55])
    for i in range(39):
        Bi = 1.9 + i * 0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
            rpo = CQCGLrpo(cgl)
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1)):
                x, T, nstp, th, phi, err = rpo.readRpoBiGi(fileName, Bi, Gi, 1)
                a0 = x[:cgl.Ndim]
                v0 = cgl.velocity(a0)
                t1 = cgl.transTangent(a0)
                t2 = cgl.phaseTangent(a0)
                ang = pAngle(v0, np.vstack((t1, t2)).T)
                angs[i, j] = ang
                if ang < 1e-3:
                    print Bi, Gi, ang

if case == 43:
    """
    L = 50
    plot the stability table of the rpos
    """
    N = 1024
    d = 50 

    fileName = '../../data/cgl/rpoBiGiEV.h5'
    
    cs = {0: 'g'}#, 10: 'm', 2: 'c', 4: 'r', 6: 'b', 8: 'y'}#, 56: 'r', 14: 'grey'}
    ms = {0: 's'}#, 10: '^', 2: '+', 4: 'o', 6: 'D', 8: 'v'}#, 56: '4', 14: 'v'}

    es = {}
    e1 = {}
    unconverge = {}
    Ts = np.zeros((39, 55))
    ns = set()

    fig, ax = pl2d(size=[8, 6], labs=[r'$G_i$', r'$B_i$'], axisLabelSize=25, tickSize=20,
                   xlim=[-5.7, -3.95], ylim=[1.8, 6])
    for i in range(39):
        Bi = 1.9 + i*0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            rpo = CQCGLrpo()
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1) + '/er'):
                x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi(fileName, Bi, Gi, 1, flag=2)
                es[(Bi, Gi)] = e
                m, ep, accu = numStab(e, nmarg=3, tol=1e-4, flag=1)
                if accu == False:
                    unconverge[(Bi, Gi)] = 1
                    print Bi, Gi, e[m:m+3]
                e1[(Bi, Gi)] = ep[0]
                Ts[i, j] = T
                ns.add(m)
                # print index, Bi, Gi, m
                ax.scatter(Gi, Bi, s=60, edgecolors='none',
                           marker=ms.get(m, 'o'), c=cs.get(m, 'r'))

    #ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.yaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.grid(which='major', linewidth=2)
    #ax.grid(which='minor', linewidth=1)
    ax2d(fig, ax)
    plotIm(Ts, [-5.6, 0, -4, 6], size=[8, 6], labs=[r'$G_i$', r'$B_i$'])
    fig, ax = pl2d(size=[8, 6], labs=[r'$G_i$', r'$B_i$'], axisLabelSize=20, tickSize=15,
                   xlim=[-5.7, -3.95], ylim=[1.8, 6])
    keys = unconverge.keys()
    for i in keys:
        ax.scatter(i[1], i[0], s=60, edgecolors='none', marker='o', c='k')
    #ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.yaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.grid(which='major', linewidth=2)
    #ax.grid(which='minor', linewidth=1)
    ax2d(fig, ax)
    

if case == 44:
    """
    L = 50
    Plot the rpo existence in the Bi-Gi plane
    """
    N = 1024
    d = 50 

    fileName = '../../data/cgl/rpoBiGi2.h5'
    fig, ax = pl2d(size=[8, 6], labs=[r'$G_i$', r'$B_i$'], axisLabelSize=25,
                   xlim=[-5.8, -3.5], ylim=[1.8, 6])
    for i in range(39):
        Bi = 1.9 + i*0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            rpo = CQCGLrpo()
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1)):
                ax.scatter(Gi, Bi, s=15, edgecolors='none', marker='o', c='r')

    ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    ax.yaxis.set_minor_locator(AutoMinorLocator(10))
    ax.grid(which='major', linewidth=2)
    ax.grid(which='minor', linewidth=1)
    ax2d(fig, ax)
    
if case == 45:
    """
    use L = 50 to view the rpo
    """
    N, d = 1024, 50
    Bi, Gi = 1.9, -5.6
    
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo()
    cp = CQCGLplot(cgl)
    x, T, nstp, th, phi, err = rpo.readRpoBiGi('../../data/cgl/rpoBiGi2.h5',
                                               Bi, Gi, 1, flag=0)
    a0 = x[:cgl.Ndim]

    for i in range(2):
        aa = cgl.intg(a0, T/nstp, 15*nstp, 10)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, 2*T])

if case == 46:
    """
    use L = 50 to view the rpo int the symmetry reduced state space
    """
    N = 1024
    d = 50
    Bi = 4.8
    Gi = -4.5
    sysFlag = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)

    x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi('../../data/cgl/rpoBiGiEV.h5',
                                                     Bi, Gi, 1, flag=2)
    a0 = x[:cgl.Ndim]
    po = cgl.intg(a0, T/nstp, nstp, 10)
    poH = cgl.orbit2slice(po, sysFlag)[0]

    aE = a0 + 0.001 * norm(a0) * v[0];

    aa = cgl.intg(aE, T/nstp, 12*nstp, 10)
    cp.config(aa, [0, d, 0, 12*T])
    aaH, ths, phis = cgl.orbit2slice(aa, sysFlag)
    cp. config(aaH, [0, d, 0, 12*T])

    # req = CQCGLreq(cgl)
    # reqe, reqaH, reqvH = req.getAxes('../../data/cgl/reqBiGiEV.h5', Bi, Gi, 1, sysFlag)
    # e1, e2, e3 = orthAxes(reqvH[0].real, reqvH[1].real, reqvH[2].real)
    # bases = np.vstack((e1, e2, e3))
    # poHP, aaHP = poH.dot(bases.T), aaH.dot(bases.T)
    
    vrH = cgl.ve2slice(v.real.copy(), a0, sysFlag)
    viH = cgl.ve2slice(v.imag.copy(), a0, sysFlag)
    e1, e2, e3 = orthAxes(vrH[0], viH[0], vrH[1])
    bases = np.vstack((e1, e2, e3))
    poHP, aaHP = poH.dot(bases.T), aaH.dot(bases.T)
    
    fig, ax = pl3d(size=[8, 6])
    ax.plot(poH[:, -1], poH[:, 4], poH[:, 5], c='r', lw=2)
    ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)
    #ax.plot(poHP[:, 0], poHP[:, 1], poHP[:, 2], c='r', lw=2)
    #ax.plot(aaHP[:, 0], aaHP[:, 1], aaHP[:, 2], c='b', lw=1)
    ax3d(fig, ax)
    
if case == 47:
    """
    L = 50 find all moving rpo 
    """
    N = 1024
    d = 50

    fileName = '../../data/cgl/rpoBiGi2.h5'
    mv = {}
    nmv = {}
    for i in range(39):
        Bi = 1.9 + i * 0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            rpo = CQCGLrpo()
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1)):
                x, T, nstp, th, phi, err = rpo.readRpoBiGi(fileName, Bi, Gi, 1)
                if abs(th) > 1e-4:
                    mv[(Bi, Gi)] = th
                else :
                    nmv[(Bi, Gi)] = th
                

    fig, ax = pl2d(size=[8, 6], labs=[r'$G_i$', r'$B_i$'], axisLabelSize=20, tickSize=15,
                   xlim=[-5.7, -3.95], ylim=[1.8, 6])
    mvkeys = mv.keys()
    for i in mvkeys:
        ax.scatter(i[1], i[0], s=60, edgecolors='none', marker='o', c='r')
    nmvkeys = nmv.keys()
    for i in nmvkeys:
        ax.scatter(i[1], i[0], s=60, edgecolors='none', marker='s', c='g')
    ax2d(fig, ax)

if case == 50:
    """
    plot all the rpos I have
    """
    N = 1024
    d = 30
    
    dis, rpos = cqcglReadRPOAll('../../data/cgl/rpoT2X1.h5', 1)
    for i in range(len(rpos)):
        x, T, nstp, th, phi, err = rpos[i]
        di = dis[i]
        h = T / nstp
        cgl = pyCqcgl1d(N, d, h, False, 0, 4.0, 0.8, 0.01, di, 4)
        
        M = 4
        aa = cgl.intg(x[0], nstp*M, 1)
        plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h*M],
                                   save=True,
                                   name='cqcglHopfCycle' + str(di) + '_4T.eps')

if case == 60:
    """
    test the correctness of the Floquet exponents/vectors
    obtained from the Krylov-Schur algorithm
    """
    N = 1024
    d = 30
    di = 0.36
    x, T, nstp, th, phi, err, es, vs = cqcglReadRPOEVdi(
        '../../data/cgl/rpoT2X1_v2.h5', di, 1)
    h = T / nstp
    cgl = pyCqcgl1d(N, d, h, False, 0, 4.0, 0.8, 0.01, di, 4)

    U = vs[0:3]
    # angle between velocity and marginal subspace
    v0 = cgl.velocity(x)
    ang1 = pAngle(v0, U.T)

    # angle between group tangent and marginal subspace
    tx_tau = cgl.transTangent(x)
    ang2 = pAngle(tx_tau, U.T)
    tx_rho = cgl.phaseTangent(x)
    ang3 = pAngle(tx_rho, U.T)

    print es
    print ang1, ang2, ang3

if case == 61:
    """
    Test whether the Krylov-Schur algorithm produces the correct
    number of marginal exponents.
    This is very import indicator for it to resolve degenercy.
    """
    for di in np.arange(0.36, 0.4211, 0.001).tolist() + np.arange(0.4211, 0.42201, 0.0001).tolist() + [0.4225, 0.4226]:
        x, T, nstp, th, phi, err, es, vs = cqcglReadRPOEVdi(
            '../../data/cgl/rpoT2X1EV30.h5', di, 1)
        print di, es[0][:4]

if case == 70:
    """
    move rpo with FE/FV
    """
    inFile = '../../data/cgl/rpoT2X1_v3.h5'
    outFile = '../../data/cgl/rpoT2X1EV30.h5'
    # for di in np.arange(0.36, 0.411, 0.001).tolist() + np.arange(0.414, 0.418, 0.001).tolist() + [0.4225, 0.4226]:
    for di in np.arange(0.361, 0.4191, 0.002).tolist():
        disp(di)
        cqcglMoveRPOEVdi(inFile, outFile, di, 1)

if case == 80:
    """
    plot the largest non-marginal Floquet exponent and periods of all
    RPO founded.
    """
    dis, xx = cqcglReadRPOAll('../../data/cgl/rpoT2X1EV30.h5', 1, True)
    fe = []
    T = []
    for i in range(len(dis)):
        e = xx[i][6][0]
        ep = removeMarginal(e, 3)
        fe.append(ep)
        T.append(xx[i][1])

    e1 = []
    e2 = []
    for i in range(len(dis)):
        e1.append(fe[i][0])
        e2.append(fe[i][1])

    # plot
    scale = 1.3
    fig = plt.figure(figsize=[6/scale, 4/scale])
    ax = fig.add_subplot(111)
    ax.plot(dis, e1,  c='b', lw=1, ls='-', marker='o', ms=5, mfc='r', mec='none')
    ax.plot(dis, np.zeros(len(dis)), c='g', ls='--', lw=2)
    ax.set_xlabel(r'$d_i$', fontsize=20)
    ax.set_ylabel(r'$\mu_1$', fontsize=20)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    
    scale = 1.3
    fig = plt.figure(figsize=[6/scale, 4/scale])
    ax = fig.add_subplot(111)
    ax.plot(dis, T,  c='b', lw=1, ls='-', marker='o', ms=5, mfc='r',
            mec='none')
    ax.set_xlabel(r'$d_i$', fontsize=20)
    ax.set_ylabel(r'$T_p$', fontsize=20)
    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 81:
    """
    For the Hopf bifurcation, we can actually estimate the parameters
    by experimental data. Here,
    we plot 1/T and the leading stable expoent of rpo and unstable expoent
    of req
    """
    dic = 0.36

    dis, xx = cqcglReadRPOAll('../../data/cgl/rpoT2X1EV30.h5', 1, True)
    T = []
    e1 = []
    for i in range(len(dis)):
        e = xx[i][6][0]
        ep = removeMarginal(e, 3)
        e1.append(ep[0])
        T.append(xx[i][1])

    ix = [i for i in range(len(dis)) if dis[i] <= dic+0.01 and dis[i] >= dic]

    dis2, xx2 = cqcglReadReqAll('../../data/cgl/reqDi.h5', 1, True)
    e1p = []
    for i in range(len(dis2)):
        e = xx2[i][4]
        ep = removeMarginal(e, 2)
        e1p.append(ep[0])
        
    ix2 = [i for i in range(len(dis2)) if dis2[i] <= dic+0.01 and dis2[i] >= dic]

    # plot
    scale = 1.3
    fig = plt.figure(figsize=[6/scale, 4/scale])
    ax = fig.add_subplot(111)
    ax.scatter(np.array(dis)[ix] - dic, -np.array(e1)[ix]/2,
               s=25, marker='o', facecolor='r', edgecolor='none')
    ax.scatter(np.array(dis2)[ix2] - dic, np.array(e1p)[ix2],
               s=25, marker='s', facecolor='b', edgecolor='none')
    # ax.plot(dis, np.zeros(len(dis)), c='g', ls='--', lw=2)
    ax.set_xlabel(r'$d_i - d_{ic}$', fontsize=20)
    # ax.set_ylabel(r'$\mu_1$', fontsize=20)
    ax.set_xlim([-0.001, 0.011])
    ax.set_ylim([0, 0.1])
    fig.tight_layout(pad=0)
    plt.show(block=False)
    
    scale = 1.3
    fig = plt.figure(figsize=[6/scale, 4/scale])
    ax = fig.add_subplot(111)
    ax.scatter(np.array(dis)[ix] - dic, 1 / np.array(T)[ix],
               s=25, marker='o', facecolor='r', edgecolor='none')
    ax.set_xlim([-0.001, 0.011])
    ax.set_xlabel(r'$d_i - d_{ic}$', fontsize=20)
    ax.set_ylabel(r'$1/T_p$', fontsize=20)
    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 90:
    """
    calculate the distance of rpo to the zero state
    because we guess the reason that rpo does not exit
    after a certain di is that it goes close to zero state
    which is contracting.
    """
    N = 1024
    d = 30
    dis = np.arange(0.36, 0.421, 0.002).tolist() + np.arange(0.421, 0.42201, 0.0001).tolist() + [0.4225, 0.4226]
    minNors = []
    for di in dis:
        print di
        x, T, nstp, th, phi, err = cqcglReadRPOdi(
            '../../data/cgl/rpoT2X1.h5', di, 1)
        h = T / nstp
        nstp = np.int(nstp)
        cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
        aa = cgl.intg(x, nstp, 1)
        aaHat, th2, phi2 = cgl.orbit2slice(aa)
        nors = []
        for i in range(aaHat.shape[0]):
            nor = norm(aaHat[i])
            nors.append(nor)

        minNors.append(min(nors))

    scale = 1.3
    fig = plt.figure(figsize=[6/scale, 4/scale])
    ax = fig.add_subplot(111)
    ax.plot(dis, minNors,  c='b', lw=1, ls='-', marker='o', ms=5, mfc='r',
            mec='none')
    ax.set_xlabel(r'$d_i$', fontsize=20)
    ax.set_ylabel(r'$\min|A|$', fontsize=20)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 100:
    """
    view the unstable manifold for some unstable Hopf cycles
    """
    N = 1024
    d = 30
    di = 0.4226

    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCqcgl1d(N, d, 0.0002, True, 0, 4.0, 0.8, 0.01, di, 4)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    x, T, nstp, th, phi, err, e, v = cqcglReadRPOEVdi(
        '../../data/cgl/rpoT2X1EV31.h5', di, 1)
    h = T / nstp
    nstp = np.int(nstp)
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    aa = cgl.intg(x, nstp, 1)
    aaHat, th, phi = cgl.orbit2slice(aa)
    aaHat -= a0Hat

    h3 = 0.0005
    cgl3 = pyCqcgl1d(N, d, h3, False, 0, 4.0, 0.8, 0.01, di, 4)
    a0Erg = x + v[0] * 1e-3
    nstp = 70000
    aaErg = cgl3.intg(a0Erg, 10000, 10000)
    a0Erg = aaErg[-1]
    aaErg = cgl3.intg(a0Erg, nstp, 2)
    aaErgHat, th, th = cgl3.orbit2slice(aaErg)
    aaErgHat -= a0Hat
    
    # e1, e2 = orthAxes2(veHat[0], veHat[1])
    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[6])
    aaHatProj = np.dot(aaHat, np.vstack((e1, e2, e3)).T)
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2, e3)).T)
    OProj = np.dot(-a0Hat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aaHatProj[:, 0], aaHatProj[:, 1], aaHatProj[:, 2], c='r', lw=2)
    ax.plot(aaErgHatProj[:, 0], aaErgHatProj[:, 1],
            aaErgHatProj[:, 2], c='g', lw=1, alpha=0.4)
    ax.scatter([0], [0], [0], s=80, marker='o', c='b',  edgecolors='none')
    ax.scatter(OProj[0], OProj[1], OProj[2], s=60, marker='o', c='c',
               edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    # plotConfigSurfaceFourier(cgl, aa1, [0, d, 0, T1])

if case == 110:
    """
    view the not converged rpo
    """
    N = 1024
    d = 30
    di = 0.04
    
    x, T, nstp, th, phi, err = cqcglReadRPO('rpo2.h5', '2')
    M = x.shape[0]
    h = T / nstp / M
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    es, ev = eigReq(cgl, a0, wth0, wphi0)
    ev = Tcopy(realve(ev))
    a0H = cgl.orbit2slice(a0)[0]
    veH = cgl.ve2slice(ev, a0)

    nsp = 20
    aas = np.empty([0, cgl.Ndim])
    aaHs = []
    for i in range(M):
        aa = cgl.intg(x[i], nstp, nsp)
        aaH = cgl.orbit2slice(aa)[0]
        aas = np.vstack((aas, aa))
        aaHs.append(aaH)
    
    plotConfigSpaceFromFourier(cgl, aas, [0, d, 0, T])

    e1, e2, e3 = orthAxes(veH[0], veH[1], veH[10])
    bases = np.vstack((e1, e2, e3))
    aaHPs = []
    for i in range(M):
        aaHP = np.dot(aaHs[i]-a0H, bases.T)
        aaHPs.append(aaHP)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    for i in range(M):
        ax.plot(aaHPs[i][:, 0], aaHPs[i][:, 1],
                aaHPs[i][:, 2], c='g', lw=1)
        if i == 0:
            c = 'r'
        elif i == M-1:
            c = 'k'
        else:
            c = 'b'
        # ax.scatter(aaHPs[i][0, 0], aaHPs[i][0, 1], aaHPs[i][0, 2],
        #           s=50, marker='o', c=c,  edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    for i in range(M-1):
        tmp = ax.scatter(aaHPs[i][-1, 0], aaHPs[i][-1, 1], aaHPs[i][-1, 2],
                         s=50, marker='o', c='k',  edgecolors='none')
        tmp2 = ax.scatter(aaHPs[i+1][0, 0], aaHPs[i+1][0, 1], aaHPs[i+1][0, 2],
                          s=50, marker='o', c='r',  edgecolors='none')
        t = raw_input("input: ")
        tmp.remove()
        tmp2.remove()


if case == 120:
    """
    view the not converged rpo
    the full multistep method
    """
    N = 512
    d = 30
    di = 0.04
    
    x, T, nstp, th, phi, err = cqcglReadRPO('rpo4.h5', '3')
    M = x.shape[0]
    Ts = x[:, -3]
    ths = x[:, -2]
    phis = x[:, -1]
    x = x[:, :-3]

    h = T / nstp / M
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    
    nsp = 2
    aas = np.empty([0, cgl.Ndim])
    aas2 = []
    aaHs = []
    for i in range(M):
        newh = Ts[i] / nstp
        cgl.changeh(newh)
        aa = cgl.intg(x[i], nstp, nsp)
        aaH = cgl.orbit2slice(aa)[0]
        aas = np.vstack((aas, aa))
        aas2.append(aa)
        aaHs.append(aaH)

    ers = np.zeros(M)
    ers2 = np.zeros(M)
    for i in range(M):
        j = (i+1) % M
        ers[i] = norm(aaHs[i][-1] - aaHs[j][0])
        ers2[i] = norm(cgl.Rotate(aas2[i][-1], ths[i], phis[i]) - aas2[j][0])

    plotConfigSpaceFromFourier(cgl, aas, [0, d, 0, T])

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    for i in range(M):
        ax.plot(aaHs[i][:, 0], aaHs[i][:, 1],
                aaHs[i][:, 2], c='g', lw=1)
        if i == 0:
            c = 'r'
        elif i == M-1:
            c = 'k'
        else:
            c = 'b'
        # ax.scatter(aaHPs[i][0, 0], aaHPs[i][0, 1], aaHPs[i][0, 2],
        #           s=50, marker='o', c=c,  edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    for i in range(M-1):
        tmp = ax.scatter(aaHPs[i][-1, 0], aaHPs[i][-1, 1], aaHPs[i][-1, 2],
                         s=50, marker='o', c='k',  edgecolors='none')
        tmp2 = ax.scatter(aaHPs[i+1][0, 0], aaHPs[i+1][0, 1], aaHPs[i+1][0, 2],
                          s=50, marker='o', c='r',  edgecolors='none')
        t = raw_input("input: ")
        tmp.remove()
        tmp2.remove()


if case == 130:
    """
    use odeint to integrate in the slice directly
    """
    N = 512
    d = 30
    di = 0.04
    
    x, T, nstp, th, phi, err = cqcglReadRPO('rpo4.h5', '3')
    M = x.shape[0]
    Ts = x[:, -3]
    ths = x[:, -2]
    phis = x[:, -1]
    x = x[:, :-3]

    h = T / nstp / M
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
  
    nsp = 2
    aas = np.empty([0, cgl.Ndim])
    aas2 = []
    aaHs = []
    for i in range(M):
        newh = Ts[i] / nstp
        cgl.changeh(newh)
        aa = cgl.intg(x[i], nstp, nsp)
        aaH = cgl.orbit2slice(aa)[0]
        aas = np.vstack((aas, aa))
        aas2.append(aa)
        aaHs.append(aaH)

    def vel(x, t):
        return cgl.velocity(x)
    
    pH = np.empty([0, cgl.Ndim])
    pHs = []
    for k in range(M):
        x0H = aaHs[k][0]
        xH, infodict = odeint(vel, x0H, np.linspace(0, Ts[k], nstp),
                              full_output=True)
        print np.min(infodict['hu']), np.max(infodict['hu'])
        pH = np.vstack((pH, xH))
        pHs.append(xH)

if case == 140:
    cgl.changeh(cgl.h/10)
    J = cgl.intgj(x[0], 10, 10, 10)[1].T
    J2 = np.eye(cgl.Ndim) + cgl.stab(x[0]).T * cgl.h * 10
    print np.max(J), np.max(J2), np.min(J), np.min(J2)
    print J[:3, :3]
    print J2[:3, :3]
    
    def velJ(xj, t):
        x = xj[:cgl.Ndim]
        J = xj[cgl.Ndim:].reshape(cgl.Ndim, cgl.Ndim)
        v = cgl.velocity(x)
        A = cgl.stab(x).T
        AJ = A.dot(J)
        return np.concatenate((v, AJ.ravel()))
        
    def calJ(x, n):
        j = np.eye(cgl.Ndim)
        xj = np.concatenate((x, j.ravel()))
        y = odeint(velJ, xj, np.linspace(0, cgl.h*n, n+1))
        
        return y[:, :cgl.Ndim].copy(), y[-1, cgl.Ndim:].copy().reshape((cgl.Ndim, cgl.Ndim))

    def calJ2(x, n):
        y = odeint(velJ, x, np.linspace(0, cgl.h*n, n+1))
        return y[-1]

    def calJ3(x, n):
        j = np.eye(cgl.Ndim)
        xj = np.concatenate((x, j.ravel()))
        y = odeint(velJ, xj, np.linspace(0, cgl.h*n, n+1))
  
        return y[-1]
        
    aa, J = cgl.intgj(x[0], 10, 10, 10)
    aa2, J2 = calJ(x[0], 10)

    cgl.changeh(cgl.h / 10)
    aa3, J3 = cgl.intgj(x[0], 100, 100, 100)
    aa4, J4 = calJ(x[0], 100)

    print norm(aa3[-1] - aa[-1]), norm(aa4[-1] - aa2[-1])
    print np.max(np.max(np.abs(J3-J))), np.max(np.max(np.abs(J4-J2)))
    
    y = calJ3(x[0], 10)
    for i in range(2):
        print i
        y = calJ2(y, 100)
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' KSvelocity.cc ../ksint.cc  -I../../../include -I$XDAPPS/eigen/include/eigen3 -lfftw3
 *
 * usage :
 * >> v = ksVelocity(aa(:,i) );
 * */
#include "ksint.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <cassert>
#include <Eigen/Dense>

using namespace Eigen;

static MatrixXd
KSvelocity(double *x, const int N){
    KS ks(N+2);
    Map<VectorXd> x2(x, N);
    return ks.velocity(x2);
}


void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    // get the pointer and the size of input 
    double *x = mxGetPr(prhs[0]);
    mwSize N = mxGetM(prhs[0]);
    mwSize M = mxGetN(prhs[0]);
    assert(M2 = 1);
    
    plhs[0] = mxCreateDoubleMatrix(N, 1, mxREAL);

    MatrixXd v = KSvelocity(x, N);
    memcpy(mxGetPr(plhs[0]), &v(0), N*M*sizeof(double));
}
<file_sep>/* to compile:
 * g++ test_ksint.cc -std=c++11 -lksint -ldenseRoutines -lfftw3 -I ../../include/ -L ../../lib/ -I$EIGEN -O3 -DEIGEN_FFTW_DEFAULT && ./a.out
 */
#include "ksint.hpp"
#include "denseRoutines.hpp"
#include "myH5.hpp"
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;
using namespace MyH5;
using namespace denseRoutines;

#define N10

int main(){
    
#ifdef N10
    //======================================================================
    // 
    int N = 64;
    double L = 22;
    ArrayXd a0 = ArrayXd::Random(N-2) * 0.1;
    KS ks(N, L);
    ArrayXXd aa = ks.intgC(a0, 0.01, 20, 10);
#endif
#if 0
    case 10 :{		  /* find eq and req for N = 64 from N = 32 */
	std::string file = "../../data/ksReqx32.h5";
	std::string outFile = "tmp.h5";
	const int N = 64;
	KS ks(N, 0.01, 22);

	for (int i = 0; i < 2; i++){
	    int Id = i+1;
	    auto tmp = KSreadReq(file, Id);
	    VectorXd x0(VectorXd::Zero(N-1));
	    x0.head(30) = tmp.first; 
	    x0(N-2) = tmp.second * 2*M_PI/22; 

	    auto result = ks.findReq(x0, 1e-13, 100, 20);
	
	    VectorXd &a0 = std::get<0>(result);
	    double omega = std::get<1>(result);
	    double err = std::get<2>(result);
	    
	    KSwriteReq(outFile, Id, a0, omega, err);
	}

	for (int i = 0; i < 3; i++){
	    int Id = i + 1;
	    auto a0 = KSreadEq(file, Id);
	    VectorXd x0(VectorXd::Zero(N-2));
	    x0.head(30) = a0;
	
	    auto result = ks.findEq(x0, 1e-13, 100, 20);

	    VectorXd &a = std::get<0>(result);
	    double err = std::get<1>(result);
	    
	    KSwriteEq(outFile, Id, a, err);
	}
	

	break;
    }

	
    case 11 : {		/* calculate the stability exponents of eq */
	std::string file = "../../data/ks22Reqx64.h5";
	auto eq = KSreadEq(file, 1);
	VectorXd a0 = eq.first;
	double err = eq.second;

	const int N = 64;
	KS ks(N, 0.01, 22);
	auto ev = ks.stabEig(a0);
	cout << ev.first << endl;

	break;
    }
	
    case 12 : {		/* calculate the stability exponents of req */
	std::string file = "../../data/ks22Reqx64.h5";
	auto req = KSreadReq(file, 1);
	VectorXd &a0 = std::get<0>(req);
	double w = std::get<1>(req);
	double err = std::get<2>(req);

	const int N = 64;
	KS ks(N, 0.01, 22);
	auto ev = ks.stabReqEig(a0, w);

	cout << ev. first << endl;
	
	break;
    }

    case 13: {			/* write stability exponents */
	std::string file = "../../data/ks22Reqx64.h5";
	std::string outFile = "ks22Reqx64.h5";
	const int N = 64;
	KS ks(N, 0.01, 22);
	
	for(int i = 0; i < 3 ; i++){
	    int Id = i + 1;
	    auto eq = KSreadEq(file, Id);
	    VectorXd &a0 = eq.first;
	    auto ev = ks.stabEig(a0);
	    
	    KSwriteEqE(outFile, Id, ev.first);
	}

	for(int i = 0; i < 2; i++){
	    int Id = i + 1;
	    auto req = KSreadReq(file, Id);
	    VectorXd &a0 = std::get<0>(req);
	    double w = std::get<1>(req);
	    auto ev = ks.stabReqEig(a0, w);
	    
	    KSwriteReqE(outFile, Id, ev.first);
	}

	break;
    }

    case 14: {
	
	std::string file = "../../data/ks22h001t120x64.h5";
	std::string poType = "rpo";
	
	MatrixXd a0;
	double T, r, s;
	int nstp;
	std::tie(a0, T, nstp, r, s) = KSreadRPO(file, poType, 1);
	
        KS ks(64, 22);
	auto tmp = ks.aintgj(a0, 0.01, T, 1);
	savetxt("a.dat", ks.hs);

	break;
    }
	
	
    default :
	{
	    cout << "please indicate the correct index." << endl;
	}
    }

#endif
    return 0;
}
<file_sep>/* to comiple:
 * (Note : libksdim.a is static library, so the following order is important)
 *
 * h5c++ test_ksFEFV.cc -std=c++11 -O3 -march=corei7 -msse4 -msse2 -I$XDAPPS/eigen/include/eigen3 -I$RESH/include  -L$RESH/lib -lksFEFV -lksint -lmyfft -lfftw3 -literMethod -ldenseRoutines -lmyH5 -lped
 * 
 */

#include <iostream>
#include <Eigen/Dense>
#include <string>
#include <fstream>
#include <algorithm> 
#include "ksFEFV.hpp"
#include "myH5.hpp"
#include "denseRoutines.hpp"


using namespace std;
using namespace Eigen;
using namespace MyH5;
using namespace denseRoutines;

int main(){
    cout.precision(16);

    switch (5) {
	
    case 1: {
	/* calculate FE, FV for a single orbit */
	const double L = 22;
	const int nqr = 5; // spacing 	
	const int MaxN = 2000;  // maximal iteration number for PED
	const double tol = 1e-12; // torlearance for PED   
	const int trunc = 30; // number of vectors	
	const size_t ppId = 33;
	const string inputfileName = "../../data/ks22h001t120x64EV.h5";
	const string outputfileName = "ex.h5";
	const string ppType = "rpo";
	// KScalWriteFEFVInit(inputfileName, outputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
	auto tmp = KScalFEFV(inputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
	cout << tmp.first << endl;
	
	break;
    }

    case 5: {
	const double L = 22;
	const int nqr = 5; // spacing 	
	const int MaxN = 2000;  // maximal iteration number for PED
	const double tol = 1e-12; // torlearance for PED   
	const int trunc = 30; // number of vectors	
	const size_t ppId = 147;
	const string inputfileName = "../../data/ks22h001t120x64EV.h5";
	const string outputfileName = "ex.h5";
	const string ppType = "ppo";
	MatrixXd R = KSgetR(inputfileName, ppType, ppId, L, MaxN, tol, nqr);

	int rs = R.rows(), cs = R.cols() / rs;
	cout << rs << ' ' << cs << endl;
	
	VectorXd maxElements(cs/10);
	for(int k = 0; k < cs/10; k++){
	    MatrixXd r(MatrixXd::Identity(10, 10));
	    for(int i = 0; i < cs; i++){
		int index = (2 * cs - 1 - i - k*10) % cs;
		r = R.middleCols(index*rs, rs).topLeftCorner(10, 10) * r;
	    }
	    r -= r.diagonal().asDiagonal(); // get rid of diagonal
	    maxElements(k) = r.array().abs().maxCoeff();
	    // cout << maxElements(k) << endl;	
	}

	savetxt("maxElement.dat", maxElements);

	break;
    }

    case 20: {
	/*
	  calculate FE, FV for a set of orbits 
	 */
	const double L = 22;
	const int nqr = 5; // spacing 	
	const int MaxN = 500;  // maximal iteration number for PED
	const double tol = 1e-12; // torlearance for PED   
	const int trunc = 30; // number of vectors	

	const string inName = "../../data/ks22h001t120x64EV.h5";
	const string outName = "ex.h5";
	
	int ppIds[] = {33, 36, 59, 60, 79, 81, 109, 114};
	const string ppType = "rpo";

	for(size_t i = 0; i < sizeof(ppIds)/sizeof(int); i++){
	    printf("ppId = %d\n ", ppIds[i]);

	    // auto tmp = KSreadRPO(inName, ppType, ppIds[i]);
	    // printf("T=%f, nstp=%d, r=%g, s=%f\n", std::get<1>(tmp), (int)std::get<2>(tmp), 
	    //	   std::get<3>(tmp), std::get<4>(tmp));
	    KScalWriteFEFVInit(inName, outName, ppType, ppIds[i], L, MaxN, tol, nqr, trunc);
	}

	break;

    }

    case 30: {
	/*
	  move KS data base 
	  all ppo from one file
	  rpo from 2 files
	 */
	const string inFile1 = "../../data/ks22h001t120x64EV.h5";
	const string inFile2 = "../../data/ex.h5";
	const string outFile1 = "../../data/ks22h001t120x64_t.h5";
	const string outFile2 = "../../data/ks22h001t120x64_t2.h5";

	std::vector<int> ppIds1;
	for(int i = 0; i < 200; i++) ppIds1.push_back(i+1);
	std::vector<int> ppIds2 = {33, 36, 59, 60, 79, 81, 109, 114};

	for(int i = 0; i < ppIds1.size(); i++) {
	    printf("f1 ppo, i = %d, ppId = %d \n", i, ppIds1[i]);
	    KSmoveFE(inFile1, outFile1, "ppo", ppIds1[i]);
	    KSmoveFEFV(inFile1, outFile2, "ppo", ppIds1[i]);
	}

	for(int i = 0; i < ppIds1.size(); i++) {
	    if(std::find(ppIds2.begin(), ppIds2.end(), ppIds1[i]) == ppIds2.end()){
		printf("f1 rpo, i = %d, ppId = %d \n", i, ppIds1[i]);
		KSmoveFE(inFile1, outFile1, "rpo", ppIds1[i]);
		KSmoveFEFV(inFile1, outFile2, "rpo", ppIds1[i]);
	    }
	    else {
		printf("f2 rpo, i = %d, ppId = %d \n", i, ppIds1[i]);
		KSmoveFE(inFile2, outFile1, "rpo", ppIds1[i]);
		KSmoveFEFV(inFile2, outFile2, "rpo", ppIds1[i]);
	    }
	}
	
	break;
    }

    case 40: {
	/* move KS initial condtions 
	   The purpose is to reduce the space
	   Also it changes double nstp to int nstp
	*/
	const string inFile = "../../data/ks22h001t120x64.h5";		
	const string outFile = "../../data/ks22h001t120x64_2.h5";
	
	for(int i = 0; i < 840; i++){
	    int ppId = i+1;
	    printf("ppo, i = %d, ppId = %d \n", i, ppId);
	    KSmoveRPO(inFile, outFile, "ppo", ppId);
	}
	
	for(int i = 0; i < 834; i++){
	    int ppId = i+1;
	    printf("rpo, i = %d, ppId = %d \n", i, ppId);
	    KSmoveRPO(inFile, outFile, "rpo", ppId);
	}
	
	break;
    }

    case 50: {
	/* calculate left FE, FV for a single orbit */
	const double L = 22;
	const int nqr = 5; // spacing 	
	const int MaxN = 2000;  // maximal iteration number for PED
	const double tol = 1e-13; // torlearance for PED   
	const int trunc = 30; // number of vectors	
	const size_t ppId = 1;
	const string inputfileName = "../../data/ks22h001t120x64EV.h5";
	const string outputfileName = "left.h5";
	const string ppType = "ppo";
	KScalWriteLeftFEFV(inputfileName, outputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
	// auto tmp = KScalLeftFEFV(inputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
	// cout << tmp.first << endl;
	
	break;

    }
	
	
    default: {
	cout << "Please indicate the right #" << endl;
    }
	
    }


    return 0;
}
<file_sep>#include "CQCGL2d.hpp"
#include <cmath>
#include <iostream>
#include <algorithm>    // std::max

#define cee(x) (cout << (x) << endl << endl)

using namespace denseRoutines;
using namespace MyH5;
using namespace Eigen;
using namespace std;
using namespace MyFFT;

//////////////////////////////////////////////////////////////////////
//                        Class CQCGLgeneral                             //
//////////////////////////////////////////////////////////////////////

/* ------------------------------------------------------ */
/* ----                constructor/destructor     ------- */
/* ------------------------------------------------------ */

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = Mu A + (Dr + Di*i) (A_{xx} + A_{yy}) + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
 *
 * @param[in] N            the number of Fourier modes
 * @param[in] d            the spacial period, size
 * @param[in] doEnableTan   false : forbid tangent space integration 
 * @param[in] threadNum    number of threads for integration
 */
CQCGL2d::CQCGL2d(int N, int M, double dx, double dy,
		 double Mu, double Dr, double Di,
		 double Br, double Bi, double Gr,
		 double Gi,  
		 int threadNum)
    : N(N), M(M), dx(dx), dy(dy),
      Mu(Mu), Dr(Dr), Di(Di), Br(Br), Bi(Bi),
      Gr(Gr), Gi(Gi),
      
      F{ FFT2d(M, N, threadNum), 
	FFT2d(M, N, threadNum), 
	FFT2d(M, N, threadNum), 
	FFT2d(M, N, threadNum), 
	FFT2d(M, N, threadNum) },    
				      
				       JF{ FFT2d(M, N, threadNum), 
					       FFT2d(M, N, threadNum), 
					       FFT2d(M, N, threadNum), 
					       FFT2d(M, N, threadNum), 
					       FFT2d(M, N, threadNum) }      
{
    CGLInit(); // calculate coefficients.
}

///  M = N, dx = dy
CQCGL2d::CQCGL2d(int N, double dx,
		 double Mu, double Dr, double Di,
		 double Br, double Bi, double Gr,
		 double Gi,  
		 int threadNum)
    : CQCGL2d(N, N, dx, dx, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) {}


/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = -A + (1 + b*i) (A_{xx} + A_{yy}) + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
 */
CQCGL2d::CQCGL2d(int N, int M,  double dx, double dy, 
		 double b, double c, double dr, double di, 
		 int threadNum)
    : CQCGL2d(N, M, dx, dy, -1, 1, b, 1, c, -dr, -di, threadNum) {}

CQCGL2d::CQCGL2d(int N, double dx,
		 double b, double c, double dr, double di, 
		 int threadNum)
    : CQCGL2d(N, N, dx, dx, -1, 1, b, 1, c, -dr, -di, threadNum) {}


CQCGL2d::~CQCGL2d(){}

CQCGL2d & CQCGL2d::operator=(const CQCGL2d &x){
    return *this;
}

/* ------------------------------------------------------ */
/* ----          Initialization functions         ------- */
/* ------------------------------------------------------ */

/**
 * @brief calculate the number of effective modes: Ne
 * @note N must be initialized first
 */
inline int CQCGL2d::calNe(const double N){
    return (N/3) * 2 - 1;	/* make it an odd number */
}


/**
 * @brief set the corret dimension of the system
 *     
 * Dealiasing is the method to calculate correct convolution term. For centralized
 * FFT, it works as set Fourier modes a_k = 0 for wave number |k| > 2/3 * N.
 * More specifically, in this code, the middle part of modes
 * is set to zero.
 *
 *    |<---------------------------------------------------------->|
 *                             FFT length: N
 *               
 *    |<--------------->|<--------------------->|<---------------->|
 *        (Ne + 1) / 2         N - Ne                (Ne - 1) /2
 *         = Nplus             = Nalias               = Nminus
 *
 *    @Note each term has real and imaginary part, so the indices are
 *          0, 1, 2,... Nplus*2, Nplus*2+1,... 2*Ne-1
 */
void CQCGL2d::CGLInit(){
    Ne = calNe(N);			
    Nplus = (Ne + 1) / 2;
    Nminus = (Ne - 1) / 2;
    Nalias = N - Ne;

    Me = calNe(M);
    Mplus = (Me + 1) / 2;
    Mminus = (Me - 1) / 2;
    Malias = M - Me;
    
    // calculate the Linear part
    Kx.resize(N,1);
    Kx << ArrayXd::LinSpaced(N/2, 0, N/2-1), 0, ArrayXd::LinSpaced(N/2-1, -N/2+1, -1); 
    Kx2.resize(Ne, 1);
    Kx2 << ArrayXd::LinSpaced(Nplus, 0, Nplus-1), ArrayXd::LinSpaced(Nminus, -Nminus, -1); 

    Ky.resize(M,1);
    Ky << ArrayXd::LinSpaced(M/2, 0, M/2-1), 0, ArrayXd::LinSpaced(M/2-1, -M/2+1, -1); 
    Ky2.resize(Me, 1);
    Ky2 << ArrayXd::LinSpaced(Mplus, 0, Mplus-1), ArrayXd::LinSpaced(Mminus, -Mminus, -1); 
    
    QKx = 2*M_PI/dx * Kx;  
    QKy = 2*M_PI/dy * Ky;
    
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * (QKx.square().replicate(1, M).transpose() + 
					 QKy.square().replicate(1, N)); 
    L.middleRows(Mplus, Malias) = ArrayXXcd::Zero(Malias, N); 
    L.middleCols(Nplus, Nalias) = ArrayXXcd::Zero(M, Nalias);
}

void CQCGL2d::changeOmega(double w){
    Omega = w;
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * (QKx.square().replicate(1, M).transpose() + 
					 QKy.square().replicate(1, N)); 
    L.middleRows(Mplus, Malias) = ArrayXXcd::Zero(Malias, N); 
    L.middleCols(Nplus, Nalias) = ArrayXXcd::Zero(M, Nalias);
}

/** 
 * @brief calculate the coefficients of ETDRK4 or Krogstad
 *
 * Note, we give up using
 *     Map<ArrayXcd> hLv(hL.data(), hL.size());
 *     ArrayXXcd LR = ZR(hLv);
 * to save memory
 */
void CQCGL2d::calCoe(const double h){
    
    ArrayXXcd hL = h*L;
    
    E = hL.exp();
    E2 = (hL/2).exp();
    
    a21.resize(M, N);
    b1.resize(M, N);
    b2.resize(M, N);
    b4.resize(M, N);
    
    if (Method == 2){
	a31.resize(M, N);
	a32.resize(M, N);
	a41.resize(M, N);
	a43.resize(M, N);
    }
    
    for (int i = 0; i < N; i++){

	ArrayXXcd LR = ZR(hL.col(i));

	ArrayXXcd LR2 = LR.square();
	ArrayXXcd LR3 = LR.cube();
	ArrayXXcd LRe = LR.exp();
	ArrayXXcd LReh = (LR/2).exp();
    
	a21.col(i) = h * ( (LReh - 1)/LR ).rowwise().mean(); 
	b1.col(i) = h * ( (-4.0 - LR + LRe*(4.0 - 3.0 * LR + LR2)) / LR3 ).rowwise().mean();
	b2.col(i) = h * 2 * ( (2.0 + LR + LRe*(-2.0 + LR)) / LR3 ).rowwise().mean();
	b4.col(i) = h * ( (-4.0 - 3.0*LR -LR2 + LRe*(4.0 - LR) ) / LR3 ).rowwise().mean();
    
	if (Method == 2) {
	    a31.col(i) = h * ( (LReh*(LR - 4) + LR + 4) / LR2 ).rowwise().mean();
	    a32.col(i) = h * 2 * ( (2*LReh - LR - 2) / LR2 ).rowwise().mean();
	    a41.col(i) = h * ( (LRe*(LR-2) + LR + 2) / LR2 ).rowwise().mean();
	    a43.col(i) = h * 2 * ( (LRe - LR - 1)  / LR2 ).rowwise().mean();
	}

    }
}


void 
CQCGL2d::oneStep(double &du, const bool onlyOrbit){

    if (1 == Method) {
	NL(0, onlyOrbit);
	
	F[1].v1 = E2 * F[0].v1 + a21 * F[0].v3;
	if(!onlyOrbit) JF[1].v1 = E2 * JF[0].v1 + a21 * JF[0].v3;
	NL(1, onlyOrbit);
	
	F[2].v1 = E2 * F[0].v1 + a21 * F[1].v3;
	if(!onlyOrbit) JF[2].v1 = E2 * JF[0].v1 + a21 * JF[1].v3;
	NL(2, onlyOrbit);
	
	F[3].v1 = E2 * F[1].v1 + a21 * (2*F[2].v3 - F[0].v3);
	if(!onlyOrbit) JF[3].v1 = E2 * JF[1].v1 + a21 * (2*JF[2].v3 - JF[0].v3);
	NL(3, onlyOrbit);

	F[4].v1 = E * F[0].v1 + b1 * F[0].v3 + b2 * (F[1].v3+F[2].v3) + b4 * F[3].v3;
	if(!onlyOrbit) JF[4].v1 = E * JF[0].v1 + b1 * JF[0].v3 + b2 * (JF[1].v3+JF[2].v3) + b4 * JF[3].v3;
	NL(4, onlyOrbit);

    }
    else {
	NL(0, onlyOrbit);

	F[1].v1 = E2 * F[0].v1 + a21 * F[0].v3; 
	if(!onlyOrbit) JF[1].v1 = E2 * JF[0].v1 + a21 * JF[0].v3; 
	NL(1, onlyOrbit);

	F[2].v1 = E2 * F[0].v1 + a31 * F[0].v3 + a32 * F[1].v3;
	if(!onlyOrbit) JF[2].v1 = E2 * JF[0].v1 + a31 * JF[0].v3 + a32 * JF[1].v3;
	NL(2, onlyOrbit);

	F[3].v1 = E * F[0].v1 + a41 * F[0].v3 + a43 * F[2].v3;
	if(!onlyOrbit) JF[3].v1 = E * JF[0].v1 + a41 * JF[0].v3 + a43 * JF[2].v3;
	NL(3, onlyOrbit);
	
	F[4].v1 = E * F[0].v1 + b1 * F[0].v3 + b2 * (F[1].v3+F[2].v3) + b4 * F[3].v3;
	if(!onlyOrbit) JF[4].v1 = E * JF[0].v1 + b1 * JF[0].v3 + b2 * (JF[1].v3+JF[2].v3) + b4 * JF[3].v3;
	NL(4, onlyOrbit);

    }

    // infinity norm
    du = (b4 * (F[4].v3-F[3].v3)).abs().maxCoeff() / F[4].v1.abs().maxCoeff();
    if(!onlyOrbit){
	double x = (b4 * (JF[4].v3-JF[3].v3)).abs().maxCoeff() / JF[4].v1.abs().maxCoeff();
	du = std::max(du, x);
    }
}



/**
 * @brief calcuate the matrix to do averge of phi(z). 
 */

ArrayXXcd CQCGL2d::ZR(const Ref<const ArrayXcd> &z){
    
    int M1 = z.size();
    ArrayXd K = ArrayXd::LinSpaced(MC, 1, MC); // 1,2,3,...,M 
    
    ArrayXXcd r = R * (K/MC*dcp(0,2*M_PI)).exp().transpose(); // row array.
    
    return z.replicate(1, MC) + r.replicate(M1, 1);
    
}

/**
 * @brief calculat the damping factor of time step
 *
 * @param[out] doChange    true if time step needs change
 * @param[out] doAccept    true if accept current time step
 * @param[in]  s           estimate damping factor
 * @return     mu          final dampling factor 
 */
double
CQCGL2d::adaptTs(bool &doChange, bool &doAccept, const double s){
    double mu = 1;
    doChange = true;
    doAccept = true;

    if ( s > mumax) mu = mumax;
    else if (s > mue) mu = s;
    else if (s >= 1) {
	mu = 1;
	doChange = false;
    }
    else {
	doAccept = false;
	if (s > muc) mu = muc;
	else if (s > mumin) mu = s;
	else mu = mumin;
    }

    return mu;
}

void CQCGL2d::saveState(H5File &file, int id, const ArrayXXcd &a, 
			       const ArrayXXcd &v, const int flag){
    char groupName[10];
    sprintf (groupName, "%.6d", id);
    std::string s = "/"+std::string(groupName);
    Group group(file.createGroup(s));
    std:: string DS = s + "/";
    
    if (1 == flag || 0 == flag){
	writeMatrixXd(file, DS + "ar", a.real());
	writeMatrixXd(file, DS + "ai", a.imag());
    }
    if (2 == flag || 0 == flag) {
	writeMatrixXd(file, DS + "vr", v.real());
	writeMatrixXd(file, DS + "vi", v.imag());
    }
}

/**
 * @brief Constant time step integrator
 */
ArrayXXcd 
CQCGL2d::constETD(const ArrayXXcd &a0, const ArrayXXcd &v0, 
			 const double h, const int Nt, 
			 const int skip_rate, const bool onlyOrbit,
			 const bool doSaveDisk, const string fileName){
    int s = 1;
    if(!onlyOrbit) s = 2;
    
    const int m = (Nt+skip_rate-1)/skip_rate + 1;
    lte.resize(m-1);

    ArrayXXcd aa;
    H5File file;
    if (doSaveDisk){
	file = H5File(fileName, H5F_ACC_TRUNC); /* openFile fails */
	saveState(file, 0, a0, v0, onlyOrbit ? 1 : 0);
    }
    else{
	aa.resize(Me, Ne*m*s);
	aa.leftCols(Ne) = a0;
	if(!onlyOrbit) aa.middleCols(Ne, Ne) = v0;
    }
    
    F[0].v1 = pad(a0);
    if(!onlyOrbit) JF[0].v1 = pad(v0);
    NCallF = 0;

    calCoe(h);

    double du;
    int num = 0;
    for(int i = 0; i < Nt; i++){
	if( constETDPrint > 0 && i % constETDPrint == 0) fprintf(stderr, "%d/%d\n", i, Nt);
	
	oneStep(du, onlyOrbit);
	F[0].v1 = F[4].v1;	// update state
	if(!onlyOrbit) JF[0].v1 = JF[4].v1;
	NCallF += 5;
	if ( (i+1)%skip_rate == 0 || i == Nt-1) {
	    lte(num) = du;
	    if(doSaveDisk){
		saveState(file, num+1, unpad(F[4].v1), unpad(JF[4].v1), onlyOrbit ? 1 : 0);
	    }
	    else{
		aa.middleCols((num+1)*Ne, Ne) = unpad(F[4].v1);
		if(!onlyOrbit) aa.middleCols((M+num+1)*Ne, Ne) = unpad(JF[4].v1);
	    }
	    num++;
	}
    }	
    
    return aa;
}



/**
 * @brief time step adaptive integrator
 */
ArrayXXcd
CQCGL2d::adaptETD(const ArrayXXcd &a0, const ArrayXXcd &v0, 
			 const double h0, const double tend, 
			 const int skip_rate, const bool onlyOrbit,
			 const bool doSaveDisk, const string fileName){
    
    int s = 1;
    if(!onlyOrbit) s = 2;
    
    double h = h0; 
    calCoe(h);

    const int Nt = (int)round(tend/h);
    const int m = (Nt+skip_rate-1) /skip_rate + 1;
    F[0].v1 = pad(a0);
    if(!onlyOrbit) JF[0].v1 = pad(v0);
						
    ArrayXXcd aa;
    H5File file;
    if (doSaveDisk) {
	file = H5File(fileName, H5F_ACC_TRUNC);
	saveState(file, 0, a0, v0, onlyOrbit ? 1:0);
    }
    else {
	aa.resize(Me, Ne*m*s);
	aa.leftCols(Ne) = a0;
	if(!onlyOrbit) aa.middleCols(Ne, Ne) = v0;
    }

    Ts.resize(m);
    Ts(0) = 0;

    NCalCoe = 0;
    NReject = 0;
    NCallF = 0;    
    NSteps = 0;
    hs.resize(m-1);
    lte.resize(m-1);

    double t = 0;
    double du = 0;
    int num = 1;
    bool doChange, doAccept;

    bool TimeEnds = false;
    while(!TimeEnds){ 

	if ( t + h > tend){
	    h = tend - t;
	    calCoe(h);
	    NCalCoe++;
	    TimeEnds = true;
	}

	oneStep(du, onlyOrbit);
	NCallF += 5;		
	double s = nu * std::pow(rtol/du, 1.0/4);
	double mu = adaptTs(doChange, doAccept, s);
	
	if (doAccept){
	    t += h;
	    NSteps++;
	    F[0].v1 = F[4].v1;
	    if(!onlyOrbit) JF[0].v1 = JF[4].v1;
	    if ( NSteps % skip_rate == 0 || TimeEnds) {
		if (num >= Ts.size()) {
		    int m = Ts.size();
		    Ts.conservativeResize(m+cellSize);
		    if(!doSaveDisk) aa.conservativeResize(Eigen::NoChange, (m+cellSize)*Ne*s); 
		    hs.conservativeResize(m-1+cellSize);
		    lte.conservativeResize(m-1+cellSize);
		}
		hs(num-1) = h;
		lte(num-1) = du;
		if(doSaveDisk) saveState(file, num, unpad(F[4].v1), unpad(JF[4].v1), onlyOrbit ? 1:0);
		else {
		    aa.middleCols(num*Ne*s, Ne) = unpad(F[4].v1);
		    if (!onlyOrbit) aa.middleCols(num*Ne*s+1, Ne) = unpad(JF[4].v1);
		}
		Ts(num) = t;
		num++;
	    }
	}
	else {
	    NReject++;
	    TimeEnds = false;
	}
	
	if (doChange) {
	    h *= mu;
	    calCoe(h);
	    NCalCoe++;
	}
    }
    
    // lte = lte.head(num) has aliasing problem 
    hs.conservativeResize(num-1);
    lte.conservativeResize(num-1);
    Ts.conservativeResize(num);
    
    if (doSaveDisk) return aa;
    else return aa.leftCols(num*Ne*s);
}


/** @brief Integrator of 2d cqCGL equation.
 *
 */
ArrayXXcd 
CQCGL2d::intg(const ArrayXXcd &a0, const double h, const int Nt, const int skip_rate,
		     const bool doSaveDisk, const string fileName){
    
    assert(a0.rows() == Me && a0.cols() == Ne);
    ArrayXXcd v0(1, 1);
    return constETD(a0, v0, h, Nt, skip_rate, true, doSaveDisk, fileName);
}


ArrayXXcd
CQCGL2d::aintg(const ArrayXXcd &a0, const double h, const double tend, 
		      const int skip_rate, const bool doSaveDisk, const string fileName){
    assert(a0.rows() == Me && a0.cols() == Ne);
    ArrayXXcd v0(1, 1);
    return adaptETD(a0, v0, h, tend, skip_rate, true, doSaveDisk, fileName);
}

/**
 * @brief integrate the state and a subspace in tangent space
 */
ArrayXXcd
CQCGL2d::intgv(const ArrayXXcd &a0, const ArrayXXcd &v0, const double h,
		      const int Nt, const int skip_rate,
		      const bool doSaveDisk, const string fileName){
    assert(a0.rows() == Me && a0.cols() == Ne && v0.rows() == Me && v0.cols() == Ne);
    ArrayXXcd aa = constETD(a0, v0, h, Nt, skip_rate, false, doSaveDisk, fileName);
    return aa;
}

ArrayXXcd 
CQCGL2d::aintgv(const ArrayXXcd &a0, const ArrayXXcd &v0, const double h,
		       const double tend, const int skip_rate,
		       const bool doSaveDisk, const string fileName){
    assert(a0.rows() == Me && a0.cols() == Ne && v0.rows() == Me && v0.cols() == Ne);
    ArrayXXcd aa = adaptETD(a0, v0, h, tend, skip_rate, false, doSaveDisk, fileName);
    return aa;
}

/**
 * @brief get rid of the high modes
 */
void CQCGL2d::dealias(const int k, const bool onlyOrbit){
    F[k].v3.middleRows(Mplus, Malias) = ArrayXXcd::Zero(Malias, N); 
    F[k].v3.middleCols(Nplus, Nalias) = ArrayXXcd::Zero(M, Nalias);
    if (!onlyOrbit) {
	JF[k].v3.middleRows(Mplus, Malias) = ArrayXXcd::Zero(Malias, N); 
	JF[k].v3.middleCols(Nplus, Nalias) = ArrayXXcd::Zero(M, Nalias);
    }
}

/* 3 different stage os ETDRK4:
 *  v --> ifft(v) --> fft(g(ifft(v)))
 * */
void CQCGL2d::NL(const int k, const bool onlyOrbit){
    dcp B(Br, Bi);
    dcp G(Gr, Gi);

    if(onlyOrbit){
	F[k].ifft();
	ArrayXXcd A2 = (F[k].v2.real().square() + F[k].v2.imag().square()).cast<dcp>();
	F[k].v2 = B * F[k].v2 * A2 + G * F[k].v2 * A2.square();
	F[k].fft();

	dealias(k, onlyOrbit);
    }
    else {
	F[k].ifft();
	JF[k].ifft(); 
	
	ArrayXXcd aA2 = (F[k].v2.real().square() + F[k].v2.imag().square()).cast<dcp>();
	ArrayXXcd A2 = F[k].v2.square();
	
	F[k].v2 = B * F[k].v2 * aA2 + G * F[k].v2 * aA2.square();
	JF[k].v2 = JF[k].v2.conjugate() * ((B+G*2.0*aA2) * A2) + JF[k].v2 * ((2.0*B+3.0*G*aA2)*aA2);
	
	F[k].fft();
	JF[k].fft();
	
	dealias(k, onlyOrbit);
    }
}

ArrayXXcd CQCGL2d::unpad(const ArrayXXcd &v){
    int m = v.rows();
    int n = v.cols();
    assert(m == M && n % N == 0);
    int s = n / N;
    
    ArrayXXcd vt(Me, Ne*s);
    for (int i = 0; i < s; i++){
	
	vt.middleCols(i*Ne, Ne) <<
	    
	    v.block(0, i*N, Mplus, Nplus), 
	    v.block(0, i*N+Nplus+Nalias, Mplus, Nminus),

	    v.block(Mplus+Malias, i*N, Mminus, Nplus),
	    v.block(Mplus+Malias, i*N+Nplus+Nalias, Mminus, Nminus)
	    ;
    }
    
    return vt;
}

ArrayXXcd CQCGL2d::pad(const ArrayXXcd &v){
    int m = v.rows();
    int n = v.cols();
    assert( n % Ne == 0 && m == Me);
    int s = n / Ne;
    
    ArrayXXcd vp(M, N*s);
    for (int i = 0; i < s; i++){
	
	vp.middleCols(i*N, N) << 
	    
	    v.block(0, i*Ne, Mplus, Nplus), 
	    ArrayXXcd::Zero(Mplus, Nalias), 
	    v.block(0, i*Ne+Nplus, Mplus, Nminus),
	    
	    ArrayXXcd::Zero(Malias, N),
	    
	    v.block(Mplus, i*Ne, Mminus, Nplus), 
	    ArrayXXcd::Zero(Mminus, Nalias), 
	    v.block(Mplus, i*Ne+Nplus, Mminus, Nminus)
	    ;
    }
    
    return vp;
}

ArrayXd CQCGL2d::c2r(const ArrayXXcd &v){
    assert(v.rows() == Me && v.cols() == Ne);
    return Map<ArrayXd>((double*)&v(0,0), 2 * v.rows() * v.cols());
}

ArrayXXcd CQCGL2d::r2c(const ArrayXd &v){
    assert( v.size() == 2*Me*Ne);
    return Map<ArrayXXcd>((dcp*)&v(0,0), Me, Ne);
}



/* -------------------------------------------------- */
/* -------  Fourier/Configure transformation -------- */
/* -------------------------------------------------- */

/**
 * @brief back Fourier transform of the states. 
 */
ArrayXXcd CQCGL2d::Fourier2Config(const Ref<const ArrayXXcd> &aa){
    ArrayXXcd ap = pad(aa);
    int s = ap.cols() / N;
    ArrayXXcd AA(M, N*s);
    
    for (size_t i = 0; i < s; i++){
	F[0].v1 = ap.middleCols(i*N, N);
	F[0].ifft();
	AA.middleCols(i*N, N) = F[0].v2;
    }
    
    return AA;
}


/**
 * @brief Fourier transform of the states. Input and output are both real.
 */
ArrayXXcd CQCGL2d::Config2Fourier(const Ref<const ArrayXXcd> &AA){
    int s = AA.cols() / N;
    ArrayXXcd aa(M, N*s);
    
    for(size_t i = 0; i < s; i++){
	F[0].v2 = AA.middleCols(i*N, N);
	F[0].fft();
	aa.middleCols(i*N, N) = F[0].v3;
    }
    
    return unpad(aa);
}



/* -------------------------------------------------- */
/* --------            velocity field     ----------- */
/* -------------------------------------------------- */

/**
 * @brief velocity field
 */
ArrayXXcd CQCGL2d::velocity(const ArrayXXcd &a0){
    assert(a0.rows() == Me && a0.cols() == Ne);
    F[0].v1 = pad(a0);
    NL(0, true);
    ArrayXXcd vel = L*F[0].v1 + F[0].v3;
    return unpad(vel);
}

/**
 * @brief the generalized velociyt for relative equilibrium
 *
 *   v(x) + \omega_\tau * t_\tau(x) + \omega_\rho * t_\rho(x)
 */
ArrayXXcd CQCGL2d::velocityReq(const ArrayXXcd &a0, const double wthx,
				    const double wthy, const double wphi){
    return velocity(a0) + wthx*tangent(a0, 1) + wthy*tangent(a0, 2) + 
	wphi*tangent(a0, 3);
}


/* -------------------------------------------------- */
/* --------          stability matrix     ----------- */
/* -------------------------------------------------- */
/**
 * @brief calculate the product of stability matrix with a vector
 */
ArrayXXcd CQCGL2d::stab(const ArrayXXcd &a0, const ArrayXXcd &v0){
    assert(a0.rows() == Me && a0.cols() == Ne && v0.rows() == Me && v0.cols() == Ne);
    F[0].v1 = pad(a0);
    JF[0].v1 = pad(v0); 

    NL(0, false);
    ArrayXXcd Ax = L*JF[0].v1 + JF[0].v3;
    return unpad(Ax);
}

/**
 * @brief stability for relative equilbrium
 */
ArrayXXcd CQCGL2d::stabReq(const ArrayXXcd &a0, const ArrayXXcd &v0,
				  const double wthx, const double wthy,
				  const double wphi){
    ArrayXXcd z = stab(a0, v0);
    return z + wthx*tangent(v0, 1) + wthy*tangent(v0, 2) + wphi*tangent(v0, 3);
}

/* -------------------------------------------------- */
/* ------           symmetry related           ------ */
/* -------------------------------------------------- */

ArrayXXcd CQCGL2d::rotate(const Ref<const ArrayXXcd> &a0, const int mode, const double th1,
				 const double th2, const double th3){
    switch(mode) {

    case 1 : {		     /* translation rotation in x direction */
	double thx = th1;
	ArrayXXd th = (thx*Kx2).replicate(1, Me).transpose();

	return a0 * (dcp(0, 1) * th).exp();
    }
	
    case 2: {		     /* translation rotation in y direction */
	double thy = th1;
	ArrayXXd th = (thy*Ky2).replicate(1, Ne);

	return a0 * (dcp(0, 1) * th).exp();
    }

    case 3 : {			/* phase rotation */
	double phi = th1;
	return a0 * exp(dcp(0, 1)*phi); // a0*e^{i\phi}
    }
	
    case 4 : {	  /* translation rotation in both x and y direction */
	double thx = th1;
	double thy = th2;
	ArrayXXd th = (thx*Kx2).replicate(1, Me).transpose() + (thy*Ky2).replicate(1, Ne);

	return a0 * (dcp(0, 1) * th).exp();
    }

    case 5 : {			/* both rotate */
	double thx = th1;
	double thy = th2;
	double phi = th3;
	ArrayXXd th = (thx*Kx2).replicate(1, Me).transpose() + (thy*Ky2).replicate(1, Ne) + phi;
	
	return a0 * (dcp(0, 1) * th).exp();
    }

    default :{
	fprintf(stderr, "indicate a valid rotate mode !\n");
    }
	
    }

}

ArrayXXcd CQCGL2d::tangent(const Ref<const ArrayXXcd> &a0, const int mode){
    switch (mode) {
    
    case 1 : {		      /* translation tangent in x direction */
	ArrayXXcd R = dcp(0, 1) * Kx2;
	return a0 * R.replicate(1, Me).transpose();
    }

    case 2 : {		      /* translation tangent in y direction */
	ArrayXXcd R = dcp(0, 1) * Ky2;
	return a0 * R.replicate(1, Ne);
    }

    case 3 : {			/* phase rotation tangent  */
	return a0 * dcp(0, 1);
    }
	
    default :{
	fprintf(stderr, "indicate a valid tangent mode !\n");
    }
	
    }
}

//====================================================================================================
// H5 related
//

std::tuple<ArrayXXcd, double, double, double, double>
CQCGL2d::readReq(const string fileName, const string groupName){
    H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";
	
    ArrayXXcd a(Me, Ne);
    a.real() = readMatrixXd(file, DS + "ar");
    a.imag() = readMatrixXd(file, DS + "ai");
    return make_tuple(a,
		      readScalar<double>(file, DS + "wthx"),
		      readScalar<double>(file, DS + "wthy"),
		      readScalar<double>(file, DS + "wphi"),
		      readScalar<double>(file, DS + "err")
		      );
}


#if 0 

/**
 * @brief rotate the state points in the full state space to the slice
 *
 * @param[in] aa       states in the full state space
 * @return    aaHat, theta, phi
 *
 * @note  g(theta, phi)(x+y) is different from gx+gy. There is no physical
 *        meaning to transform the sum/subtraction of two state points.
 */
std::tuple<ArrayXXd, ArrayXd, ArrayXd>
CQCGLgeneral::orbit2sliceWrap(const Ref<const ArrayXXd> &aa){
    int n = aa.rows();
    int m = aa.cols();
    assert(Ndim == n);
    ArrayXXd raa(n, m);
    ArrayXd th(m);
    ArrayXd phi(m);

    for(size_t i = 0; i < m; i++){
	double am1 = atan2(aa(n-1, i), aa(n-2, i));
	double a1 = atan2(aa(3, i), aa(2, i));
	phi(i) = 0.5 * (a1 + am1);
	th(i) = 0.5 * (a1 - am1);
	raa.col(i) = Rotate(aa.col(i), -th(i), -phi(i));
    }
    return std::make_tuple(raa, th, phi);
}

/**
 * @brief reduce the continous symmetries without wrapping the phase
 *        so there is no continuity
 * @see orbit2sliceWrap()
 */
std::tuple<ArrayXXd, ArrayXd, ArrayXd>
CQCGLgeneral::orbit2slice(const Ref<const ArrayXXd> &aa){
    int n = aa.rows();
    int m = aa.cols();
    assert(Ndim == n);
    ArrayXXd raa(n, m);
    ArrayXd th(m);
    ArrayXd phi(m);
    
    for(size_t i = 0; i < m; i++){
	double am1 = atan2(aa(n-1, i), aa(n-2, i));
	double a1 = atan2(aa(3, i), aa(2, i));
	phi(i) = 0.5 * (a1 + am1);
	th(i) = 0.5 * (a1 - am1);
    }

    const double M_2PI = 2 * M_PI;
    for(size_t i = 1; i < m; i++){
	double t0 = th(i) - th(i-1);
	double t1 = t0 - M_PI;
	double t2 = t0 + M_PI;
	double t0WrapAbs = fabs(remainder(t0, M_2PI));
	if(fabs(t1) < t0WrapAbs) { // theta jump pi up
	    th(i) = remainder(th(i) - M_PI, M_2PI);
	    phi(i) = remainder(phi(i) - M_PI, M_2PI);
	    continue;
	}
	if(fabs(t2) < t0WrapAbs) { // theta jump pi down
	    th(i) = remainder(th(i) + M_PI, M_2PI);
	    phi(i) = remainder(phi(i) + M_PI, M_2PI);
	}
    }
    
    for(size_t i = 0; i < m; i++){
	raa.col(i) = Rotate(aa.col(i), -th(i), -phi(i));
    }

    return std::make_tuple(raa, th, phi);
}

/**
 * @ simple version of orbit2slice(). Discard translation and phase information.
 */
ArrayXXd CQCGLgeneral::orbit2sliceSimple(const Ref<const ArrayXXd> &aa){
    auto tmp = orbit2slice(aa);
    return std::get<0>(tmp);
}


/** @brief project covariant vectors to 1st mode slice
 *
 * projection matrix is h = (I - |tx><tp|/<tx|tp>) * g(-th), so eigenvector |ve> is
 * projected to |ve> - |tx>*(<tp|ve>|/<tx|tp>), before which, g(-th) is 
 * performed.
 *
 * In 1th and -1st mode slice, template point is 
 * |xp_\rho>=(0, ...,1, 0) ==> |tp_\rho>=(0,0,0,...,0,1)
 * |xp_\tau>=(0,0,1,...,0) ==> |tp_\tau>=(0,0,0,1,...,0)
 * <tp_\rho|ve> = ve.bottomRows(1) // last row
 * <tp_\tau|ve> = ve.row(3) // 4th row
 *
 * @note vectors are not normalized
 */
MatrixXd CQCGLgeneral::ve2slice(const ArrayXXd &ve, const Ref<const ArrayXd> &x){
    int n = x.size();
    std::tuple<ArrayXXd, ArrayXd, ArrayXd> tmp = orbit2slice(x);
    ArrayXXd &xhat =  std::get<0>(tmp); // dimension [2*N, 1]
    double th = std::get<1>(tmp)[0];
    double phi = std::get<2>(tmp)[0];
    VectorXd tx_rho = phaseTangent(xhat);
    VectorXd tx_tau = transTangent(xhat);
	
    MatrixXd vep = Rotate(ve, -th, -phi);
    vep = vep - 0.5 * ((tx_rho - tx_tau) * vep.row(n-1) / xhat(n-2) +
		       (tx_rho + tx_tau) * vep.row(3) / xhat(2));
  
    return vep;

}

#endif
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "KSETD.hpp"
#include "ETDRK4.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
class pyKSETD : public KSETD {
public :
    pyKSETD(int N, double d) : KSETD(N, d) {}

    bp::tuple PYetd(bn::ndarray a0, double tend, double h, int skip_rate, 
		    int method, bool adapt){
	int m, n;
	getDims(a0, m, n);
	Map<VectorXd> tmpa0((double*)a0.get_data(), n * m);

	auto tmp = etd(tmpa0, tend, h, skip_rate, method, adapt);
	return bp::make_tuple(copy2bn(tmp.first), 
			      copy2bn(tmp.second)
			      );
    }

    bn::ndarray PYhs() {
	return copy2bn(etdrk4->hs);
    }
    
    bn::ndarray PYduu() {
	return copy2bn(etdrk4->duu);
    }

    bp::tuple PYetdParam(){
	return bp::make_tuple(etdrk4->NCalCoe,
			      etdrk4->NReject,
			      etdrk4->NCallF,
			      etdrk4->rtol
			      );
    }
    
    void PYsetRtol(double x){
	etdrk4->rtol = x;
    }

};


BOOST_PYTHON_MODULE(py_ks) {
    bn::initialize();    
    bp::class_<KSETD>("KSETD", bp::init<int, double>())
	;
    
    bp::class_<pyKSETD, bp::bases<KSETD> >("pyKSETD", bp::init<int, double>())
	.def_readonly("N", &pyKSETD::N)
	.def_readonly("d", &pyKSETD::d)
	.def("etdParam", &pyKSETD::PYetdParam)
	.def("setRtol", &pyKSETD::PYsetRtol)
	.def("etd", &pyKSETD::PYetd)
	.def("hs", &pyKSETD::PYhs)
	.def("duu", &pyKSETD::PYduu)
	; 
}
<file_sep>
logisticMap.py
==============

This file is copied from dasbuch/SOOC/Course2w12/hw12/logistMap_answer.py
<file_sep>#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <ctime>
#include <H5Cpp.h>
#include "myH5.hpp"
#include "denseRoutines.hpp"
#include "ksdim.hpp"
#include "ksint.hpp"

using namespace std;
using namespace Eigen;

/** @brief calculate angle between two subspaces along an upo
 *
 *  @param[in] fileName file that stores the ppo/rpo information
 *  @param[in] ppType ppo or rpo
 *  @param[in] ppId id of the periodic orbit
 *  @param[in] subspDim 4xM2  matrix storing the bounds of subspaces
 *  @return first matrix : each row stores the angles at one point
 *          second matrix: matrix indicating whether bounds are the
 *          same as specified
 *  @see subspBound
 */
std::pair<MatrixXd, MatrixXi> 
anglePO(const string fileName, const string ppType,
	const int ppId, const MatrixXi subspDim){
    assert(subspDim.rows() == 4);
    MatrixXd eigVals = MyH5::KSreadFE(fileName, ppType, ppId); // Floquet exponents
    MatrixXd eigVecs = MyH5::KSreadFV(fileName, ppType, ppId); // Floquet vectors
    // left and right bounds
    MatrixXi ixSp = denseRoutines::indexSubspace(eigVals.col(2), eigVals.col(0));
  
    const int N = eigVals.rows(); // be careful about N when FVs are not complete
    assert ( eigVecs.rows()  % N == 0);
    const int NFV = eigVecs.rows() / N;
    const int M = eigVecs.cols();
    const int M2 = subspDim.cols();
    MatrixXd ang_po(M, M2);
   
    // calculate the exact bound of this indices.
    std::pair<MatrixXi, MatrixXi> tmp = denseRoutines::subspBound(subspDim, ixSp);
    MatrixXi &bound = tmp.first;
    MatrixXi &boundStrict = tmp.second; 

    for(size_t i = 0; i < M; i++){
	MatrixXd ve = eigVecs.col(i);
	ve.resize(N, NFV);
	for(size_t j = 0; j < M2; j++){      
	    double ang = denseRoutines::angleSubspace(ve.middleCols(bound(0, j), bound(1,j)-bound(0,j)+1), 
						      ve.middleCols(bound(2, j), bound(3,j)-bound(2,j)+1) );
	    ang_po(i, j) = ang;
	}
    }
  
    return std::make_pair(ang_po, boundStrict);
}


/**
 * Test the tangency of tangent bundle.
 *
 * @param[in] N         number of FVs at each point 
 * @param[in] NN        number of periodic orbits
 * @param[in] spType    "vector" or "space"
 * @param[in] M         number of angles
 * @param[in] saveFolder folder name to save angles
 * @see anglePOs()
 */
void
anglePOs(const string fileName, const string ppType,
	 const int N, const int NN,
	 const string saveFolder,
	 const string spType, const int M)
{
    std::vector<int> ppIds(NN);
    for(int i = 0; i < NN; i++) ppIds[i] = i+1;
    anglePOs(fileName, ppType, N, ppIds, saveFolder, spType, M);
}


void
anglePOs(const string fileName, const string ppType,
	 const int N, const std::vector<int> ppIds,
	 const string saveFolder,
	 const string spType, const int M)
{
    ////////////////////////////////////////////////////////////
    // judge subspace or vector
    MatrixXi subspDim(4, M);
    if(spType.compare("vector") == 0)
	for (size_t i = 0; i < M; i++) subspDim.col(i) << i, i, i+1, i+1;
    else if(spType.compare("space") == 0)
	for (size_t i = 0; i < M; i++) subspDim.col(i) << 0, i, i+1, N-1;
    else {
	printf("invalid spType.\n");
    }
    ////////////////////////////////////////////////////////////
    
    //////////////////////////////////////////////////////////// 
    // create subfolders for each ppId
    for(size_t i = 0; i < ppIds.size(); i++){
	std::string tmp = saveFolder + '/' + to_string(ppIds[i]);
	int s = mkdir( tmp.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
	if(s != 0){
	    fprintf(stderr, "\n creating ppId folder fails. \n");
	    exit(-1);
	}
    }
    ////////////////////////////////////////////////////////////
    
    /////////////////////////////////////////////////////////////////	
    // get the index of POs which converge.
    MatrixXi status = MyH5::checkExistEV(fileName, ppType, ppIds); 
    for(size_t i = 0; i < ppIds.size(); i++){

	if( 1 == status(i,0) ){

	    int ppId = ppIds[i];	      
	    printf("========= i = %zd, ppId = %d ========\n", i, ppId);

	    // create files 
	    ofstream file[M];
	    string angName("ang");
	    for(size_t j = 0; j < M; j++){
		std::string tmp = saveFolder + '/' + to_string(ppId) + '/' + angName + to_string(j) + ".dat";
		file[j].open(tmp, ios::trunc);
		file[j].precision(16);
	    }
		
	    // calculation
	    
	    std::pair<MatrixXd, MatrixXi> tmp =
		anglePO(fileName, ppType, ppId, subspDim);
	    MatrixXd &ang = tmp.first;
	    MatrixXi &boundStrict = tmp.second;
	    cout << boundStrict << endl;
	    // check whether there are degeneracy
	    MatrixXi pro = boundStrict.row(0).array() *
		boundStrict.row(1).array() *
		boundStrict.row(2).array() *
		boundStrict.row(3).array();
	    for(size_t i = 0; i < M; i++){
		// only keep the orbits whose 4 bounds are not degenerate
		if(pro(0, i) == 1) file[i] << ang.col(i) << endl;
	    }
		
	    // close files
	    for(size_t i = 0; i < M; i++) file[i].close();
	}
    }
}


/**
 * Calucate local expansion rate of FVs along a periodic orbit
 *
 * @param[in] fileName   h5 file that stores the ppo/rpo
 * @param[in] ppType     'rpo' or 'ppo'
 * @param[in] ppId       index of po
 * @return               expansion rate. each column is the expansion rate
 *                       at a specific point along the orbit
 */
MatrixXd partialHyperb(const string fileName, const string ppType,
		       const int ppId)
{
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);
    MatrixXd eigVals = MyH5::KSreadFE(fileName, ppType, ppId); // Floquet exponents
    MatrixXd eigVecs = MyH5::KSreadFV(fileName, ppType, ppId); // Floquet vectors
    
    const int N = eigVals.rows(); // be careful about N when FVs are not complete
    assert ( eigVecs.rows()  % N == 0);
    const int NFV = eigVecs.rows() / N;
    const int M = eigVecs.cols();

    const int Nks = a.rows() + 2;
    const double L = 22;
    assert(nstp % M == 0);
    const int space = nstp / M;
    KS ks(Nks, T/nstp, L);
    auto tmp2 = ks.intgj(a.col(0), nstp, nstp, space);
    ArrayXXd &daa = tmp2.second;
    
    MatrixXd Jv(N, NFV*M); 
    for(size_t i = 0; i < M; i++){
	MatrixXd ve = eigVecs.col(i);
	ve.resize(N, NFV);
	MatrixXd J = daa.col(i); 
	J.resize(N, N);
	Jv.middleCols(i*NFV, NFV) = J * ve; 
    }

    MatrixXd expand(NFV, M);
    for(size_t i = 0; i < NFV; i++){
	if (eigVals(i, 2) == 0) { // real case 
	    for(int j = 0; j < M; j++){
		expand(i, j) = Jv.col(j*NFV+i).norm();
	    }
	}
	else {			// complex case
	    for(int j = 0; j < M; j++){
		double e1 = Jv.col(j*NFV+i).squaredNorm();
		double e2 = Jv.col(j*NFV+i+1).squaredNorm();
		expand(i, j) = sqrt(e1+e2);
		expand(i+1, j) = expand(i, j);
	    }
	    i++;
	}
    }

    return expand;
}

void partialHyperbOneType(const string fileName, const string ppType,
		      const int NN, const string saveFolder){
    ofstream file;
    for(size_t i = 0; i < NN; i++){
	int ppId = i + 1;
	file.open(saveFolder + "FVexpand" + to_string(ppId) + ".dat", ios::trunc);
	file.precision(16);
	printf("========= i = %zd ========\n", i);
	MatrixXd expand = partialHyperb( fileName,  ppType, ppId);
	file << expand << endl;
	file.close();
    }
}

void partialHyperbAll(const string fileName, const int NNppo, const int NNrpo,
		      const string saveFolder){
    partialHyperbOneType(fileName, "ppo", NNppo, saveFolder + "ppo/");
    partialHyperbOneType(fileName, "rpo", NNrpo, saveFolder + "rpo/");
}


/** @brief calculate the local Floquet exponents by stability matrix 
 *
 */
MatrixXd
localFE(const std::string fileName, const std::string ppType, const int ppId){
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);
    MatrixXd eigVals = MyH5::KSreadFE(fileName, ppType, ppId); // Floquet exponents
    MatrixXd eigVecs = MyH5::KSreadFV(fileName, ppType, ppId); // Floquet vectors

    const int N = eigVals.rows();
    assert ( eigVecs.rows()  % N == 0);
    const int NFV = eigVecs.rows() / N;
    const int M = eigVecs.cols();

    const int Nks = a.rows() + 2;
    const double L = 22;
    assert(nstp % M == 0);
    const int space = nstp / M;
    KS ks(Nks, T/nstp, L);
    ArrayXXd aa = ks.intg(a.col(0), nstp, space);
    
    MatrixXd expand(NFV, M);
    for(size_t i = 0; i < M; i++){ 
	MatrixXd ve = eigVecs.col(i);
	ve.resize(N, NFV); 
	MatrixXd A = ks.stab(aa.col(i)); 
	for(int j = 0; j < NFV; j++){ 
	    expand(j, i) = ve.col(j).transpose() * A * ve.col(j);
	}
    }

    for(int i = 0; i < NFV; i++){
	if(eigVals(i, 2) == 1) { // complex case
	    VectorXd tmp = expand.row(i) + expand.row(i+1);
	    expand.row(i) = tmp;
	    expand.row(i+1) = tmp;
	    i++;
	}
    }
    
    return expand;
}

void localFEOneType(const string fileName, const string ppType,
		    const int NN, const string saveFolder){
    ofstream file;
    for(size_t i = 0; i < NN; i++){
	int ppId = i + 1;
	file.open(saveFolder + "FVexpand" + to_string(ppId) + ".dat", ios::trunc);
	file.precision(16);
	printf("========= i = %zd ========\n", i);
	MatrixXd expand = localFE( fileName,  ppType, ppId);
	file << expand << endl;
	file.close();
    }
}

void localFEAll(const string fileName, const int NNppo, const int NNrpo,
		const string saveFolder){
    localFEOneType(fileName, "ppo", NNppo, saveFolder + "ppo/");
    localFEOneType(fileName, "rpo", NNrpo, saveFolder + "rpo/");
}

/*
void expandDifvAngle(const string fileName, const string ppType,
		     const int ppId, const int gTpos,
		     const MatrixXd difv, const VectorXi indexPO){
    int num = difv.cols();
    int N = difv.rows();
    assert(num == indexPO.size());
    
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);
    MatrixXd eigVecs = MyH5::KSreadFV(fileName, ppType, ppId); // Floquet vectors
    
    assert ( eigVecs.rows()  % N == 0);
    const int NFV = eigVecs.rows() / N;
    const int M = eigVecs.cols();    
    const int Nks = a.rows() + 2;
    const double L = 22;
    assert(nstp % M == 0);
    const int space = nstp / M;
    KS ks(Nks, T/nstp, L);
    ArrayXXd aa = ks.intg(a.col(0), nstp, space);

    if(ppType.compare("ppo") == 0) {
	aaWhole = ks.half2whole(aa.leftCols(aa.cols()-1));
	eigVecsWhole = ks.half2whole(eigVecs); // this is correct. Think carefully.
    } else {
	aaWhole = aa.leftCols(aa.cols()-1); // one less
	eigVecsWhole = eigVecs;
    }

    MatrixXd veSlice = ks.veToSliceAll(eigVecsWhole, aaWhole, NFV);
    MatrixXd ve_trunc = veTrunc(veSlice, gTpos, Trunc);
    
    
}
*/
<file_sep>/** \mainpage trail the fftw routines for my purpose 
 *
 *  \section sec_intro Introduction
 *
 *  \section sec_use usage
 *  Example:
 *  \code
 *  g++ yourfile.cc -I/path/to/fft.hpp -I/path/to/eigen -std=c++0x
 *  \endcode
 *
 *  \note Also use shared_ptr of FFT, not define it directly.
 */

#ifndef FFT_H
#define FFT_H

#include <fftw3.h>
#include <complex>
#include <Eigen/Dense>

namespace MyFFT {

    extern long NumOfInstance;
    
    //////////////////////////////////////////////////////////////////////////////////////////
    //                                     FFT                                              //
    //////////////////////////////////////////////////////////////////////////////////////////
    /** @brief Structure for convenience of fft.   */  
    class FFT {
    
    protected:
	fftw_plan p, rp; // plan for fft/ifft.
	fftw_complex *c1, *c2, *c3; // c1 = v, c2 = ifft(v), c3 = fft(c2)
    
    public:
    
	typedef std::complex<double> dcp;
	
	int N;
	int M;
	bool hasInit = false;
	
	Eigen::Map<Eigen::ArrayXXcd> v1, v2, v3; // mapping for c1, c2, c3 respectively
	
	//////////////////////////////////////////////////////////////////////
	// member functions	
	FFT(const int N, const int M);
	FFT();
	~FFT();
	void init(const int N, const int M);

	void fft();
	void ifft();
	
    };
    
    //////////////////////////////////////////////////////////////////////////////////////////
    //                                    RFFT                                              //
    //////////////////////////////////////////////////////////////////////////////////////////
    class RFFT {

    public:
	typedef std::complex<double> dcp;
	
	const int N;
	const int M;
	const int threadNum;
	
	Eigen::Map<Eigen::ArrayXXd> vr2;
	Eigen::Map<Eigen::ArrayXXcd> vc1, vc3;
	
	fftw_plan p, rp;
	fftw_complex *c1, *c3;
	double *r2;
	
	////////////////////////////////////////////////////////////
	RFFT(const int N, const int M, const int threadNum = 4);
	~RFFT();

	void fft();
	void ifft();

    };

    //////////////////////////////////////////////////////////////////////////////////////////
    //                                     FFT2d                                            //
    //////////////////////////////////////////////////////////////////////////////////////////
    class FFT2d {
    
    public:
	typedef std::complex<double> dcp;

	const int N;
	const int M;
	const int threadNum;

	fftw_plan p, rp; // plan for fft/ifft.
	fftw_complex *c1, *c2, *c3; // c1 = v, c2 = ifft(v), c3 = fft(c2)
    
	Eigen::Map<Eigen::ArrayXXcd> v1, v2, v3; // mapping for c1, c2, c3 respectively

	//////////////////////////////////////////////////////////////////////
	// member functions                           

	FFT2d(const int N, const int M, const int threadNum = 4);
	~FFT2d();    
	void fft();    
	void ifft();    
	
    };
    

}



#endif	/* FFT_H */
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CQCGL1dSub.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class pyCQCGL1dSub : public CQCGL1dSub {
  
public:

    pyCQCGL1dSub(int N, double d,
		 double Mu, double Dr, double Di, double Br, double Bi, 
		 double Gr, double Gi, int dimTan):
	CQCGL1dSub(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}
    
    pyCQCGL1dSub(int N, double d,
		 double b, double c, double dr, double di,
		 int dimTan) :
	CQCGL1dSub(N, d, b, c, dr, di, dimTan) {}

    pyCQCGL1dSub(int N, double d,
		 double delta, double beta, double D, double epsilon,
		 double mu, double nu, int dimTan):
	CQCGL1dSub(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }

    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

    /* K */
    bn::ndarray PYK(){
	return copy2bn(K);
    }

    /* L */
    bn::ndarray PYL(){
	return copy2bnc(L);
    }

   /* wrap the integrator */
    bn::ndarray PYintgC(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intgC(tmpa, h, tend, skip_rate));
    }

    /* wrap the integrator with Jacobian */
    bp::tuple PYintgjC(bn::ndarray a0, double h, double tend, size_t skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	auto result = intgjC(tmpa, h, tend, skip_rate);
	return bp::make_tuple(copy2bn(result.first), copy2bn(result.second));
    }
    
    bn::ndarray PYintgvC(bn::ndarray a0, bn::ndarray v, double h, double tend){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	getDims(v, m, n);
	Map<ArrayXXd> tmpv((double*)v.get_data(), n, m);
	return copy2bn(intgvC(tmpa, tmpv, h, tend));
    }    

    bn::ndarray PYintg(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intg(tmpa, h, tend, skip_rate));
    }

    bp::tuple PYintgj(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	auto result = intgj(tmpa, h, tend, skip_rate);
	return bp::make_tuple(copy2bn(result.first), copy2bn(result.second));
    }

    bn::ndarray PYintgv(bn::ndarray a0, bn::ndarray v, double h, double tend){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	getDims(v, m, n);
	Map<ArrayXXd> tmpv((double*)v.get_data(), n, m);
	return copy2bn(intgv(tmpa, tmpv, h, tend));
    }

    /* wrap Fourier2Config */
    bn::ndarray PYFourier2Config(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bnc( Fourier2Config(tmpaa) );
    }

    /* wrap Config2Fourier */
    bn::ndarray PYConfig2Fourier(bn::ndarray AA){
	int m, n;
	getDims(AA, m, n);
	Map<ArrayXXcd> tmpAA((dcp*)AA.get_data(), n, m);
	return copy2bn( Config2Fourier(tmpAA) );
    }

    bn::ndarray PYcalQ(const bn::ndarray &aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(calQ(tmpaa));
    }
    
    bn::ndarray PYcalMoment(const bn::ndarray &aa, const int p){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(calMoment(tmpaa, p));
    }
    
    /* wrap the velocity */
    bn::ndarray PYvelocity(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(velocity(tmpa));
    }

    /* wrap velocityReq */
    bn::ndarray PYvelocityReq(bn::ndarray a0, double phi){
	int m, n;
	getDims(a0, m, n);	
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	ArrayXd tmpv = velocityReq(tmpa, phi);
	return copy2bn(tmpv);
    }

    /* stability matrix */
    bn::ndarray PYstab(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	return copy2bn(stab(tmpa));
    }

    /* stability matrix for relative equibrium */
    bn::ndarray PYstabReq(bn::ndarray a0, double phi){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	return copy2bn(stabReq(tmpa, phi));
    }

    /* phaseRotate */
    bn::ndarray PYphaseRotate(bn::ndarray aa, double phi){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( phaseRotate(tmpaa, phi) );
    }
    
    /* phaseTangent */
    bn::ndarray PYphaseTangent(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( phaseTangent(tmpaa) );
    }

};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_CQCGL1dSub) {
    bn::initialize();

    // must provide the constructor
    bp::class_<CQCGL1dSub>("CQCGL1dSub", bp::init<
			int, double, 
			double, double, double, double, 
			int>())
	;
    
    // the EIDc class
    bp::class_<EIDc>("EIDc", bp::init<>())
	.def_readonly("NCalCoe", &EIDc::NCalCoe)
	.def_readonly("NReject", &EIDc::NReject)
	.def_readonly("NCallF", &EIDc::NCallF)
	.def_readonly("NSteps", &EIDc::NSteps)
	.def_readonly("TotalTime", &EIDc::TotalTime)
	.def_readonly("CoefficientTime", &EIDc::CoefficientTime)
	.def_readwrite("rtol", &EIDc::rtol)
	;
    
    bp::class_<pyCQCGL1dSub, bp::bases<CQCGL1dSub> >("pyCQCGL1dSub", bp::init<
					       int, double, 
					       double, double, double, double,
					       int >())
	.def(bp::init<int, double, double, double, double, double, double, 
	     double, double, int>())
	.def(bp::init<int, double, double, double, double, double,
	     double, double, int>())
	.def_readonly("N", &pyCQCGL1dSub::N)
	.def_readonly("d", &pyCQCGL1dSub::d)
	.def_readwrite("IsQintic", &pyCQCGL1dSub::IsQintic)
	.def_readonly("Mu", &pyCQCGL1dSub::Mu)
	.def_readwrite("Br", &pyCQCGL1dSub::Br)
	.def_readwrite("Bi", &pyCQCGL1dSub::Bi)
	.def_readonly("Dr", &pyCQCGL1dSub::Dr)
	.def_readonly("Di", &pyCQCGL1dSub::Di)
	.def_readwrite("Gr", &pyCQCGL1dSub::Gr)
	.def_readwrite("Gi", &pyCQCGL1dSub::Gi)
	.def_readonly("Ndim", &pyCQCGL1dSub::Ndim)
	.def_readonly("Ne", &pyCQCGL1dSub::Ne)
	.def_readonly("Omega", &pyCQCGL1dSub::Omega)
	.def_readwrite("eidc", &pyCQCGL1dSub::eidc)
	.def_readwrite("eidc2", &pyCQCGL1dSub::eidc2)
	.def("Ts", &pyCQCGL1dSub::PYTs)
	.def("hs", &pyCQCGL1dSub::PYhs)
	.def("lte", &pyCQCGL1dSub::PYlte)
	.def("K", &pyCQCGL1dSub::PYK)
	.def("L", &pyCQCGL1dSub::PYL)
	
	.def("changeOmega", &pyCQCGL1dSub::changeOmega)
	.def("intgC", &pyCQCGL1dSub::PYintgC)
	.def("intgjC", &pyCQCGL1dSub::PYintgjC)
	.def("intgvC", &pyCQCGL1dSub::PYintgv)
	.def("intg", &pyCQCGL1dSub::PYintg)
	.def("intgj", &pyCQCGL1dSub::PYintgj)
	.def("intgv", &pyCQCGL1dSub::PYintgv)
	.def("Fourier2Config", &pyCQCGL1dSub::PYFourier2Config)
	.def("Config2Fourier", &pyCQCGL1dSub::PYConfig2Fourier)
	.def("calQ", &pyCQCGL1dSub::PYcalQ)
	.def("calMoment", &pyCQCGL1dSub::PYcalMoment)
	.def("velocity", &pyCQCGL1dSub::PYvelocity)
	.def("velocityReq", &pyCQCGL1dSub::PYvelocityReq)
	.def("stab", &pyCQCGL1dSub::PYstab)
	.def("stabReq", &pyCQCGL1dSub::PYstabReq)
	.def("phaseRotate", &pyCQCGL1dSub::PYphaseRotate)
	.def("phaseTangent", &pyCQCGL1dSub::PYphaseTangent)
	;
}
<file_sep>/* to comiple:
 * first use
 * mpicxx --showme -O3 test_CQCGL1dReq_mpi.cc  -L../../lib -I../../include -I$EIGEN -std=c++11 -lCQCGL1dReq -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm
 * to get the actual linkages. Then change g++ to h5c++
 *
 * h5c++ -O3 test_CQCGL1dReq_mpi.cc -L../../lib -I../../include -I/usr/local/home/xiong/apps/eigen/include/eigen3 -std=c++11 -lCQCGL1dReq -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lmyfft -lfftw3 -lm -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -L/usr//lib -L/usr/lib/openmpi/lib -lmpi_cxx -lmpi -ldl -lhwloc 
 *
 * execute : mpiexec -np 4 ./a.out
 */
#include "CQCGL1dReq.hpp"
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <H5Cpp.h>
#include <mpi.h>

using namespace std;
using namespace Eigen;
using namespace denseRoutines;

typedef std::complex<double> dcp;


#define N30

int main(int argc, char **argv){

#ifdef N10
    //======================================================================
    // extend the soliton solution in the Bi-Gi plane
    iterMethod::LM_OUT_PRINT = false;
    iterMethod::LM_IN_PRINT = false;
    iterMethod::CG_PRINT = false;

    const int N = 1024;
    const int L = 50;
    double Bi = 3.4;
    double Gi = -5.6;

    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    string fileName = "../../data/cgl/reqBiGi";

    double stepB = 0.1;
    int NsB = 24;

    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = NsB / num;
    int rem = NsB - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////
    H5File file(fileName + "_" + to_string(rank) + ".h5", H5F_ACC_RDWR);

    int ids[] = {1, 2};
    for (int i = 0; i < 2; i++){	
	int id = ids[i];
	// cgl.findReqParaSeq(file, id, stepB, NsB, true);
	for (int i = p_start; i < p_end; i++){
	    cgl.Bi = Bi+i*stepB;
	    cgl.findReqParaSeq(file, id, 0.1, 53, false);
	}
    }
    
    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////

#endif
#ifdef N20
    //======================================================================
    // try to calculate the eigenvalue and eigenvector
    const int N = 1024;
    const int L = 50;
    double Bi = 5.7;
    double Gi = -5.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    
    // string file = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGiEV.h5";
    string fileName = "../../data/cgl/reqBiGiEV_add_";
    ArrayXd a0;
    double wth0, wphi0, err0;

    VectorXcd e;
    MatrixXcd v;
    
    std::vector<double> Bis, Gis;
    for(int i = 0; i < 55; i++) Gis.push_back(Gi+0.1*i);
    
    int NsB = 23;
    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = NsB / num;
    int rem = NsB - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    for (int i = p_start; i < p_end; i++) Bis.push_back(Bi-0.1*i);
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////
    
    H5File file(fileName + to_string(rank) + ".h5", H5F_ACC_RDWR);
    cgl.calEVParaSeq(file, std::vector<int>{1, 2}, Bis, Gis, true);

    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////

#endif
#ifdef N30
    //======================================================================
    // try to calculate the eigenvalue and eigenvector. Parallel for Gi.
    const int N = 1024;
    const int L = 50;
    double Bi = 3.6;
    double Gi = -5.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    
    // string file = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGiEV.h5";
    string fileName = "../../data/cgl/reqBiGiEV_add_";
    ArrayXd a0;
    double wth0, wphi0, err0;

    VectorXcd e;
    MatrixXcd v;
    
    std::vector<double> Bis, Gis;
    Bis.push_back(Bi);
    
    int NsG = 55;
    ////////////////////////////////////////////////////////////
    // mpi part 
    MPI_Init(&argc, &argv);
    int rank, num;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &num);
    int inc = NsG / num;
    int rem = NsG - inc * num;
    int p_size = inc + (rank < rem ? 1 : 0);
    int p_start = inc*rank + (rank < rem ? rank : rem);
    int p_end = p_start + p_size;
    for (int i = p_start; i < p_end; i++) Gis.push_back(Gi+0.1*i);
    fprintf(stderr, "MPI : %d / %d; range : %d - %d \n", rank, num, p_start, p_end);
    ////////////////////////////////////////////////////////////
    
    H5File file(fileName + to_string(rank) + ".h5", H5F_ACC_RDWR);
    cgl.calEVParaSeq(file, std::vector<int>{1, 2}, Bis, Gis, true);

    ////////////////////////////////////////////////////////////
    MPI_Finalize();
    ////////////////////////////////////////////////////////////

#endif
    
    return 0;
}
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' veToSlice.cc ../ksint.cc  -I../../../include -I$XDAPPS/eigen/include/eigen3 -lfftw3
 *
 * usage :
 * >> vep = veToSlice(ve, aa(:,i) );
 * */
#include "ksint.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <cassert>
#include <Eigen/Dense>

using namespace Eigen;

/* transform trajectory into 1st mode slice */
static MatrixXd
veToSlice(double *ve, double *x, const int N, const int M){
    KS ks(N+2);
    Map<MatrixXd> aa2(ve, N, M);
    Map<VectorXd> x2(x, N);
    return ks.veToSlice(aa2, x2);
}


void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    // get the pointer and the size of input 
    double *aa = mxGetPr(prhs[0]);
    double *x = mxGetPr(prhs[1]);
    mwSize N = mxGetM(prhs[0]);
    mwSize M = mxGetN(prhs[0]);
    mwSize N2 = mxGetM(prhs[1]);
    mwSize M2 = mxGetN(prhs[1]);
    assert(N == N2 && M2 = 1);
    
    plhs[0] = mxCreateDoubleMatrix(N, M, mxREAL);

    MatrixXd vep = veToSlice(aa, x, N, M);
    memcpy(mxGetPr(plhs[0]), &vep(0,0), N*M*sizeof(double));
}
<file_sep>/** \mainpage some frequently used dense matrix related routines 
 *
 *  \section sec_intro Introduction
 *  \section sec_use usage
 *  Example:
 *  \code
 *  g++ yourfile.cc /path/to/denseRoutines.cc -I/path/to/sparseRoutines.hpp -I/path/to/eigen -std=c++0x
 *  \endcode
 */

#ifndef DENSEROUTINES_H
#define DENSEROUTINES_H

#include <Eigen/Dense>
#include <vector>
#include <iostream>
#include <fstream>

namespace denseRoutines {

    using namespace std;
    using namespace Eigen;

    double angleSubspace(const Ref<const MatrixXd> &A,
			 const Ref<const MatrixXd> &B);
    double angleSpaceVector(const Ref<const MatrixXd> &Q,
			    const Ref<const VectorXd> &V);
   
    std::vector< std::pair<double, int> > 
    findMarginal(const Ref<const VectorXd> &Exponent,
		 const int k = 2 );
    MatrixXi 
    indexSubspace(const Ref<const VectorXd> &RCP, 
		  const Ref<const VectorXd> &Exponent);
    std::pair<MatrixXi, MatrixXi> 
    subspBound(const MatrixXi subspDim, const MatrixXi ixSp);

    void normc(MatrixXd &A);
    std::vector<int> csort(const VectorXcd &e, int flag);
    MatrixXcd
    vr2vc(const VectorXcd &e, const Ref<const MatrixXd> &v);
    MatrixXd 
    vc2vr(const Ref<const MatrixXcd> &v);
    VectorXcd eEig(const MatrixXd &A, int flag);
    MatrixXcd vEig(const MatrixXd &A, int flag);
    std::pair<VectorXcd, MatrixXcd> evEig(const MatrixXd &A, int flag);
    VectorXd centerRand(const int N, const double frac);
    MatrixXd realv(const MatrixXcd &v);
    MatrixXd orthAxes(const Ref<const MatrixXd> &v);
    MatrixXd orthAxes(const Ref<const VectorXd> &e1, 
		      const Ref<const VectorXd> &e2);
    MatrixXd orthAxes(const Ref<const VectorXd> &e1, 
		      const Ref<const VectorXd> &e2, 
		      const Ref<const VectorXd> &e3);
    VectorXd spacing(const Ref<const MatrixXd> &v);
    int minDisIndex(const Ref<const VectorXd> &a, 
		    const Ref<const MatrixXd> &v, double &minD);
    int minDisIndex(const Ref<const VectorXd> &a, 
		    const Ref<const MatrixXd> &v);
    std::pair<MatrixXd, MatrixXd>
    GS(const Ref<const MatrixXd> &A);
    MatrixXd
    GSsimple(const Ref<const MatrixXd> &A);

    std::pair<MatrixXd, MatrixXd>
    QR(const Ref<const MatrixXd> &A);
    MatrixXd
    randM(int M, int N);
    MatrixXcd 
    loadComplex(const std::string f1, const std::string f2);
    ArrayXXd 
    calPhase(const Ref<const ArrayXXcd> &AA);
    
    /////////////////////////// template or inline function implementation ////////////////////////////////////////////////////////////////////////////////////

    /** @brief save a matrix into a text file  */
    inline void savetxt(const std::string f, const Ref<const MatrixXd> &A){
	ofstream file(f, ios::trunc);
	file.precision(16);
	file << A << endl;
	file.close();
    }

    /** @brief read data from text file  */
    template<class T = double>
    Matrix<T, Dynamic, Dynamic>
    loadtxt(const std::string f){
	int cols = 0; 
	int rows = 0;
	std::vector<T> buff;
	buff.reserve(1000);
	
	ifstream infile(f);
	assert(!infile.fail());
	while (! infile.eof()) {
	    string line;
	    std::getline(infile, line); 
	
	    int temp_cols = 0;
	    stringstream stream(line); 
	    while(!stream.eof()){
		T x;
		stream >> x; 
		buff.push_back(x);
		temp_cols++;
	    }
	    if (rows == 0) cols = temp_cols;
	    else if (temp_cols != cols) break;

	    rows++;
	}
	infile.close();

	Matrix<T, Dynamic, Dynamic> result(rows, cols);
	for (int i = 0; i < rows; i++)
	    for (int j = 0; j < cols; j++)
		result(i, j) = buff[ cols*i+j];

	return result;
    }
    
    /* @brief create 2d centerized random variables */
    inline MatrixXcd
    center2d(const int M, const int N, const double f1, const double f2){
	MatrixXcd a(M, N);
	a.real() = MatrixXd::Random(M, N)*0.5+0.5*MatrixXd::Ones(M, N);
	a.imag() = MatrixXd::Random(M, N)*0.5+0.5*MatrixXd::Ones(M, N);
	int M2 = (int) (0.5 * M * (1-f1));
	int N2 = (int) (0.5 * N * (1-f2));
	a.topRows(M2) = MatrixXcd::Zero(M2, N);
	a.bottomRows(M2) = MatrixXcd::Zero(M2, N);
	a.leftCols(N2) = MatrixXcd::Zero(M, N2);
	a.rightCols(N2) = MatrixXcd::Zero(M, N2);

	return a;
    }
    
    /** @brief Gaussian profile
     *
     *  $f(x) = a exp(\frac{-(x-b)^2}{2 c^2})$
     */
    inline VectorXcd
    Gaussian(const int N, const int b, const double c, const double a = 1){
	ArrayXd dx = ArrayXd::LinSpaced(N, 0, N-1) - b;
	VectorXd f = (- dx.square() / (2*c*c)).exp() * a;
	return f.cast<std::complex<double>>();	
    }

    /** @brief 2d Gaussian profile
     *
     *  $f(x, y) = a exp(\frac{-(x-b_1)^2}{2 c_1^2} + \frac{-(y-b_2)^2}{2 c_2^2})$
     *  The rectangle size is [M x N] corresponding to y and x direction.
     */
    inline MatrixXcd
    Gaussian2d(const int M, const int N, const int b1, const int b2, const double c1, 
	       const double c2, const double a = 1){
	MatrixXd dx = (VectorXd::LinSpaced(N, 0, N-1)).replicate(1, M).transpose() - MatrixXd::Constant(M, N, b1);
	MatrixXd dy = (VectorXd::LinSpaced(M, 0, M-1)).replicate(1, N) - MatrixXd::Constant(M, N, b2);
	
	MatrixXd d = dx.array().square() / (2*c1*c1) + dy.array().square() / (2*c2*c2);
	MatrixXd f = (-d).array().exp() * a;
	return f.cast<std::complex<double>>();	
    }

    inline MatrixXcd
    soliton(const int M, const int N, const int x, const int y, const double a, const double b){
	
	MatrixXd dx = (VectorXd::LinSpaced(M, 0, M-1)).replicate(1, N) - MatrixXd::Constant(M, N, x);
	MatrixXd dy = (VectorXd::LinSpaced(N, 0, N-1)).replicate(1, M).transpose() - MatrixXd::Constant(M, N, y);
	MatrixXd d = (dx.array() / M / a).square() + (dy.array() / N / b).square();
	
	return (-d).array().exp().cast<std::complex<double>>();
    }

    inline MatrixXcd
    solitons(const int M, const int N, const VectorXd xs, const VectorXd ys,
	     const VectorXd as, const VectorXd bs){
	int n = xs.size();
	MatrixXcd A(MatrixXcd::Zero(M, N));
	for (int i = 0; i < n; i++){
	    A += soliton(M, N, xs(i), ys(i), as(i), bs(i));
	}
	return A;
    }
    
    inline MatrixXcd
    solitonMesh(const int M, const int N, const int nx, const int ny, const double a){
	MatrixXd px = (VectorXd::LinSpaced(nx, M/nx/2, M-1-M/nx/2)).replicate(1, ny);
	MatrixXd py = (VectorXd::LinSpaced(ny, N/ny/2, N-1-N/ny/2)).replicate(1, nx).transpose();
	
	px.resize(nx*ny, 1);
	py.resize(nx*ny, 1);
	
	VectorXd as = VectorXd::Constant(nx*ny, a);

	return solitons(M, N, px, py, as, as);
    }
	
    /** create a matrix with designed eigenvalues.
     *  A V = V E
     */
    inline MatrixXd matE(const VectorXd &e){
	int n = e.size();
	MatrixXd V(MatrixXd::Random(n, n));
	return V * e.asDiagonal() * V.inverse();
    }
    
}

#endif	// DENSEROUTINES_H

<file_sep>from cglHelp import *
from matplotlib import rc
rc('font',**{'family':'serif','serif':['Times']})  # I love Times
rc('text', usetex=True)
import matplotlib.gridspec as gridspec

case = 240

if case == 15:
    """
    same as case 10, bu plot contourf plot
    Note: the problem of contourf() is that whenever there is a jump
    in the levels, say from lv1 to lv2 but lv2 = lv1 + 2, then it will
    interpolate these two levels, thus a line for lv1 + 1 is plotted
    between these two regions.
    I need to draw each region indivisually. 
    """
    saveData = np.loadtxt("BiGiReqStab.dat")
    BiRange = [-3.2, 3.5]
    GiRange = [-5.6, -0.5]
    inc = 0.1

    nx = np.int(np.rint( (BiRange[1] - BiRange[0])/inc ) + 1)
    ny = np.int(np.rint( (GiRange[1] - GiRange[0])/inc ) + 1)

    x = np.linspace(BiRange[0], BiRange[1], nx)
    y = np.linspace(GiRange[0], GiRange[1], ny)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros([ny, nx]) - 1  # initialized with -1

    for item in saveData:
        Gi, Bi, m = item
        idx = np.int(np.rint((Bi - BiRange[0]) / inc))
        idy = np.int(np.rint((Gi - GiRange[0]) / inc))
        if idx >= 0 and idx < nx and idy >= 0 and idy < ny:
            Z[idy, idx] = m if m < 8 else 8

    levels = [-1, 0, 2, 4, 6, 8]
    cs = ['w', 'm', 'c', 'grey', 'r', 'y']
    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30,
                   tickSize=25)
    for i in range(len(levels)):
        vfunc = np.vectorize(lambda t : 0 if t == levels[i] else 1)
        Z2 = vfunc(Z)
        ax.contourf(X, Y, Z2, levels=[-0.1, 0.9], colors=cs[i])

    # add zoom rectangle
    BiZoom = [1.9, 3.5]
    GiZoom = [-5.6, -4]
    ax.plot([BiZoom[0], BiZoom[0]], [GiZoom[0], GiZoom[1]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[1], BiZoom[1]], [GiZoom[0], GiZoom[1]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[0], BiZoom[1]], [GiZoom[0], GiZoom[0]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[0], BiZoom[1]], [GiZoom[1], GiZoom[1]], ls='--', lw=3, c='k')

    ax.text(0, -2, r'$S$', fontsize=30)
    ax.text(0, -4.5, r'$U_1$', fontsize=30)
    ax.text(1.8, -2.5, r'$U_2$', fontsize=30)
    ax.text(2., -4.8, r'$U_3$', fontsize=30)
    ax.text(2.7, -3, r'$U_{\geq 4}$', fontsize=30)
    #ax.scatter(2.0,-5, c='k', s=100, edgecolor='none')
    #ax.scatter(2.7,-5, c='k', s=100, edgecolor='none')
    ax.scatter(0.8, -0.6, c='k', s=100, edgecolor='none')
    ax.scatter(1.4,-3.9, c='k', marker='*', s=200, edgecolor='none')
    ax.set_xlim(BiRange)
    ax.set_ylim(GiRange)

    ax.set_xticks(range(-3, 4))
    ax2d(fig, ax)

if case == 60:
    """
    plot the stability table of the rpos
    """
    N, d = 1024, 50

    fileName = '../../data/cgl/rpoBiGiEV.h5'
    
    cs = {0: 'g'}#, 10: 'm', 2: 'c', 4: 'r', 6: 'b', 8: 'y'}#, 56: 'r', 14: 'grey'}
    ms = {0: 's'}#, 10: '^', 2: '+', 4: 'o', 6: 'D', 8: 'v'}#, 56: '4', 14: 'v'}

    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30, tickSize=25,
                   ylim=[-5.65, -3.95], xlim=[1.8, 5.8])
    for i in range(39):
        Bi = 1.9 + i*0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            rpo = CQCGLrpo()
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1) + '/er'):
                x, T, nstp, th, phi, err, e, v = rpo.read(fileName, rpo.toStr(Bi, Gi, 1), flag=2)
                m, ep, accu = numStab(e, nmarg=3, tol=1e-4, flag=1)
                ax.scatter(Bi, Gi, s=60, edgecolors='none',
                           marker=ms.get(m, 'o'), c=cs.get(m, 'r'))

    # add zoom rectangle
    BiZoom = [1.9, 3.5]
    GiZoom = [-5.6, -4]
    ax.plot([BiZoom[1], BiZoom[1]], [GiZoom[0], GiZoom[1]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[0], BiZoom[0]], [GiZoom[0], GiZoom[1]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[0], BiZoom[1]], [GiZoom[0], GiZoom[0]], ls='--', lw=3, c='k')
    ax.plot([BiZoom[0], BiZoom[1]], [GiZoom[1], GiZoom[1]], ls='--', lw=3, c='k')
    # ax.plot([BiZoom[0], BiZoom[1]], [GiZoom[1], GiZoom[1]], ls='--', lw=3, c='k')

    #ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.yaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.grid(which='major', linewidth=2)
    #ax.grid(which='minor', linewidth=1)
    ax.scatter(4.6, -5.0, c='k', s=200, edgecolor='none')
    ax.scatter(4.8, -4.5, c='k', marker='*', s=400, edgecolor='none')

    ax.set_yticks([-4, -4.5, -5, -5.5])
    ax.set_xticks(np.arange(2, 6, 0.5))
    ax2d(fig, ax)


if case == 90:
    """
    plot the two coexisting soltions for the same paramter in the same figure
    load saved data
    """
    N, d = 1024, 50
    
    fig, ax = pl2d(size=[8, 6], labs=[r'$x$', r'$|A|$'], axisLabelSize=30, tickSize=25)
    Bi, Gi = 0.8, -0.6
    
    profiles = np.load('solitonProfileFor08n06.npz')
    absA1, absA2 = profiles['absA1'], profiles['absA2']
    ax.plot(np.linspace(0, d, absA1.shape[0]), absA1, lw=2, ls='-', c='r')
    ax.plot(np.linspace(0, d, absA2.shape[0]), absA2, lw=2, ls='--', c='b')
    
    ax2d(fig, ax)

if case == 76:
    """
    plot one Hopf bifurcation using save data
    subplot (a) : heat map of the limit cycle
    subplot (b) : symmetry-reduced state space figure
    """
    N, d = 1024, 50
    data = np.load('hopfCycleAndWuOfReq.npz')
    hopfCycleProfiles4Periods, T, aaP, aapP = data['hopfCycleProfiles4Periods'], data['T'], data['aaP'], data['aapP']

    # plot figure 
    fig = plt.figure(figsize=[8, 4])
    nx, ny = 8, 4
    gs = gridspec.GridSpec(nx, ny)
    
    ax = fig.add_subplot(gs[:nx-1, 0])
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='white')
    ax.set_xlabel(r'$x$', fontsize=25)
    ax.set_ylabel(r'$t$', fontsize=25)
    ax.set_xticks(range(0, 60, 10))
    ax.set_yticks(range(0, 16, 3))
    ax.tick_params(axis='both', which='major', labelsize=15)
    im = ax.imshow(hopfCycleProfiles4Periods, cmap=plt.get_cmap('jet'), extent=[0, d, 0, 4*T], 
                   aspect='auto', origin='lower')
    # ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    cb = plt.colorbar(im, cax=cax, ticks=np.arange(0, 2, 0.4))
    cb.ax.tick_params(labelsize=15)
    
    ax = fig.add_subplot(gs[:, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(b)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18)
    ax.set_xlabel(r'$v_1$', fontsize=25)
    ax.set_ylabel(r'$v_2$', fontsize=25)
    ax.set_zlabel(r'$v_3$', fontsize=25)
    # ax.set_xlim([-20, 20])
    # ax.set_ylim([0, 250])
    # ax.set_zlim([-30, 30])
    ax.tick_params(axis='both', which='major', labelsize=15)
    ax.locator_params(nbins=4)
    # ax.scatter(a0H[], a0H[4], a0H[5], c='r', s=40)
    # ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)
    # ax.plot(aapH[:, -1], aapH[:, 4], aapH[:, 5], c='r', lw=2)
    ax.scatter(0, 0, 0, c='r', s=40)
    ax.plot(aaP[:, 0], aaP[:, 1], aaP[:, 2], c='b', lw=1, alpha=0.7)
    ax.plot(aapP[:, 0], aapP[:, 1], aapP[:, 2], c='r', lw=2)

    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 150:
    """
    plot the example explosions using loaded data
    """
    N, d = 1024, 50
    data = np.load('explosionExample08n06.npz')
    Aamp1 = data['AampSymmetric']
    T1 = data['Tsymmetric']
    Aamp2 = data['AampAsymmetric']
    T2 = data['Tasymmetric']
    
    # plot the figure
    fig = plt.figure(figsize=[8, 5])    

    ax = fig.add_subplot(121)
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=30, color='white')
    ax.set_xlabel(r'$x$', fontsize=30)
    ax.set_ylabel(r'$t$', fontsize=30)
    ax.set_xticks(range(0, 60, 10))
    ax.set_yticks(range(0, 12, 2))
    ax.tick_params(axis='both', which='major', labelsize=20)
    im = ax.imshow(Aamp1, cmap=plt.get_cmap('jet'), extent=[0, d, 0, T1], 
                   aspect='auto', origin='lower')
    # ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    cb = plt.colorbar(im, cax=cax, ticks=np.arange(0, 4, 1))
    cb.ax.tick_params(labelsize=20)


    ax = fig.add_subplot(122)
    ax.text(0.1, 0.9, '(b)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=30, color='white')
    ax.set_xlabel(r'$x$', fontsize=30)
    ax.set_ylabel(r'$t$', fontsize=30)
    ax.set_xticks(range(0, 60, 10))
    ax.set_yticks(range(0, 12, 2))
    ax.tick_params(axis='both', which='major', labelsize=20)
    im = ax.imshow(Aamp2, cmap=plt.get_cmap('jet'), extent=[0, d, 0, T2], 
                   aspect='auto', origin='lower')
    # ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    cb = plt.colorbar(im, cax=cax, ticks=np.arange(0, 4, 1))
    cb.ax.tick_params(labelsize=20)

    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 200:
    """
    print out the eigen exponents of Hopt RPO
    """
    Bi, Gi = 1.4, -3.9
    rpo = CQCGLrpo()
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoHopfBiGi.h5', rpo.toStr(Bi, Gi, 1), flag=2)
    mu = np.log(np.abs(e)) / T
    theta = np.arctan2(e.imag, e.real)
    
if case == 220:
    """
    print out the eigen exponents of rpos
    """
    rpo = CQCGLrpo()
    Bi, Gi = (4.6, -5.0) if False else (4.8, -4.5)
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5', rpo.toStr(Bi, Gi, 1), flag=2)
    mu = np.log(np.abs(e)) / T
    theta = np.arctan2(e.imag, e.real)

if case == 240:
    """
    plot the stability exponent diagram
    """
    req = CQCGLreq()
    Bi, Gi = 0.8, -0.6
    
    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=2)
    def Lam(k):
        return -0.1 - (0.125 + 0.5j) * (2*np.pi/50 * k)**2
    # Lam = lambda k : -0.1 - (0.125 + 0.5j) * (2*np.pi/50 * k)**2
    
    M = (e.shape[0] - 2 ) / 4
    x = [0, 0]
    for i in range(1, M+1):
        x = x + [i]*4
    x = np.array(x)

    e_thresh = 180
    eip = -np.abs(e.imag)
    eip[:e_thresh] *= -1

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111)
    ax.tick_params(axis='x', which='major', labelsize=22)
    ax.set_xlabel(r'$k$', fontsize=30)
    ax.tick_params(axis='y', which='major', colors='r', labelsize=22)
    ax.set_ylabel(r'$\mu^{(j)}$', color='r', fontsize=30)

    ax.scatter(x, e.real, s=10, facecolors='none', edgecolors='r')
    ax.plot(x, Lam(x).real, c='y', ls='--', lw=2)
    ax.set_ylim([-250, 50])

    ax2 = ax.twinx()
    ax2.tick_params(axis='y', which='major', colors='b', labelsize=22)
    ax2.set_ylabel(r'$\omega^{(j)}$', color='b', fontsize=30)

    ax2.scatter(x, eip, s=10, facecolors='none', edgecolors='b')
    ax2.plot(x, Lam(x).imag, c='k', ls='--', lw=2)
    ax2.set_ylim([-1200, 50])

    # Plot insert
    x = x[:200]
    e = e[:200]
    eip = eip[:200]
    axInsert = plt.axes([.23, .25, .32, .32])
    axInsert.tick_params(axis='x', which='major', labelsize=18)
    axInsert.set_xlabel(r'$k$', fontsize=25)
    axInsert.tick_params(axis='y', which='major', colors='r', labelsize=18)

    axInsert.scatter(x, e.real, s=10, facecolors='none', edgecolors='r')
    axInsert.plot(x, Lam(x).real, c='y', ls='--', lw=3)

    axInsert2 = axInsert.twinx()
    axInsert2.tick_params(axis='y', which='major', colors='b', labelsize=18)

    axInsert2.scatter(x, eip, s=10, facecolors='none', edgecolors='b')
    axInsert2.plot(x, Lam(x).imag, c='k', ls='--', lw=3)
    axInsert2.set_ylim([-30, 20])

    # END
    ax2d(fig, ax)
    
    # fig, ax = pl2d(size=[8, 6], labs=[r'$j$', r'$\omega^{(j)}$'], axisLabelSize=30, tickSize=25)
    # ax.scatter(x, np.abs(e.imag), c='r', s=10)
    # #ax.plot(x, np.abs(e.imag))
    # ax.plot(x, np.abs(Lam(x).imag), c='b', ls='--', lw=2)
    # ax2d(fig, ax)


if case == 250:
    """
    test of case 240
    """
    req = CQCGLreq()
    Bi, Gi = 0.8, -0.6
    
    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=2)
    def Lam(k):
        return -0.1 - (0.125 + 0.5j) * (2*np.pi/50 * k)**2
    
    M = (e.shape[0] - 2 ) / 4
    x = [0, 0]
    for i in range(1, M+1):
        x = x + [i]*4
    x = np.array(x)

    e_thresh = 180
    eip = -np.abs(e.imag)
    eip[:e_thresh] *= -1

    x = x[200:300]
    e = e[200:300]
    eip = eip[200:300]

    fig = plt.figure(figsize=[8, 6])
    ax = fig.add_subplot(111)
    ax.tick_params(axis='x', which='major', labelsize=25)
    ax.set_xlabel(r'$k$', fontsize=30)
    ax.tick_params(axis='y', which='major', colors='r', labelsize=25)
    ax.set_ylabel(r'$\mu^{(j)}$', color='r', fontsize=30)

    ax.scatter(x, e.real, s=10, facecolors='none', edgecolors='r')
    ax.plot(x, Lam(x).real, c='k', ls='--', lw=2)

    # ax2 = ax.twinx()
    # ax2.tick_params(axis='y', which='major', colors='b', labelsize=25)
    # ax2.set_ylabel(r'$\omega^{(j)}$', color='b', fontsize=30)

    # ax2.scatter(x, eip, s=10, facecolors='none', edgecolors='b')
    # ax2.plot(x, Lam(x).imag, c='k', ls='--', lw=2)
    # ax2.set_ylim([-1200, 50])

    # END
    ax2d(fig, ax)
<file_sep>#!/bin/bash

# usage:
# ./createAll 

DEST=/usr/local/home/xiong/00git/research/lib/boostPython/ 

rm -rf bin pylib
b2 && mv pylib/py_CQCGL1dEIDc.so $DEST  && rm -rf bin pylib


<file_sep>import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
from mpl_toolkits.mplot3d import Axes3D
from scipy.interpolate import interp1d;

fig=plt.figure(figsize=(8,5))
ax=fig.add_subplot(111)

pp = sio.loadmat('./ppo4/angAver.mat');
dis = pp['x'][:,0]; ang = pp['angleAverage'];
logDis = np.linspace(np.log10(dis[0]), np.log10(dis[-1]), 100)
Ncol = 9 # ang.shape[1];
cix =  [0, 1, 2, 3, 4, 6, 8, 9, 10]
spix = [3, 4, 5, 6, 7, 9, 13, 15, 21]
colors = ['b','g', 'm','c', 'r', 'DarkGreen', 'Brown', 'Purple', 'Navy']

##############################################
for i in range(Ncol):
    f = interp1d(np.log10(dis), np.log10(ang[:,cix[i]]))
    ax.plot(10**logDis, 10**(f(logDis)), c = colors[i], ls = '--' );
    ax.scatter(dis, ang[:,cix[i]], s=30,  c = colors[i],
               edgecolor='none', label='1-'+str(spix[i]))
    if i < 6:
        ax.text(dis[0]-0.0005, ang[0, cix[i]], str(spix[i]))
    else :
        ax.text(dis[7], ang[7, cix[i]], str(spix[i]))
    
ax.set_yscale('log')    
ax.set_xscale('log')
#ax.legend(loc='upper left')
#ax.set_title('(a)')
ax.set_ylabel(r'$< \sin(\theta) >$',size='large')
ax.set_xlabel(r'$||\Delta x||_2$',size='large')

fig.tight_layout(pad=0)
plt.show()
<file_sep># My research C++ code
This repository contains all my code for research at
[Center for Nonliear Science](http://www.cns.gatech.edu/)
at School of Physics in Georgia Institute of Technology.

It is mainly C++ code and a few Python/Matlab bindings. Large datasets are not committed.
## folder structure 
* **source**   C++ files and their Matlab/Python binding files
* **include**  header files
* **lib**      The shared/static library, compiled Matlab/Python binding library
* **PythonWrapper** The Boost.Python bindings for C++ classes
* **MatlabWrapper** The Matlab bindings for C++ functions

## Requirement
* G++ 4.7 above (supporting C++11)
* Eigen 3.1 or above
* FFTW3 library
* HDF5 

If you need build python binding, you also need
* [Boost.Python](http://www.boost.org/doc/libs/1_58_0/libs/python/doc/)
* [Boost.NumPy](https://github.com/ndarray/Boost.NumPy)

For Arpack++ support, you need
* [arpackpp](https://github.com/m-reuter/arpackpp)

<file_sep>from personalFunctions import *
from py_ks import *
from scipy.interpolate import interp1d
from personalPlotly import *
from ksInv22 import *


###############################################################################

if __name__ == '__main__':

    
    reqFile = '../../data/ks22Reqx64.h5'
    poFile = '../../data/ks22h001t120x64EV.h5'
    
    case = 40

    if case == 10:
        """
        view the unstable manifold of eq/req
        """
        inv = Inv(reqFile, poFile, 2, True, 3)
        nn = 30
        aas, dom, jumps = inv.Es[2].getMu(vId=0, nn=nn, T=120)
        ii = [3, 7, 11]
        E2, E3 = inv.Es[1].go, inv.Es[2].go
            
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        inv.plotRE(ax, ii)
        for i in range(nn):
            inv.plotFundOrbit(ax, aas[i], jumps[i], ii)
        # ax.plot(E2[:, ii[0]], E2[:, ii[1]], E2[:, ii[2]])
        ax.plot(E3[:, ii[0]], E3[:, ii[1]], E3[:, ii[2]])
        ax3d(fig, ax)

    if case == 20:
        """
        view the unstable manifold of a single eq/req and one po/rpo
        This is done in Fourier projection space
        """
        inv = Inv(reqFile, poFile, 2, True, 3, [], [1, 4])
        nn = 30
        aas, dom, jumps = inv.Es[1].getMu(vId=0, nn=nn, T=100)
        
        ii = [3, 7, 11]
        E2, E3 = inv.Es[1].go, inv.Es[2].go

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        inv.plotRE(ax, ii)
        for i in range(nn):
            inv.plotFundOrbit(ax, aas[i], jumps[i], ii)
        cs = ['r', 'b']
        for i in range(len(inv.rpos)):
            inv.plotFundOrbit(ax, inv.rpos[i].fdo, inv.rpos[i].jumps, ii,
                                c='k' if i > 0 else cs[i],
                                alpha=1, lw=1.5)
        #ax.plot(E2[:, ii[0]], E2[:, ii[1]], E2[:, ii[2]], c='c')
        ax.plot(E3[:, ii[0]], E3[:, ii[1]], E3[:, ii[2]], c='b')
        ax3d(fig, ax, angle=[50, 80])

    if case == 30:
        """
        same with 20 but to save figures
        """
        inv = Inv(reqFile, poFile, 2, True, 3, [], [])
        nn = 30
        aas, dom, jumps = inv.Es[1].getMu(vId=0, nn=nn, T=100)

        ii = [3, 7, 11]
        E2, E3 = inv.Es[1].go, inv.Es[2].go


        for k in range(2, 51):
            inv.rpoIds = [1, k]
            inv.loadPO()

            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
            inv.plotRE(ax, ii)
            for i in range(nn):
                inv.plotFundOrbit(ax, aas[i], jumps[i], ii)
            for i in range(len(inv.rpos)):
                inv.plotFundOrbit(ax, inv.rpos[i].fdo, inv.rpos[i].jumps, ii,
                                    c='k' if i > 0 else 'r',
                                    alpha=1, lw=1.5,
                                    label='rpo'+str(inv.rpoIds[i]))
            ax.plot(E3[:, ii[0]], E3[:, ii[1]], E3[:, ii[2]], c='b')
            ax3d(fig, ax, angle=[50, 80], save=True, name='rpo'+str(k)+'.png')

    if case == 40:
        """
        just try to have a look at the 3rd slice
        """
        inv = Inv(reqFile, poFile, 3, True, 2, [], [1, 3])
        nn = 30
        aas, dom, jumps = inv.Es[2].getMu(vId=0, nn=nn, T=120)
        
        ii = [1, 3, 5]
        E2, E3 = inv.Es[1].go, inv.Es[2].go
       
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        inv.plotRE(ax, ii)
        
        for i in range(nn):
            inv.plotFundOrbit(ax, aas[i], jumps[i], ii)

        cs = ['r', 'b']
        for i in range(len(inv.rpos)):
            inv.plotFundOrbit(ax, inv.rpos[i].fdo, inv.rpos[i].jumps, ii,
                              c='k' if i > 0 else cs[i],
                              alpha=1, lw=1.5,
                              label='rpo'+str(inv.rpoIds[i]))
        ax.plot(E2[:, ii[0]], E2[:, ii[1]], E2[:, ii[2]], c='c')
        #ax.plot(E3[:, ii[0]], E3[:, ii[1]], E3[:, ii[2]], c='b')
        ax3d(fig, ax, angle=[30, 120])

    if case == 50:
        """
        same with 40 but to save figures
        """
        inv = Inv(reqFile, poFile, 3, True, 2, [], [])
        nn = 30
        aas, dom, jumps = inv.Es[2].getMu(vId=0, nn=nn, T=120)

        ii = [1, 3, 5]
        E2, E3 = inv.Es[1].go, inv.Es[2].go

        for k in range(2, 51):
            inv.rpoIds = [1, k]
            inv.loadPO()

            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
            inv.plotRE(ax, ii)
            for i in range(nn):
                inv.plotFundOrbit(ax, aas[i], jumps[i], ii)
            for i in range(len(inv.rpos)):
                inv.plotFundOrbit(ax, inv.rpos[i].fdo, inv.rpos[i].jumps, ii,
                                    c='k' if i > 0 else 'r',
                                    alpha=1, lw=1.5,
                                    label='rpo'+str(inv.rpoIds[i]))
            ax.plot(E2[:, ii[0]], E2[:, ii[1]], E2[:, ii[2]], c='c')
            ax3d(fig, ax, angle=[30, 120], save=True, name='rpo'+str(k)+'.eps', picForm='eps')
        
        

    if case == 14:
        """
        save the symbolic dynamcis
        """
        data = np.load('PoPoincare.npz')
        ppo = data['ppo']
        rpo = data['rpo']

        po = rpo
        poName = 'rpo'

        for i in range(len(po)):
            x, y, z = po[i][:, 0], po[i][:, 1], po[i][:, 2]
            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
            ax.scatter(0, 0, 0, c='m', edgecolors='none', s=100, marker='^')
            for j in range(len(ppo)):
                p = ppo[j]
                ax.scatter(p[:, 0], p[:, 1], p[:, 2], c=[0, 0, 0, 0.2],
                           marker='o', s=10, edgecolors='none')
            for j in range(len(rpo)):
                p = rpo[j]
                ax.scatter(p[:, 0], p[:, 1], p[:, 2], c=[0, 0, 0, 0.2],
                           marker='o',
                           s=10, edgecolors='none')
            ax.scatter(x[::2], y[::2], z[::2], c='r', marker='o', s=40,
                       edgecolors='none')
            ax.scatter(x[1::2], y[1::2], z[1::2], c='b', marker='o', s=40,
                       edgecolors='none')
            for j in range(po[i].shape[0]):
                ax.text(x[j], y[j], z[j], str(j+1), fontsize=20, color='g')
                s = poName + str(i+1)
            # ax3d(fig, ax, angle=[20, -120], save=True, name=s+'.png', title=s)
            ax3d(fig, ax, angle=[30, 180], save=True, name=s+'.png', title=s)
            
    if case == 15:
        """
        visulaize the symmbolic dynamcis
        """
        data = np.load('PoPoincare.npz')
        borderPtsP = data['borderPtsP']
        pcN = data['pcN']
        ncN = data['ncN']
        M = len(borderPtsP)

        ii = [0, 1, 2]
        fig, ax = pl3d(size=[12, 10], labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        ax.scatter(0, 0, 0, c='k', s=70, edgecolors='none')
        for i in range(M):
            x, y, z = [borderPtsP[i][:, ii[0]], borderPtsP[i][:, ii[1]],
                       borderPtsP[i][:, ii[2]]]
            ax.scatter(x, y, z, c=[0, 0, 0, 0.2], marker='o', s=10,
                       edgecolors='none')
        ax3d(fig, ax)
        for i in range(100, 110):
            x, y, z = [borderPtsP[i][:, ii[0]], borderPtsP[i][:, ii[1]],
                       borderPtsP[i][:, ii[2]]]
            add3d(fig, ax, x, y, z, maxShow=20)

    if case == 16:
        """
        plot 3 cases together
        """
        trace = []
        trace.append(ptlyTrace3d([0], [0], [0], plotType=1, ms=7, mc='black'))
        
        ii = [0, 1, 2]
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        ax.scatter(0, 0, 0, c='k', s=70, edgecolors='none')
        if True:
            borderPtsP = np.load('ErgodicPoincare.npy')
            ax.scatter(borderPtsP[:, ii[0]], borderPtsP[:, ii[1]],
                       borderPtsP[:, ii[2]], c='r', s=20,
                       edgecolors='none')
            trace.append(ptlyTrace3d(borderPtsP[:, ii[0]],
                                     borderPtsP[:, ii[1]],
                                     borderPtsP[:, ii[2]],
                                     plotType=1, ms=2, mc='red'))
        if True:
            borderPtsP = np.load('E2Poincare.npy')
            M = borderPtsP.shape[0]
            for i in range(M):
                ax.scatter(borderPtsP[i][:, ii[0]], borderPtsP[i][:, ii[1]],
                           borderPtsP[i][:, ii[2]], c='b', marker='s',
                           s=20, edgecolors='none')
            for i in range(M):
                trace.append(ptlyTrace3d(borderPtsP[i][:, ii[0]],
                                         borderPtsP[i][:, ii[1]],
                                         borderPtsP[i][:, ii[2]],
                                         plotType=1, ms=2, mc='blue'))
        if True:
            borderPtsP = np.load('PoPoincare.npy')
            M = borderPtsP.shape[0]
            for i in range(M):
                ax.scatter(borderPtsP[i][:, ii[0]], borderPtsP[i][:, ii[1]],
                           borderPtsP[i][:, ii[2]], c='g', marker='o',
                           s=20, edgecolors='none')
            for i in range(M):
                trace.append(ptlyTrace3d(borderPtsP[i][:, ii[0]],
                                         borderPtsP[i][:, ii[1]],
                                         borderPtsP[i][:, ii[2]],
                                         plotType=1, ms=2, mc='green'))
        ax3d(fig, ax)
        
        if True:
            ptly3d(trace, 'mixPoincare', off=True,
                   labs=['$v_1$', '$v_2$', '$v_3$'])

    if case == 17:
        """
        use the poincare section b2=0 and b2 from negative to positive for
        unstable manifold of E2.
        Note, the unstable manifold lives in the invariant subspace,
        which is also the poincare section border.
        """
        nn = 50
        pos, poDom, poJumps = inv.getMuEq('e', eId=1, vId=0, p=1, nn=nn,
                                            T=100)
        M = len(pos)
        borderPts = []
        for i in range(M):
            borderPts.append(pos[i][::100, :])

        data = np.load('bases.npz')
        Ori = data['Ori']
        bases = data['bases']
        borderPtsP = []
        for i in range(M):
            p = (borderPts[i]-Ori).dot(bases.T)
            borderPtsP.append(p)
           
        ii = [0, 1, 2]
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        ax.scatter(0, 0, 0, c='k', s=70, edgecolors='none')
        for i in range(M):
            ax.scatter(borderPtsP[i][:, ii[0]], borderPtsP[i][:, ii[1]],
                       borderPtsP[i][:, ii[2]], c='b' if i < 50 else 'r',
                       marker='o' if i < 50 else 's',
                       s=20, edgecolors='none')
        ax3d(fig, ax)
        
        if False:
            trace = []
            trace.append(ptlyTrace3d(0, 0, 0, plotType=1, ms=7, mc='black'))
            for i in range(M):
                trace.append(ptlyTrace3d(borderPtsP[i][:, ii[0]],
                                         borderPtsP[i][:, ii[1]],
                                         borderPtsP[i][:, ii[2]],
                                         plotType=1, ms=2, mc='red'))
            ptly3d(trace, 'E2Poincare', labs=['$v_1$', '$v_2$', '$v_3$'])
        
        spt = pos
        ii = [1, 5, 3]
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        inv.plotRE(ax, ii)
        for i in range(nn):
            inv.plotFundOrbit(ax, spt[i], poJumps[i], ii)
        ax3d(fig, ax)

        # np.save('E2Poincare', borderPtsP)

    if case == 18:
        """
        use the poincare section b2=0 and b2 from negative to positive for
        ergodic trajectories
        """
        a0 = rand(N-2)
        aa = inv.ks.aintg(a0, 0.01, 100, 1)
        aa = inv.ks.aintg(aa[-1], 0.01, 6000, 1)
        raa, dids, ths = inv.ks.redO2f(aa, 1)
        jumps = getJumpPts(dids)

        borderIds, borderPts, pcN, ncN = inv.getPoinc(raa, dids, jumps)

        data = np.load('bases.npz')
        Ori = data['Ori']
        bases = data['bases']
        borderPtsP = (borderPts - Ori).dot(bases.T)

        ii = [0, 1, 2]
        x, y, z = [borderPtsP[:, ii[0]], borderPtsP[:, ii[1]],
                   borderPtsP[:, ii[2]]]
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        ax.scatter(0, 0, 0, c='k', s=70, edgecolors='none')
        ax.scatter(x, y, z, c='y', s=20, edgecolors='none')
        ax3d(fig, ax)
        add3d(fig, ax, x, y, z, maxShow=20)

        if False:
            trace = []
            trace.append(ptlyTrace3d(0, 0, 0, plotType=1, ms=7, mc='black'))
            trace.append(ptlyTrace3d(borderPtsP[:, ii[0]],
                                     borderPtsP[:, ii[1]],
                                     borderPtsP[:, ii[2]],
                                     plotType=1, ms=2, mc='red'))
            ptly3d(trace, 'ErgodicPoincare', labs=['$v_1$', '$v_2$', '$v_3$'])

        # np.save('ErgodicPoincare', borderPtsP)
        
    if case == 19:
        """
        use the poincare section b2=0 and b2 from negative to positive
        """
        inv.loadPO(1, ppoIds=range(1, 101), rpoIds=range(1, 101))
       
        # ptsId = inv.rpos[0].jumps[0]
        # Ori = inv.rpos[0].pp[0]
        # fe, fv, rfv, bases = inv.poFvPoinc('rpo', 1, ptsId, 1, [0, 3, 4],
        #                                      reflect=True)
        
        ptsId = inv.rpos[1].jumps[1]
        Ori = inv.rpos[1].pp[1]
        fe, fv, rfv, bases = inv.poFvPoinc('rpo', 2, ptsId, 1, [0, 1, 4],
                                             reflect=False)

        inv.poPoincProject(bases, Ori)

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        ax.scatter(0, 0, 0, c='k', s=70, edgecolors='none')
        for i in range(len(inv.ppos)):
            p = inv.ppos[i].ppp
            ax.scatter(p[:, 0], p[:, 1], p[:, 2], c='y', marker='o',
                       s=20, edgecolors='none')
        for i in range(len(inv.rpos)):
            p = inv.rpos[i].ppp
            ax.scatter(p[:, 0], p[:, 1], p[:, 2], c='y', marker='o',
                       s=20, edgecolors='none')
        ax3d(fig, ax)
        
        if True:
            trace = []
            trace.append(ptlyTrace3d([0], [0], [0], plotType=1, ms=7,
                                     mc='black'))
            for i in range(len(inv.ppos)):
                p = inv.ppos[i].ppp
                trace.append(ptlyTrace3d(p[:, 0], p[:, 1], p[:, 2],
                                         plotType=1, ms=2, mc='red',
                                         mt='circle'))
            for i in range(len(inv.rpos)):
                p = inv.rpos[i].ppp
                trace.append(ptlyTrace3d(p[:, 0], p[:, 1], p[:, 2],
                                         plotType=1, ms=2, mc='red',
                                         mt='circle'))
            ptly3d(trace, 'PoPoincare', labs=['$v_1$', '$v_2$', '$v_3$'])

        if False:
            ii = [2, 6, 4]
            # ii = [1, 5, 3]
            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
            for i in range(len(pos)):
                inv.plotFundOrbit(ax, pos[i], poJumps[i], ii, alpha=0.5)
                ax.scatter(borderPts[i][:, ii[0]], borderPts[i][:, ii[1]],
                           borderPts[i][:, ii[2]], c='k')
            ax3d(fig, ax)

        np.savez_compressed('bases', Ori=Ori, bases=bases)
        inv.savePoPoincProject()

    if case == 25:
        """
        view 2 shadowing orbits
        """
        poIds = [[1, 26], range(4, 4)]
        pos, poDom, poJumps = inv.loadPO('../../data/ks22h001t120x64EV.h5',
                                           poIds, 1)
        ii = [1, 3, 2]

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        for i in range(len(pos)):
            inv.plotFundOrbit(ax, pos[i], poJumps[i], ii,
                                c='k' if i > 0 else 'r',
                                alpha=1, lw=1.5)
        ax3d(fig, ax)
        
    if case == 200:
        """
        visualize the unstable manifold of eq and req together
        """
        nn = 10
        MuE, MuTw = inv.getMuAll(1, nn=nn)
        ii = [1, 3, 5]
        
        cs = ['r', 'b', 'c', 'k', 'y']
        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        inv.plotRE(ax, ii)
        for k in range(1, len(MuE)-3):
            for i in range(nn):
                inv.plotFundOrbit(ax, MuE[0][0][i], MuE[0][2][i],
                                    ii, c=cs[k])
        E2, E3 = inv.Eg['E2'], inv.Eg['E3']
        ax.plot(E2[:, ii[0]], E2[:, ii[1]], E2[:, ii[2]])
        ax.plot(E3[:, ii[0]], E3[:, ii[1]], E3[:, ii[2]])
        ax3d(fig, ax)

    if case == 400:
        """
        watch an ergodic trajectory after reducing O2 symmetry
        """
        N = 64
        d = 22
        ks = pyKS(N, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)

        a0 = rand(N-2) * 0.1
        aa = ks.aintg(a0, 0.001, 300, 1)
        raa, dids, ths = ks.redO2f(aa, 1)

        ii = [1, 2, 3]

        doProj = False
        if doProj:
            pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])
            paas = raa.dot(bases.T)

            reqr = reqr.dot(bases.T)
            eqr = eqr.dot(bases.T)
            paas -= eqr[1]
            reqr -= eqr[1]
            eqr -= eqr[1]

            ii = [0, 1, 2]

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        plotRE(ax, reqr, eqr, ii)
        if doProj:
            ax.plot(paas[:, ii[0]], paas[:, ii[1]],
                    paas[:, ii[2]], alpha=0.5)
        else:
            ax.plot(raa[:, ii[0]], raa[:, ii[1]], raa[:, ii[2]],
                    alpha=0.5)
        ax3d(fig, ax)

        doMovie = False
        if doMovie:
            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'],
                           xlim=[-1, 0.4], ylim=[-0.6, 0.6], zlim=[-0.15, 0.15],
                           isBlack=False)
            frame, = ax.plot([], [], [], c='gray', ls='-', lw=1, alpha=0.5)
            frame2, = ax.plot([], [], [], c='r', ls='-', lw=1.5, alpha=1)
            pts, = ax.plot([], [], [], 'co', lw=3)

            def anim(i):
                k = max(0, i-500)
                j = min(i, paas.shape[0])
                frame.set_data(paas[:k, ii[0]], paas[:k, ii[1]])
                frame.set_3d_properties(paas[:k, ii[2]])
                frame2.set_data(paas[k:j, ii[0]], paas[k:j, ii[1]])
                frame2.set_3d_properties(paas[k:j, ii[2]])
                pts.set_data(paas[j, ii[0]], paas[j, ii[1]])
                pts.set_3d_properties(paas[j, ii[2]])

                ax.view_init(30, 0.5 * i)
                return frame, frame2, pts

            ani = animation.FuncAnimation(fig, anim, frames=paas.shape[0],
                                          interval=0, blit=False, repeat=False)
            # ax3d(fig, ax)
            ax.legend()
            fig.tight_layout(pad=0)
            # ani.save('ani.mp4', dpi=200, fps=30, extra_args=['-vcodec', 'libx264'])
            plt.show()

    if case == 500:
        """
        view a collection of rpo and ppo
        """
        N = 64
        L = 22
        ks = pyKS(N, L)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        poIds = [[1]+range(1, 10), range(1, 10)]
        aas = loadPO('../../data/ks22h001t120x64EV.h5', poIds)

        ii = [1, 2, 3]
        # ii = [7, 8, 11]

        doProj = False
        if doProj:
            pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])
            reqr = reqr.dot(bases.T)
            eqr = eqr.dot(bases.T)
            paas = []
            for i in range(len(aas)):
                paas.append(aas[i].dot(bases.T) - eqr[1])
            reqr -= eqr[1]
            eqr -= eqr[1]

            ii = [0, 1, 2]

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        plotRE(ax, reqr, eqr, ii)
        if doProj:
            for i in range(len(aas)):
                ax.plot(paas[i][:, ii[0]], paas[i][:, ii[1]], paas[i][:, ii[2]],
                        alpha=0.2)
            ax.plot(paas[0][:, ii[0]], paas[0][:, ii[1]], paas[0][:, ii[2]], c='k',
                    label=r'$rpo_{16.31}$')
        else:
            for i in range(len(aas)):
                ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]], aas[i][:, ii[2]],
                        alpha=0.2)
        ax3d(fig, ax)


    if case == 60:
        """
        view rpo/ppo pair one at a time
        """
        N = 64
        L = 22
        h = 0.001
        ks = pyKS(N, h, L)

        for i in range(1, 20):
            req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)

            poIds = [[1] + range(i, i+1), range(i, i+1)]
            aas = loadPO('../../data/ks22h001t120x64EV.h5', poIds)

            ii = [0, 3, 4]

            doProj = True
            if doProj:
                pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])
                # pev, bases = getBases(ks, 'eq', eq[0], [2, 3, 5])
                # pev, bases = getBases(ks, 'req', req[0], [0, 1, 3], ws[0])
                reqr = reqr.dot(bases.T)
                eqr = eqr.dot(bases.T)
                paas = []
                for i in range(len(aas)):
                    paas.append(aas[i].dot(bases.T) - eqr[1])
                reqr -= eqr[1]
                eqr -= eqr[1]

                ii = [0, 1, 2]

            fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
            plotRE(ax, reqr, eqr, ii)
            if doProj:
                for i in range(1, len(aas)):
                    ax.plot(paas[i][:, ii[0]], paas[i][:, ii[1]],
                            paas[i][:, ii[2]],
                            alpha=0.8)
                ax.plot(paas[0][:, ii[0]], paas[0][:, ii[1]], paas[0][:, ii[2]],
                        c='k', ls='--',
                        label=r'$rpo_{16.31}$')
            else:
                for i in range(len(aas)):
                    ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]], aas[i][:, ii[2]],
                            alpha=0.7)
            ax3d(fig, ax, doBlock=True)

    if case == 70:
        """
        construct poincare section in ergodic trajectory
        """
        N = 64
        d = 22
        h = 0.001
        ks = pyKS(N, h, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])

        reqr = reqr.dot(bases.T)
        eqr = eqr.dot(bases.T)
        reqr -= eqr[1]
        x0 = eqr[1]

        paas, poinc, poincf = ergoPoinc(ks, bases, x0,  2*np.pi/6, 'n')
        eqr -= eqr[1]

        ii = [0, 1, 2]

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        plotRE(ax, reqr, eqr, ii)
        ax.plot(paas[:, ii[0]], paas[:, ii[1]],
                paas[:, ii[2]], alpha=0.5)
        ax.scatter(poincf[:, 0], poincf[:, 1], poincf[:, 2])
        ax3d(fig, ax)

        scatter2dfig(poinc[:, 1], poinc[:, 2], ratio='equal')

    if case == 80:
        """
        construct poincare section with po
        """
        N = 64
        d = 22
        h = 0.001
        ks = pyKS(N, h, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])

        reqr = reqr.dot(bases.T)
        eqr = eqr.dot(bases.T)
        reqr -= eqr[1]
        x0 = eqr[1]

        i = 40
        poIds = [range(1, i+1), range(1, i+1)]
        # poIds = [[], [2, 4, 8]]
        aas, poinc, nums = poPoinc('../../data/ks22h001t120x64EV.h5', poIds,
                                   bases, x0,  0.5 * np.pi/6, 'p')
        eqr -= eqr[1]

        ii = [0, 1, 2]

        fig, ax = pl3d(labs=[r'$v_1$', r'$v_2$', r'$v_3$'])
        plotRE(ax, reqr, eqr, ii)
        for i in range(1, len(aas)):
            ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]],
                    aas[i][:, ii[2]],
                    alpha=0.2)
        ax.plot(aas[0][:, ii[0]], aas[0][:, ii[1]], aas[0][:, ii[2]],
                c='k', ls='--',
                label=r'$rpo_{16.31}$')
        ax.scatter(poinc[:, 0], poinc[:, 1], poinc[:, 2])
        ax3d(fig, ax)

        fig, ax = pl2d(labs=[r'$v_1$', r'$v_2$'])
        for i in range(1, len(aas)):
            ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]],
                    alpha=0.2)
        ax.plot(aas[0][:, ii[0]], aas[0][:, ii[1]],
                c='k', ls='--',
                label=r'$rpo_{16.31}$')
        ax.scatter(poinc[:, 0], poinc[:, 1])
        ax3d(fig, ax)

        scatter2dfig(poinc[:, 1], poinc[:, 2], ratio='equal')
        plot1dfig(nums)


    if case == 90:
        """
        construct poincare section in ergodic trajectory and
        try to  find the map
        """
        N = 64
        d = 22
        ks = pyKS(N, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])

        reqr = reqr.dot(bases.T)
        eqr = eqr.dot(bases.T)
        reqr -= eqr[1]
        x0 = eqr[1].copy()
        eqr -= eqr[1]

        paas, poinc, poincf, poincRaw = ergoPoinc2(ks, bases, x0,
                                                   2*np.pi/6, 2.0/3*np.pi/6)

        ii = [0, 1, 2]

        fig, ax = pl2d(labs=[r'$v_1$', r'$v_2$'])
        plotRE2d(ax, reqr, eqr, ii)
        ax.plot(paas[:, ii[0]], paas[:, ii[1]], c='b', alpha=0.5)
        ax.scatter(poincf[:, 0], poincf[:, 1], c='r', edgecolors='none')
        ax2d(fig, ax)

        fig, ax = pl2d(size=[8, 3], labs=[None, 'z'], axisLabelSize=20,
                       ratio='equal')
        ax.scatter(poinc[:, 1], poinc[:, 2], c='r', edgecolors='none')
        ax2d(fig, ax)

        plt.hold('on')
        for i in range(40):
            print i
            ax.scatter(poinc[i, 1], poinc[i, 2], c='g', s=20)
            plt.savefig(str(i))

    if case == 100:
        """
        New version to get Poincare points from pos
        """
        N = 64
        d = 22
        ks = pyKS(N, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])

        reqr = reqr.dot(bases.T)
        eqr = eqr.dot(bases.T)
        reqr -= eqr[1]
        x0 = eqr[1].copy()
        eqr -= eqr[1]

        i = 100
        poIds = [range(1, i+1), range(1, i+1)]
        aas, poinc, poincf, poincRaw, nums = poPoinc(
            '../../data/ks22h001t120x64EV.h5',
            poIds, bases, x0,  2*np.pi/6, 2.0/3*np.pi/6)
        ii = [0, 1, 2]

        fig, ax = pl2d(labs=[r'$v_1$', r'$v_2$'])
        plotRE2d(ax, reqr, eqr, ii)
        for i in range(len(aas)):
            ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]], c='gray', alpha=0.2)
        ax.scatter(poincf[:, 0], poincf[:, 1], c='r', edgecolors='none')
        ax2d(fig, ax)

        fig, ax = pl2d(size=[8, 3], labs=[None, 'z'], axisLabelSize=20,
                       ratio='equal')
        ax.scatter(poinc[:, 1], poinc[:, 2], c='r', edgecolors='none')
        ax2d(fig, ax)

        plot1dfig(nums)

    if case == 110:
        """
        Get the return map from the Poincare section points
        """
        N = 64
        d = 22
        h = 0.001
        ks = pyKS(N, d)

        req, ws, reqr, eq, eqr = loadRE('../../data/ks22Reqx64.h5', N)
        pev, bases = getBases(ks, 'eq', eq[1], [6, 7, 10])

        reqr = reqr.dot(bases.T)
        eqr = eqr.dot(bases.T)
        reqr -= eqr[1]
        x0 = eqr[1].copy()
        eqr -= eqr[1]

        i = 100
        poIds = [range(1, i+1), range(1, i+1)]
        aas, poinc, poincf, poincRaw, nums = poPoinc(
            '../../data/ks22h001t120x64EV.h5', poIds,
            bases, x0,  2*np.pi/6, 2.0/3*np.pi/6)
        ii = [0, 1, 2]

        fig, ax = pl2d(labs=[r'$v_1$', r'$v_2$'])
        plotRE2d(ax, reqr, eqr, ii)
        for i in range(len(aas)):
            ax.plot(aas[i][:, ii[0]], aas[i][:, ii[1]], c='gray', alpha=0.2)
        ax.scatter(poincf[:, 0], poincf[:, 1], c='r', edgecolors='none')
        ax2d(fig, ax)

        fig, ax = pl2d(size=[8, 3], labs=[None, 'z'], axisLabelSize=20,
                       ratio='equal')
        ax.scatter(poinc[:, 1], poinc[:, 2], c='r', edgecolors='none')
        ax2d(fig, ax)

        plot1dfig(nums)

        xf = poinc[:, 1:]
        sel = xf[:, 0] > 0
        # xf = xf[sel]
        # poincRaw = poincRaw[sel]
        scale = 10
        nps = 5000
        svr = GridSearchCV(SVR(kernel='rbf', gamma=0.1), cv=5,
                           param_grid={"C": [1e0, 1e1, 1e2, 1e3],
                                       "gamma": np.logspace(-2, 2, 5),
                                       "degree": [3]})

        svr.fit(xf[:, 0:1], xf[:, 1]*scale)
        xp = linspace(0.43, -0.3, nps)  # start form right side
        xpp = xp.reshape(nps, 1)
        yp = svr.predict(xpp)/scale
        fig, ax = pl2d(size=[8, 3], labs=[None, 'z'], axisLabelSize=20,
                       ratio='equal')
        ax.scatter(poinc[:, 1], poinc[:, 2], c='r', s=10, edgecolors='none')
        ax.plot(xp, yp, c='g', ls='-', lw=2)
        ax2d(fig, ax)

        curve = np.zeros((nps, 2))
        curve[:, 0] = xp
        curve[:, 1] = yp
        minIds, minDs = getCurveIndex(xf, curve)
        sortId = np.argsort(minIds)

        dis, coor = getCurveCoordinate(sortId, poincRaw)
        fig, ax = pl2d(size=[6, 4], labs=[r'$S_n$', r'$S_{n+1}$'],
                       axisLabelSize=15)
        ax.scatter(coor[:-1], coor[1:], c='r', s=10, edgecolors='none')
        ax2d(fig, ax)

<file_sep>#include <iostream>
#include <functional>
#include "CQCGL1dReq.hpp"
#include "iterMethod.hpp"


#define cee(x) (cout << (x) << endl << endl)

namespace ph = std::placeholders;

using namespace std;
using namespace Eigen;
using namespace iterMethod;
using namespace denseRoutines;
using namespace MyH5;

//////////////////////////////////////////////////////////////////////
//                      constructor                                 //
//////////////////////////////////////////////////////////////////////

// A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
CQCGL1dReq::CQCGL1dReq(int N, double d,
		       double Mu, double Dr, double Di, double Br, double Bi, 
		       double Gr, double Gi, int dimTan):
    CQCGL1d(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}

// A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
CQCGL1dReq::CQCGL1dReq(int N, double d, 
		       double b, double c, double dr, double di, 
		       int dimTan):
    CQCGL1d(N, d, b, c, dr, di, dimTan){}
    
// iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
CQCGL1dReq::CQCGL1dReq(int N, double d,
		       double delta, double beta, double D, double epsilon,
		       double mu, double nu, int dimTan) :
    CQCGL1d(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

CQCGL1dReq::~CQCGL1dReq(){}

CQCGL1dReq & CQCGL1dReq::operator=(const CQCGL1dReq &x){
    return *this;
}


//////////////////////////////////////////////////////////////////////
//                      member functions                            //
//////////////////////////////////////////////////////////////////////

std::string 
CQCGL1dReq::toStr(double Bi, double Gi, int id){
    //  avoid possibilty that 000000.000000 or -00000.000000
    if (fabs(Bi) < 1e-6) Bi = 0; 
    if (fabs(Gi) < 1e-6) Gi = 0;

    char g1[20], g2[20];
    sprintf(g1, "%013.6f", Bi);
    sprintf(g2, "%013.6f", Gi);
    
    string s1(g1);
    string s2(g2);
    string s = s1 + '/' + s2 + '/' + to_string(id);
    
    return s;
}

/**
 * @brief read req (relative equibrium) info from hdf5 file
 *
 */
std::tuple<VectorXd, double, double ,double>
CQCGL1dReq::read(H5File &file, const std::string groupName){
    // H5File file(fileName, H5F_ACC_RDONLY);
    string DS = "/" + groupName + "/";

    return make_tuple(readMatrixXd(file, DS + "a").col(0),
		      readScalar<double>(file, DS + "wth"),
		      readScalar<double>(file, DS + "wphi"),
		      readScalar<double>(file, DS + "err")
		      );
}



/**
 * @brief write [a, wth, wphi, err] of Req of cqcgl into a group
 * 
 * @note group should be a new group
 */
void 
CQCGL1dReq::write(H5File &file, const std::string groupName,
		     const ArrayXd &a, const double wth, 
		     const double wphi, const double err){
    
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
	
    writeMatrixXd(file, DS + "a", a);
    writeScalar<double>(file, DS + "wth", wth);
    writeScalar<double>(file, DS + "wphi", wphi);
    writeScalar<double>(file, DS + "err", err);
}

VectorXcd 
CQCGL1dReq::readE(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    VectorXd er = readMatrixXd(file, DS + "er");
    VectorXd ei = readMatrixXd(file, DS + "ei");
    VectorXcd e(er.size());
    e.real() = er;
    e.imag() = ei;

    return e;
}

MatrixXcd 
CQCGL1dReq::readV(H5File &file, const std::string groupName){
    string DS = "/" + groupName + "/";
    MatrixXd vr = readMatrixXd(file, DS + "vr");
    MatrixXd vi = readMatrixXd(file, DS + "vi");
    MatrixXcd v(vr.rows(), vr.cols());
    v.real() = vr;
    v.imag() = vi;

    return v;
}

void 
CQCGL1dReq::writeE(H5File &file, const std::string groupName, 
		   const VectorXcd e){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "er", e.real());
    writeMatrixXd(file, DS + "ei", e.imag());
}


void 
CQCGL1dReq::writeV(H5File &file, const std::string groupName, 
		   const MatrixXcd v){
    // H5File file(fileName, H5F_ACC_RDWR);
    checkGroup(file, groupName, true);
    string DS = "/" + groupName + "/";
    
    writeMatrixXd(file, DS + "vr", v.real());
    writeMatrixXd(file, DS + "vi", v.imag());
}

void 
CQCGL1dReq::move(H5File &fin, std::string gin, H5File &fout, std::string gout,
		    int flag){
    VectorXd a;
    VectorXcd e;
    MatrixXcd v;
    double wth, wphi, err;

    std::tie(a, wth, wphi, err) = read(fin, gin);
    if (flag == 1 || flag == 2) e = readE(fin, gin);
    if (flag == 2) v = readV(fin, gin);
    
    write(fout, gout, a, wth, wphi, err);
    if (flag == 1 || flag == 2) writeE(fout, gout, e);
    if (flag == 2) writeV(fout, gout, v);
}

//====================================================================================================

VectorXd
CQCGL1dReq::Fx(const VectorXd &x){
    assert(x.size() == 2*Ne + 2);

    Vector2d th = x.tail<2>();	// wth, wphi
    VectorXd a = x.head(2*Ne); // use matrix type for resizing

    ArrayXd v = velocityReq(a, th(0), th(1));

    VectorXd F(2*Ne+2);
    F << v, 0, 0;
    
    return F;
}

std::tuple<MatrixXd, MatrixXd, VectorXd>
CQCGL1dReq::calJJF(const VectorXd &x){
    ArrayXd a0 = x.head(2*Ne);
    double wth = x(2*Ne);
    double wphi = x(2*Ne+1);

    int n = a0.rows();
    assert(Ndim == n); 
  
    MatrixXd DF(n, n+2); 
    ArrayXd tx_trans = transTangent(a0);
    ArrayXd tx_phase = phaseTangent(a0); 
    DF.topLeftCorner(2*Ne, 2*Ne) = stabReq(a0, wth, wphi); 
    DF.col(2*Ne).head(2*Ne)= tx_trans;
    DF.col(2*Ne+1).head(2*Ne) = tx_phase;
    VectorXd F(n);
    F.head(n) = velocity(a0) + wth*tx_trans + wphi*tx_phase;


    MatrixXd JJ = DF.transpose() * DF;
    MatrixXd D  = JJ.diagonal().asDiagonal();
    VectorXd df = DF.transpose() * F; 

    return std::make_tuple(JJ, D, df);
}


std::tuple<VectorXd, double, double, double, int>
CQCGL1dReq::findReq_LM(const ArrayXd &a0, const double wth0, const double wphi0, 
		       const double tol,
		       const int maxit,
		       const int innerMaxit){
    
    VectorXd x(2*Ne+2);
    x << a0, wth0, wphi0;
    
    auto fx = std::bind(&CQCGL1dReq::Fx, this, ph::_1);    
    CQCGL1dReqJJF<MatrixXd> jj(this);
    PartialPivLU<MatrixXd> solver;
    
    VectorXd xe;
    std::vector<double> res;
    int flag;
    std::tie(xe, res, flag) = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    if(flag != 0) fprintf(stderr, "Req not converged ! \n");
    
    VectorXd a = xe.head(2*Ne);
    double wth = xe(2*Ne);
    double wphi = xe(2*Ne+1);
    return std::make_tuple( a, wth, wphi, res.back(), flag );
}


/** @brief find the optimal guess of wth and wphi for a candidate req
 * 
 *  When we find a the inital state of a candidate of req, we also need
 *  to know the appropriate th and phi to start the Newton search.
 *  According to the definition of velocityReq(), this is a residual
 *  minimization problem.
 *
 *  @return    [wth, wphi, err] such that velocityReq(a0, wth, wphi) minimal
 */
std::vector<double>
CQCGL1dReq::optThPhi(const ArrayXd &a0){ 
    VectorXd t1 = transTangent(a0);
    VectorXd t2 = phaseTangent(a0);
    double c = t2.dot(t1) / t1.dot(t1);
    VectorXd t3 = t2 - c * t1;

    VectorXd v = velocity(a0);
    double a1 = t1.dot(v) / t1.dot(t1);
    double a2 = t3.dot(v) / t3.dot(t3);
    
    double err = (v - a1 * t1 - a2 * t3).norm();
    
    std::vector<double> x = {-(a1-a2*c), -a2, err};
    return x;
}

/**
 * @brief find req with a sequence of Bi or Gi
 */ 
void 
CQCGL1dReq::findReqParaSeq(H5File &file, int id, double step, int Ns, bool isBi){
    double Bi0 = Bi;
    double Gi0 = Gi;
    
    ArrayXd a0;
    double wth0, wphi0, err0;
    std::tie(a0, wth0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
    
    ArrayXd a;
    double wth, wphi, err;
    int flag;
    
    int Nfail = 0;

    for (int i = 0; i < Ns; i++){
	if (isBi) Bi += step;
	else Gi += step;
	
	// if exist, use it as seed, otherwise find req
	if ( checkGroup(file, toStr(Bi, Gi, id), false) ){ 
	    std::tie(a0, wth0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
	}
	else {
	    fprintf(stderr, "%d %g %g \n", id, Bi, Gi);
	    std::tie(a, wth, wphi, err, flag) = findReq_LM(a0, wth0, wphi0, 1e-10, 100, 1000);
	    if (flag == 0){
		write(file, toStr(Bi, Gi, id), a, wth, wphi, err);
		a0 = a;
		wth0 = wth;
		wphi0 = wphi;
	    }
	    else {
		if(++Nfail == 3) break;
	    }
	}
    }
    
    Bi = Bi0; 			// restore Bi, Gi
    Gi = Gi0;
}

/// @brief calculate the eigenvalues and eigenvectors of req in certain range 
void 
CQCGL1dReq::calEVParaSeq(H5File &file, std::vector<int> ids, std::vector<double> Bis,
			 std::vector<double> Gis, bool saveV){
    double Bi0 = Bi;
    double Gi0 = Gi;
    int id;

    ArrayXd a0;
    double wth0, wphi0, err0;
    VectorXcd e;
    MatrixXcd v;
    
    for (int i = 0; i < ids.size(); i++){
	id = ids[i]; 
	for (int j = 0; j < Bis.size(); j++){
	    Bi = Bis[j];
	    for(int k = 0; k < Gis.size(); k++){
		Gi = Gis[k];
		if ( checkGroup(file, toStr(Bi, Gi, id), false) ){
		    if( !checkGroup(file, toStr(Bi, Gi, id) + "/er", false)){
			fprintf(stderr, "%d %g %g \n", id, Bi, Gi);
			std::tie(a0, wth0, wphi0, err0) = read(file, toStr(Bi, Gi, id));
			std::tie(e, v) = evReq(a0, wth0, wphi0); 	
			writeE(file, toStr(Bi, Gi, id), e);
			if (saveV) writeV(file, toStr(Bi, Gi, id), v.leftCols(10));
		    }
		}
	    }
	}
    }
    Bi = Bi0; 			// restore Bi, Gi
    Gi = Gi0;
}

#if 0
//====================================================================================================
VectorXd
CQCGL1dReq::DFx(const VectorXd &x, const VectorXd &dx){
    assert(x.size() == 2*Ne*Me + 3 && dx.size() == 2*Ne*Me + 3);
    
    Vector3d th = x.tail<3>();	// wthx, wthy, wphi
    Vector3d dth = dx.tail<3>();
    VectorXd ra = x.head(2*Me*Ne);
    VectorXd rda = dx.head(2*Me*Ne); 
    ArrayXXcd a = r2c(ra);
    ArrayXXcd da = r2c(rda); 
    
    ArrayXXcd t1 = tangent(a, 1);
    ArrayXXcd t2 = tangent(a, 2);
    ArrayXXcd t3 = tangent(a, 3);

    ArrayXXcd Ax = stabReq(a, da, th(0), th(1), th(2)) +
	dth(0) * t1 + dth(1) * t2 + dth(2) * t3;

    double t1x = (t1 * da.conjugate()).sum().real();
    double t2x = (t2 * da.conjugate()).sum().real();
    double t3x = (t3 * da.conjugate()).sum().real();

    VectorXd DF(2*Ne*Me+3);
    DF << c2r(Ax), t1x, t2x, t3x; 

    return DF;
}

std::tuple<ArrayXXcd, double, double, double, double>
CQCGL1dReq::findReq_hook(const ArrayXXcd &x0, const double wthx0, 
			 const double wthy0, const double wphi0){
    HOOK_PRINT_FREQUENCE = hookPrint;
    
    assert(x0.rows() == Me && x0.cols() == Ne);
    
    auto fx = std::bind(&CQCGL1dReq::Fx, this, ph::_1);
    auto dfx = std::bind(&CQCGL1dReq::DFx, this, ph::_1, ph::_2);
    
    VectorXd x(2*Me*Ne+3);
    x << c2r(x0), wthx0, wthy0, wphi0;

    VectorXd xnew;
    std::vector<double> errs;
    int flag;
    auto Pre = [this](const VectorXd &x, const VectorXd &dx){
	Vector3d th = x.tail<3>();
	Vector3d dth = dx.tail<3>();
	VectorXd dra = dx.head(2*Me*Ne);
	ArrayXXcd da = r2c(dra);

	ArrayXXcd px = 1/(Lu + Tx*th(0) + Ty*th(1) + Tp*th(2)) * da;
	VectorXd p(2*Ne*Me+3);
	p << c2r(px), dth;

	return p; 
    };
    std::tie(xnew, errs, flag) = Gmres0HookPre(fx, dfx, Pre, x, tol, minRD, maxit, maxInnIt, 
					       GmresRtol, GmresRestart, GmresMaxit,
					       false, 1); 
    if(flag != 0) fprintf(stderr, "Req not converged ! \n");
    
    Vector3d th = xnew.tail<3>();
    VectorXd y = xnew.head(2*Me*Ne); 
    
    return std::make_tuple(r2c(y), th(0), th(1), th(2), errs.back());
}
#endif
<file_sep>#include "myH5.hpp"
#include <iostream>
#include <sstream>

namespace MyH5 {

    /**
     * @brief read a double matrix
     */
    MatrixXd readMatrixXd(H5File &file, string DSitem){
	DataSet item = file.openDataSet(DSitem);
	DataSpace dsp = item.getSpace();
	const int D = dsp.getSimpleExtentNdims();
	if (D == 2) {
	    hsize_t dims[2];
	    int ndims = dsp.getSimpleExtentDims(dims, NULL);
	    MatrixXd x(dims[1], dims[0]);	/* HDF5 uses row major by default */
	    item.read(x.data(), PredType::NATIVE_DOUBLE);
	    return x;
	}
	else if (D == 1) {
	    hsize_t dims[1];
	    int ndims = dsp.getSimpleExtentDims(dims, NULL);
	    MatrixXd x(dims[0], 1);
	    item.read(x.data(), PredType::NATIVE_DOUBLE);
	    return x;
	}
	else {
	    fprintf(stderr, "readMatrixXd() dimension wrong !\n");
	    exit(-1);
	}
    }
    
    /**
     * @brief read a double vector
     */
    VectorXd readVectorXd(H5File &file, string DSitem){
	DataSet item = file.openDataSet(DSitem);
	DataSpace dsp = item.getSpace();
	const int D = dsp.getSimpleExtentNdims();
	assert ( D == 1);
	
	hsize_t dims[1];
	int ndims = dsp.getSimpleExtentDims(dims, NULL);
	VectorXd x(dims[0]);
	item.read(x.data(), PredType::NATIVE_DOUBLE);

	return x;
    }

    /**
     * @brief write a double matrix
     */
    void writeMatrixXd(H5File &file, string DSitem, const MatrixXd &mat){
	const int N = mat.rows();
	const int M = mat.cols();
	
	if ( 1 == M){
	    hsize_t dim[] = {N};
	    DataSpace dsp(1, dim);
	    DataSet item = file.createDataSet(DSitem, PredType::NATIVE_DOUBLE, dsp);
	    item.write(mat.data(), PredType::NATIVE_DOUBLE);
	}
	else {
	    hsize_t dim[] = {M, N};	/* HDF5 uses row major by default */
	    DataSpace dsp(2, dim);
	    DataSet item = file.createDataSet(DSitem, PredType::NATIVE_DOUBLE, dsp);
	    item.write(mat.data(), PredType::NATIVE_DOUBLE);
	}
	
    }

    /**
     * @brief write a double vector
     */
    void writeVectorXd(H5File &file, string DSitem, const VectorXd &vec){
	const int N = vec.size();
	
	hsize_t dim[] = {N};
	DataSpace dsp(1, dim);
	DataSet item = file.createDataSet(DSitem, PredType::NATIVE_DOUBLE, dsp);
	item.write(vec.data(), PredType::NATIVE_DOUBLE);
    }

    /**
     * @brief check the existence of groups recursively. 
     *
     * If doCreate = false, it will immediately return if not exist
     * If doCreate = true. It will finish the loop 
     * 
     * @param[in] groupName  some string like "a/b/c". Note, no '/' at the head or tail.
     * @param[in] doCreate   if not exist, whether create the group
     */
    bool checkGroup(H5File &file, const std::string groupName, const bool doCreate){
	stringstream ss(groupName);
	string item, g;
	hid_t id = file.getId();
	
	bool exist = true;
	
	while (getline(ss, item, '/')) {
	    g += '/' + item;
	    if(H5Lexists(id, g.c_str(), H5P_DEFAULT) == false){
		exist = false;
		if (doCreate) file.createGroup(g.c_str());
		else return exist;
	    }
	}
    
	return exist;
    }

    bool checkGroup(std::string fileName, const std::string groupName, const bool doCreate){
	H5File file(fileName, H5F_ACC_RDWR);
	return checkGroup(file, groupName, doCreate);
    }
    
    // obtain all unique groupnames in a file
    // if file has datasets /a/b/c/d1, /a/b/c/d2, /a/b/d3
    // the it outputs a/b/c, a/b
    // from https://support.hdfgroup.org/ftp/HDF5/examples/misc-examples/h5_info.c
    vector<vector<string>> scanGroup(std::string fileName){
	H5File file(fileName, H5F_ACC_RDONLY);
	unordered_set<string> record;
	vector<vector<string>> result;
	vector<string> curt;
	scanGroupHelp(file.getId(), result, record, curt);
	
	return result;
    }
    
    // I do not know why H5Gopen does not work but H5Gopen1 works
    void scanGroupHelp(hid_t gid, vector<vector<string>> &result, unordered_set<string> &record,
		       vector<string> &curt) {
	int MAX_NAME = 100;
	char memb_name[MAX_NAME];
	hsize_t nobj;
	
	herr_t err = H5Gget_num_objs(gid, &nobj);
	for (int i = 0; i < nobj; i++) {
	    int len = H5Gget_objname_by_idx(gid, (hsize_t)i, memb_name, (size_t)MAX_NAME );
	    int otype =  H5Gget_objtype_by_idx(gid, (size_t)i );
	    switch(otype) {
	    case H5G_GROUP: {
		hid_t grpid = H5Gopen1(gid, memb_name);
		curt.push_back(string(memb_name));
		scanGroupHelp(grpid, result, record, curt);
		curt.pop_back();
		H5Gclose(grpid);
		break;
	    }
	    case H5G_DATASET: {
		string groupName;
		for(auto s : curt) groupName += s + "/";
		groupName.pop_back();
		if (record.find(groupName) == record.end()){
		    record.insert(groupName);
		    result.push_back(curt);
		}
		break;
	    }
	    default:
		fprintf(stderr, "scanGroup unknown? \n");
	    }
	}
    }


    ////////////////////////////////////////////////////////////////////////////////
    //                             KS related
    ////////////////////////////////////////////////////////////////////////////////

    std::pair<VectorXd, double>
    KSreadEq(const std::string fileName, const int Id){
	H5File file(fileName, H5F_ACC_RDONLY);
	string DS = "/E/" + to_string(Id) + "/";
	return std::make_pair(readMatrixXd(file, DS + "a"),
			      readScalar<double>(file, DS + "err")
			      );
    }
    
    std::tuple<VectorXd, double, double>
    KSreadReq(const std::string fileName, const int Id){
	H5File file(fileName, H5F_ACC_RDONLY);
	string DS = "/tw/" + to_string(Id) + "/";
	return std::make_tuple(readMatrixXd(file, DS + "a"),
			       readScalar<double>(file, DS + "w"),
			       readScalar<double>(file, DS + "err")
			       );
    }

   

}
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CQCGL1d.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class pyCQCGL1d : public CQCGL1d {
  
public:

    pyCQCGL1d(int N, double d,
	      double Mu, double Dr, double Di, double Br, double Bi, 
	      double Gr, double Gi, int dimTan):
	CQCGL1d(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi, dimTan) {}
    
    pyCQCGL1d(int N, double d,
	      double b, double c, double dr, double di,
	      int dimTan) :
	CQCGL1d(N, d, b, c, dr, di, dimTan) {}

    pyCQCGL1d(int N, double d,
	      double delta, double beta, double D, double epsilon,
	      double mu, double nu, int dimTan):
	CQCGL1d(N, d, delta, beta, D, epsilon, mu, nu, dimTan) {}

    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }

    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

    /* K */
    bn::ndarray PYK(){
	return copy2bn(K);
    }

    /* L */
    bn::ndarray PYL(){
	return copy2bnc(L);
    }

   /* wrap the integrator */
    bn::ndarray PYintgC(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intgC(tmpa, h, tend, skip_rate));
    }

    /* wrap the integrator with Jacobian */
    bp::tuple PYintgjC(bn::ndarray a0, double h, double tend, size_t skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	auto result = intgjC(tmpa, h, tend, skip_rate);
	return bp::make_tuple(copy2bn(result.first), copy2bn(result.second));
    }
    
    bn::ndarray PYintgvC(bn::ndarray a0, bn::ndarray v, double h, double tend){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	getDims(v, m, n);
	Map<ArrayXXd> tmpv((double*)v.get_data(), n, m);
	return copy2bn(intgvC(tmpa, tmpv, h, tend));
    }    

    bn::ndarray PYintg(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intg(tmpa, h, tend, skip_rate));
    }

    bp::tuple PYintgj(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	auto result = intgj(tmpa, h, tend, skip_rate);
	return bp::make_tuple(copy2bn(result.first), copy2bn(result.second));
    }

    bn::ndarray PYintgv(bn::ndarray a0, bn::ndarray v, double h, double tend){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	getDims(v, m, n);
	Map<ArrayXXd> tmpv((double*)v.get_data(), n, m);
	return copy2bn(intgv(tmpa, tmpv, h, tend));
    }


    /* wrap the velocity */
    bn::ndarray PYvelocity(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(velocity(tmpa));
    }

    /* wrap the velSlice */
    bn::ndarray PYvelSlice(bn::ndarray aH){
	int m, n;
	getDims(aH, m, n);
	Map<VectorXd> tmpa((double*)aH.get_data(), m*n);
	return copy2bn(velSlice(tmpa));
    }

    /* wrap the velPhase */
    bn::ndarray PYvelPhase(bn::ndarray aH){
	int m, n;
	getDims(aH, m, n);
	Map<VectorXd> tmpa((double*)aH.get_data(), m*n);
	VectorXd tmpv = velPhase(tmpa);
	return copy2bn(tmpv);
    }
    

    /* wrap velocityReq */
    bn::ndarray PYvelocityReq(bn::ndarray a0, double th, double phi){
	int m, n;
	getDims(a0, m, n);	
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	ArrayXd tmpv = velocityReq(tmpa, th, phi);
	return copy2bn(tmpv);
    }

    /* wrap Fourier2Config */
    bn::ndarray PYFourier2Config(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bnc( Fourier2Config(tmpaa) );
    }

    /* wrap Config2Fourier */
    bn::ndarray PYConfig2Fourier(bn::ndarray AA){
	int m, n;
	getDims(AA, m, n);
	Map<ArrayXXcd> tmpAA((dcp*)AA.get_data(), n, m);
	return copy2bn( Config2Fourier(tmpAA) );
    }
    
    /* wrap Fourier2ConfigMag */
    bn::ndarray PYFourier2ConfigMag(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( Fourier2ConfigMag(tmpaa) );
    }
    
    /* wrap Fourier2Phase */
    bn::ndarray PYFourier2Phase(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( Fourier2Phase(tmpaa) );
    }
    
    bn::ndarray PYcalQ(const bn::ndarray &aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(calQ(tmpaa));
    }
    
    bn::ndarray PYcalMoment(const bn::ndarray &aa, const int p){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(calMoment(tmpaa, p));
    }
    
    bn::ndarray PYcalMoment2(const bn::ndarray &aa){
	return PYcalMoment(aa, 1);
    }
    
    /* orbit2slice */
    bp::tuple PYorbit2slice(const bn::ndarray &aa, int method){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	std::tuple<ArrayXXd, ArrayXd, ArrayXd> tmp = orbit2slice(tmpaa, method);
	return bp::make_tuple(copy2bn(std::get<0>(tmp)), 
			      copy2bn(std::get<1>(tmp)),
			      copy2bn(std::get<2>(tmp)));
    }

    bn::ndarray PYve2slice(const bn::ndarray &ve, const bn::ndarray &x, int flag){
	int m, n;
	getDims(ve, m, n);
	Map<ArrayXXd> tmpve((double*)ve.get_data(), n, m);
	getDims(x, m, n);
	Map<ArrayXd> tmpx((double*)x.get_data(), n*m);

	return copy2bn(ve2slice(tmpve, tmpx, flag));
    }

    /* stability matrix */
    bn::ndarray PYstab(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	return copy2bn(stab(tmpa));
    }

    /* stability matrix for relative equibrium */
    bn::ndarray PYstabReq(bn::ndarray a0, double th, double phi){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	return copy2bn(stabReq(tmpa, th, phi));
    }


    /* reflection */
    bn::ndarray PYreflect(const bn::ndarray &aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( reflect(tmpaa) );
    }


    /* reduceReflection */
    bn::ndarray PYreduceReflection(const bn::ndarray &aa){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( reduceReflection(tmpaa) );
    }

    /* refGradMat */
    bn::ndarray PYrefGradMat(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXd> tmpaa((double*)aa.get_data(), n * m);
	return copy2bn( refGradMat(tmpaa) );
    }

    /* reflectVe */
    bn::ndarray PYreflectVe(const bn::ndarray &veHat, const bn::ndarray &xHat){
	int m, n;
	getDims(veHat, m, n);	
	Map<MatrixXd> tmpveHat((double*)veHat.get_data(), n, m);
	int m2, n2;
	getDims(xHat, m2, n2);
	Map<ArrayXd> tmpxHat((double*)xHat.get_data(), n2*m2);
	return copy2bn( reflectVe(tmpveHat, tmpxHat) );
    }
    
    /* transRotate */
    bn::ndarray PYtransRotate(bn::ndarray aa, double th){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( transRotate(tmpaa, th) );
    }

    /* transTangent */
    bn::ndarray PYtransTangent(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( transTangent(tmpaa) );
    }

    /* phaseRotate */
    bn::ndarray PYphaseRotate(bn::ndarray aa, double phi){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( phaseRotate(tmpaa, phi) );
    }
    
    /* phaseTangent */
    bn::ndarray PYphaseTangent(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( phaseTangent(tmpaa) );
    }

    /* Rotate */
    bn::ndarray PYRotate(bn::ndarray aa, double th, double phi){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn( Rotate(tmpaa, th, phi) );
    }

    /* rotateOrbit */
    bn::ndarray PYrotateOrbit(bn::ndarray aa, bn::ndarray th, bn::ndarray phi){
	int m, n;
	getDims(aa, m, n);
	int m2, n2;
	getDims(th, m2, n2);
	int m4, n4;
	getDims(phi, m4, n4);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	Map<ArrayXd> tmpth((double*)th.get_data(), n2 * m2);
	Map<ArrayXd> tmpphi((double*)phi.get_data(), n4 * m4);
	return copy2bn( rotateOrbit(tmpaa, tmpth, tmpphi) );
    }

    bn::ndarray PYC2R(bn::ndarray v){
	int m, n;
	getDims(v, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v.get_data(), n, m);
	return copy2bn( C2R(tmpv) );
    }
    
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_CQCGL1d) {
    bn::initialize();

    // must provide the constructor
    bp::class_<CQCGL1d>("CQCGL1d", bp::init<
			int, double, 
			double, double, double, double, 
			int>())
	;
    
    // the EIDc class
    bp::class_<EIDc>("EIDc", bp::init<>())
	.def_readonly("NCalCoe", &EIDc::NCalCoe)
	.def_readonly("NReject", &EIDc::NReject)
	.def_readonly("NCallF", &EIDc::NCallF)
	.def_readonly("NSteps", &EIDc::NSteps)
	.def_readonly("TotalTime", &EIDc::TotalTime)
	.def_readonly("CoefficientTime", &EIDc::CoefficientTime)
	.def_readwrite("rtol", &EIDc::rtol)
	;
    
    bp::class_<pyCQCGL1d, bp::bases<CQCGL1d> >("pyCQCGL1d", bp::init<
					       int, double, 
					       double, double, double, double,
					       int >())
	.def(bp::init<int, double, double, double, double, double, double, 
	     double, double, int>())
	.def(bp::init<int, double, double, double, double, double,
	     double, double, int>())
	.def_readonly("N", &pyCQCGL1d::N)
	.def_readonly("d", &pyCQCGL1d::d)
	.def_readwrite("IsQintic", &pyCQCGL1d::IsQintic)
	.def_readonly("Mu", &pyCQCGL1d::Mu)
	.def_readwrite("Br", &pyCQCGL1d::Br)
	.def_readwrite("Bi", &pyCQCGL1d::Bi)
	.def_readonly("Dr", &pyCQCGL1d::Dr)
	.def_readonly("Di", &pyCQCGL1d::Di)
	.def_readwrite("Gr", &pyCQCGL1d::Gr)
	.def_readwrite("Gi", &pyCQCGL1d::Gi)
	.def_readonly("Ndim", &pyCQCGL1d::Ndim)
	.def_readonly("Ne", &pyCQCGL1d::Ne)
	.def_readonly("Omega", &pyCQCGL1d::Omega)
	.def_readwrite("eidc", &pyCQCGL1d::eidc)
	.def_readwrite("eidc2", &pyCQCGL1d::eidc2)
	.def("Ts", &pyCQCGL1d::PYTs)
	.def("hs", &pyCQCGL1d::PYhs)
	.def("lte", &pyCQCGL1d::PYlte)
	.def("K", &pyCQCGL1d::PYK)
	.def("L", &pyCQCGL1d::PYL)
	
	.def("changeOmega", &pyCQCGL1d::changeOmega)
	.def("intgC", &pyCQCGL1d::PYintgC)
	.def("intgjC", &pyCQCGL1d::PYintgjC)
	.def("intgvC", &pyCQCGL1d::PYintgv)
	.def("intg", &pyCQCGL1d::PYintg)
	.def("intgj", &pyCQCGL1d::PYintgj)
	.def("intgv", &pyCQCGL1d::PYintgv)
	.def("velocity", &pyCQCGL1d::PYvelocity)
	.def("velSlice", &pyCQCGL1d::PYvelSlice)
	.def("velPhase", &pyCQCGL1d::PYvelPhase)
	.def("velocityReq", &pyCQCGL1d::PYvelocityReq)
	.def("Fourier2Config", &pyCQCGL1d::PYFourier2Config)
	.def("Config2Fourier", &pyCQCGL1d::PYConfig2Fourier)
	.def("Fourier2ConfigMag", &pyCQCGL1d::PYFourier2ConfigMag)
	.def("Fourier2Phase", &pyCQCGL1d::PYFourier2Phase)
	.def("calQ", &pyCQCGL1d::PYcalQ)
	.def("calMoment", &pyCQCGL1d::PYcalMoment)
	.def("calMoment", &pyCQCGL1d::PYcalMoment2)
	.def("orbit2slice", &pyCQCGL1d::PYorbit2slice)
	.def("ve2slice", &pyCQCGL1d::PYve2slice)
	.def("stab", &pyCQCGL1d::PYstab)
	.def("stabReq", &pyCQCGL1d::PYstabReq)
	.def("reflect", &pyCQCGL1d::PYreflect)
	.def("reduceReflection", &pyCQCGL1d::PYreduceReflection)
	.def("refGradMat", &pyCQCGL1d::PYrefGradMat)
	.def("reflectVe", &pyCQCGL1d::PYreflectVe)
	.def("transRotate", &pyCQCGL1d::PYtransRotate) 
	.def("transTangent", &pyCQCGL1d::PYtransTangent)
	.def("phaseRotate", &pyCQCGL1d::PYphaseRotate)
	.def("phaseTangent", &pyCQCGL1d::PYphaseTangent)
	.def("Rotate", &pyCQCGL1d::PYRotate)
	.def("rotateOrbit", &pyCQCGL1d::PYrotateOrbit)
	.def("C2R", &pyCQCGL1d::PYC2R)
	;
}
<file_sep>/* try to form the Jacobian for finding the relative equilibirum
 *
 *      | A+wT , tx|
 *  J = | tx   ,  0|
 *
 *  @param[in] x  [a0, omega]
 *  return J^T*J, diag(J^T*J), J^T * F
 */
std::tuple<MatrixXd, MatrixXd, VectorXd>
KS::calReqJJF(const Ref<const VectorXd> &x){
    assert(x.size() == N-1);
    double omega = x(N-2); 

    MatrixXd A = stabReq(x.head(N-2), omega); 
    VectorXd tx = gTangent(x.head(N-2)); 
    
    MatrixXd J(N-1, N-1);
    J << 
	A, tx, 
	tx.transpose(), 0; 

    VectorXd F(N-1);
    F << velg(x.head(N-2), omega), 0 ;

    MatrixXd JJ = J.transpose() * J; 
    MatrixXd DJJ = JJ.diagonal().asDiagonal(); 
    VectorXd JF = J.transpose() * F; 
    
    return std::make_tuple(JJ, DJJ, JF); 
}
/**
 * @see calReqJJF
 */
std::tuple<MatrixXd, MatrixXd, VectorXd>
KS::calEqJJF(const Ref<const VectorXd> &x){
    assert(x.size() == N-2);
    
    MatrixXd J = stab(x);
    VectorXd F = velocity(x);

    MatrixXd JJ  = J.transpose() * J;
    MatrixXd DJJ = JJ.diagonal().asDiagonal(); 
    VectorXd JF = J.transpose() * F; 
    
    return std::make_tuple(JJ, DJJ, JF);
}

/* find reqs in KS  */
std::tuple<VectorXd, double, double>
KS::findReq(const Ref<const VectorXd> &x, const double tol, 
	    const int maxit, const int innerMaxit){

    auto fx = [&](const VectorXd &x){
	VectorXd F(N-1);
	F << velg(x.head(N-2), x(N-2)), 0; 
	return F;
    };
    
    KSReqJJF<MatrixXd> jj(*this);    
    ColPivHouseholderQR<MatrixXd> solver; 

    auto result = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);    
    if(std::get<2>(result) != 0) fprintf(stderr, "Req not converged ! \n");
    
    VectorXd at = std::get<0>(result);
    return std::make_tuple(at.head(N-2), at(N-2) , std::get<1>(result).back() );
}

/* find eq in KS */
std::pair<VectorXd, double>
KS::findEq(const Ref<const VectorXd> &x, const double tol,
	   const int maxit, const int innerMaxit){
    
    auto fx = [&](const VectorXd &x){
	return velocity(x);
    };
    
    KSEqJJF<MatrixXd> jj(*this);
    ColPivHouseholderQR<MatrixXd> solver;
    
    auto result = LM0(fx, jj, solver, x, tol, maxit, innerMaxit);
    if(std::get<2>(result) != 0) fprintf(stderr, "Req not converged ! \n");
    
    return std::make_pair(std::get<0>(result), std::get<1>(result).back() );   
}
<file_sep>import h5py
from pylab import *
import numpy as np
from numpy.linalg import norm, eig
from time import time
from py_cqcgl1d_threads import pyCqcgl1d, pyCqcglRPO
from personalFunctions import *


case = 1


if case == 1:
    """
    use different N and h to view the explosion process.
    Try to find the optimal values.
    """
    N = 512
    d = 50
    h = 0.0001

    cgl = pyCqcgl1d(N, d, h, True, 0,
                    -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
                    4)
    Ndim = cgl.Ndim

    nstp3 = 200000
    a0Erg3 = cgl.Config2Fourier(centerRand(2*N, 0.25))
    aaErg3 = cgl.intg(a0Erg3, 20000, 20000)
    a0Erg3 = aaErg3[-1]
    aaErg3 = cgl.intg(a0Erg3, nstp3, 1)
    aaErgHat3, th3, phi3 = cgl.orbit2slice(aaErg3)
    aaErgTilde3 = cgl.reduceReflection(aaErgHat3)

    # plot3dfig(aaErgTildeProj3[:, 0], aaErgTildeProj3[:, 1], aaErgTildeProj3[:, 2])
    # plot the variance => indicator of the integration error.
    plot1dfig(aaErg3[:, 0])
    plot1dfig(aaErg3[:-1, 0]-aaErg3[1:, 0])
    plot1dfig(abs(aaErg3[:, Ndim/2]), yscale='log')
    # plotConfigSpace(cgl.Fourier2Config(aaErg3), [0, d, 0, nstp3*h])
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3 -march=corei7 -msse4.2' MEXcqcgl1d.cpp cqcgl1d.cc -I../../include -I/usr/include/eigen3 -lm -lfftw3
 * */

#include "cqcgl1d.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>

using namespace Eigen;


static int getNdim(int N){
    double d = 1;
    double h = 1;
    bool enableJacv = false;
    int Njacv = 0;
    double b = 1;
    double c = 1;
    double dr = 1;
    double di = 1;
    int threadNum = 4;

    Cqcgl1d cgl(N, d, h, enableJacv, Njacv, b, c, dr, di, threadNum);
   
    return cgl.Ndim;
}

void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    int N = mxGetScalar(prhs[0]);

    double Ndim = (double) getNdim(N); // to simply the process, transform it to double

    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    memcpy(mxGetPr(plhs[0]), &Ndim, 1*sizeof(double));
}
<file_sep>/* g++ test_dense.cc -O3 -std=c++11 -I$EIGEN -I${RESH}/include -L${RESH}/lib -ldenseRoutines */

#include <iostream>
#include <Eigen/Dense>
#include "denseRoutines.hpp"

#define CE(x) (cout << x << endl << endl)
using namespace std;
using namespace Eigen;
using namespace denseRoutines;

int main(){
    
    switch (1)
	{
	case 1 : {		/* test savetxt */
	    MatrixXcd A(2, 3);
	    A.real() << 1, 2, 3, 4, 5, 6;
	    A.imag() = A.real()/2;
	    CE(A);

	    savetxt("f1.dat", A.real());
	    savetxt("f2.dat", A.imag());
	    break;
	}
	    
	default :{
	    fprintf(stderr, "indicate a case \n");
	}
	    
    }

    return 0;

}
<file_sep># One- and two-dimensional cubic-quintic complex Ginzburg-Landau equation

## Inheritance diagram
![CQCGL1d](../../include/classCQCGL1d__inherit__graph.png)
![CQCGL2d](../../include/classCQCGL2d__inherit__graph.png)
<file_sep>/* to comiple:
 * (Note : libksdim.a is static library, so the following order is important)
 *
 * h5c++ test_ksdim.cc -std=c++11 -O3 -march=corei7 -msse4 -msse2 -I$XDAPPS/eigen/include/eigen3 -I$RESH/include  -L$RESH/lib -lksdim -lksint -lfftw3 -ldenseRoutines -lmyH5
 * 
 */

#include <iostream>
#include <Eigen/Dense>
#include <string>
#include <fstream>
#include "ksdim.hpp"
#include <sys/types.h>
#include <sys/stat.h> 		/* for create folder */
#include <unistd.h>


using namespace std;
using namespace Eigen;

int main(){
    cout.precision(16);

    switch (50) {

    case 1: {
	MatrixXi subspDim(4,3); 
	subspDim << 
	  0, 0, 0,
	  0, 7, 27,
	  1, 8, 28,
	  1, 29, 29; // (0-6,7-29), (0-7,8-29), (0-8,9-29)
	cout << subspDim << endl;
	string fileName("../../data/ks22h001t120x64EV.h5");
	string ppType("rpo");	
	int ppId = 33;
	auto ang = anglePO(fileName, ppType, ppId, subspDim);
	
	cout << ang.second << endl;
	
	ofstream file;
	file.precision(16);
	file.open("good.dat", ios::trunc);
	file << ang.first << endl;
	file.close();

	break;
	
    }
	
    case 2: {			/* test the angle tangency */
	string fileName("../../data/ks22h001t120x64EV.h5");
	string ppType("rpo");
	anglePOs(fileName, ppType, 30, 200, "./anglePOs64/rpo/vector", "vector", 29);
	break;
    }

    case 3: {			/* test the angle tangency
				   but with diefferent style
				*/
	// string fileName("../../data/ks22h001t120x64EV.h5");
	string fileName("../../data/ex.h5");
	// std::vector<int> ppIds(10);
	// for(int i = 0; i < 10; i++) ppIds[i] = i+191;
	int pid[] = {33, 36, 59, 60, 79, 81, 109, 114};
	std::vector<int> ppIds(pid, pid+8);
	
	char buf[1000];
	char* buffer = getcwd(buf, 1000);
	string pwd = buf;
	pwd = pwd + "/anglePOs64/"; 

	// create folders
	bool doCreate = true;
	std::string fs[6]{"ppo", "ppo/space", "ppo/vector", "rpo", "rpo/space", "rpo/vector"};
	int ss = 0;
	if(doCreate){
	    for(int i = 0; i < 6; i++){
		int s = mkdir( (pwd + fs[i]).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
		ss += s;
	    }
	}
	
	if ( ss == 0 ){
	    anglePOs(fileName, "rpo", 30, ppIds, "./anglePOs64/rpo/space", "space", 29);
	    // anglePOs(fileName, "ppo", 30, ppIds, "./anglePOs64/ppo/space", "space", 29);
	}

	break;
    }

    case 30: {			/* test partialHyperb */
	string fileName("../../data/ks22h001t120x64EV.h5");
	string ppType("rpo");
	MatrixXd expand  = partialHyperb(fileName, ppType, 3);
	// cout << expand << endl;
	
	break;
    }

    case 40: {	       /* calculate the local expansion rate of FVs */
	string fileName("../../data/ks22h001t120x64EV.h5");
	partialHyperbOneType(fileName, "rpo", 200, "./FVexpand/rpo/");
	// partialHyperbAll(fileName, 200, 200, "./FVexpand/");
	break;
    }

    case 50: {			/* calculate the local Floquet exponents */
	string fileName("../../data/ks22h001t120x64EV.h5");
	localFEAll(fileName, 200, 200, "./localFE/");
	break;
    }

    default: {
	fprintf(stderr, "indicate a case\n");	
    }
	
    }
}
<file_sep>#ifndef CQCGL1dRpo_H
#define CQCGL1dRpo_H

#include <complex>
#include <utility>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <vector>
#include "CQCGL1d.hpp"
#include "iterMethod.hpp"
#include "sparseRoutines.hpp"
#include "denseRoutines.hpp"

using Eigen::Vector3d;

class CQCGL1dRpo : public CQCGL1d {

public:

    typedef std::complex<double> dcp;
    typedef Eigen::SparseMatrix<double> SpMat;
    typedef Eigen::Triplet<double> Tri;

    ////////////////////////////////////////////////////////////
    // A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    CQCGL1dRpo(int N, double d,
	       double Mu, double Dr, double Di, double Br, double Bi, 
	       double Gr, double Gi, int dimTan);
    
    // A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
    CQCGL1dRpo(int N, double d, 
	       double b, double c, double dr, double di, 
	       int dimTan);
    
    // iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
    CQCGL1dRpo(int N, double d,
	       double delta, double beta, double D, double epsilon,
	       double mu, double nu, int dimTan);
    ~CQCGL1dRpo();
    CQCGL1dRpo & operator=(const CQCGL1dRpo &x);
    
    
    ////////////////////////////////////////////////////////////    
    static
    std::string toStr(double x);
    
    static
    std::string toStr(double x, double y, int id);

    static
    void write(const std::string fileName, const std::string groupName,
	       const MatrixXd &x, const double T, const int nstp,
	       const double th, const double phi, double err);    

    static
    void write2(const std::string fileName, const std::string groupName, 
		const MatrixXd &x, const int nstp, double err);

    static
    std::tuple<MatrixXd, double, int, double, double, double>
    read(const std::string fileName, const std::string groupName);

    static
    void
    move(std::string infile, std::string ingroup, 
	 std::string outfile, std::string outgroup, int flag);

    static
    VectorXcd 
    readE(std::string fileName, const std::string groupName);

    static
    MatrixXd 
    readV(std::string fileName, const std::string groupName);
    
    static
    void 
    writeE(std::string fileName, const std::string groupName, 
	   const VectorXcd &e);

    static
    void 
    writeV(std::string fileName, const std::string groupName, 
	   const MatrixXd &v);
    
    ////////////////////////////////////////////////////////////  


    std::tuple<VectorXd, double, double, double, double>
    findRPO(const VectorXd &x0, const double T,
	    const double th0, const double phi0,
	    const double tol = 1e-12,
	    const int btMaxIt = 20,
	    const int maxit = 100,
	    const double eta0 = 1e-4,
	    const double t = 1e-4,
	    const double theta_min = 0.1,
	    const double theta_max = 0.5,
	    const int GmresRestart = 30,
	    const int GmresMaxit = 100);

    std::tuple<MatrixXd, double, double, double, double>
    findRPOM(const MatrixXd &x0, const double T,
	     const double th0, const double phi0,
	     const double tol = 1e-12,
	     const int btMaxIt = 20,
	     const int maxit = 100,
	     const double eta0 = 1e-4,
	     const double t = 1e-4,
	     const double theta_min = 0.1,
	     const double theta_max = 0.5,
	     const int GmresRestart = 30,
	     const int GmresMaxit = 100);

    std::tuple<VectorXd, double, double, double, double>
    findRPO_hook(const VectorXd &x0, const double T,
		 const double th0, const double phi0,
		 const double tol,
		 const double minRD,
		 const int maxit,
		 const int maxInnIt,
		 const double GmresRtol,
		 const int GmresRestart,
		 const int GmresMaxit);
    
    std::tuple<MatrixXd, double, double, double, double>
    findRPOM_hook(const MatrixXd &x0, const double T,
		  const double th0, const double phi0,
		  const double tol = 1e-12,
		  const double minRD = 1e-3,
		  const int maxit = 100,
		  const int maxInnIt = 20,
		  const double GmresRtol = 1e-6,
		  const int GmresRestart = 100,
		  const int GmresMaxit = 100);

    VectorXd calPre(const VectorXd &x, const VectorXd &dx);

    std::tuple<MatrixXd, double, int>
    findRPOM_hook2(const MatrixXd &x0, 
		   const int nstp,
		   const double tol,
		   const double minRD,
		   const int maxit,
		   const int maxInnIt,
		   const double GmresRtol,
		   const int GmresRestart,
		   const int GmresMaxit);

    void 
    findRpoParaSeq(const std::string file, int id, double step, int Ns, bool isBi,
		   int nstpFlag, int paraNstp);
    
    std::tuple<SpMat, SpMat, VectorXd> 
    calJJF(const VectorXd &x);
    std::tuple<MatrixXd, double>
    findRPOM_LM(const MatrixXd &x0, 
		const double tol,
		const int maxit,
		const int innerMaxit);
    
    ////////////////////////////////////////////////////////////
    VectorXd MFx(const VectorXd &x, int nstp);
    VectorXd MDFx(const VectorXd &x, const VectorXd &dx, int nstp);
    VectorXd MFx2(const VectorXd &x, int nstp);
    VectorXd MDFx2(const VectorXd &x, const VectorXd &dx, int nstp);
    
};

template<class Mat>
struct cqcglJJF {
    typedef Eigen::SparseMatrix<double> SpMat;
    
    CQCGL1dRpo &rpo;
    
    
    cqcglJJF(CQCGL1dRpo &rpo_) : rpo(rpo_){}
    
    std::tuple<SpMat, SpMat, VectorXd>
    operator()(const VectorXd &x) {
	return rpo.calJJF(x);
    }	
};



#endif	/* CQCGL1dRpo */
<file_sep>// how to compile
// h5c++ -O3 test_myH5.cc -L../../lib -I../../include -I$EIGEN -std=c++11 -lmyH5 -lm

#include "myH5.hpp"

using namespace H5;
using namespace std;
using namespace Eigen;
using namespace MyH5;

#define N10

int main(){
    
#ifdef N10
    //======================================================================
    string s = "/usr/local/home/xiong/00git/research/data/cgl/reqsubBiGi.h5";
    vector<vector<string>> x = scanGroup(s);
    for(auto v : x){
	for(auto s : v)
	    cout << s;
	cout << endl;
    }
    
#endif
    return 0;
}
<file_sep>#include <boost/python.hpp>
#include <cstdio>

using namespace std;
namespace bp = boost::python;

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

class Base {
public :
    int x;
    Base(int x) : x(x) {}
    Base(){}
};

class Test {
 
public:
    int N;
    Base b;
    Test(int N) : N(N) {
	b.x = 1;
    }
};

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


BOOST_PYTHON_MODULE(py_test) {
    
    bp::class_<Base>("Base", bp::init<int>())
	.def_readwrite("x", &Base::x)
	;
    
    bp::class_<Test>("Test", bp::init<int>())
	.def_readwrite("N", &Test::N)
	.def_readwrite("b", &Test::b)
	//.def("redV2", &pyKS::PYredV2)
	;

}
<file_sep>from personalFunctions import *

case = 10

if case == 10:
    """
    check the angle along one orbit
    maxElement.dat stores the data for ppo147 the largest absolute 
    off diagonal elements
    """
    f = './anglePOs64/ppo/space/147/ang1.dat'
    ang = np.arccos(np.loadtxt(f))

    fig, ax = pl2d(yscale='log', labs=[r'$t$', r'$\theta$'], tickSize=18)
    ax.plot(ang[::10])
    ax2d(fig, ax)

    off = np.loadtxt('maxElement.dat')
    fig, ax = pl2d(yscale='log', labs=[r'$t$', r'$\max|R_{ij}|$'], tickSize=18)
    ax.plot(off)
    ax2d(fig, ax)
    

    
    
<file_sep>CC = g++
AR = ar

OPTIM = -O3 -msse2 -msse4 -march=corei7
INCLUDE = ../../include
EIGEN = /usr/local/home/xiong/apps/eigen/include/eigen3
CFLAGS = -std=c++11 
LIB = ../../lib

# for pace cluster 
ifdef pace
OPTIM = -O3
EIGEN = /nv/hp16/xding35/data/apps/eigen/include/eigen3
endif
####

CLEANUP = no
ifeq ($(CLEANUP), yes)
CFLAGS += -DCLEAN
endif

SOURCE = myfft.cc
SHARED = $(addprefix lib, $(addsuffix .so, $(basename $(word 1, $(SOURCE)))))
STATIC = $(addprefix lib, $(addsuffix .a, $(basename $(word 1, $(SOURCE)))))


all : $(SHARED) $(STATIC) 

$(SHARED): $(SOURCE)
	$(CC) -shared -fpic $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^ -o $@
$(SOURCE:.cc=.o) : $(SOURCE)
	$(CC) -c $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
$(STATIC): $(SOURCE:.cc=.o)
	$(AR) crs $@ $^

clean:
	rm -f *.so *.o *.a
move:
	mv *.so *.a  $(LIB)
<file_sep>/* How to compile:
 * h5c++ test_KSPO.cc -L../../lib -I../../include -I$EIGEN -std=c++11 -lKSPO -lksint -lmyH5 -literMethod -ldenseRoutines -lsparseRoutines -lped -lfftw3 -lm 
 *
 * mpicxx  has flag -cxx, which can be used to specify cc compiler. eg. -cxx=h5c++
 * */
#include "KSPO.hpp"
#include "ksint.hpp"
#include "myH5.hpp"
#include <iostream>
#include <cmath>				
//#include <mpi.h>
using namespace std;
using namespace Eigen;
using namespace MyH5;

#define CASE_60

int main(int argc, char **argv) {

#ifdef CASE_10
    //================================================================================    
    // move data
    string fin = "../../data/ks22h001t120x64EV.h5";
    H5File fin2(fin, H5F_ACC_RDONLY);
    string fout = "tmp.h5";
    H5File fout2(fout, H5F_ACC_TRUNC);

    VectorXd a;
    double T, r, s;
    int nstp; 
    MatrixXd es, vs;

    vector<vector<string>> gs = scanGroup(fin);
    for(auto v : gs){
	bool isRPO = v[0] == "rpo";
	std::tie(a, T, nstp, s, r) = KSPO::read(fin2, v[0] + "/" + v[1], isRPO);
	KSPO::write(fout2, KSPO::toStr(v[0], stoi(v[1])), isRPO, a, T, nstp, -s/22*2*M_PI, r);
	if(checkGroup(fin2, v[0] + "/" + v[1] + "/e", false)){
	    es = KSPO::readE(fin2, v[0] + "/" + v[1]); 
	    vs = KSPO::readV(fin2, v[0] + "/" + v[1]);
	    KSPO::writeE(fout2, KSPO::toStr(v[0], stoi(v[1])), es);
	    KSPO::writeV(fout2, KSPO::toStr(v[0], stoi(v[1])), vs);
	}
    }
    
#endif
#ifdef CASE_20
    //================================================================================    
    // test multiF(). For rpo, the shift should be reversed.
    int N = 64;
    double L = 22;
    KSPO ks(N, L);
    
    string fileName = "../../data/ks22h001t120x64EV.h5";
    H5File file(fileName, H5F_ACC_RDONLY);
    string ppType = "rpo";
    bool isRPO = ppType == "rpo";
    int ppId = 1;

    ArrayXd a;
    double T, theta, err;
    int nstp;
    std::tie(a, T, nstp, theta, err) = ks.read(file, ks.toStr(ppType, ppId), isRPO);
    VectorXd x(ks.N);
    x << a, T, theta;

    VectorXd F = ks.MFx(x, nstp, isRPO);
    cout << F.norm() << endl;
	
#endif
#ifdef CASE_30
    //================================================================================
    // findPO from one L = 22 orbit 
    int N = 64;
    double L = 21.95;
    KSPO ks(N, L);
    
    string fileName = "../../data/ks22h001t120x64EV.h5";
    H5File file(fileName, H5F_ACC_RDONLY);
    string ppType = "rpo";
    bool isRPO = ppType == "rpo";
    int ppId = 1;
    int M = 10;

    ArrayXd a;
    double T, theta, err;
    int nstp;
    std::tie(a, T, nstp, theta, err) = ks.read(file, ks.toStr(ppType, ppId), isRPO);
    nstp /= 10;
    ArrayXXd aa = ks.intgC(a, T/nstp, T, nstp/M); 

    ArrayXXd x;
    if(isRPO){
	x.resize(ks.N, M);
	x << aa, ArrayXXd::Ones(1, M) * T/M, ArrayXXd::Zero(1, M);
	x(N-1, M-1) = theta;
    }
    else {
	x.resize(ks.N - 1, M);
	x << aa, ArrayXXd::Ones(1, M) * T/M;
    }
    ArrayXXd ap;
    double errp;
    int flag;
    std::tie(ap, errp, flag) = ks.findPO_LM(x, isRPO, nstp/M, 1e-12, 100, 30);
    double Tp = ap.row(N-2).sum();
    double thetap = isRPO ? ap.row(N-1).sum() : 0;
    H5File fout("tmp.h5", H5F_ACC_RDWR);
    if (flag == 0) ks.write(fout, ks.toStr(L, ppType, ppId), isRPO, ap.col(0).head(N-2), Tp, nstp, thetap, errp); 

#endif
#ifdef CASE_40
    //================================================================================
    // findPO sequentially change parameters
    int N = 64;
    
    string fileName = "../../data/ksh01x64.h5";
    H5File file(fileName, H5F_ACC_RDWR);
    string ppType = "rpo";
    bool isRPO = ppType == "rpo";
    int ppId = 2;
    int M = 10;
    
    ArrayXd a;
    double T, theta, err, errp;
    int nstp, flag;
    ArrayXXd ap;
    
    double dL = 0.05, L0 = 21.4;
    for(int i = 0; i < 5; i++){
	double L = L0 - i*dL;
	KSPO ks(N, L);
	
	std::tie(a, T, nstp, theta, err) = ks.read(file, ks.toStr(L + dL, ppType, ppId), isRPO);
	ArrayXXd aa = ks.intgC(a, T/nstp, T, nstp/M); 
	
	ArrayXXd x;
	if(isRPO){
	    x.resize(ks.N, M);
	    x << aa, ArrayXXd::Ones(1, M) * T/M, ArrayXXd::Zero(1, M);
	    x(N-1, M-1) = theta;
	}
	else {
	    x.resize(ks.N - 1, M);
	    x << aa, ArrayXXd::Ones(1, M) * T/M;
	}
	
	std::tie(ap, errp, flag) = ks.findPO_LM(x, isRPO, nstp/M, 1e-12, 100, 30);
	double Tp = ap.row(N-2).sum();
	double thetap = isRPO ? ap.row(N-1).sum() : 0;
	if (flag == 0) ks.write(file, ks.toStr(L, ppType, ppId), isRPO, ap.col(0).head(N-2), Tp, nstp, thetap, errp);
	else exit(1);
    }
#endif
#ifdef CASE_50
    //================================================================================
    // calculate E/V
    int N = 64;
    double L = 21.95;
    KSPO ks(N, L);
    
    string fileName = "../../data/ksh01x64.h5";
    H5File file(fileName, H5F_ACC_RDONLY);
    string ppType = "ppo";
    bool isRPO = ppType == "rpo";
    int ppId = 1;

    ArrayXd a;
    double T, theta, err;
    int nstp;
    std::tie(a, T, nstp, theta, err) = ks.read(file, ks.toStr(L, ppType, ppId), isRPO);
    
    auto ev = ks.calEV(isRPO, a, T, nstp, theta, 1e-12, 1000, 10);
    MatrixXd &e = ev.first, &v = ev.second;

    cout << e << endl;   
#endif
#ifdef CASE_60
    //================================================================================
    // calculate E/V for all rpo/ppo
    int N = 64;
    string fileName = "../../data/ksh01x64EV.h5";
    H5File file(fileName, H5F_ACC_RDWR);
    auto gs = scanGroup(fileName);
    
    ArrayXd a;
    double T, theta, err;
    int nstp;
    
    for(auto ss : gs){
	double L = stod(ss[0]);
	string ppType = ss[1];
	bool isRPO = ppType == "rpo";
	int ppId = stoi(ss[2]);	
	string groupName = KSPO::toStr(L, ppType, ppId);
	if (!checkGroup(file, groupName + "/e", false)){
	    KSPO ks(N, L);
	    std::tie(a, T, nstp, theta, err) = ks.read(file, groupName, isRPO);
	    auto ev = ks.calEV(isRPO, a, T, nstp, theta, 1e-12, 1500, 10);
	    MatrixXd &e = ev.first, &v = ev.second;
	    ks.writeE(file, groupName, e.topRows(10));
	    ks.writeV(file, groupName, v);
	}
    }

#endif

    return 0;
}


<file_sep>#include "iterMethod.hpp"

namespace iterMethod {

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    // global variables
    
    bool CG_PRINT = true;
    int CG_PRINT_FREQUENCE = 100;

    bool GMRES_OUT_PRINT = true;
    int GMRES_OUT_PRINT_FREQUENCE = 1;

    bool GMRES_IN_PRINT = true;
    int GMRES_IN_PRINT_FREQUENCE = 1;

    bool HOOK_PRINT = true;
    int HOOK_PRINT_FREQUENCE = 1;

    bool INB_OUT_PRINT = true;
    int INB_OUT_PRINT_FREQUENCE = 1;

    bool INB_IN_PRINT = true;
    int INB_IN_PRINT_FREQUENCE = 1;

    bool LM_OUT_PRINT = true;
    int LM_OUT_PRINT_FREQUENCE = 1;

    bool LM_IN_PRINT = true;
    int LM_IN_PRINT_FREQUENCE = 1;

    double LM_LAMBDA_INCREASE_FACTOR = 10;
    double LM_LAMBDA_DECREASE_FACTOR = 10;
    double LM_MAX_LAMBDA = 1e10;
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////




    /**
     * @brief obtain the cos and sin from coordinate (x, y)
     */
    void rotmat(const double &x, const double &y,
		double *c, double *s){
	if(y == 0){
	    *c = 1;
	    *s = 0;
	}
	else if ( fabs(y) > fabs(x) ){
	    double tmp = x / y;
	    *s = 1.0 / sqrt(1.0 + tmp*tmp);
	    *c = tmp * (*s);
	}
	else {
	    double tmp = y / x;
	    *c = 1.0 / sqrt(1.0 + tmp*tmp);
	    *s = tmp * (*c);
	}
    }


    /**
     * @brief choose the scaling parameter theta in the Inexact Newton Backtracking algorithm
     *
     * When choosing theta, we take a quadratic model
     *      g(theta) = ||F(x + theta * s)|| = (g(1) - g(0) - g'(0))*theta^2 + g'(0)*theta + g(0)
     * with
     *      g'(0) = 2 * F^{T}(x) * F'(x) * s
     * The derivatives are:
     *      g'(theta) = 2 * (g(1) - g(0) - g'(0))*theta + g'(0)
     *      g''(theta) = 2 * (g(1) - g(0) - g'(0))
     *
     * If g''(0) < 0, take theta = theta_max
     * If g''(0) > 0, take theta =  - g'(0) /  2 * (g(1) - g(0) - g'(0))
     */
    double chooseTheta(const double g0, const double g1, const double gp0,
		       const double theta_min, const double theta_max){
	double theta;
	double gpp0 = 2 * (g1 - g0 - gp0);
	if (gpp0 < 0) theta = theta_max;
	else theta = -gp0 / gpp0;
	
	// restrict theta in [theta_min, theta_max]
	return theta > theta_max ? theta_max : (theta < theta_min ? theta_min : theta);
    }


    //////////////////////////////////////////////////////////////////////
    ///////////////////   trust region GMRES related /////////////////////
    //////////////////////////////////////////////////////////////////////
    /**
     * @brief calculate z = d_i * p_i / (d_i^2 + mu)
     */
    ArrayXd calz(const ArrayXd &D, const ArrayXd &p, const double mu){
	return D * p / (D.square() + mu);
    }

    /**
     * @brief use newton method to find the parameter mu which minize
     *        ||D*z - p|| w.r.t. ||z||< delta
     */
    std::tuple<double, std::vector<double>, int>
    findTrustRegion(const ArrayXd &D, const ArrayXd &p, double delta,
		    const double tol, const int maxit,
		    const double mu0){
	double mu = mu0;
	std::vector<double> errVec;

	// first check whether mu = 0 is enough
	if( (p / D).matrix().norm() <= delta )
	    return std::make_tuple(0, errVec, 0);
	
	// use Newton iteration to find mu
	for(size_t i = 0; i < maxit; i++){
	    ArrayXd denorm = D.square() + mu;	  /* di^2 + mu */
	    ArrayXd z = D * p / denorm;		  /* z  */
	    double z2 = z.matrix().squaredNorm(); /* ||z||^2 */
	    double phi = z2 - delta * delta;	  /* phi(mu) */
		
	    errVec.push_back(phi);
	    if(fabs(phi) < tol) return std::make_tuple(mu, errVec, 0);
		
	    double dphi = (-2*(D * p).square() / denorm * denorm * denorm).sum();
	    mu -= (sqrt(z2) / delta) * ( phi / dphi );
	    // mu -=  phi / dphi ;  
	}

	// run out of loop => not converged
	return std::make_tuple(mu, errVec, 1);
    }

    //////////////////////////////////////////////////////////////////////
    //            Levenberg-Marquardt related                           //
    //////////////////////////////////////////////////////////////////////
    
    /*
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    JJF(const MatrixXd &J, const VectorXd &x){
	MatrixXd JJ = J.transpose() * J;
	MatrixXd d = JJ.diagonal().asDiagonal();
	return std::make_tuple(JJ, d, J*x);
    }

    */
    
    std::tuple<VectorXd, std::vector<double>, int>
    LM( const MatrixXd &A, const VectorXd &b,
	const VectorXd &x0, const double tol,
	const int maxit, const int innerMaxit){
	
	ColPivHouseholderQR<MatrixXd> solver;
	auto fx = [&A, &b](const VectorXd &x) { return A*x - b; };
	JJF<MatrixXd> jj(A, b); 
	return LM0( fx, jj, solver, x0, tol, maxit, innerMaxit );
    }

}
<file_sep>from py_CQCGL1d import *
from cglHelp import *

case = 16

if case == 8:
    """
    calculate the stability exponents of req
    of different di.
    At the same time, compare it with the linear part of
    the velocity
    """
    N = 1024
    d = 30
    di = 0.06

    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5', di, 1)
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    print eigvalues[:10]
    
    e = eigvalues
    L0 = cgl.L()
    L1 = cgl.C2R(L0)
    L2 = L1[::2] + 1j*L1[1::2]
    L2 = 1 / L2
    L3 = np.zeros(cgl.Ndim)
    L3[::2] = L2.real
    L3[1::2] = L2.imag
    L = cgl.L()[:cgl.Ne/2]
    scatter2dfig(L.real, L.imag)
    scatter2dfig(e.real, e.imag)

    def dp(A, L):
        n = len(L)
        for i in range(n):
            A[:, i] = A[:, i] * L[i]
        return A
    
    A = cgl.stabReq(a0, wth0, wphi0).T
    Ap = dp(A, L3)
    e2, v2 = eig(Ap)
    e2, v2 = sortByReal(e2, v2)
    

if case == 10:
    """
    use the new data to calculate tyhe stability exponents of req
    """
    N = 1024
    d = 50
    Bi = 0.8
    Gi = -0.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)

    a0, wth0, wphi0, err0 = req.readReqBiGi('../../data/cgl/reqBiGi.h5',
                                            Bi, Gi, index)
    e, v = req.eigReq(a0, wth0, wphi0)
    print e[:10]

if case == 11:
    """
    calculate the stability exponents and 10 leading vectors
    save them into the database
    """
    N = 1024
    d = 30
    h = 0.0002
    
    for i in range(len(dis)):
        a0, wth0, wphi0, err = cqcglReadReq(files[i], '1')
        cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, dis[i], 4)
        e, v = eigReq(cgl, a0, wth0, wphi0)
        print e[:8]
        cqcglAddEV2Req(files[i], '1', e.real, e.imag,
                       v[:, :10].real, v[:, :10].imag)

if case == 12:
    """
    simply view the heat map of relative equilibria
    """
    N = 1024
    d = 30
    h = 1e-4
    di = 0.96

    a0, wth0, wphi0, err0 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                           di, 2)
    cgl = pyCQCGL1d(N, d, 4.0, 0.8, 0.01, di, -1)

    nstp = 10000
    for i in range(3):
        aa = cgl.intg(a0, h, nstp, 10)
        a0 = aa[-1]
        plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])


if case == 13:
    """
    new size L = 50
    """
    N = 1024
    d = 50
    h = 1e-4
    di = 0.96

    a0, wth0, wphi0, err0 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                           di, 1)
    a1, wth1, wphi1, err1 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                           di, 2)
    cgl = pyCQCGL1d(N, d, 4.0, 0.8, 0.01, di, -1)
    plotOneConfigFromFourier(cgl, a0)
    plotOneConfigFromFourier(cgl, a1)

    
if case == 14:
    N = 1024
    d = 30
    h = 1e-4

    Q0 = []
    Q1 = []
    dis = np.arange(0.08, 0.57, 0.01)
    for i in range(len(dis)):
        di = dis[i]
        cgl = pyCQCGL1d(N, d, 4.0, 0.8, 0.01, di, -1)
        a0, wth0, wphi0, err0 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                               di, 1)
        a1, wth1, wphi1, err1 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                               di, 2)
        Q0.append(cgl.calQ(a0)[0])
        Q1.append(cgl.calQ(a1)[0])
    
    fig, ax = pl2d(labs=[r'$d_i$', r'$Q$'], axisLabelSize=25, tickSize=15)
    ax.plot(dis, Q0, lw=2, c='r', ls='-')
    ax.plot(dis, Q1, lw=2, c='b', ls='--')
    ax2d(fig, ax)

if case == 16:
    """
    to see different profiles with L = 50
    More : to see the transition from req to rpo in the stable region
    """
    N, d = 1024, 50
    h = 2e-3

    Bi, Gi = 0.8, -0.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    req = CQCGLreq(cgl)
    cp = CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.readBiGi('../../data/cgl/reqBiGiEV.h5', Bi, Gi, index, flag=2)
    print e[:20]
    
    T = 60
    a0 += 0.1*norm(a0)*v[0].real
    for i in range(1):
        aa = cgl.intgC(a0, h, T, 10)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, T])

if case == 17:
    """
    view the req with new L
    """
    N = 1024
    d = 50
    h = 2e-3
    
    Bi = 2.7
    Gi = -5.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)

    fig, ax = pl2d(size=[8, 6], labs=[r'$x$', r'$|A|$'], axisLabelSize=25, tickSize=16)

    a0, wth0, wphi0, err0 = req.readReqBiGi('../../data/cgl/reqBiGiEV.h5', Bi, Gi, 1, flag=0)
    Aamp = np.abs(cgl.Fourier2Config(a0))
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2, c='r')
    a0, wth0, wphi0, err0 = req.readReqBiGi('../../data/cgl/reqBiGiEV.h5', Bi, Gi, 2, flag=0)
    Aamp = np.abs(cgl.Fourier2Config(a0))
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2, c='b')

    ax2d(fig, ax)
            

if case == 18:
    """
    Plot the solitons in the Bi-Gi plane to see the transition.
    """
    N = 1024
    d = 50
    h = 2e-3
    
    fileName = '../../data/cgl/reqBiGi.h5'
    
    for i in range(90):
        Bi = -3.2 + i * 0.1
        fig, ax = pl2d(size=[8, 6], labs=[r'$x$', r'$|A|$'], ylim=[-0.5, 3], axisLabelSize=25)
        name = format(Bi, '013.6f') + '.png'
        for j in range(55):
            Gi = -0.2 - 0.1*j
            cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
            req = CQCGLreq(cgl)
            if req.checkExist(fileName, req.toStr(Bi, Gi, 1)):
                a0, wth0, wphi0, err0 = req.readReqBiGi(fileName, Bi, Gi, 1)
                Aamp = np.abs(cgl.Fourier2Config(a0))
                ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp)
            if req.checkExist(fileName, req.toStr(Bi, Gi, 2)):
                a0, wth0, wphi0, err0 = req.readReqBiGi(fileName, Bi, Gi, 2)
                Aamp = np.abs(cgl.Fourier2Config(a0))
                ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp)
        ax2d(fig, ax, save=True, name='ex/'+name)
        

if case == 19:
    """
    plot the stability of req in the Bi-Gi plane
    and save the data
    """
    N = 1024
    d = 50
    h = 2e-3
    
    fileName = '../../data/cgl/reqBiGiEV.h5'
    index = 1
    
    cs = {0: 'g', 1: 'm', 2: 'c', 4: 'r', 6: 'b'}#, 8: 'y', 56: 'r', 14: 'grey'}
    ms = {0: 's', 1: '^', 2: '+', 4: 'o', 6: 'D'}#, 8: '8', 56: '4', 14: 'v'}

    es = np.zeros([90, 55, 1362], dtype=np.complex)
    e1 = np.zeros((90, 55), dtype=np.complex)
    ns = set()
    saveData = np.zeros([0, 3])

    fig, ax = pl2d(size=[8, 6], labs=[r'$G_i$', r'$B_i$'], axisLabelSize=25,
                   xlim=[-6, 0], ylim=[-4, 6])
    for i in range(90):
        Bi = 5.7 - i*0.1
        for j in range(55):
            Gi = -0.2 - 0.1*j
            req = CQCGLreq()
            if req.checkExist(fileName, req.toStr(Bi, Gi, index) + '/vr'):
                a0, wth0, wphi0, err0, e, v = req.readReqBiGi(fileName, Bi, Gi, index, flag=2)
                es[i, j, :] = e
                m, ep, accu = numStab(e)
                e1[i, j] = ep[0]
                ns.add(m)
                # print index, Bi, Gi, m
                ax.scatter(Gi, Bi, s=15, edgecolors='none',
                           marker=ms.get(m, '*'), c=cs.get(m, 'k'))
                saveData = np.vstack((saveData, np.array([Gi, Bi, m])));
    
    ax.grid(which='both')
    ax2d(fig, ax)
    np.savetxt("BiGiReqStab.dat", saveData)

if case == 20:
    """
    check req really converges
    """
    fileName = '../../data/cgl/reqBiGiEV.h5'
    index = 2

    for i in range(90):
        Bi = 3.4 - i*0.1
        for j in range(55):
            Gi = -0.2 - 0.1*j
            req = CQCGLreq()
            if req.checkExist(fileName, req.toStr(Bi, Gi, index)):
                a0, wth0, wphi0, err0= req.readReqBiGi(fileName, Bi, Gi, index)
                if err0 > 1e-6:
                    print err0, Bi, Gi
    
if case == 30:
    """
    Try to locate the Hopf bifurcation limit cycle.
    There is singularity for reducing the discrete symmetry
    """
    N = 1024
    d = 30
    h = 0.0005
    di = 0.37
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    a0Tilde = cgl.reduceReflection(a0Hat)
    veHat = cgl.ve2slice(eigvectors, a0)
    # veTilde = cgl.reflectVe(veHat, a0Hat)
    
    nstp = 10000
    # a0Erg = a0 + eigvectors[0]*1e2
    A0 = 2*centerRand(2*N, 0.2)
    a0Erg = cgl.Config2Fourier(A0)
    for i in range(2):
        aaErg = cgl.intg(a0Erg, nstp, 1)
        a0Erg = aaErg[-1]

    aaErgHat, th, phi = cgl.orbit2slice(aaErg)
    # aaErgTilde = cgl.reduceReflection(aaErgHat)
    # aaErgTilde -= a0Tilde
    aaErgHat -= a0Hat

    # e1, e2, e3 = orthAxes(veTilde[0], veTilde[1], veTilde[6])
    e1, e2 = orthAxes2(veHat[0], veHat[1])
    # aaErgTildeProj = np.dot(aaErgTilde, np.vstack((e1, e2, e3)).T)
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2)).T)
    
    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    # ax.plot(aaErgTildeProj[:, 0], aaErgTildeProj[:, 1],
    #         aaErgTildeProj[:, 2], c='r', lw=1)
    ax.plot(aaErgHatProj[:, 0], aaErgHatProj[:, 1],
            c='r', lw=1)
    ax.scatter(aaErgHatProj[0, 0], aaErgHatProj[0, 1], s=30, facecolor='g')
    ax.scatter(aaErgHatProj[-1, 0], aaErgHatProj[-1, 1], s=30, facecolor='k')
    ax.scatter([0], [0], s=160)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
 
if case == 31:
    """
    Try to find the guess of the limit cycle for di large enough
    such that the soliton is unstable.
    """
    N = 1024
    d = 30
    h = 0.0004
    di = 0.43

    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    A0 = 2*centerRand(2*N, 0.2)
    a0 = cgl.Config2Fourier(A0)
    nstp = 10000
    x = []
    for i in range(3):
        aa = cgl.intg(a0, nstp, 1)
        a0 = aa[-1]
        plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, nstp*h])
        # plotPhase(cgl, aa, [0, d, 0, nstp*h])
        # plotOneConfigFromFourier(cgl, aa[-1], d)
        # plotOnePhase(cgl, aa[-1], d)
        # plot1dfig(aa[:, 0])
        x.append(aa)
        
    aaHat, th, phi = cgl.orbit2slice(aa)
    i1 = 3000
    i2 = 6800
    plot3dfig(aaHat[i1:i2, 0], aaHat[i1:i2, 1], aaHat[i1:i2, 2])
    plotConfigSpaceFromFourier(cgl, aa[i1:i2], [0, d, 0, nstp*h])
    nstp = i2 - i1
    T = nstp * h
    th0 = th[i1] - th[i2]
    phi0 = phi[i1] - phi[i2]
    err = norm(aaHat[i1] - aaHat[i2])
    print nstp, T, th0, phi0, err
    # cqcglSaveRPOdi('rpot.h5', di, 1, aa[i1], T, nstp, th0, phi0, err)
    
if case == 40:
    """
    compare the Hopf bifurcation limit cycle with slightly different di
    """
    N = 1024
    d = 30
    h = 0.0002

    dis = [-0.07985, -0.0799, -0.08]
    files = ['req07985.h5', 'req0799.h5', 'req08.h5']
    
    orbits = []
    for i in range(len(dis)):
        a0, wth0, wphi0, err = cqcglReadReq(files[i], '1')
        cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, -0.01, dis[i], 4)

        eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
        print eigvalues[:8]
        eigvectors = Tcopy(realve(eigvectors))
        a0Hat = cgl.orbit2slice(a0)[0]
        veHat = cgl.ve2slice(eigvectors, a0)
        
        nstp = 20000
        a0Erg = a0 + eigvectors[0]*1e-3
        for i in range(10):
            aaErg = cgl.intg(a0Erg, nstp, 1)
            a0Erg = aaErg[-1]

        aaErgHat, th, phi = cgl.orbit2slice(aaErg)
        aaErgHat -= a0Hat
        e1, e2 = orthAxes2(veHat[0], veHat[1])
        aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2)).T)
        orbits.append(aaErgHatProj)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    for i in range(len(orbits)):
        ax.plot(orbits[i][:, 0], orbits[i][:, 1], lw=1,
                label=str(dis[i]))
    ax.scatter([0], [0], s=160)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.legend(loc='upper right', frameon=False)
    plt.show(block=False)

if case == 50:
    """
    visualize a few explosion examples in the covariant coordinate.
    Only care about the part after explosion.
    """
    N = 1024
    d = 30
    h = 0.0002

    di = -0.0799
    a0, wth0, wphi0, err = cqcglReadReq('req0799.h5', '1')
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, -0.01, di, 4)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)
    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[4])

    aa1 = load('0799_v6.npz')['x']
    aa1Hat, th1, phi1 = cgl.orbit2slice(aa1)
    aa1Hat -= a0Hat
    aa1HatProj = np.dot(aa1Hat, np.vstack((e1, e2, e3)).T)

    plotConfigSpaceFromFourier(cgl, aa1, [0, d, 0, aa1.shape[0]*h])
    
    id1 = 4000
    id2 = aa1.shape[0] - 12000

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    ax.plot(aa1HatProj[id1:id2, 0], aa1HatProj[id1:id2, 1],
            c='r', lw=1)
    ax.scatter(aa1HatProj[id1, 0], aa1HatProj[id1, 1], s=30)
    ax.scatter([0], [0], s=160)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa1HatProj[id1:id2, 0], aa1HatProj[id1:id2, 1],
            aa1HatProj[id1:id2, 2], c='r', lw=1)
    ax.scatter(aa1HatProj[id1, 0], aa1HatProj[id1, 1],
               aa1HatProj[id1, 2], s=30)
    ax.scatter([0], [0], [0], s=160)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 60:
    """
    In the case that we visualize Hopf limit cycle and the explosion in the
    same frame, we find that after explosion, the system almost lands
    in a closed cycle. This is a good candidate for search periodic orbits.
    So, we record it.
    """
    N = 1024
    d = 30
    h = 0.0002

    di = -0.0799
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, -0.01, di, 4)

    aa1 = load('0799_v4.npz')['x']
    aa1Hat, th1, phi1 = cgl.orbit2slice(aa1)
    i1 = 0
    i2 = 1
    i3 = 2

    id1 = 19810
    id2 = 20000
    plot3dfig(aa1Hat[id1:id2+1, i1], aa1Hat[id1:id2+1, i2],
              aa1Hat[id1:id2+1, i3])

    x = aa1[id1]
    nstp = id2 - id1
    T = nstp * h
    th = th1[id1] - th1[id2]
    phi = phi1[id1] - phi1[id2]
    err = 1000.0
    print T, th, phi, err
    cqcglSaveRPO('rpo3.h5', '1', x, T, nstp, th, phi, err)

if case == 70:
    """
    construct the plane wave solutions and get their stability
    """
    N = 1024
    L = 30
    h = 0.0002
    b = 4.0
    c = 0.8
    dr = 0.01
    di = 0.07985

    cgl = pyCqcgl1d(N, L, h, True, 0, b, c, dr, di, 4)

    m = 14
    k = 2*np.pi / L * m
    a2 = 1/(2*dr) * (1 + np.sqrt(1-4*dr*(k**2+1)))
    w = b*k**2 - c*a2 + di*a2**2

    a0 = np.zeros(cgl.Ndim)
    a0[2*m] = sqrt(a2) * N
    nstp = 5000
    aa = cgl.intg(a0, nstp, 1)
    plotConfigSpaceFromFourier(cgl, aa, [0, L, 0, nstp*h])

    eigvalues, eigvectors = eigReq(cgl, a0, 0, w)
    eigvectors = Tcopy(realve(eigvectors))
    print eigvalues[:20]
    

if case == 80:
    """
    plot the figure show the stability of solition solutions for
    different di
    """
    N = 1024
    d = 30
    
    dis, reqs = cqcglReadReqEVAll('../../data/cgl/reqDi.h5', 1)
    ers = []
    for i in range(len(reqs)):
        a, wth, wphi, err, er, ei, vr, vi = reqs[i]
        k = 0
        while abs(er[k]) < 1e-8:
            k += 1
        ers.append(er[k])
        
    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    ax.plot([min(dis), max(dis)], [0, 0], c='r', ls='--', lw=1.5)
    ax.scatter(dis, ers, s=10, marker='o', facecolor='b', edgecolors='none')
    ax.set_xlabel(r'$d_i$', fontsize=20)
    ax.set_ylabel(r'$\mu$', fontsize=20)
    # ax.set_yscale('log')
    ax.set_xlim(0, 1)
    # ax.set_ylim(-2, 18)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 90:
    """
    view the unstable manifold of the req in the symmetry reduced projected
    coordinates
    """
    N = 1024
    d = 30
    di = 0.06
   
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    cgl.changeOmega(-wphi0)
    cgl.rtol = 1e-10
    eigvalues, eigvectors = eigReq(cgl, a0, wth0, 0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    T = 20
    
    a0Erg = a0 + eigvectors[0]*1e-3
    aaErg = cgl.aintg(a0Erg, 0.001, T, 1)
    aaErgHat, th, th = cgl.orbit2slice(aaErg)
    aaErgHat -= a0Hat
    
    a0E2 = a0 + eigvectors[2]*1e-3
    aaE2 = cgl.aintg(a0E2, 0.001, T, 1)
    aaE2H, th2, phi2 = cgl.orbit2slice(aaE2)
    aaE2H -= a0Hat

    # e1, e2 = orthAxes2(veHat[0], veHat[1])
    e1, e2, e3 = orthAxes(veHat[3], veHat[2], veHat[6])
    bases = np.vstack((e1, e2, e3)).T
    aaErgHatProj = np.dot(aaErgHat, bases)
    OProj = np.dot(-a0Hat, bases)
    
    aaE2HP = np.dot(aaE2H, bases)

    i1 = 32000
    i2 = 38000
    fig, ax = pl3d(labs=[r'$e_1$', r'$e_2$', r'$e_3$'],
                   axisLabelSize=25)
    #ax.plot(aaErgHatProj[i1:i2, 0], aaErgHatProj[i1:i2, 1],
    #        aaErgHatProj[i1:i2, 2], c='g', lw=1, alpha=0.4)
    ax.plot(aaE2HP[i1:i2, 0], aaE2HP[i1:i2, 1],
            aaE2HP[i1:i2, 2], c='r', lw=1, alpha=0.4)
    ax.plot(aaE2HP[:9000, 0], aaE2HP[:9000, 1],
            aaE2HP[:9000, 2], c='g', lw=1, alpha=0.4)
    ax.plot(aaErgHatProj[:11000, 0], aaErgHatProj[:11000, 1],
            aaErgHatProj[:11000, 2], c='y', lw=1, alpha=1)
    ax.scatter([0], [0], [0], s=80, marker='o', c='b',  edgecolors='none')
    ax.scatter(OProj[0], OProj[1], OProj[2], s=60, marker='o', c='c',
               edgecolors='none')
    ax3d(fig, ax)

    plotConfigSpaceFromFourier(cgl, aaErg[::10].copy(), [0, d, 0, T])
    plotConfigSpaceFromFourier(cgl, aaE2[::10].copy(), [0, d, 0, T])

    # vel = []
    # for i in range(-10000, -000):
    #     vel.append(norm(cgl.velocity(aaErg[i])))

if case == 100:
    """
    view the 2 soliton solution together, and
    see how the unstable manifold of the first
    hits the second solition.
    """
    N = 1024
    d = 30
    h = 0.0002

    di = 0.4227
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    a1, wth1, wphi1, err1 = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                           di, 2)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)
    a1Hat = cgl.orbit2slice(a1)[0]
    a1Hat -= a0Hat

    h3 = 0.0005
    cgl3 = pyCqcgl1d(N, d, h3, False, 0, 4.0, 0.8, 0.01, di, 4)
    nstp = 70000
    a0Erg = a0 + eigvectors[0]*1e-3
    aaErg = cgl3.intg(a0Erg, 50000, 50000)
    a0Erg = aaErg[-1]
    aaErg = cgl3.intg(a0Erg, nstp, 2)
    aaErgHat, th3, th3 = cgl3.orbit2slice(aaErg)
    aaErgHat -= a0Hat
    
    # e1, e2 = orthAxes2(veHat[0], veHat[1])
    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[6])
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2, e3)).T)
    OProj = np.dot(-a0Hat, np.vstack((e1, e2, e3)).T)
    a1HatProj = np.dot(a1Hat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aaErgHatProj[:, 0], aaErgHatProj[:, 1],
            aaErgHatProj[:, 2], c='g', lw=1, alpha=0.4)
    # i1 = -1000
    # ax.plot(aaErgHatProj[i1:, 0], aaErgHatProj[i1:, 1],
    #         aaErgHatProj[i1:, 2], c='k', lw=2)
    ax.scatter([0], [0], [0], s=80, marker='o', c='b',  edgecolors='none')
    ax.scatter(OProj[0], OProj[1], OProj[2], s=60, marker='o', c='c',
               edgecolors='none')
    ax.scatter(a1HatProj[0], a1HatProj[1], a1HatProj[2],
               s=60, marker='o', c='m', edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    # plotConfigSurfaceFourier(cgl, aa1, [0, d, 0, T1])

    # vel = []
    # for i in range(-10000, -000):
    #     vel.append(norm(cgl.velocity(aaErg[i])))

<file_sep>from py_CQCGL2d import *
from py_CQCGL2dReq import *
from personalFunctions import *

case = 40

if case == 10:
    """
    test find req
    """
    N = 1024
    d = 30
    di = 0.05
    
    cgl = pyCQCGL2dReq(N, d, 4.0, 0.8, 0.01, di, 4)
    c2dp = CQCGL2dPlot(d, d)
    a0 = c2dp.load('ex.h5', 721)
    # c2dp.plotOneState(cgl, 'ex.h5', 400)
    cgl.GmresRestart = 300
    cgl.GmresRtol = 1e-6
    th = -cgl.optReqTh(a0)
    print th
    x, wthx, wthy, wphi, err = cgl.findReq_hook(a0, th[0], th[1], th[2])
    
if case == 20:
    """
    find the best candidate for req
    """
    N = 1024
    d = 30
    di = 0.05
    
    cgl = pyCQCGL2dReq(N, d, 4.0, 0.8, 0.01, di, 4)
    c2dp = CQCGL2dPlot(d, d)
    es = []
    for i in range(750):
        a0 = c2dp.load('ex.h5', i)
        th = -cgl.optReqTh(a0)
        e = norm(cgl.velocityReq(a0, th[0], th[1], th[2]))
        es.append(e)
    es = np.array(es)

if case == 30:
    """
    find possible different localized invariant structures.
    """
    N = 1024
    d = 30
    di = 0.05
    
    cgl = pyCQCGL2dReq(N, d, 4.0, 0.8, 0.01, di, 4)
    c2dp = CQCGL2dPlot(d, d)
    A0 = 4*centerRand2d(N, N, 0.2, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    cgl.GmresRestart = 300
    cgl.GmresRtol = 1e-6
    th = -cgl.optReqTh(a0)
    print th
    x, wthx, wthy, wphi, err = cgl.findReq_hook(a0, th[0], th[1], th[2])
    print "norm", norm(x)

if case == 40:
    """
    check the accuracy of the req
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6
    reqFile = "../../data/cgl/req2dBiGi.h5"

    cgl = pyCQCGL2dReq(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4)
    c2dp = CQCGL2dPlot(d, d)
    a0, wthx0, wthy0, wphi0, err = c2dp.loadReq(reqFile, c2dp.toStr(Bi, Gi, 1))
    
    v = cgl.velocityReq(a0, wthx0, wthy0, wphi0)
    
    print norm(v)

if case == 60:
    """
    find possible different localized invariant structures.
    for L = 50
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6
    
    cgl = pyCQCGL2dReq(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4)
    c2dp = CQCGL2dPlot(d, d)
    a0 = c2dp.load('ex.h5', 350)
    # A0 = 1*centerRand2d(N, N, 0.2, 0.2, True)
    # a0 = cgl.Config2Fourier(A0)
    cgl.GmresRestart = 300
    cgl.GmresRtol = 1e-6
    th = -cgl.optReqTh(a0)
    print th
    x, wthx, wthy, wphi, err = cgl.findReq_hook(a0, th[0], th[1], th[2])
    print "norm", norm(x)
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' intgM1.cpp ../ksint.cc ../ksintM1.cc -I../../../include  -I$XDAPPS/eigen/include/eigen3 -lfftw3
 * */
#include "ksintM1.hpp"
#include "mex.h"
#include "matrix.h"
#include <cmath>
#include <cstring>
#include <cassert>
#include <Eigen/Dense>

using namespace Eigen;

/* ks 1st mode slice integrator without Jacobian */
static std::pair<ArrayXXd, ArrayXd>
intgM1(double *a0, int N, double h, int nstp, int np, double d){
  KSM1 ks(N+2, h, d);
  Map<ArrayXd> v0(a0, N);
  return ks.intg(v0, nstp, np);
}

void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    int np = 1;
    double d = 22;
    
    switch (nrhs) 
	{
	case 5 :
	    d =  mxGetScalar(prhs[4]); 
	case 4 :
	    np = mxGetScalar(prhs[3]); 
	case 3 : {
	    // get the pointer and the size of input 
	    double *a0 = mxGetPr(prhs[0]);
	    mwSize N = mxGetM(prhs[0]);
	    mwSize M = mxGetN(prhs[0]);
	    assert( N % 2 == 0 && M = 1 );	
	    double h = mxGetScalar(prhs[1]);
	    int nstp = mxGetScalar(prhs[2]);

	    plhs[0] = mxCreateDoubleMatrix(N, nstp/np + 1, mxREAL);
	    plhs[1] = mxCreateDoubleMatrix(nstp/np + 1, 1, mxREAL);
	    std::pair<ArrayXXd, ArrayXd> tmp = intgM1(a0, N, h, nstp, np, d);
	    memcpy(mxGetPr(plhs[0]), &tmp.first(0,0), (nstp/np+1)*N*sizeof(double));
	    memcpy(mxGetPr(plhs[1]), &tmp.second(0), (nstp/np+1)*sizeof(double));

	    break; // very import
	}
	default:
	    mexErrMsgIdAndTxt( "KS_integrator:inputMismatch", 
			       " 3 =< #input <=5. Example: intg(a0, h, nstp, np, d) \n");
	}
   
}
<file_sep>import h5py
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.ticker import ScalarFormatter

f = h5py.File('../../data/ks22h001t120x64EV.h5')
pp = '/ppo/1/'
e = np.array(f[pp + 'e'])[0]

Nh = 16
x1 = np.kron(np.arange(1, Nh), np.array([1, 1]))
x2 = np.kron(np.arange(1, 2*Nh), np.array([1, 1]))
x3 = np.arange(1, 2*Nh, 0.01)

d = 22
k = 2*np.pi/d*x3
k = k**2-k**4

# create figure
fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(111)

ax.plot(x3, k, 'g--', linewidth=1.8, label=r'$q_k^2 - q_k^4$')
ax.scatter(np.arange(1, 32), e[::2], c=(1, 0, 0), marker='o',
           s=22, edgecolors='none', label=r'$\mu_{2k-1}$')
ax.scatter(np.arange(1, 32), e[1::2], marker='s',
           s=30, facecolors='none', edgecolors='k', label=r'$\mu_{2k}$')
yfmt = ScalarFormatter()
yfmt.set_powerlimits((0, 1))
ax.yaxis.set_major_formatter(yfmt)

ax.set_xlabel('k')
ax.set_yticks((-7e3, -3e3, 0, 1e3))
ax.set_xlim((0, 35))
ax.set_ylim((-7e3, 1e3))
ax.grid('on')

axin = inset_axes(ax, width="45%", height="50%", loc=3)
axin.scatter(np.arange(1, 32), e[::2], c=(1, 0, 0), marker='o',
             s=22, edgecolors='none')
axin.scatter(np.arange(1, 32), e[1::2], c=(1, 0, 0), marker='s',
             s=30, facecolors='none', edgecolors='k')
axin.set_xlim(0.5, 4.5)
axin.set_ylim(-0.4, 0.1)
axin.yaxis.set_ticks_position('right')
axin.xaxis.set_ticks_position('top')
axin.set_xticks((1, 2, 3, 4))
# axin.set_yticks((-0.3,-0.2,-0.1,0,0.1))
axin.grid('on')

mark_inset(ax, axin, loc1=1, loc2=2, fc="none")

ax.legend()

fig.tight_layout(pad=0)
plt.show()
<file_sep>from py_CQCGL1d import *
from personalFunctions import *

case = 10

if case == 10:
    """
    use L = 50 to view the rpo, its FV and the explosion
    """
    N, d = 1024, 50
    Bi, Gi = 2.0, -5.6
    
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi('../../data/cgl/rpoBiGiEV.h5',
                                                     Bi, Gi, 1, flag=2)
    a0 = x[:cgl.Ndim]
    print e[:10]

    # plot the leading Fv
    isvReal = True
    cp.oneConfig(v[0], d=50, labs=[r'$x$', r'$|\mathbf{e}_0|$' if isvReal else r'$|Re(\mathbf{e}_0)|$'])
    
    # plot 4 period of the orbit
    aa = cgl.intg(a0, T/nstp, 4*nstp, 10)
    cp.config(aa, [0, d, 0, 4*T], axisLabelSize=25, tickSize=15, barTicks=[0.5, 1, 1.5])

    # plot the explosion
    a0 += 0.1*norm(a0)*v[0]
    skipRate = 50
    aa = cgl.intg(a0, T/nstp, 20*nstp, skipRate)
    cellSize = nstp/skipRate
    cp.config(aa[12*cellSize:19*cellSize], [0, d, T*12, T*19])


if case == 20:
    """
    plot a long integration to see whether there are only symmetric/asymmetric
    explosions or both of them
    """
    N, d = 1024, 50
    Bi, Gi = 4.6, -5.0
    
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi('../../data/cgl/rpoBiGiEV.h5',
                                                     Bi, Gi, 1, flag=2)
    a0 = x[:cgl.Ndim]
    a0 += 0.1 * norm(a0) * v[0]

    for i in range(10):
        aa = cgl.intg(a0, T/nstp, 10*nstp, 50)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, 10*T])
    
    

    
<file_sep>#include "denseRoutines.hpp"
#include <vector>
#include <algorithm>
#include <time.h>       /* time */

using namespace std;
using namespace Eigen;

/* -----------        functions    -------------- */

//////////////////////////////////////////////////////////////////////
//                       subspace angle                             //
//////////////////////////////////////////////////////////////////////

/** @brief calculate the cos() of the largest angle
 *         between the two subspaces spanned by the
 *         columns of matrices A and B.
 */
double denseRoutines::angleSubspace(const Ref<const MatrixXd> &A,
				    const Ref<const MatrixXd> &B){
    assert(A.rows() == B.rows());
    const int N = A.rows();
    const int M1 = A.cols();
    const int M2 = B.cols();
    MatrixXd thinQa(MatrixXd::Identity(N,M1));
    MatrixXd thinQb(MatrixXd::Identity(N,M2));
  
    ColPivHouseholderQR<MatrixXd> qra(A);
    thinQa = qra.householderQ() * thinQa;

    ColPivHouseholderQR<MatrixXd> qrb(B);
    thinQb = qrb.householderQ() * thinQb;
  
    JacobiSVD<MatrixXd> svd(thinQa.transpose() * thinQb);
    VectorXd sv = svd.singularValues();
  
    return sv.maxCoeff();
}


double denseRoutines::angleSpaceVector(const Ref<const MatrixXd> &Q,
				       const Ref<const VectorXd> &V){
    assert( Q.rows() == V.rows());
    VectorXd P = Q.transpose() * V;
    double cos2 = P.squaredNorm() / V.squaredNorm();
    
    return sqrt(1-cos2);
}


//////////////////////////////////////////////////////////////////////
//                   eigenspace related                             //
//////////////////////////////////////////////////////////////////////

/** @brief find the marginal exponents and their position.
 *
 *  This function tries to find the n (default 2)
 *  smallest absolute
 *  value of the exponents, and assume they are marginal.
 *
 *  @input Exponent Floquet exponent (the frist column of e)
 *  @return a n-element vector. Each element is a pair of
 *          the marginal exponent and its corresponding postion
 */
std::vector< std::pair<double, int> > 
denseRoutines::findMarginal(const Ref<const VectorXd> &Exponent,
			    const int k /* = 2 */){
    const int N = Exponent.size();
    std::vector<std::pair<double, int> > var;
    for (size_t i = 0; i < N; i++) {
	var.push_back( std::make_pair(Exponent(i), i) );
    }
    // sort the exponent from large to small by absolute value
    std::sort(var.begin(), var.end(), 
	      [](std::pair<double, int> i , std::pair<double, int> j)
	      {return fabs(i.first) < fabs(j.first);}
	      );
  
    return std::vector<std::pair<double, int> >(var.begin(), var.begin() + k);

}

/** @brief Get the supspace index.
 *
 * For each index, it has a Left value (L) and a Right value (R), which
 * denote when this index is used as the left bound or right bound
 * for a subspace. For real eigenvalues, L = index = R. For complex
 * eigenvalues, L1, L2 = index1, R1, R2 = index1+1;
 *
 * @param[in] RCP real/complex position, usually it is the third
 *                column of the Floquet exponents matrix.
 * @param[in] Exponent Floquet exponents used to get the marginal position
 * @return    N x 2 matrix
 */
MatrixXi 
denseRoutines::indexSubspace(const Ref<const VectorXd> &RCP, 
			     const Ref<const VectorXd> &Exponent){
    assert(RCP.size() == Exponent.size());
    const int N = RCP.size();
    std::vector< std::pair<double, int> > 
	marginal = findMarginal(Exponent);

    // create a new real/complex position vector whose marginal
    // will be considered to complex.
    VectorXd RCP2(RCP);
    RCP2(marginal[0].second) = 1.0; RCP2(marginal[1].second) = 1.0;
    MatrixXi index_sub(N, 2);
    for(size_t i = 0; i < N; i++){
	if(RCP2(i) == 0){ // real case
	    index_sub(i, 0) = i;
	    index_sub(i, 1) = i;
	}
	else{ // complex case
	    index_sub(i, 0) = i; index_sub(i, 1) = i+1;
	    index_sub(i+1, 0) = i; index_sub(i+1,1) = i+1;
	    i++;
	}
    }
    return index_sub;
}


/** @brief  calculate the actual subspace bound and the indicator whether the actual
 *          bound is the same as specified.
 *
 * @param[in] subspDim subspace bounds. Each column is a 4-vector storing dimension of
 *                     two subspaces.
 * @param[in] ixSp subspace index, i.e the left and right bounds
 * @see indexSubspace
 * @return a pair of integer matrix. The first one is actual subspace bound.
 *         The second one indicate whether the bounds are the same as specified.
 */
std::pair<MatrixXi, MatrixXi> 
denseRoutines::subspBound(const MatrixXi subspDim, const MatrixXi ixSp){
    assert(subspDim.rows() == 4); // two subspaces have 4 indices.
    const int M = subspDim.cols();
    MatrixXi boundStrict(MatrixXi::Zero(4,M));
    MatrixXi bound(4, M);
  
    for(size_t i = 0; i < M; i++){
	int L1 = ixSp(subspDim(0,i), 0); bound(0,i) = L1;
	int R1 = ixSp(subspDim(1,i), 1); bound(1,i) = R1;
	int L2 = ixSp(subspDim(2,i), 0); bound(2,i) = L2;
	int R2 = ixSp(subspDim(3,i), 1); bound(3,i) = R2;
	if(L1 == subspDim(0,i)) boundStrict(0,i) = 1;
	if(R1 == subspDim(1,i)) boundStrict(1,i) = 1;
	if(L2 == subspDim(2,i)) boundStrict(2,i) = 1;
	if(R2 == subspDim(3,i)) boundStrict(3,i) = 1;
    }
  
    return std::make_pair(bound, boundStrict);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/** @brief normalize each column of a matrix  */
void denseRoutines::normc(MatrixXd &A){
    int m = A.cols();
    for(size_t i = 0; i < m; i++) 
	A.col(i).array() = A.col(i).array() / A.col(i).norm();
}

/**
 * @brief get the sorted indices of a complex vector in descending order
 *        by their real part
 */
std::vector<int>
denseRoutines::csort(const VectorXcd &e, int flag){
    int n = e.size(); 
    std::vector<int> id(n);
    for(int i = 0; i < n; i++) id[i] = i;

    switch (flag){
    case 1 : 			// real part
	std::sort(id.begin(), id.end(), 
		  [&e](int i, int j){return e(i).real() > e(j).real();}
		  );
	break;

    case 2 :			// magnitude
	std::sort(id.begin(), id.end(), 
		  [&e](int i, int j){return std::abs(e(i)) > std::abs(e(j)); }
		  );
	break;

    default:
	fprintf(stderr, "errer of csort in denseRoutines\n");
    }
    
    return id;
}

/// @brief transform real-format eigenvector matrix to complex format
/// @note assume complex paris are complete
MatrixXcd
denseRoutines::vr2vc(const VectorXcd &e, const Ref<const MatrixXd> &v){
    assert(e.size() == v.cols());
    int m = v.rows();
    int n = v.cols();
    MatrixXcd vc(m, n);
    
    int i = 0;
    while(i < n-1){
	double r1 = fabs( e(i).imag() );
	double r2 = fabs( e(i).imag() + e(i+1).imag() );
	if(r1 > 1e-6 && r2 < 1e-10){
	    vc.col(i).real() = v.col(i);
	    vc.col(i).imag() = v.col(i+1);
	    vc.col(i+1).real() = v.col(i);
	    vc.col(i+1).imag() = -v.col(i+1);
	    i += 2;
	} 
	else {
	    vc.col(i).real() = v.col(i);
	    vc.col(i).imag().setZero();
	    i++;
	}
    }
    
    if (i == n-1) {
	vc.col(i).real() = v.col(i);
	vc.col(i).imag().setZero();
    }

    return vc;
}

MatrixXd 
denseRoutines::vc2vr(const Ref<const MatrixXcd> &v){
    int m = v.rows();
    int n = v.cols();
    MatrixXd vr(m, n);

    int i = 0;
    while (i < n-1) {
	double r1 = v.col(i).imag().array().abs().maxCoeff();
	double r2 = (v.col(i) + v.col(i+1)).imag().array().abs().maxCoeff();
	if (r1 > 1e-6 && r2 < 1e-10){
	    vr.col(i) = v.col(i).real();
	    vr.col(i+1) = v.col(i).imag();
	    i += 2;
	}
	else {
	    vr.col(i) = v.col(i).real();
	    i++;
	}
    }
    
    if (i == n-1) vr.col(i) = v.col(i).real();
    
    return vr;
}

/**
 * @brief calculate the eigenvalues of a real matrix.
 *
 * The eigenvalues are sorted by their real part. It returns a complex vector.
 */
VectorXcd denseRoutines::eEig(const MatrixXd &A, int flag){
    EigenSolver<MatrixXd> es(A);
    std::vector<int> id = csort(es.eigenvalues(), flag);
    int n = id.size();
    VectorXcd re(n);
    for(size_t i = 0; i < n; i++) re(i) = es.eigenvalues()(id[i]);
    return re;
}

/**
 * @brief calculate the eigenvectors of a real matrix. It returns a complex matrix.
 *
 * The eigenvalues are sorted by their real part. It returns a complex matrix.
 */
MatrixXcd denseRoutines::vEig(const MatrixXd &A, int flag){
    EigenSolver<MatrixXd> es(A);
    std::vector<int> id = csort(es.eigenvalues(), flag);
    int n = id.size();
    MatrixXcd rv(n, n);
    for(size_t i = 0; i < n; i++) rv.col(i) = es.eigenvectors().col(id[i]);
    return rv;
}

/**
 * @brief calculate the eigenvalues and eigenvectors of a real matrix. 
 *
 * The eigenvalues are sorted by their real part. 
 */
std::pair<VectorXcd, MatrixXcd>
denseRoutines::evEig(const MatrixXd &A, int flag){
    EigenSolver<MatrixXd> es(A);
    std::vector<int> id = csort(es.eigenvalues(), flag);
    int n = id.size();
    VectorXcd re(n);
    MatrixXcd rv(n, n);
    for(size_t i = 0; i < n; i++){
	re(i) = es.eigenvalues()(id[i]);
	rv.col(i) = es.eigenvectors().col(id[i]);
    }
    return make_pair(re, rv);   
}

/**
 * @brief  Reform complex eigenvector matrix to real format
 */
MatrixXd denseRoutines::realv(const MatrixXcd &v){
    int n = v.rows();
    int m = v.cols();
    MatrixXd vp(n, m);

    VectorXd tmp = v.imag().array().abs().colwise().sum();
    for(size_t i = 0; i < m; i++){
	if(tmp(i) < 1e-6) vp.col(i) = v.col(i).real();
	else {
	    vp.col(i) = v.col(i).real();
	    vp.col(i+1) = v.col(i).imag();
	    i++;
	}
    }
    
    return vp;
}

/**
 * @brief construct orthonormal bases from the coloumn vectors of a matrix
 *
 * Note: we do not use ColPivHouseHolderQR because we want to preserve the order.
 */
MatrixXd denseRoutines::orthAxes(const Ref<const MatrixXd> &v){
    int n = v.rows();
    int m = v.cols();
    HouseholderQR<MatrixXd> qr(v);
    return qr.householderQ() * MatrixXd::Identity(n, m);
}

/**
 * @brief construct orthonormal vectors from a 2 vectors
 */
MatrixXd denseRoutines::orthAxes(const Ref<const VectorXd> &e1, 
				 const Ref<const VectorXd> &e2){
    int n = e1.size();
    MatrixXd tmp(n, 2);
    tmp << e1, e2;
    return orthAxes(tmp);
}

/**
 * @brief construct orthonormal vectors from a 3 vectors
 */
MatrixXd denseRoutines::orthAxes(const Ref<const VectorXd> &e1, 
				 const Ref<const VectorXd> &e2, 
				 const Ref<const VectorXd> &e3){
    int n = e1.size();
    MatrixXd tmp(n, 3);
    tmp << e1, e2, e3;
    return orthAxes(tmp);
}

/**
 * @brief my wrapper to HouseHolderQR 
 */
std::pair<MatrixXd, MatrixXd>
denseRoutines::QR(const Ref<const MatrixXd> &A){
    int n = A.rows();
    int m = A.cols();
    assert(n >= m);
    
    // this is the only correct way to extract Q and R
    // which makes sure the returned matrices have continous memory layout 
    HouseholderQR<MatrixXd> qr(A);
    MatrixXd Q = qr.householderQ() * MatrixXd::Identity(n, m);
    MatrixXd R = MatrixXd::Identity(m, n) * qr.matrixQR().triangularView<Upper>();
    return std::make_pair(Q, R);
}

/**
 * @brief My personal implimentation of Gram-Schmidt orthonormalization method
 *
 * We suggest using HouseholderQR instead of our method.
 */
std::pair<MatrixXd, MatrixXd>
denseRoutines::GS(const Ref<const MatrixXd> &A){
    const int N = A.rows();
    const int M = A.cols();
    
    MatrixXd Q(N, M);
    MatrixXd R(MatrixXd::Zero(N, M)); // make sure the lower part is zero

    R(0, 0) = A.col(0).norm();
    Q.col(0) = A.col(0) / R(0, 0);
    for(int j = 1; j < M; j++){
	VectorXd v = A.col(j);
	VectorXd coe = Q.leftCols(j-1).transpose() * v;
	R.col(j).head(j-1) = coe;
	v -= Q.leftCols(j-1) * coe;
	R(j, j) = v.norm();
	Q.col(j) = v / R(j, j);
    }

    return std::make_pair(Q, R);
}

/**
 * @see GS()
 */
MatrixXd
denseRoutines::GSsimple(const Ref<const MatrixXd> &A){
    return GS(A).first;
}


/**
 * @brief return the spacing between adjacent vectors
 *
 * @param[in] v    mxn matrix
 * @return         n-1 vector 
 */
VectorXd denseRoutines::spacing(const Ref<const MatrixXd> &v){
    int m = v.rows();
    int n = v.cols();
    
    VectorXd sp(n-1);
    for(size_t i = 0; i < n-1; i++) sp(i) = (v.col(i) - v.col(i+1)).norm();
    
    return sp;
}

/**
 * @brief return the index of vector which is closest to the sample point
 *
 * @param[in]   a       sample pointx
 * @param[in]   v       a trajectory
 * @param[out] minD     minimal distance
 * @return              index of v closest to a
 */
int 
denseRoutines::minDisIndex(const Ref<const VectorXd> &a, 
			   const Ref<const MatrixXd> &v,
			   double &minD){
    
    int m = v.rows();
    int n = v.cols();
    
    int id = 0;
    minD = (a - v.col(0)).norm();
    for(size_t i = 0; i < n; i++){
	double d = (a - v.col(i)).norm();
	if(d < minD) {
	    id = i;
	    minD = d;
	}
    }
    return id;
}

int
denseRoutines::minDisIndex(const Ref<const VectorXd> &a, 
			   const Ref<const MatrixXd> &v){
    double minD;
    return minDisIndex(a, v, minD);
}


MatrixXcd 
denseRoutines::loadComplex(const std::string f1, const std::string f2){
    MatrixXd re = loadtxt<double>(f1);
    MatrixXd im = loadtxt<double>(f2);
    int n1 = re.rows();
    int m1 = re.cols();
    int n2 = im.rows();
    int m2 = im.cols();
    assert(n1 == n2 && m1 == m2);
    
    MatrixXcd A(n1, m1);
    A.real() = re;
    A.imag() = im;

    return A;
}

ArrayXXd 
denseRoutines::calPhase(const Ref<const ArrayXXcd> &AA){
    int m = AA.cols();
    int n = AA.rows();
    ArrayXXd phase(n, m);
    for(size_t i = 0; i < m; i++)
	for(size_t j =0; j < n; j++)
	    phase(j, i) = atan2(AA(j, i).imag(), AA(j, i).real());

    return phase;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// special matrix generator

/**
 * Generate center localized random initial condition
 */
VectorXd denseRoutines::centerRand(const int N, const double frac){
    VectorXd a(VectorXd::Random(N)); /* -1 to 1 */
    int N2 = (int) (0.5 * N * (1-frac));
    a.head(N2) = VectorXd::Zero(N2);
    a.tail(N2) = VectorXd::Zero(N2);
    
    return a;
}


MatrixXd 
denseRoutines::randM(int M, int N){
    srand(time(NULL));
    MatrixXd A(M, N);

    for (int i = 0; i < M; i++) 
	for (int j = 0; j < N; j++) 
	    A(i,j) = (double)rand() / RAND_MAX - 0.5; 

    return A;
}


<file_sep>#include "ksint.hpp"
#include "denseRoutines.hpp"
#include <cmath>
#include <iostream>

using namespace denseRoutines;

//////////////////////////////////////////////////////////////////////
KS::NL::NL(){}
KS::NL::NL(KS *ks, int cols) : ks(ks), N(ks->N) {
    u.resize(ks->N, cols);
}
KS::NL::~NL(){}
void KS::NL::operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t){
    int cs = x.cols();
    assert(cs == dxdt.cols() && N/2+1 == x.rows() && N/2+1 == dxdt.rows());
    
    for(int i = 0; i < cs; i++)
	ks->fft.inv(u.data() + i*N, x.data() + i*(N/2+1), N); 
    ArrayXd orbit = u.col(0);
    u = u.colwise() * orbit;
    for(int i = 0; i < cs; i++)
	ks->fft.fwd(dxdt.data() + i*(N/2+1), u.data() + i*N, N); 
    dxdt.col(0) *= ks->G;
    if(cs > 1)
	dxdt.rightCols(cs-1).colwise() *= 2.0 * ks->G;
}

//////////////////////////////////////////////////////////////////////
/*-------------------- constructor, destructor -------------------- */
// dimension of physical state : N
// dimension of state space    : N - 2 (zeroth and highest mode are excluded)
// dimension of Fourier space  : N/2 + 1
KS::KS(int N, double d) : N(N), d(d), nl(this, 1), nl2(this, N-1) {
    K = ArrayXd::LinSpaced(N/2+1, 0, N/2) * 2 * M_PI / d; //2*PI/d*[0, 1, 2,...,N/2]
    K(N/2) = 0;
    L = K*K - K*K*K*K; 
    G = 0.5 * dcp(0,1) * K * N;   
    
    fft.SetFlag(fft.HalfSpectrum); // very important
    
    int nYN0 = eidr.names.at(eidr.scheme).nYN; // do not call setScheme here. Different.
    for(int i = 0; i < nYN0; i++){
	Yv[i].resize(N/2+1, 1);
	Nv[i].resize(N/2+1, 1);
	Yv2[i].resize(N/2+1, N-1);
	Nv2[i].resize(N/2+1, N-1);
    }
    eidr.init(&L, Yv, Nv);
    eidr2.init(&L, Yv2, Nv2);
}
KS & KS::operator=(const KS &x){
    return *this;
}
KS::~KS(){}

/*------------------- member methods ------------------ */
void KS::setScheme(std::string x){
    int nYN0 = eidr.names.at(eidr.scheme).nYN;
    eidr.scheme = x;
    int nYN1 = eidr.names.at(eidr.scheme).nYN;
    for (int i = nYN0; i < nYN1; i++) {
	Yv[i].resize(N/2+1, 1);
	Nv[i].resize(N/2+1, 1);
	Yv2[i].resize(N/2+1, N-1);
	Nv2[i].resize(N/2+1, N-1);
    }
}

ArrayXXd 
KS::intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert(a0.size() == N-2);
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N/2+1, M);
    lte.resize(M);
    int count = 0;
    auto ss = [this, &count, &aa](ArrayXXcd &x, double t, double h, double err){
	aa.col(count) = x;
	lte(count++) = err;
    };
    eidr.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
    
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
KS::intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert(a0.size() == N-2);
    ArrayXXd v0(N-2, N-1); 
    v0 << a0, MatrixXd::Identity(N-2, N-2);
    ArrayXXcd u0 = R2C(v0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N/2+1, M), daa(N/2+1, (N-2)*M);
    lte.resize(M);
    int count = 0;
    auto ss = [this, &count, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	aa.col(count) = x.col(0);
	daa.middleCols(count*(N-2), N-2) = x.rightCols(N-2);
	lte(count++) = err;
	x.rightCols(N-2) = R2C(MatrixXd::Identity(N-2, N-2));
    };
    
    eidr2.intgC(nl2, ss, 0, u0, tend, h, skip_rate);
    return std::make_pair(C2R(aa), C2R(daa));
}


ArrayXXd
KS::intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert(a0.size() == N-2);
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt+skip_rate-1)/skip_rate;
    ArrayXXcd aa(N/2+1, M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int count = 0;
    auto ss = [this, &count, &aa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (count >= m ) {
	    Ts.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); 
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	}
	hs(count) = h;
	lte(count) = err;
	aa.col(count) = x;
	Ts(count++) = t;
    };
    
    eidr.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
    hs.conservativeResize(count);
    lte.conservativeResize(count);
    Ts.conservativeResize(count);
    aa.conservativeResize(Eigen::NoChange, count);
    
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
KS::intgj(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert(a0.size() == N-2);
    ArrayXXd v0(N-2, N-1); 
    v0 << a0, MatrixXd::Identity(N-2, N-2);
    ArrayXXcd u0 = R2C(v0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N/2+1, M), daa(N/2+1, (N-2)*M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int count = 0;
    auto ss = [this, &count, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (count >= m ) {
	    Ts.conservativeResize(m+cellSize);	    
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
	    daa.conservativeResize(Eigen::NoChange, (m+cellSize)*(N-2));
	}
	hs(count) = h;
	lte(count) = err;
	Ts(count) = t;
	aa.col(count) = x.col(0);
	daa.middleCols(count*(N-2), N-2) = x.rightCols(N-2);
	x.rightCols(N-2) = R2C(MatrixXd::Identity(N-2, N-2));
	count++;
    };

    eidr2.intg(nl2, ss, 0, u0, tend, h, skip_rate);
    return std::make_pair(C2R(aa), C2R(daa));
}

/* @brief complex matrix to the corresponding real matrix.
 * [N/2+1, M] --> [N-2, M]
 * Since the Map is not address continous, the performance is
 * not good enough.
 */
ArrayXXd KS::C2R(const ArrayXXcd &v){
    int rs = v.rows(), cs = v.cols();
    assert(N/2+1 == rs);
    ArrayXXcd vt = v.middleRows(1, rs-2);
    ArrayXXd vp = Map<ArrayXXd>((double*)(vt.data()), N-2, cs);
    return vp;
}

ArrayXXcd KS::R2C(const ArrayXXd &v){
    int rs = v.rows(), cs = v.cols();
    assert( N - 2 == rs); 
    ArrayXXcd vp(N/2+1, cs); 
    vp << ArrayXXcd::Zero(1, cs), 
	Map<ArrayXXcd>((dcp*)(v.data()), N/2-1, cs), 
	ArrayXXcd::Zero(1, cs);
    return vp;
}


/*************************************************** 
 *           stability ralated                     *
 ***************************************************/

/** @brief calculate the velocity 
 *
 * @param[in] a0 state vector
 * @return velocity field at a0
 */
ArrayXd
KS::velocity(const Ref<const ArrayXd> &a0){
    assert( N - 2 == a0.rows() );
    ArrayXXcd u = R2C(a0);
    ArrayXXcd v(N/2+1, 1);
    nl(u, v, 0);
    return C2R(L*u + v);
}

/* return v(x) + theta *t(x) */
ArrayXd
KS::velReq(const Ref<const VectorXd> &a0, const double theta){
    return velocity(a0) + theta * gTangent(a0);
}

/** @brief calculate the stability matrix 
 *    A = (qk^2 - qk^4) * v  - i*qk* F( F^{-1}(a0) * F^{-1}(v))
 */
MatrixXd KS::stab(const Ref<const ArrayXd> &a0){
    assert(a0.size() == N-2);
    ArrayXXd v0(N-2, N-1); 
    v0 << a0, MatrixXd::Identity(N-2, N-2);
    ArrayXXcd u0 = R2C(v0);
    
    ArrayXXcd v(N/2+1, N-1); 
    nl2(u0, v, 0); 
	
    ArrayXXcd j0 = R2C(MatrixXd::Identity(N-2, N-2));
    MatrixXcd Z = L.matrix().asDiagonal() * j0.matrix()  + v.rightCols(N-2).matrix();
    
    return C2R(Z);   
}

/* the stability matrix of a relative equilibrium */
MatrixXd KS::stabReq(const Ref<const VectorXd> &a0, const double theta){
    return stab(a0) + theta * gGenerator();
}

/* Eigenvalues/Eigenvectors of equilibrium */
std::pair<VectorXcd, MatrixXcd>
KS::evEq(const Ref<const VectorXd> &a0){
    return evEig(stab(a0), 1);
}

/* Eigenvalues/Eigenvectors of equilibrium */
std::pair<VectorXcd, MatrixXcd>
KS::evReq(const Ref<const VectorXd> &a0, const double theta){
    return evEig(stabReq(a0, theta), 1);
}

/*************************************************** 
 *           energe ralated                        *
 ***************************************************/
double KS::pump(const ArrayXcd &vc){
    VectorXcd tmp = vc * K;
    return tmp.squaredNorm();
}

double KS::disspation(const ArrayXcd &vc){
    VectorXcd tmp = vc * K * K;
    return tmp.squaredNorm();
}

/*************************************************** 
 *           Symmetry related                      *
 ***************************************************/

/** @brief apply reflection on each column of input  */
ArrayXXd KS::reflect(const Ref<const ArrayXXd> &aa){
    int n = aa.rows();
    int m = aa.cols();
    assert( 0 == n%2 );
  
    ArrayXd R(n);
    for(size_t i = 0; i < n/2; i++) {
	R(2*i) = -1;
	R(2*i+1) = 1;
    }
  
    ArrayXXd Raa = aa.colwise() * R;
    return Raa;
}


ArrayXXd KS::half2whole(const Ref<const ArrayXXd> &aa){
    int n = aa.rows();
    int m = aa.cols();
  
    ArrayXXd raa = reflect(aa);
    ArrayXXd aaWhole(n, 2*m);
    aaWhole << aa, raa;
  
    return aaWhole;
}

/** @brief apply rotation to each column of input with the
 *         same angle specified
 *    a_k => a_k * e^{ik*th}
 */
ArrayXXd KS::rotate(const Ref<const ArrayXXd> &aa, const double th){
    assert(aa.rows() == N - 2);
    ArrayXd indices = ArrayXd::LinSpaced(N/2+1, 0, N/2); // different from K
    return C2R( R2C(aa).colwise() * (dcp(0, th) * indices).exp() );
}

/** @brief group tangent of SO(2)
 *
 *  x=(b1, c1, b2, c2, ...) ==> tx=(-c1, b1, -2c2, 2b2, ...)
 *  That is a_k => a_k * {ik}
 */
ArrayXXd KS::gTangent(const Ref<const ArrayXXd> &x){
    assert(x.rows() == N - 2);
    ArrayXd indices = ArrayXd::LinSpaced(N/2+1, 0, N/2); // different from K
    return  C2R(R2C(x).colwise() * (dcp(0, 1) * indices) );
}

/* group generator matrix T */
MatrixXd KS::gGenerator(){
    MatrixXd T(MatrixXd::Zero(N-2, N-2));
    for (int i = 0; i < N/2-1; i++ ){
	T(2*i, 2*i+1) = -(i+1);
	T(2*i+1, 2*i) = i+1;
    }
    return T;
}

/**
 * @brief transform the SO2 symmetry to C_p.
 *
 * Use p-th mode to reduce SO2 symmetry. If p > 1, then the symmetry is not reduced
 * but tranformed to cyclic symmetry.
 *
 * For example, if p = 2, then SO2 is reduced to C2, so together with reflection,
 * we have D2 symmetry. If we rotate to the imaginary axis, then we have rules
 * R : ( - +  - +  - + ...)
 * C2: ( - -  + +  - - ...)
 * 
 *
 * @param[in]   p          index of Fourier mode 
 * @param[in]  toY         True => tranform to positive imaginary axis.
 */
std::pair<MatrixXd, VectorXd>
KS::redSO2(const Ref<const MatrixXd> &aa, const int p, const bool toY){
    int n = aa.rows();
    int m = aa.cols();
    assert( 0 == n%2 && p > 0);
    MatrixXd raa(n, m);
    VectorXd ang(m);
    
    double s = toY ? M_PI/2 : 0; /* pi/2 or 0 */
    
    for(int i = 0; i < m; i++){
	double th = (atan2(aa(2*p-1, i), aa(2*p-2, i)) - s )/ p;
	ang(i) = th;
	raa.col(i) = rotate(aa.col(i), -th);
    }
    return std::make_pair(raa, ang);
}

/**
 * If we use the 2nd mode to reduce SO2, then we use 1st mode or 3rd mode
 * to define fundamental domain. b_1 > 0 && c_1 > 0
 *
 * If we use the 1st mode to reduce SO2, then we use 2nd mode
 * to define fundamental domain. b_2 > 0
 *
 * In all these cases, we assume SO2 is reduced to positive y-axis.
 *
 * @param[in] pSlice     index of Fourier mode used to define slice
 * @param[in] pFund      index of Fourier mode used to define fundamental domain
 * 
 */
std::pair<MatrixXd, VectorXi>
KS::fundDomain(const Ref<const MatrixXd> &aa, const int pSlice, const int pFund){
    int n = aa.rows();
    int m = aa.cols();
    assert( 0 == n%2 && pSlice > 0 && pFund > 0 && pSlice != pFund);
 
    MatrixXd faa(n, m);
    VectorXi DomainIds(m);
    
    ArrayXd R(n);		// reflection matrix
    for(int i = 0; i < n/2; i++){
	R(2*i) = -1;
	R(2*i+1) = 1;
    }
    
    if (pSlice == 1){		//  1st mode slice	
	int id = 2 * (pFund - 1);
	for (int i = 0; i < m; i++) {
	    if(aa(id, i) > 0 ) {
		faa.col(i) = aa.col(i);
		DomainIds(i) = 1;
	    }
	    else {
		faa.col(i) = aa.col(i).array() * R;
		DomainIds(i) = 2;
	    }
	}
    }
    
    else if (pSlice == 2){	// 2nd mode slice	
	ArrayXd C(n);		// rotation by pi
	int s = -1;
	for(int i = 0; i < n/2; i++){
	    C(2*i) = s;
	    C(2*i+1) = s;
	    s *= -1;
	}
    
	ArrayXd RC = R * C;
	
	int id = 2 * (pFund - 1);
	for(int i = 0; i < m; i++){
	    bool x = aa(id, i) > 0;
	    bool y = aa(id+1, i) > 0;
	    if(x && y) {
		faa.col(i) = aa.col(i);
		DomainIds(i) = 1;
	    }
	    else if (!x && y) {
		faa.col(i) = aa.col(i).array() * R;
		DomainIds(i) = 2;
	    }
	    else if (!x && !y) {
		faa.col(i) = aa.col(i).array() * C;
		DomainIds(i) = 3;
	    }
	    else { // if (x && !y) {
		faa.col(i) = aa.col(i).array() * RC;
		DomainIds(i) = 4;
	    }
	}
	
    }

    else if (pSlice == 3){ 
	ArrayXcd C1(n/2+2), C2(n/2+2);
	for (int i = 0; i < n/2; i++){
	    double th = (i+1) * 2 * M_PI / 3;
	    C1[i+1] = dcp(cos(th), sin(th));
	    C2[i+1] = dcp(cos(2*th), sin(2*th));
	}

	int id = 2 * (pFund - 1); 

	for(int i = 0; i < m; i++){
	    int x = aa(id, i), y = aa(id+1, i);
	    if ( y <= x/2 && y >= -x/2){ // domain 1
		faa.col(i) = aa.col(i);
		DomainIds(i) = 1;
	    }
	    else if (y >= x/2 && y <= -x/2){ // domain 4
		faa.col(i) = aa.col(i).array() * R;
		DomainIds(i) = 4;
	    }
	    else if (y >= x/2 && x >= 0) { // domain 2 
		faa.col(i) = C2R(C1 * R2C(aa.col(i)).array()) * R;
		DomainIds(i) = 2;
	    }
	    else if(y <= x/2 && x <= 0) { // domain 5 
		faa.col(i) = C2R(C1 * R2C(aa.col(i)).array());
		DomainIds(i) = 5; 
	    }
	    else if (y >= -x/2 && x <= 0){ // domain 3
		faa.col(i) = C2R(C2 * R2C(aa.col(i)).array());
		DomainIds(i) = 3;
	    }
	    else {		// domain 6
		faa.col(i) = C2R(C2 * R2C(aa.col(i)).array()) * R;
		DomainIds(i) = 6;
	    }
	}
    }
    
    else {
	fprintf(stderr, "wrong index of Fourier mode !\n");
    }

    return std::make_pair(faa, DomainIds);
}
    
/** @brief reduce O2 symmetry to fundamental domain
 *
 *
 * @param[in] aa         states in the full state space
 * @param[in] pSlice     index of Fourier mode used to define slice
 * @param[in] pFund      index of Fourier mode used to define fundamental domain
 * @return    state in fundamental domain, domain indices, angles
 **/
std::tuple<MatrixXd, VectorXi, VectorXd>
KS::redO2f(const Ref<const MatrixXd> &aa, const int pSlice, const int pFund){
    auto tmp = redSO2(aa, pSlice, true);
    auto tmp2 = fundDomain(tmp.first, pSlice, pFund);

    return std::make_tuple(tmp2.first, tmp2.second, tmp.second);
}

// projection matrix is h= (I - |tx><tp|/<tx|tp>) * g(-th)
MatrixXd
KS::redV(const Ref<const MatrixXd> &v, const Ref<const VectorXd> &a,
	 const int p, const bool toY){
    auto tmp = redSO2(a, p, toY);
    MatrixXd &aH = tmp.first;
    double th = tmp.second(0);
    VectorXd tx = gTangent(aH);

    VectorXd x0(VectorXd::Zero(N-2));
    if (toY) x0(2*p-1) = 1;
    else x0(2*p-2) = 1;    
    VectorXd t0 = gTangent(x0);
    
    MatrixXd vep = rotate(v, -th);
    MatrixXd dot = (t0.transpose() * vep) / (t0.transpose() * tx);
    vep = vep - tx * dot;
    
    return vep;
}

#if 0
/** @beief project the sequence of Floquet vectors to 1st mode slice
 *
 *  Usaully, aa has one more column the the Floquet vectors, so you can
 *  call this function like:
 *  \code
 *      veToSliceAll(eigVecs, aa.leftCols(aa.cols()-1))
 *  \endcode
 *  
 *  @param[in] eigVecs Floquet vectors along the orbit. Dimension: [N*Trunc, M]
 *  @param[in] aa the orbit
 *  @return projected vectors on the slice with dimension [N, M*Trunc]
 *
 *  @note vectors are not normalized
 */
MatrixXd KS::veToSliceAll(const MatrixXd &eigVecs, const MatrixXd &aa,
			  const int trunc /* = 0*/){
    int Trunc = trunc;
    if(trunc == 0) Trunc = sqrt(eigVecs.rows());

    assert(eigVecs.rows() % Trunc == 0);
    const int n = eigVecs.rows() / Trunc ;  
    const int m = eigVecs.cols();
    const int n2 = aa.rows();
    const int m2 = aa.cols();

    assert(m == m2 && n == n2);
    MatrixXd newVe(n, Trunc*m);
    for(size_t i = 0; i < m; i++){
	MatrixXd ve = eigVecs.col(i);
	ve.resize(n, Trunc);
	newVe.middleCols(i*Trunc, Trunc) = veToSlice(ve, aa.col(i));
    }

    return newVe;
}


/**
 * @brief get the full orbit and full set of Fvs
 * 
 * Given the inital point and the set of Fvs, the whole set is
 * twice bigger for ppo, but for rpo, it is the single piece.
 *
 * @param[in] a0       the inital condition of the ppo/rpo
 * @param[in] ve       the set of Fvs. Dimension [(N-2)*NFV, M]
 * @param[in] nstp     number of integration steps
 * @param[in] ppTpe    ppo/rpo
 * @return             the full orbit and full set of Fvs.
 */
std::pair<ArrayXXd, ArrayXXd>
KS::orbitAndFvWhole(const ArrayXd &a0, const ArrayXXd &ve,
		    const double h,
		    const size_t nstp, const std::string ppType
		    ){
    assert(N-2 == a0.rows());
    const int M = ve.cols();
    assert(nstp % M == 0);
    const int space = nstp / M;
    
    ArrayXXd aa = intg(a0, h, nstp, space);
    if(ppType.compare("ppo") == 0) 
	return std::make_pair(
			      half2whole(aa.leftCols(aa.cols()-1)),
			      half2whole(ve) // this is correct. Think carefully.
			      );
    
    else 
	return std::make_pair(
			      aa.leftCols(aa.cols()-1), // one less
			      ve
			      );
}

/**
 * @brief get rid of the marginal direction of the Fvs
 * 
 * @param[in] ve        dimension [N, M*trunc]
 * @param[in] pos       the location of the group tangent margianl Floquet vector.
 *                      pos starts from 0.
 * @param[in] return    the clean set of Fvs
 */
MatrixXd KS::veTrunc(const MatrixXd ve, const int pos, const int trunc /* = 0 */){
    int Trunc = trunc;
    if(trunc == 0) Trunc = ve.rows();

    const int N = ve.rows();
    const int M = ve.cols() / Trunc;
    assert(ve.cols()%M == 0);
  
    MatrixXd newVe(N, (Trunc-1)*M);
    for(size_t i = 0; i < M; i++){
	newVe.middleCols(i*(Trunc-1), pos) = ve.middleCols(i*Trunc, pos);
	newVe.middleCols(i*(Trunc-1)+pos, Trunc-1-pos) = 
	    ve.middleCols(i*Trunc+pos+1, Trunc-1-pos);
    }
    return newVe;
}


/**
 * @brief get the full orbit and full set of Fvs on the slice
 *
 * @return             the full orbit and full set of Fvs on slice
 * @see                orbitAndFvWhole(),  veTrunc()
 */
std::pair<ArrayXXd, ArrayXXd>
KS::orbitAndFvWholeSlice(const ArrayXd &a0, const ArrayXXd &ve,
			 const double h,
			 const size_t nstp, const std::string ppType,
			 const int pos
			 ){
    assert(ve.rows() % (N-2) == 0);
    const int NFV = ve.rows() / (N-2);
    auto tmp = orbitAndFvWhole(a0, ve, h, nstp, ppType);
    auto tmp2 = orbitToSlice(tmp.first);
    MatrixXd veSlice = veToSliceAll(tmp.second, tmp.first, NFV);
    MatrixXd ve_trunc = veTrunc(veSlice, pos, NFV);

    return std::make_pair(tmp2.first, ve_trunc);
}

#endif
/*************************************************** 
 *                  Others                         *
 ***************************************************/

/* calculate mode modulus */
MatrixXd KS::calMag(const Ref<const MatrixXd> &aa){
    assert(aa.rows() == N - 2);
    ArrayXXcd u = R2C(aa).middleRows(1, N/2-1);
    return (u * u.conjugate()).real();
}

std::pair<MatrixXd, MatrixXd>
KS::toPole(const Ref<const MatrixXd> &aa){
    assert(aa.rows() == N - 2);
    ArrayXXcd u = R2C(aa).middleRows(1, N/2-1);
    
    MatrixXd mag = (u * u.conjugate()).real();
    MatrixXd th(u.rows(), u.cols());    
    for(int i = 0; i < u.rows(); i++){
	for(int j = 0; j < u.cols(); j++){
	    th(i, j) = arg(u(i, j));
	}
    }
    
    return std::make_pair(mag, th);

}


<file_sep>/* to comiple:
 * h5c++ -O3 test_CQCGL1dReq.cc  -L../../lib -I../../include -I$EIGEN -std=c++11 -lCQCGL1dReq -lCQCGL1d -lsparseRoutines -ldenseRoutines -literMethod -lmyH5 -lfftw3 -lm
 */
#include "CQCGL1dReq.hpp"
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <H5Cpp.h>

using namespace std;
using namespace Eigen;
using namespace denseRoutines;
using namespace MyH5;

typedef std::complex<double> dcp;


#define N10

int main(int argc, char **argv){

#ifdef N10
    //======================================================================
    // test the accuracy of req.
    const int N = 1024, L = 50;
    double Bi = 0.8, Gi = -0.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	
    string fileName = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    H5File file(fileName, H5F_ACC_RDWR);
    ArrayXd a0;
    double wth0, wphi0, err0;
    std::tie(a0, wth0, wphi0, err0) = cgl.read(file, cgl.toStr(Bi, Gi, 1));
    a0 += ArrayXd::Random(a0.size()) * 0.1;

    ArrayXd a;
    double wth, wphi, err;
    int flag;
    std::tie(a, wth, wphi, err, flag) = cgl.findReq_LM(a0, wth0, wphi0, 1e-10, 100, 1000);
    fprintf(stderr, "%g %g %g\n", wth, wphi, err);

#endif
#ifdef N20
    //======================================================================
    // use a Gaussian shape guess to find the 2nd soliton. 
    const int N = 1024;
    const double L = 50;
    double Bi = 0.8;
    double Gi = -0.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	
    VectorXcd A0 = Gaussian(N, N/2, N/20, 1);
    ArrayXd  a0 = cgl.Config2Fourier(A0);
    std::vector<double> th = cgl.optThPhi(a0);
    double wth0 = th[0], wphi0 = th[1];
    cout << wth0 << ' ' << wphi0 << endl;

    ArrayXd a;
    double wth, wphi, err;
    int flag;
    std::tie(a, wth, wphi, err, flag) = cgl.findReq_LM(a0, wth0, wphi0, 1e-10, 100, 1000);
    fprintf(stderr, "%g %g %g\n", wth, wphi, err);
    string file = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    if (flag == 0) cgl.write(file, Bi, Gi, 2, a, wth, wphi, err);

#endif
#ifdef N30
    //======================================================================
    // use a Gaussian shape guess and evove it for a while and then to find
    // the 1st soliton
    const int N = 1024;
    const double L = 50;
    double Bi = 0.8;
    double Gi = -0.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
	
    VectorXcd A0 = Gaussian(N, N/2, N/20, 3);
    ArrayXd  a0 = cgl.Config2Fourier(A0);
    ArrayXXd aa = cgl.intg(a0, 1e-3, 10000, 10000);
    a0 = aa.rightCols(1);
    std::vector<double> th = cgl.optThPhi(a0);
    double wth0 = th[0], wphi0 = th[1];
    cout << wth0 << ' ' << wphi0 << endl;

    ArrayXd a;
    double wth, wphi, err;
    int flag;
    std::tie(a, wth, wphi, err, flag) = cgl.findReq_LM(a0, wth0, wphi0, 1e-10, 100, 1000);
    fprintf(stderr, "%g %g %g\n", wth, wphi, err);
    string file = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    if (flag == 0) cgl.write(file, Bi, Gi, 1, a, wth, wphi, err);
    

#endif
#ifdef N40
    //======================================================================
    // try to calculate the eigenvalue and eigenvector of one req
    const int N = 1024;
    const double L = 50;
    double Bi = 1.8;
    double Gi = -0.6;
    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    
    string file = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    int id = 1;

    ArrayXd a0;
    double wth0, wphi0, err0;
    std::tie(a0, wth0, wphi0, err0) = cgl.read(file, cgl.toStr(Bi, Gi, id));
    VectorXcd e;
    MatrixXcd v;
    std::tie(e, v) = cgl.evReq(a0, wth0, wphi0); 
    
    cout << e.head(10) << endl;
    cout << endl;
    cout << v.cols() << ' ' << v.rows() << endl;

#endif
#ifdef N50
    //======================================================================
    // combine the calculated E/V data
   
    string s = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGiEV";
    H5File fout(s + ".h5", H5F_ACC_RDWR);
    int ids[] = {1, 2};
    
    for ( int i = 0; i < 8; i++){
	H5File fin(s + "_add_" + to_string(i) + ".h5", H5F_ACC_RDONLY);
	for (int j = 0; j < 2; j++){
	    int id = ids[j];
	    for( int k = 0; k < 24; k++){
		double Bi = 3.5 + 0.1*k;
		for(int p = 0; p < 55; p++){
		    double Gi = -5.6 + 0.1*p;
		    string g = CQCGL1dReq::toStr(Bi, Gi, id);
		    if (checkGroup(fin, g+"/vr", false)){
			fprintf(stderr, "%d %g %g\n", id, Bi, Gi);
			CQCGL1dReq::move(fin, g, fout, g, 2);
		    }
		}
	    }
	}
    }

#endif
#ifdef N60
    //======================================================================
    // extend the soliton in one direction of parameter space
    iterMethod::LM_OUT_PRINT = false;
    iterMethod::LM_IN_PRINT = false;
    iterMethod::CG_PRINT = false;

    const int N = 1024;
    const double L = 50;
    double Bi = 4.5;
    double Gi = -5.6;

    CQCGL1dReq cgl(N, L, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0);
    string fileName = "/usr/local/home/xiong/00git/research/data/cgl/reqBiGi.h5";
    H5File file(fileName, H5F_ACC_RDWR);

    double stepB = 0.1;
    int NsB = 55;
    
    cgl.findReqParaSeq(file, 1, stepB, NsB, false);
    cgl.findReqParaSeq(file, 2, stepB, NsB, false);
    // cgl.findReqParaSeq(file, 2, 0.1, 53, false);
    
#endif
    
    return 0;
}
<file_sep>import numpy as np
import matplotlib.pyplot as plt
import h5py

N = 256;

f = h5py.File('/usr/local/home/xiong/svn/DOGS/blog/code/data/req.h5', 'r')
ver = f['/req1/vecr']; n1, n2 = ver.shape
vei = f['/req1/veci']
vr = np.zeros((n1,n2), np.double); 
vi = np.zeros((n1,n2), np.double);
ver.read_direct(vr); vei.read_direct(vi);
ve = vr+1j*vi

taa = ve.T
ia = np.fft.ifft(taa, axis=0)

fig = plt.figure(figsize=(5,5));
ax = fig.add_subplot(111)
ax.plot(np.linspace(0, 50, 2*N), ia[:,0].real, 'r-', lw = 2.0,
        label='real')
ax.plot(np.linspace(0, 50, 2*N), ia[:,0].imag, 'b--', lw = 2.0,
        label='imag')
ax.locator_params(nbins=5)

ax.set_ylim((-0.008, 0.008))

plt.tight_layout(pad=0)
plt.legend()
plt.show()
f.close()
<file_sep>#ifndef EID_H
#define EID_H

#include <cmath>
#include <ctime>
#include <chrono>
#include <iostream>
#include <unordered_map>
#include <Eigen/Dense>
// #include "denseRoutines.hpp"

using namespace std;
using namespace Eigen;

//////////////////////////////////////////////////////////////////////////////////
//              Exponetial Integrator with Diagonal Linear Part
//////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Exponential Integrator
 *
 * DT          : data type (double/complex)
 */
template<typename DT>
class EID {
    
public:

    typedef std::complex<double> dcp;
    typedef Array<DT, Dynamic, 1> Ary;

    //////////////////////////////////////////////////////////////////////

    Ary *L;
    ArrayXXcd *N, *Y;		// single or multiple states

    struct Scheme {
	// string name;		// scheme name
	int nstage; /* number of stages, which is used to indicate which Y[?]  store the update */
	int nYN;    // number of Y[], N[] needed in the internal stage
	int nnl;    // number of nonlinear evaluations per step
	int nab;    // number of calculation of a, b whenever change step
	int order;  // orders of scheme
	
	Scheme(int nstage, int nYN, int nnl, int nab, int order) :
	    nstage(nstage), nYN(nYN), nnl(nnl), nab(nab), order(order)
	{}
    };

    const std::unordered_map<std::string, Scheme> names = {
	//   name                    nstage   nYN   nnl     nab     order
        {"Cox_Matthews",        Scheme(4,      5,    5,      4,      4)},
        {"Krogstad",            Scheme(4,      5,    5,      8,      4)},
        {"Hochbruck_Ostermann", Scheme(5,      5,    5,      11,     4)},
	{"Luan_Ostermann",      Scheme(8,      9,    9,      23,     5)},
	{"IFRK43",              Scheme(4,      5,    5,      0,      4)},
	{"IFRK54",              Scheme(6,      7,    7,      0,      5)},
	{"SSPP43",              Scheme(3,      4,    24,     0,      4)}               
    };

    std::string scheme = "Cox_Matthews"; /* default scheme  */
    
    Ary a[9][9], b[9], c[9];
    
    int M = 64;			/* number of sample points */
    int R = 1;			/* radius for evaluating phi(z) */
    int CN = 0;			/* counter number. When L has large dimension, we should split
				   L into pieces and then do counter average. The purpose is
				   to save memory. Name, L -> L[0:CN], L[CN+1, 2*CN], ...
				   If CN <= 0, then not split.
				*/

    double a1, a2, a3;		// for split step method 

    ////////////////////////////////////////////////////////////
    // time adaptive method related parameters
    double rtol = 1e-8;
    double nu = 0.9;	       /* safe factor */
    double mumax = 4;	       /* maximal time step increase factor */
    double mumin = 0.4;	       /* minimal time step decrease factor */
    double mue = 1.25;	       /* upper lazy threshold */
    double muc = 0.85;	       /* lower lazy threshold */
    //double mue = 1.35;
    //double  muc = 0.8;

    int NCalCoe = 0;	      /* times to evaluate coefficient */
    int NReject = 0;	      /* times that new state is rejected */
    int NCallF = 0;	      /* times to call velocity function f */
    int NSteps = 0;	      /* total number of integrations steps */
    double TotalTime = 0;
    double CoefficientTime = 0;
        
    double err = 0;	 /* LTE : local truncation error estimation */

    ////////////////////////////////////////////////////////////
    // constructor and desctructor
    
    EID(){}
    EID(Ary *L, ArrayXXcd *Y, ArrayXXcd *N) : L(L), Y(Y), N(N){}
    ~EID(){}
    
    void init(Ary *L, ArrayXXcd *Y, ArrayXXcd *N){
	this->L = L;
	this->Y = Y;
	this->N = N;
    }
    ////////////////////////////////////////////////////////////

    // NL : the nonlinear function
    // SS : save state function
    template<class NL, class SS>
    void 
    intg(NL nl, SS saveState, const double t0, const ArrayXXcd &u0, const double tend, const double h0, 
	 const int skip_rate){
	auto t_start = std::chrono::high_resolution_clock::now();
	
	int ns = names.at(scheme).nstage;
	int od = names.at(scheme).order;
	int nnl = names.at(scheme).nnl;
	int nab = names.at(scheme).nab;

	NCalCoe = 0;
	NReject = 0;
	NCallF = 0;    
	NSteps = 0;
	TotalTime = 0;
	CoefficientTime = 0;
	
	double h = h0;
	CoefficientTime += calCoe(h);
	NCalCoe += nab;
	
	double t = t0;
	Y[0] = u0;
	bool doChange, doAccept;

	bool TimeEnds = false;
	while(!TimeEnds){ 

	    if ( t + h > tend){
		h = tend - t;
		CoefficientTime += calCoe(h);
		NCalCoe += nab;
		TimeEnds = true;
	    }

	    oneStep(t, h, nl);
	    NCallF += nnl;		
	    double s = nu * std::pow(rtol/err, 1.0/od);
	    double mu = adaptTs(doChange, doAccept, s);
	
	    if (doAccept){
		t += h;
		NSteps++;
		Y[0] = Y[ns];
		if ( NSteps % skip_rate == 0 || TimeEnds) saveState(Y[0], t, h, err);
	    }
	    else {
		NReject++;
		TimeEnds = false;
	    }
	
	    if (doChange) {
		h *= mu;
		CoefficientTime += calCoe(h);
		NCalCoe += nab;
	    }
	}
	
	auto t_end = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double> t_elapse = t_end - t_start;
	TotalTime = t_elapse.count();
    }
    
    /// @brief constant time-stepping integrator.
    /// @note the initial condition will not be recorded.
    template<class NL, class SS>
    void 
    intgC(NL nl, SS saveState, const double t0, const ArrayXXcd &u0, const double tend, const double h, 
	  const int skip_rate){
	int ns = names.at(scheme).nstage;
	int nnl = names.at(scheme).nnl;
	int nab = names.at(scheme).nab;

	NCallF = 0;
	NSteps = 0; 
	NCalCoe = 0;

	calCoe(h);
	NCalCoe += nab;

	const int Nt = static_cast<int>( round((tend-t0)/h) );
	
	double t = t0;
	Y[0] = u0; 
	for(int i = 0; i < Nt; i++){
	    oneStep(t, h, nl); 
	    NCallF += nnl;
	    NSteps++;
	    t += h;
	    Y[0] = Y[ns]; 
	    if((i+1)%skip_rate == 0 || i == Nt-1) saveState(Y[0], t, h, err);
	}	
    }

    /**
     * @brief calculat the damping factor of time step
     *
     * @param[out] doChange    true if time step needs change
     * @param[out] doAccept    true if accept current time step
     * @param[in]  s           estimate damping factor
     * @return     mu          final dampling factor 
     */
    inline 
    double
    adaptTs(bool &doChange, bool &doAccept, const double s){
	double mu = 1;
	doChange = true;
	doAccept = true;

	if ( s > mumax)
	    mu = mumax;
	else if (s > mue)
	    mu = s;
	else if (s >= 1) {
	    mu = 1;
	    doChange = false;
	}
	else {
	    doAccept = false; 
	    if (s > muc) 
		mu = muc;
	    else if (s > mumin) 
		mu = s;
	    else 
		mu = mumin; // cout << mu << '\t' << rtol << '\t' << err << '\t' << NSteps << endl;
	}
	return mu;
    }
    
    /**
     * nonlinear class NL provides container for intermediate steps
     *
     * @note the multiplication operator blow is overloaded.
     */
    template<class NL>
    void 
    oneStep(double t, double h, NL nl){

	if(scheme == "Cox_Matthews") { 
	    nl(Y[0], N[0], t);
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);     
	    
	    nl(Y[1], N[1], t+h/2);	
	    Y[2] = MUL(c[1], Y[0]) + MUL(a[1][0], N[1]);
	    
	    nl(Y[2], N[2], t+h/2);	
	    Y[3] = MUL(c[1], Y[1]) + MUL(a[1][0], 2*N[2]-N[0]);
	
	    nl(Y[3], N[3], t+h);	
	    Y[4] = MUL(c[3], Y[0]) + MUL(b[0], N[0]) + MUL(b[1], N[1]+N[2]) + MUL(b[3], N[3]);
	    
	    nl(Y[4], N[4], t+h);
	
	    err = MUL(b[3], N[4]-N[3]).abs().maxCoeff() / Y[4].abs().maxCoeff(); 
	}
	else if (scheme == "Krogstad") {
	    nl(Y[0], N[0], t);	
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);

	    nl(Y[1], N[1], t+h/2);
	    Y[2] = MUL(c[1], Y[0]) + MUL(a[2][0], N[0]) + MUL(a[2][1], N[1]);

	    nl(Y[2], N[2], t+h/2);
	    Y[3] = MUL(c[3], Y[0]) + MUL(a[3][0], N[0]) + MUL(a[3][2], N[2]);
	
	    nl(Y[3], N[3], t+h);
	    Y[4] = MUL(c[3], Y[0]) + MUL(b[0], N[0]) + MUL(b[1], N[1]+N[2]) + MUL(b[3], N[3]);
	
	    nl(Y[4], N[4], t+h);
	
	    err = MUL(b[3], N[4]-N[3]).abs().maxCoeff() / Y[4].abs().maxCoeff();
	}
	else if (scheme == "Hochbruck_Ostermann") {
	    nl(Y[0], N[0], t);	
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);

	    nl(Y[1], N[1], t+h/2);
	    Y[2] = MUL(c[1], Y[0]) + MUL(a[2][0], N[0]) + MUL(a[2][1], N[1]);

	    nl(Y[2], N[2], t+h/2);
	    Y[3] = MUL(c[3], Y[0]) + MUL(a[3][0], N[0]) + MUL(a[3][1], N[1]+N[2]);
	
	    nl(Y[3], N[3], t+h);
	    Y[4] = MUL(c[1], Y[0]) + MUL(a[4][0], N[0]) + MUL(a[4][1], N[1]+N[2]) + MUL(a[4][3], N[3]);
	
	    nl(Y[4], N[4], t+h/2);
	    Y[5] = MUL(c[3], Y[0]) + MUL(b[0], N[0]) + MUL(b[3], N[3]) + MUL(b[4], N[4]);

	    err = MUL(b[4], N[4]-0.5*N[2]-0.5*N[1]).abs().maxCoeff() / Y[5].abs().maxCoeff();
	}
	else if (scheme == "Luan_Ostermann"){
	    nl(Y[0], N[0], t);	
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);

	    nl(Y[1], N[1], t+h/2);
	    Y[2] = MUL(c[1], Y[0]) + MUL(a[2][0], N[0]) + MUL(a[2][1], N[1]);

	    nl(Y[2], N[2], t+h/2);
	    Y[3] = MUL(c[3], Y[0]) + MUL(a[3][0], N[0]) + MUL(a[3][2], N[2]);
	
	    nl(Y[3], N[3], t+h/4);
	    Y[4] = MUL(c[1], Y[0]) + MUL(a[4][0], N[0]) + MUL(a[4][2], N[2]) + MUL(a[4][3], N[3]);
	
	    nl(Y[4], N[4], t+h/2);
	    Y[5] = MUL(c[5], Y[0]) + MUL(a[5][0], N[0]) + MUL(a[5][3], N[3]) + MUL(a[5][4], N[4]);

	    nl(Y[5], N[5], t+h/5);
	    Y[6] = MUL(c[6], Y[0]) + MUL(a[6][0], N[0]) + MUL(a[6][3], N[3]) + MUL(a[6][4], N[4]) + MUL(a[6][5], N[5]);

	    nl(Y[6], N[6], t+2*h/3);
	    Y[7] = MUL(c[7], Y[0]) + MUL(a[7][0], N[0]) + MUL(a[7][4], N[4]) + MUL(a[7][5], N[5]) + MUL(a[7][6], N[6]);
	    
	    nl(Y[7], N[7], t+h);
	    Y[8] = MUL(c[7], Y[0]) + MUL(b[0], N[0]) + MUL(b[5], N[5]) + MUL(b[6], N[6]) + MUL(b[7], N[7]);

	    nl(Y[8], N[8], t+h);
	    
	    err = MUL(b[7], N[8]-N[7]).abs().maxCoeff() / Y[8].abs().maxCoeff();
	}
	else if (scheme == "IFRK43") {
	    nl(Y[0], N[0], t);	
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);

	    nl(Y[1], N[1], t+h/2);
	    Y[2] = MUL(c[1], Y[0]) + (h*0.5)*N[1];

	    nl(Y[2], N[2], t+h/2);
	    Y[3] = MUL(c[3], Y[0]) + MUL(a[3][2], N[2]);
	
	    nl(Y[3], N[3], t+h);
	    Y[4] = MUL(c[3], Y[0]) + MUL(b[0], N[0]) + MUL(b[1], N[1]+N[2]) + (h/6)*N[3];

	    nl(Y[4], N[4], t+h);

	    err = h*(1.0/10)*(N[4] - N[3]).abs().maxCoeff() / Y[4].abs().maxCoeff();
	}
	else if (scheme == "IFRK54"){
	    nl(Y[0], N[0], t);	
	    Y[1] = MUL(c[1], Y[0]) + MUL(a[1][0], N[0]);

	    nl(Y[1], N[1], t+h/5);
	    Y[2] = MUL(c[2], Y[0]) + MUL(a[2][0], N[0]) + MUL(a[2][1], N[1]);

	    nl(Y[2], N[2], t+3*h/10);
	    Y[3] = MUL(c[3], Y[0]) + MUL(a[3][0], N[0]) + MUL(a[3][1], N[1]) + MUL(a[3][2], N[2]);
	
	    nl(Y[3], N[3], t+4*h/5);
	    Y[4] = MUL(c[4], Y[0]) + MUL(a[4][0], N[0]) + MUL(a[4][1], N[1]) + MUL(a[4][2], N[2]) + MUL(a[4][3], N[3]);

	    nl(Y[4], N[4], t+8*h/9);
	    Y[5] = MUL(c[5], Y[0]) + MUL(a[5][0], N[0]) + MUL(a[5][1], N[1]) + MUL(a[5][2], N[2]) + MUL(a[5][3], N[3]) + MUL(a[5][4], N[4]);

	    nl(Y[5], N[5], t+h);
	    Y[6] = MUL(c[5], Y[0]) + MUL(b[0], N[0]) + MUL(b[2], N[2]) + MUL(b[3], N[3]) + MUL(b[4], N[4]) + (h*11./84)*N[5];

	    nl(Y[6], N[6], t+h);	    
	    err = h*(-71./57600*N[0] + 71./16695*N[2] - 71./1920*N[3] + 17253./339200*N[4]
		     -22./525*N[5] + 1./40*N[6]).abs().maxCoeff() / Y[4].abs().maxCoeff();
	}
	else if (scheme == "SSPP43") {
	    ArrayXcd y0 = Y[0];
	    
	    Y[0] = MUL(c[0], Y[0]);
	    Y[0] = rk4(t+a1*h, a3*h, nl);

	    Y[0] = MUL(c[1], Y[0]);
	    Y[0] = rk4(t+(a1+a2+a3)*h, a2*h, nl);

	    Y[0] = MUL(c[2], Y[0]);
	    ArrayXcd t1 = rk4(t+(a1+2*a3+2*a2)*h, a1*h, nl);

	    Y[0] = y0;	    	    

	    Y[0] = rk4(t, a1*h, nl);
	    Y[0] = MUL(c[2], Y[0]);

	    Y[0] = rk4(t+(a1+a3)*h, a2*h, nl);
	    Y[0] = MUL(c[1], Y[0]);

	    Y[0] = rk4(t+(a1+a3+2*a2)*h, a3*h, nl);
	    ArrayXcd t2 = MUL(c[0], Y[0]);
	    
	    Y[3] = 0.5*(t1 + t2);
	    err = 0.5*(t1 - t2).abs().maxCoeff() / Y[3].abs().maxCoeff();
	    
	    Y[0] = y0;		// reset previous state
	}
	else {
	    fprintf(stderr, "Please indicate the scheme !\n");
	    exit(1);
	}
    }

    template<class NL>
    ArrayXcd rk4(double t, double h, NL nl){
	nl(Y[0], N[0], t);
	Y[1] = Y[0] + h/2 * N[0];
	
	nl(Y[1], N[1], t+h/2);
	Y[2] = Y[0] + h/2 * N[1];
	
	nl(Y[2], N[2], t+h/2);
	Y[3] = Y[0] + h * N[2];
	
	nl(Y[3], N[3], t+h);
	
	return Y[0] + h/6* (N[0] + 2*(N[1]+N[2]) + N[3]);
    }

    /// @brief calculate the coefficients of Butcher table.
    /// The size of coefficient is determined by L.
    /// 
    /// @return time used in seconds
    double
    calCoe(double h){
	auto t_start = std::chrono::high_resolution_clock::now();
	
	int sL = (*L).size();	// size of L
	int p = 1;
	int n = sL;
	
	if (CN > 0){
	    p = sL / CN;
	    n = CN;
	} 
	
	Ary hL = h * (*L);

	if(scheme == "Cox_Matthews") {
	    c[1] = (hL/2).exp();
	    c[3] = hL.exp();

	    a[1][0].resize(sL);
	    b[0].resize(sL);
	    b[1].resize(sL);
	    b[3].resize(sL);

	    for (int i = 0; i < p; i++){
		int s = i != p-1 ? n : sL-(p-1)*n;
		Ary hLs = h * (*L).segment(i*n, s);
		ArrayXXcd z = ZR(hLs);
		
		ArrayXXcd z2 = z.square();
		ArrayXXcd z3 = z.cube();
		ArrayXXcd ze = z.exp();
		ArrayXXcd zeh = (z/2).exp();
		
		a[1][0].segment(i*n, s) = h * mean( (zeh - 1)/z );
		
		b[0].segment(i*n, s) = h * mean( (-4.0 - z + ze*(4.0 - 3.0 * z + z2)) / z3 );
		b[1].segment(i*n, s) = h*2*mean( (2.0 + z + ze*(-2.0 + z)) / z3 );
		b[3].segment(i*n, s) = h * mean( (-4.0 - 3.0*z -z2 + ze*(4.0 - z) ) / z3 );

	    }
	}
	else if (scheme == "Krogstad") {
	    c[1] = (hL/2).exp();
	    c[3] = hL.exp();
	    
	    a[1][0].resize(sL);
	    a[2][0].resize(sL);
	    a[2][1].resize(sL);
	    a[3][0].resize(sL);
	    a[3][2].resize(sL);
	    b[0].resize(sL);
	    b[1].resize(sL);
	    b[3].resize(sL);
	    
	    for(int i = 0; i < p; i++){
		int s = i != p-1 ? n : sL-(p-1)*n;
		Ary hLs = h * (*L).segment(i*n, s);
		ArrayXXcd z = ZR(hLs);
		
		ArrayXXcd z2 = z.square();
		ArrayXXcd z3 = z.cube();
		ArrayXXcd ze = z.exp();
		ArrayXXcd zeh = (z/2).exp();

		ArrayXXcd t1 = z + 2;
		ArrayXXcd t2 = z - 2;
		ArrayXXcd t3 = z - 4;
		ArrayXXcd t4 = z + 4;
		
	    

		a[1][0].segment(i*n, s) = h * mean( (zeh - 1)/z );
		a[2][0].segment(i*n, s) = h * mean( (zeh*t3 + t4) / z2 );
		a[2][1].segment(i*n, s) = h*2*mean( (2*zeh - t1) / z2 );
		a[3][0].segment(i*n, s) = h * mean( (ze*t2 + t1) / z2 );
		a[3][2].segment(i*n, s) = h*2*mean( (ze - z - 1)  / z2 );
	    
		b[0].segment(i*n, s) = h * mean( (-t4 + ze*(4.0 - 3.0 * z + z2)) / z3 );
		b[1].segment(i*n, s) = h*2*mean( (t1 + ze*t2) / z3 );
		b[3].segment(i*n, s) = h * mean( (-4.0 - 3.0*z -z2 - ze*t3 ) / z3 );
	    }   
	}
	else if (scheme == "Hochbruck_Ostermann") {	    
	    c[1] = (hL/2).exp();
	    c[3] = hL.exp();

	    a[1][0].resize(sL);
	    a[2][0].resize(sL);
	    a[2][1].resize(sL);
	    a[3][0].resize(sL);
	    a[3][1].resize(sL);
	    a[4][0].resize(sL);
	    a[4][1].resize(sL);
	    a[4][3].resize(sL);
	    b[0].resize(sL);
	    b[3].resize(sL);
	    b[4].resize(sL);
	    
	    for (int i = 0; i < p; i++){
		int s = i != p-1 ? n : sL-(p-1)*n;
		Ary hLs = h * (*L).segment(i*n, s);
		ArrayXXcd z = ZR(hLs);

		ArrayXXcd z2 = z.square();
		ArrayXXcd z3 = z.cube();
		ArrayXXcd ze = z.exp();
		ArrayXXcd zeh = (z/2).exp();



		ArrayXXcd t1 = -4 + z;	   
		ArrayXXcd t2 = 4*z3;
		ArrayXXcd t3 = 20 + ze*t1;
		ArrayXXcd t4 = 4 + z;
		ArrayXXcd t5 = -2 + z;
		ArrayXXcd t6 = 2 + z;

		a[1][0].segment(i*n, s) = h * mean( (zeh - 1)/z );
		a[2][0].segment(i*n, s) = h * mean( (zeh*t1 + t4) / z2 );
		a[2][1].segment(i*n, s) = h*2*mean( (2*zeh - t6) / z2 );
		a[3][0].segment(i*n, s) = h * mean( (ze*t5 + t6) / z2 );
		a[3][1].segment(i*n, s) = h * mean( (ze - z - 1)  / z2 );
		a[4][0].segment(i*n, s) =-h * mean( (t3 - z + z2 - 4*zeh*(4-3*z+z2))  / t2 );
		a[4][1].segment(i*n, s) = h * mean( (t3 + 3*z - z2 + 8*zeh*t5)  / t2 );
		a[4][3].segment(i*n, s) =-h * mean( (t3 + 7*z + z2 + 4*zeh*t1)  / t2 );

		b[0].segment(i*n, s) = h * mean( (-t4 + ze*(4 - 3*z + z2)) / z3 );
		b[3].segment(i*n, s) =-h * mean( (4 + 3*z + z2 + ze*t1) / z3 );
		b[4].segment(i*n, s) = h*4*mean( (t6 + ze*t5 ) / z3 );

	    }
	}
	    
	else if (scheme == "Luan_Ostermann"){
	    c[1] = (hL/2).exp();
	    c[3] = (hL/4).exp();
	    c[5] = (hL/5).exp();
	    c[6] = (2*hL/3).exp();
	    c[7] = hL.exp();

	    a[1][0].resize(sL);
	    a[2][0].resize(sL);
	    a[2][1].resize(sL);
	    a[3][0].resize(sL);
	    a[3][2].resize(sL);
	    a[4][0].resize(sL);
	    a[4][2].resize(sL);
	    a[4][3].resize(sL);
	    a[5][0].resize(sL);
	    a[5][3].resize(sL);
	    a[5][4].resize(sL);
	    a[6][0].resize(sL);
	    a[6][3].resize(sL);
	    a[6][4].resize(sL);
	    a[6][5].resize(sL);
	    a[7][0].resize(sL);
	    a[7][4].resize(sL);
	    a[7][5].resize(sL);
	    a[7][6].resize(sL);
	    b[0].resize(sL);
	    b[5].resize(sL);
	    b[6].resize(sL);
	    b[7].resize(sL);
	    
	    for (int i = 0; i < p; i++){
		int s = i != p-1 ? n : sL-(p-1)*n;
		Ary hLs = h * (*L).segment(i*n, s);
		ArrayXXcd z = ZR(hLs);

		ArrayXXcd z2 = z.square();
		ArrayXXcd z3 = z.cube();
		ArrayXXcd z4 = z2.square();
		ArrayXXcd ze = z.exp();
		ArrayXXcd zeh = (z/2).exp();
		ArrayXXcd ze4 = (z/4).exp();
		ArrayXXcd ze5 = (z/5).exp();
		ArrayXXcd ze3 = (2*z/3).exp();



		ArrayXXcd t1 = -4 + z;	   
		ArrayXXcd t2 = 2*z2;
		ArrayXXcd t3 = 25*z3;
		ArrayXXcd t4 = 4 + z;
		ArrayXXcd t5 = 60-14*z+z2;
		ArrayXXcd t6 = -375*ze5*t5 - 486*ze3*t5;
		ArrayXXcd t7 = 16-6*z+z2;
		ArrayXXcd t8 = 100-5*z-3*z2;
	    
		a[1][0].segment(i*n, s) = h * mean( (zeh - 1)/z );
		a[2][0].segment(i*n, s) = h * mean( (zeh*(-2+z) + 2) / z2 );
		a[2][1].segment(i*n, s) = h * mean( (2*zeh - z - 2) / z2 );
		a[3][0].segment(i*n, s) = h * mean( (2*ze4*(-2+z)- t1) / t2 );
		a[3][2].segment(i*n, s) = h * mean( (4*ze4 - t4)  / t2 );	    
		a[4][0].segment(i*n, s) = h * mean( (zeh*t7 - 2*(8+z))  / z3 );
		a[4][2].segment(i*n, s) =-h * mean( (2*zeh*(-8+z) + 16 + 6*z + z2)  / z3 );
		a[4][3].segment(i*n, s) = h*8*mean( (zeh*t1 + t4)  / z3 );
		a[5][0].segment(i*n, s) = h * mean( (-400 + 70*z - 3*z2 + 25*ze5*t7) / t3 );
		a[5][3].segment(i*n, s) = h*8*mean( (t8 + 25*ze5*t1) / t3 );
		a[5][4].segment(i*n, s) = h*2*mean( (-200 - 25*ze5*(-8+z) - 15*z + z2) / t3 );
		a[6][0].segment(i*n, s) =-h * mean( (3740 + 125*ze5*t1 + 1001*z + 111*z2 - 162*ze3*(20-7*z+z2))
						    / (162*z3) );
		a[6][3].segment(i*n, s) =h*20*mean( (-t8 - 25*ze5*t1) / (81*z3) );
		a[6][4].segment(i*n, s) =-h * mean( (2740 + 324*ze3*(-10+z) - 125*ze5*t1 + 1861*z + 519*z2) / (243*z3) );
		a[6][5].segment(i*n, s) =h*25*mean( (125*ze5*t1 + 162*ze3*t1 + 7*(164+35*z+3*z2)) / (486*z3) );
		a[7][0].segment(i*n, s) = h * mean( (t6 + 35*ze*(-180+82*z-17*z2+2*z3) + 28*(2070+547*z+110*z2+14*z3))
						    / (70*z4) );
		a[7][4].segment(i*n, s) = h*4*mean( (t6 - 140*ze*(45-13*z+z2) + 7*(8280+2338*z+525*z2+76*z3))
						    / (105*z4) );
		a[7][5].segment(i*n, s) = h*5*mean( (-t6 + 350*ze*(18-7*z+z2) - 7*(8280+2248*z+465*z2+61*z3))
						    / (147*z4) );
		a[7][6].segment(i*n, s) =h*27*mean( (125*ze5*t5 + 162*ze3*t5 + 35*ze*t5 - 14*(1380+398*z+95*z2+16*z3))
						    / (490*z4) );
	    

		b[0].segment(i*n, s) = h * mean( (90 + 34*z + 4*z2 + ze*(-90 + 56*z -15*z2 + 2*z3)) / (2*z4) );
		b[5].segment(i*n, s)=h*125*mean( (-18 - 8*z - z2 + 2*ze*(9 - 5*z + z2)) / (28*z4) );
		b[6].segment(i*n, s)=-h*27*mean( (ze*(30 - 12*z + z2) - 2*(15 + 9*z + 2*z2)) / (14*z4) );
		b[7].segment(i*n, s) =-h * mean( (90 + 64*z + 21*z2 + 4*z3 - 2*ze*(45 - 13*z + z2)) / (4*z4) );

	    }
	}
	else if (scheme == "IFRK43") {
	    c[1] = (hL/2).exp();
	    c[3] = hL.exp();
	    
	    a[1][0] = h/2 * c[1];
	    a[3][2] = h * c[1];

	    b[0] = h * (1.0/6) * c[3];
	    b[1] = h * (1.0/3) * c[1];
	}
	else if (scheme == "IFRK54"){
	    c[1] = (hL/5).exp();
	    c[2] = (3*hL/10).exp();
	    c[3] = (4*hL/5).exp();
	    c[4] = (8*hL/9).exp();
	    c[5] = hL.exp();
	    
	    a[1][0] = (h/5) * c[1];
	    a[2][0] = (h*3/40) * c[2];
	    a[2][1] = (h*9/40) * (hL/10).exp();
	    a[3][0] = (h*44/45) * c[3];
	    a[3][1] = (-h*56.0/15) * (3*hL/5).exp();
	    a[3][2] = (h*32.0/9) * (hL/2).exp();
	    a[4][0] = (h*19372.0/6561) * c[4];
	    a[4][1] = (-h*25360.0/2187) * (31*hL/45).exp();
	    a[4][2] = (h*64448.0/6561) * (53*hL/90).exp();
	    a[4][3] = (-h*212.0/729) * (4*hL/45).exp();
	    a[5][0] = (h*9017.0/3168) * c[5];
	    a[5][1] = (-h*355.0/33) * (4*hL/5).exp();
	    a[5][2] = (h*46732.0/5247) * (7*hL/10).exp();
	    a[5][3] = (h*49.0/176) * c[1];
	    a[5][4] = (-h*5103.0/18656) * (hL/9).exp();

	    b[0] = (h*35.0/384) * c[5];
	    b[2] = (h*500./1113) * (7*hL/10).exp();
	    b[3] = (h*125./192) * c[1];
	    b[4] = (-h*2187./6784) * (hL/9).exp();
	}
	else if (scheme == "SSPP43") {
	    a1 = 0.268330095781759925;
	    a2 = -0.187991618799159782;
	    a3 = 0.919661523017399857;
	
	    c[0] = (a1*hL).exp();
	    c[1] = (a2*hL).exp();
	    c[2] = (a3*hL).exp();
	}
	else {
	    fprintf(stderr, "Please indicate the scheme !\n");
	    exit(1);
	}
	
	auto t_end = std::chrono::high_resolution_clock::now();
	std::chrono::duration<double> t_elapse = t_end - t_start;
	
	return t_elapse.count();
    }

    /// @brief multiplication
    /// @note in order to pass expressions as arguments, the arguments
    ///       must be declared as const
    inline 	
    virtual
    ArrayXXcd MUL(const Ary &C, const ArrayXXcd &Y){
	// for ArrayXcd * (ArrayXcd/ArrayXXcd): Y.colwise() * C 
	// for ArrayXd  * (ArrayXcd/ArrayXXcd): C.matrix().asDiagonal() * Y.matrix()
    }

    inline 
    virtual 
    ArrayXXcd ZR(Ary &z){}
    
    inline 
    virtual
    Ary mean(const Ref<const ArrayXXcd> &x){}

};


#endif	/* EID_H */



<file_sep>from py_CQCGL1d import *
from cglHelp import *

case = 20

if case == 5:
    """
    View the req and rpo for the same di.
    2d version
    """
    N = 1024
    d = 30
    h = 0.0002

    di = 0.422
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    e1, e2 = orthAxes2(veHat[0], veHat[1])
    
    x1, T1, nstp1, th1, phi1, err1 = cqcglReadRPOdi(
        '../../data/cgl/rpoT2X1.h5', di, 1)
    h1 = T1 / nstp1
    nstp1 = np.int(nstp1)
    cgl2 = pyCqcgl1d(N, d, h1, False, 0, 4.0, 0.8, 0.01, di, 4)
    aa1 = cgl2.intg(x1, nstp1, 1)
    aa1Hat, th2, phi2 = cgl2.orbit2slice(aa1)
    aa1Hat -= a0Hat
    aa1HatProj = np.dot(aa1Hat, np.vstack((e1, e2)).T)
    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111)
    ax.plot(aa1HatProj[:, 0], aa1HatProj[:, 1], c='r', lw=1)
    ax.scatter([0], [0], s=160)
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    # plotConfigSurfaceFourier(cgl, aa1, [0, d, 0, T1])

if case == 6:
    """
    View origin, req and rpo for the same di.
    3d version
    """
    N = 1024
    d = 30
    h = 0.0002

    di = 0.41
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    x1, T1, nstp1, th1, phi1, err1 = cqcglReadRPOdi(
        '../../data/cgl/rpoT2X1.h5', di, 1)
    h1 = T1 / nstp1
    nstp1 = np.int(nstp1)
    cgl2 = pyCqcgl1d(N, d, h1, False, 0, 4.0, 0.8, 0.01, di, 4)
    aa1 = cgl2.intg(x1, nstp1, 1)
    aa1Hat, th2, phi2 = cgl2.orbit2slice(aa1)
    aa1Hat -= a0Hat
    
    # e1, e2 = orthAxes2(veHat[0], veHat[1])
    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[6])
    aa1HatProj = np.dot(aa1Hat, np.vstack((e1, e2, e3)).T)
    OProj = np.dot(-a0Hat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa1HatProj[:, 0], aa1HatProj[:, 1], aa1HatProj[:, 2], c='r', lw=2)
    ax.scatter([0], [0], [0], s=80, marker='o', c='b',  edgecolors='none')
    ax.scatter(OProj[0], OProj[1], OProj[2], s=60, marker='o', c='c',
               edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 10:
    """
    view rep and rpo together in the symmetry reduced
    prejection frame.
    Also view the unstable manifold of the req
    """
    N = 1024
    d = 30
    h = 0.0002

    di = 0.4226
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

    eigvalues, eigvectors = eigReq(cgl, a0, wth0, wphi0)
    eigvectors = Tcopy(realve(eigvectors))
    a0Hat = cgl.orbit2slice(a0)[0]
    veHat = cgl.ve2slice(eigvectors, a0)

    x1, T1, nstp1, th1, phi1, err1 = cqcglReadRPOdi(
        '../../data/cgl/rpoT2X1.h5', di, 1)
    h1 = T1 / nstp1
    nstp1 = np.int(nstp1)
    cgl2 = pyCqcgl1d(N, d, h1, False, 0, 4.0, 0.8, 0.01, di, 4)
    aa1 = cgl2.intg(x1, nstp1, 1)
    aa1Hat, th2, phi2 = cgl2.orbit2slice(aa1)
    aa1Hat -= a0Hat

    h3 = 0.0005
    cgl3 = pyCqcgl1d(N, d, h3, False, 0, 4.0, 0.8, 0.01, di, 4)
    nstp = 70000
    a0Erg = a0 + eigvectors[0]*1e-3
    aaErg = cgl3.intg(a0Erg, 50000, 50000)
    a0Erg = aaErg[-1]
    aaErg = cgl3.intg(a0Erg, nstp, 2)
    aaErgHat, th3, th3 = cgl3.orbit2slice(aaErg)
    aaErgHat -= a0Hat
    
    # e1, e2 = orthAxes2(veHat[0], veHat[1])
    e1, e2, e3 = orthAxes(veHat[0], veHat[1], veHat[6])
    aa1HatProj = np.dot(aa1Hat, np.vstack((e1, e2, e3)).T)
    aaErgHatProj = np.dot(aaErgHat, np.vstack((e1, e2, e3)).T)
    OProj = np.dot(-a0Hat, np.vstack((e1, e2, e3)).T)

    fig = plt.figure(figsize=[6, 4])
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aa1HatProj[:, 0], aa1HatProj[:, 1], aa1HatProj[:, 2], c='r', lw=2)
    ax.plot(aaErgHatProj[:, 0], aaErgHatProj[:, 1],
            aaErgHatProj[:, 2], c='g', lw=1, alpha=0.4)
    i1 = 27500
    ax.plot(aaErgHatProj[i1:, 0], aaErgHatProj[i1:, 1],
            aaErgHatProj[i1:, 2], c='k', lw=1)
    ax.scatter([0], [0], [0], s=80, marker='o', c='b',  edgecolors='none')
    ax.scatter(OProj[0], OProj[1], OProj[2], s=60, marker='o', c='c',
               edgecolors='none')
    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    fig.tight_layout(pad=0)
    plt.show(block=False)
    # plotConfigSurfaceFourier(cgl, aa1, [0, d, 0, T1])

if case == 20:
    """
    plot req and rpo for same Bi, Gi in the full and symmetry-reduced
    state space
    """
    N, d = 1024, 50
    sysFlag = 1

    Bi, Gi = 2, -5
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)
    a0, wth, wphi, err = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1))
    OrbitEq = cgl.intg(a0, 0.001, 2, 2)
    OrbitEqH = cgl.orbit2slice(OrbitEq, sysFlag)[0]

    Bi, Gi = 4.8, -4.5 
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
    x, T, nstp, th, phi, err = rpo.read('../../data/cgl/rpoBiGi.h5', rpo.toStr(Bi, Gi, 1))
    po = cgl.intgC(x[:cgl.Ndim], T/nstp, T, 2)
    poH = cgl.orbit2slice(po, sysFlag)[0]

    fig, ax = pl2d(size=[6.5, 6], labs=[r'$b_2$', r'$c_2$'], axisLabelSize=30, tickSize=20)
    ax.plot(OrbitEq[:, 4], OrbitEq[:, 5], ls='-', lw=2, c='r')
    ax.plot(po[:, 4], po[:, 5], ls='-', lw=2, c='b')
    ax.set_xticks(ax.get_xticks()[::2])
    ax.set_yticks(ax.get_yticks()[::2])
    ax2d(fig, ax)
    
    fig, ax = pl2d(size=[6.5, 6], labs=[r'$\hat{b}_2$', r'$\hat{c}_2$'], axisLabelSize=30, tickSize=20)
    ax.scatter(OrbitEqH[0, 4], OrbitEqH[0, 5], s=100, edgecolors='none', marker='o', c='r')
    ax.plot(poH[:, 4], poH[:, 5], ls='-', lw=2, c='b')
    ax.set_xlim(25, 55)
    ax.set_xticks(ax.get_xticks()[::2])
    ax.set_yticks(ax.get_yticks()[::2])
    ax2d(fig, ax)

    """
    fig, ax = pl3d(size=[8, 6])
    ax.plot(poH[:, -1], poH[:, 4], poH[:, 5], c='r', lw=2)
    ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)
    #ax.plot(poHP[:, 0], poHP[:, 1], poHP[:, 2], c='r', lw=2)
    #ax.plot(aaHP[:, 0], aaHP[:, 1], aaHP[:, 2], c='b', lw=1)
    ax3d(fig, ax)
    """
<file_sep>from py_CQCGL1d import *
from py_CQCGL1dEIDc import *
from cglHelp import *
import matplotlib.gridspec as gridspec

case = 150


if case == 10:
    """
    plot the Bi - Gi req stability plot using the saved date from running viewReq.py
    data format : {Gi, Bi, #unstable}
    #unstalbe is 0, 2, 4, 6 ...
    """
    saveData = np.loadtxt("BiGiReqStab.dat")
    cs = {0: 'c', 1: 'm', 2: 'g', 4: 'r', 6: 'b'}#, 8: 'y', 56: 'r', 14: 'grey'}
    ms = {0: '^', 1: '^', 2: 'x', 4: 'o', 6: 'D'}#, 8: '8', 56: '4', 14: 'v'}
    fig, ax = pl2d(size=[8, 6], labs=[r'$\gamma_i$', r'$\beta_i$'], axisLabelSize=30,
                   tickSize=20, xlim=[-6, 0], ylim=[-4, 6])
    for item in saveData:
        Gi, Bi, m = item
        ax.scatter(Gi, Bi, s=18 if m > 0 else 18, edgecolors='none',
                   marker=ms.get(m, 'v'), c=cs.get(m, 'k'))
    # ax.grid(which='both')
    ax2d(fig, ax)

if case == 15:
    """
    same as case 10, bu plot contourf plot
    Note: the problem of contourf() is that whenever there is a jump
    in the levels, say from lv1 to lv2 but lv2 = lv1 + 2, then it will
    interpolate these two levels, thus a line for lv1 + 1 is plotted
    between these two regions.
    I need to draw each region indivisually. 
    """
    saveData = np.loadtxt("BiGiReqStab.dat")
    BiRange = [-3.2, 4]
    GiRange = [-5.6, -0.9]
    inc = 0.1

    nx = np.int(np.rint( (BiRange[1] - BiRange[0])/inc ) + 1)
    ny = np.int(np.rint( (GiRange[1] - GiRange[0])/inc ) + 1)

    x = np.linspace(BiRange[0], BiRange[1], nx)
    y = np.linspace(GiRange[0], GiRange[1], ny)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros([ny, nx]) - 1  # initialized with -1

    for item in saveData:
        Gi, Bi, m = item
        idx = np.int(np.rint((Bi - BiRange[0]) / inc))
        idy = np.int(np.rint((Gi - GiRange[0]) / inc))
        if idx >= 0 and idx < nx and idy >= 0 and idy < ny:
            Z[idy, idx] = m if m < 8 else 8

    levels = [-1, 0, 2, 4, 6, 8]
    cs = ['w', 'm', 'c', 'grey', 'r', 'y']
    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30,
                   tickSize=20)
    for i in range(len(levels)):
        vfunc = np.vectorize(lambda t : 0 if t == levels[i] else 1)
        Z2 = vfunc(Z)
        ax.contourf(X, Y, Z2, levels=[-0.1, 0.9], colors=cs[i])
    ax.text(0, -2, r'$S$', fontsize=30)
    ax.text(0, -4.5, r'$U_1$', fontsize=30)
    ax.text(1.8, -2.5, r'$U_2$', fontsize=30)
    ax.text(2., -4.8, r'$U_3$', fontsize=30)
    ax.text(3., -3, r'$U_{\geq 4}$', fontsize=30)
    ax.scatter(2.0,-5, c='k', s=100, edgecolor='none')
    ax.scatter(2.7,-5, c='k', s=100, edgecolor='none')
    ax.scatter(1.4,-3.9, c='k', marker='*', s=200, edgecolor='none')
    ax.set_xlim(BiRange)
    ax.set_ylim(GiRange)
    ax2d(fig, ax)
            
    
if case == 20:
    """
    use L = 50 to view the rpo, its unstable manifold and the difference plot
    """
    N, d = 1024, 50
    params = [[4.6, -5.0], [4.8, -4.5]]
    intgOfT = [19, 7]
    baseT = [[0, 4], [0, 4]]
    WuT = [[12, 19], [2, 7]]
    difT = [[7, 16], [0, 6]]
    skipRate = 10
    fig = plt.figure(figsize=[8, 7])
    for i in range(2):
        Bi, Gi = params[i]

        cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
        rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
        x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5', rpo.toStr(Bi, Gi, 1), flag=2)
        a0 = x[:cgl.Ndim]
        print e[:10]
        aa0 = cgl.intg(a0, T/nstp, nstp, 10)[:-1]

        a0 += 0.1*norm(a0)*v[0]

        aaBase = aa0
        for k in range(1, intgOfT[i]):
            aaBase = np.vstack((aaBase, cgl.Rotate(aa0, -k*th, -k*phi)))

        aa = cgl.intg(a0, T/nstp, intgOfT[i]*nstp, skipRate)
        dif = aa[:-1] - aaBase
        cellSize = nstp / skipRate
        # cp.config(dif, [0, d, 0*T, 6*T])
        
        aaBase = aaBase[baseT[i][0]*cellSize : baseT[i][1]*cellSize]
        aa = aa[WuT[i][0]*cellSize : WuT[i][1]*cellSize]
        dif = dif[difT[i][0]*cellSize : difT[i][1]*cellSize]

        states = [aaBase, aa, dif]
        for j in range(3):
            ax = fig.add_subplot('23' + str(3*i+j+1))
            ax.text(0.1, 0.9, '('+ chr(ord('a')+3*i+j) + ')', horizontalalignment='center',
                    transform=ax.transAxes, fontsize=20, color='white')
            if i == 1:
                ax.set_xlabel(r'$x$', fontsize=25)
            if j == 0:
                ax.set_ylabel(r'$t$', fontsize=25)
            if i == 0:
                ax.set_xticklabels([])
            ax.tick_params(axis='both', which='major', labelsize=12)
            if j == 0:
                extent = [0, d, baseT[i][0]*T, baseT[i][1]*T]
            elif j == 1:
                extent = [0, d, WuT[i][0]*T, WuT[i][1]*T]
            else:
                extent = [0, d, difT[i][0]*T, difT[i][1]*T]
            im = ax.imshow(np.abs(cgl.Fourier2Config(states[j])), cmap=plt.get_cmap('jet'), extent=extent, 
                           aspect='auto', origin='lower')
            ax.grid('on')
            dr = make_axes_locatable(ax)
            cax =dr.append_axes('right', size='5%', pad=0.05)
            plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
            fig.tight_layout(pad=0)

    plt.show(block=False)

if case == 30:
    """
    view the leading FV of two rpo.
    The leading FV of these two rpo are real, so there is no need to 
    special transformation
    """
    N, d = 1024 , 50
    params = [[4.6, -5.0], [4.8, -4.5]]
    fig = plt.figure(figsize=[8, 4])
    for i in range(2):
        Bi, Gi = params[i]
        cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
        rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
        x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5', rpo.toStr(Bi, Gi, 1), flag=2)
        ax = fig.add_subplot('12' + str(i+1))
        ax.text(0.1, 0.9, '('+ chr(ord('a')+i) + ')', horizontalalignment='center',
                transform=ax.transAxes, fontsize=20)
        ax.set_xlabel(r'$x$', fontsize=30)
        # ax.set_ylabel(r'$|v_1|$', fontsize=20)
        ax.tick_params(axis='both', which='major', labelsize=13)
        Aamp = np.abs(cgl.Fourier2Config(v[0]))
        ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp.shape[0]*Aamp, lw=1.5)
    fig.tight_layout(pad=0)
    plt.show(block=False)

if case == 35:
    """
    Similar to case = 30, but for rpo(4.6, -5.0), we plot all its unstable Floquet vectors.
    """
    N, d = 1024 , 50
    
    vs = []
    Bi, Gi = 4.6, -5.0
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5', rpo.toStr(Bi, Gi, 1), flag=2)
    for i in range(3):
        vs.append(v[i])

    # do not need to define another instance of cgl
    Bi, Gi = 4.8, -4.5
    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5', rpo.toStr(Bi, Gi, 1), flag=2)
    vs.insert(1, v[0])

    fig = plt.figure(figsize=[8, 7])
    for i in range(4):
        ax = fig.add_subplot('22' + str(i+1))
        ax.text(0.1, 0.9, '('+ chr(ord('a')+i) + ')', 
                horizontalalignment='center', transform=ax.transAxes, fontsize=20)
        if i > 1:
            ax.set_xlabel(r'$x$', fontsize=30)
        # ax.set_ylabel(r'$|v_1|$', fontsize=20)
        ax.tick_params(axis='both', which='major', labelsize=13)
        Aamp = np.abs(cgl.Fourier2Config(vs[i]))
        ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp.shape[0]*Aamp, lw=1.5)


    fig.tight_layout(pad=0)
    plt.show(block=False)
    

if case == 40:
    """
    use L = 50 to view the one req and one rpo int the symmetry reduced state space
    """
    N, d = 1024 , 50
    h = 2e-3
    sysFlag = 1
    
    fig = plt.figure(figsize=[8, 8])
    nx, ny = 16, 4
    gs = gridspec.GridSpec(nx, ny)

    # req
    Bi, Gi = 2, -2

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    EI = pyCQCGL1dEIDc(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=2)    
    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    
    aE = a0 + 0.001 * norm(a0) * v[0].real
    T = 50
    aa = EI.intg(aE, h, T, 10)
    aaH = cgl.orbit2slice(aa, sysFlag)[0]
    
    ax = fig.add_subplot(gs[:nx/2-1, 0])
    ax.text(0.9, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=20, color='white')
    ax.set_xlabel(r'$x$', fontsize=20)
    ax.set_ylabel(r'$t$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=12)
    aaTime = aa[cp.sliceTime(EI.Ts()), :]
    im = ax.imshow(np.abs(cgl.Fourier2Config(aaTime)), 
                   cmap=plt.get_cmap('jet'), extent=[0, d, 0, T], 
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    
    ax = fig.add_subplot(gs[:nx/2, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(b)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=20)
    ax.set_xlabel(r'$Re(a_0)$', fontsize=18)
    ax.set_ylabel(r'$Re(a_2)$', fontsize=18)
    ax.set_zlabel(r'$Im(a_2)$', fontsize=18)
    # ax.set_xlim([-20, 20])
    # ax.set_ylim([0, 250])
    # ax.set_zlim([-30, 30])
    ax.locator_params(nbins=4)
    ax.scatter(a0H[0], a0H[4], a0H[5], c='r', s=100, edgecolor='none')
    ax.plot(aaH[:, 0], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.5)
    
    # rpo
    Bi, Gi = 4.8, -4.5

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    EI = pyCQCGL1dEIDc(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)

    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5',
                                              rpo.toStr(Bi, Gi, 1), flag=2)
    a0 = x[:cgl.Ndim]
    po = EI.intg(a0, T/nstp, T, 1)
    poH = cgl.orbit2slice(po, sysFlag)[0]

    aE = a0 + 0.001 * norm(a0) * v[0];

    aa = EI.intg(aE, T/nstp, 16*T, 1)
    aaH, ths, phis = cgl.orbit2slice(aa, sysFlag)
    
    ax = fig.add_subplot(gs[nx/2:nx-1, 0])
    ax.text(0.9, 0.9, '(c)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=20, color='white')
    ax.set_xlabel(r'$x$', fontsize=20)
    ax.set_ylabel(r'$t$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=12)
    aaTime = aa[cp.sliceTime(EI.Ts()), :]
    im = ax.imshow(np.abs(cgl.Fourier2Config(aaTime)), 
                   cmap=plt.get_cmap('jet'), extent=[0, d, 0, 16*T], 
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    
    ax = fig.add_subplot(gs[nx/2:, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(d)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=20)
    ax.set_xlabel(r'$Re(a_{0})$', fontsize=18)
    ax.set_ylabel(r'$Re(a_{2})$', fontsize=18)
    ax.set_zlabel(r'$Im(a_{2})$', fontsize=18)
    # ax.set_ylim([-50, 200])
    ax.locator_params(nbins=4)
    ax.plot(poH[:, 0], poH[:, 4], poH[:, 5], c='r', lw=2)
    ax.plot(aaH[:, 0], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.5)

    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 50:
    """
    plot one req explosion and its symmetry reduced plots
    use it to test case = 40
    """
    N, d = 1024, 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi = 2, -2

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    EI = pyCQCGL1dEIDc(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=2)

    # get the bases
    vt = np.vstack([v[0].real, v[0].imag, v[6].real])
    vRed = cgl.ve2slice(vt, a0, sysFlag)
    Q = orthAxes(vRed[0], vRed[1], vRed[2])

    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    a0P = a0H.dot(Q)
    aE = a0 + 0.001 * norm(a0) * v[0].real
    T = 50
    aa = EI.intg(aE, h, T, 2)
    aaH = cgl.orbit2slice(aa, sysFlag)[0]
    aaP = aaH.dot(Q) - a0P
    
    fig, ax = pl3d(size=[8, 6], labs=[r'$v_1$', r'$v_2$', r'$v_3$'],
                   axisLabelSize=20, tickSize=20)
    ax.scatter(0, 0, 0, c='k', s=100, edgecolors='none')
    id1 = bisect_left(EI.Ts(), 24)
    ax.plot(aaP[id1/2:id1, 0], aaP[id1/2:id1, 1], aaP[id1/2:id1, 2], c='m', lw=1, alpha=0.5)
    id2 = bisect_left(EI.Ts(), 33)
    ax.plot(aaP[id2:, 0], aaP[id2:, 1], aaP[id2:, 2], c='b', lw=1, alpha=0.6)
    ax3d(fig, ax)
    
if case == 55:
    """
    plot one rpo explosion and its symmetry reduced plots
    use it to test case = 40
    """
    N, d = 1024, 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi = 4.8, -4.5

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    EI = pyCQCGL1dEIDc(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)

    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5',
                                              rpo.toStr(Bi, Gi, 1), flag=2)
    a0 = x[:cgl.Ndim]
    
    # get the bases
    vt = np.vstack([v[0], v[1], v[3]])
    vRed = cgl.ve2slice(vt, a0, sysFlag)
    Q = orthAxes(vRed[0], vRed[1], vRed[2])

    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    a0P = a0H.dot(Q)
    
    po = EI.intg(a0, T/nstp, T, 1)
    poH = cgl.orbit2slice(po, sysFlag)[0]
    poP = poH.dot(Q) - a0P

    aE = a0 + 0.001 * norm(a0) * v[0];

    aa = EI.intg(aE, T/nstp, 16*T, 2)
    aaH = cgl.orbit2slice(aa, sysFlag)[0]
    aaP = aaH.dot(Q) - a0P
    
    fig, ax = pl3d(size=[8, 6], labs=[r'$v_1$', r'$v_2$', r'$v_3$'],
                   axisLabelSize=20, tickSize=20)
    ax.scatter(0, 0, 0, c='k', s=100, edgecolors='none')
    ax.plot(poP[:, 0], poP[:, 1], poP[:, 2], c='r', lw=2)
    id1 = bisect_left(EI.Ts(), 23)
    ax.plot(aaP[id1/2:id1, 0], aaP[id1/2:id1, 1], aaP[id1/2:id1, 2], c='m', lw=1, alpha=0.5)
    id2 = bisect_left(EI.Ts(), 35)
    ax.plot(aaP[id2:, 0], aaP[id2:, 1], aaP[id2:, 2], c='b', lw=1, alpha=0.6)
    ax3d(fig, ax)
    
    
if case == 60:
    """
    plot the stability table of the rpos
    """
    N, d = 1024, 50

    fileName = '../../data/cgl/rpoBiGiEV.h5'
    
    cs = {0: 'g'}#, 10: 'm', 2: 'c', 4: 'r', 6: 'b', 8: 'y'}#, 56: 'r', 14: 'grey'}
    ms = {0: 's'}#, 10: '^', 2: '+', 4: 'o', 6: 'D', 8: 'v'}#, 56: '4', 14: 'v'}

    fig, ax = pl2d(size=[8, 6], labs=[r'$\beta_i$', r'$\gamma_i$'], axisLabelSize=30, tickSize=20,
                   ylim=[-5.65, -3.95], xlim=[1.8, 5.8])
    for i in range(39):
        Bi = 1.9 + i*0.1
        for j in range(55):
            Gi = -5.6 + 0.1*j
            rpo = CQCGLrpo()
            if rpo.checkExist(fileName, rpo.toStr(Bi, Gi, 1) + '/er'):
                x, T, nstp, th, phi, err, e, v = rpo.read(fileName, rpo.toStr(Bi, Gi, 1), flag=2)
                m, ep, accu = numStab(e, nmarg=3, tol=1e-4, flag=1)
                ax.scatter(Bi, Gi, s=60, edgecolors='none',
                           marker=ms.get(m, 'o'), c=cs.get(m, 'r'))

    #ax.xaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.yaxis.set_minor_locator(AutoMinorLocator(10))
    #ax.grid(which='major', linewidth=2)
    #ax.grid(which='minor', linewidth=1)
    ax2d(fig, ax)
    

if case == 70:
    """
    plot one Hopf bifurcation
    subplot (a) : heat map of the limit cycle
    subplot (b) : symmetry-reduced state space figure
    """
    N, d = 1024, 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi = 1.4, -3.9
    index = 1
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)

    # obtain unstable manifold of req
    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, index), flag=2)

    # get the bases
    vt = np.vstack([v[0].real, v[0].imag, v[4].real])
    vRed = cgl.ve2slice(vt, a0, sysFlag)
    Q = orthAxes(vRed[0], vRed[1], vRed[2])

    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    a0P = a0H.dot(Q)

    aE = a0 + 0.1*norm(a0)*v[0].real
    T = 800
    aa = cgl.intg(aE, h, np.int(100/h), 100000)
    aE = aa[-1] 
    aa = cgl.intg(aE, h, np.int(T/h), 50)
    aaH = cgl.orbit2slice(aa, sysFlag)[0]
    aaP = aaH.dot(Q) - a0P
    
    # obtain limit cycle
    x, T, nstp, th, phi, err = rpo.read('../../data/cgl/rpoHopfBiGi.h5', rpo.toStr(Bi, Gi, 1))
    ap0 = x[:-3]
    hp = T / nstp
    aap = cgl.intg(ap0, hp, nstp, 10)
    aapH = cgl.orbit2slice(aap, sysFlag)[0]
    aapP = aapH.dot(Q) - a0P
    
    aap4 = aap
    for k in range(1, 4):
        aap4 = np.vstack((aap4, cgl.Rotate(aap, -k*th, -k*phi)))
    
    # plot figure 
    fig = plt.figure(figsize=[8, 4])
    nx, ny = 8, 4
    gs = gridspec.GridSpec(nx, ny)

    ax = fig.add_subplot(gs[:nx-1, 0])
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='white')
    ax.set_xlabel(r'$x$', fontsize=25)
    ax.set_ylabel(r'$t$', fontsize=25)
    ax.tick_params(axis='both', which='major', labelsize=12)
    im = ax.imshow(np.abs(cgl.Fourier2Config(aap4)), cmap=plt.get_cmap('jet'), extent=[0, d, 0, 4*T], 
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    
    ax = fig.add_subplot(gs[:, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(b)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18)
    ax.set_xlabel(r'$v_1$', fontsize=25)
    ax.set_ylabel(r'$v_2$', fontsize=25)
    ax.set_zlabel(r'$v_3$', fontsize=25)
    # ax.set_xlim([-20, 20])
    # ax.set_ylim([0, 250])
    # ax.set_zlim([-30, 30])
    ax.locator_params(nbins=4)
    # ax.scatter(a0H[], a0H[4], a0H[5], c='r', s=40)
    # ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)
    # ax.plot(aapH[:, -1], aapH[:, 4], aapH[:, 5], c='r', lw=2)
    ax.scatter(0, 0, 0, c='r', s=40)
    ax.plot(aaP[:, 0], aaP[:, 1], aaP[:, 2], c='b', lw=1, alpha=0.7)
    ax.plot(aapP[:, 0], aapP[:, 1], aapP[:, 2], c='r', lw=2)

    fig.tight_layout(pad=0)
    plt.show(block=False)


if case == 75:
    """
    same as case 70 but only save the data
    """
    N, d = 1024, 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi = 1.4, -3.9
    index = 1
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)

    # obtain unstable manifold of req
    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, index), flag=2)

    # get the bases
    vt = np.vstack([v[0].real, v[0].imag, v[4].real])
    vRed = cgl.ve2slice(vt, a0, sysFlag)
    Q = orthAxes(vRed[0], vRed[1], vRed[2])

    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    a0P = a0H.dot(Q)

    aE = a0 + 0.1*norm(a0)*v[0].real
    T = 800
    aa = cgl.intgC(aE, h, 100, 100000)
    aE = aa[-1] if aa.ndim == 2 else aa 
    aa = cgl.intgC(aE, h, T, 50)
    aaH = cgl.orbit2slice(aa, sysFlag)[0]
    aaP = aaH.dot(Q) - a0P
    
    # obtain limit cycle
    x, T, nstp, th, phi, err = rpo.read('../../data/cgl/rpoHopfBiGi.h5', rpo.toStr(Bi, Gi, 1))
    ap0 = x[:-3]
    hp = T / nstp
    aap = cgl.intgC(ap0, hp, T, 10)
    aapH = cgl.orbit2slice(aap, sysFlag)[0]
    aapP = aapH.dot(Q) - a0P
    
    aap4 = aap
    for k in range(1, 4):
        aap4 = np.vstack((aap4, cgl.Rotate(aap, -k*th, -k*phi)))
    
    # save the data

    hopfCycleProfiles4Periods = np.abs(cgl.Fourier2Config(aap4))
    np.savez_compressed('hopfCycleAndWuOfReq', hopfCycleProfiles4Periods=hopfCycleProfiles4Periods, T=T, aaP=aaP, aapP=aapP)

if case == 80:
    """
    new size L = 50
    plot the plane soliton and composite soliton in the same figure.
    """
    N, d = 1024, 50
    
    fig, ax = pl2d(size=[8, 6], labs=[r'$x$', r'$|A|$'], axisLabelSize=30, tickSize=20)

    Bi, Gi = 2.0, -5
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    a0, wth0, wphi0, err0 = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=0)
    Aamp = np.abs(cgl.Fourier2Config(a0))
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2, ls='-', c='k')

    Bi, Gi = 2.7, -5
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    a0, wth0, wphi0, err0 = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=0)
    Aamp = np.abs(cgl.Fourier2Config(a0))
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2, ls='--', c='k')
    
    ax2d(fig, ax)

if case == 90:
    """
    save the data for the two coexsting solitons for the same parameter
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    a1, wth0, wphi0, err0 = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=0)
    a2, wth0, wphi0, err0 = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 2), flag=0)
    absA1 = np.abs(cgl.Fourier2Config(a1))
    absA2 = np.abs(cgl.Fourier2Config(a2))
    np.savez_compressed('solitonProfileFor08n06', absA1=absA1, absA2=absA2)

if case == 100:
    """
    same as case = 40. but in two different plots
    """
    N, d = 1024 , 50
    h = 2e-3
    sysFlag = 1
    
    fig = plt.figure(figsize=[8, 4])
    nx, ny = 8, 4
    gs = gridspec.GridSpec(nx, ny)

    # req
    Bi, Gi = 2, -2

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.readReqBiGi('../../data/cgl/reqBiGiEV.h5', Bi, Gi, 1, flag=2)
    a0H = cgl.orbit2slice(a0, sysFlag)[0]
    
    aE = a0 + 0.001 * norm(a0) * v[0].real
    T = 50
    aa = cgl.intg(aE, h, np.int(T/h), 1)
    # cp.config(aa, [0, d, 0, T])
    aaH, ths, phis = cgl.orbit2slice(aa, sysFlag)
    
    ax = fig.add_subplot(gs[:nx-1, 0])
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='white')
    ax.set_xlabel(r'$x$', fontsize=16)
    ax.set_ylabel(r'$t$', fontsize=16)
    ax.tick_params(axis='both', which='major', labelsize=12)
    im = ax.imshow(np.abs(cgl.Fourier2Config(aa)), cmap=plt.get_cmap('jet'), extent=[0, d, 0, T], 
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    
    ax = fig.add_subplot(gs[:, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(b)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18)
    ax.set_xlabel(r'$Re(a_{-1})$', fontsize=16)
    ax.set_ylabel(r'$Re(a_{2})$', fontsize=16)
    ax.set_zlabel(r'$Im(a_{2})$', fontsize=16)
    ax.set_xlim([-20, 20])
    ax.set_ylim([0, 250])
    ax.set_zlim([-30, 30])
    ax.locator_params(nbins=4)
    ax.scatter(a0H[-1], a0H[4], a0H[5], c='r', s=40)
    ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)

    fig.tight_layout(pad=0)
    plt.show(block=False)


    fig = plt.figure(figsize=[8, 4])
    nx, ny = 8, 4
    gs = gridspec.GridSpec(nx, ny)

    # rpo
    Bi, Gi = 4.8, -4.5

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)

    x, T, nstp, th, phi, err, e, v = rpo.readRpoBiGi('../../data/cgl/rpoBiGiEV.h5',
                                               Bi, Gi, 1, flag=2)
    a0 = x[:cgl.Ndim]
    po = cgl.intg(a0, T/nstp, nstp, 10)
    poH = cgl.orbit2slice(po, sysFlag)[0]

    aE = a0 + 0.001 * norm(a0) * v[0];

    aa = cgl.intg(aE, T/nstp, 20*nstp, 1)
    # cp.config(aa, [0, d, 0, 20*T])
    aaH, ths, phis = cgl.orbit2slice(aa, sysFlag)
    
    ax = fig.add_subplot(gs[:nx-1, 0])
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='white')
    ax.set_xlabel(r'$x$', fontsize=16)
    ax.set_ylabel(r'$t$', fontsize=16)
    ax.tick_params(axis='both', which='major', labelsize=12)
    im = ax.imshow(np.abs(cgl.Fourier2Config(aa)), cmap=plt.get_cmap('jet'), extent=[0, d, 0, 20*T], 
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax =dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    
    ax = fig.add_subplot(gs[:, 1:], projection='3d')
    ax.text2D(0.1, 0.9, '(b)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18)
    ax.set_xlabel(r'$Re(a_{-1})$', fontsize=16)
    ax.set_ylabel(r'$Re(a_{2})$', fontsize=16)
    ax.set_zlabel(r'$Im(a_{2})$', fontsize=16)
    # ax.set_ylim([-50, 200])
    ax.locator_params(nbins=4)
    ax.plot(poH[:, -1], poH[:, 4], poH[:, 5], c='r', lw=2)
    ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)

    # fig, ax = pl3d(size=[8, 6], labs=[r'$Re(a_{-1})$', r'$Re(a_{2})$', r'$Im(a_{2})$'],
    #                axisLabelSize=20, tickSize=20)
    # ax.plot(poH[:, -1], poH[:, 4], poH[:, 5], c='r', lw=2)
    # ax.plot(aaH[:, -1], aaH[:, 4], aaH[:, 5], c='b', lw=1, alpha=0.7)
    # ax3d(fig, ax)

    fig.tight_layout(pad=0)
    plt.show(block=False)



if case == 150:
    """
    find one representative symmetric and asymmetric explosions
    save the data
    """
    N, d = 1024 , 50
    h = 2e-3    
    Bi, Gi = 0.8, -0.6

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1), flag=2)    
    aE = a0 + 0.001 * norm(a0) * v[0].real

    # get rid of transicent
    aa = cgl.intgC(aE, h, 69, 100000)
    aE = aa[-1] if aa.ndim == 2 else aa

    # save symmetric explosion
    Tsymmetric = 10
    aa = cgl.intgC(aE, h, Tsymmetric, 10)
    AampSymmetric = np.abs(cgl.Fourier2Config(aa))
    aE = aa[-1] if aa.ndim == 2 else aa
    
    # save asymmetric explosion
    aa = cgl.intgC(aE, h, 189, 100000)
    aE = aa[-1] if aa.ndim == 2 else aa
    Tasymmetric = 10
    aa = cgl.intgC(aE, h, Tasymmetric, 10)
    AampAsymmetric = np.abs(cgl.Fourier2Config(aa))
    a0RealAsymmetric = aa[:, 0].real
    aE = aa[-1] if aa.ndim == 2 else aa

    np.savez_compressed('explosionExample08n06', AampSymmetric=AampSymmetric, AampAsymmetric=AampAsymmetric, 
                        Tsymmetric=Tsymmetric, Tasymmetric=Tasymmetric, a0RealAsymmetric=a0RealAsymmetric)
    
<file_sep>#ifndef CQCGL1dRpo_arpack_H
#define CQCGL1dRpo_arpack_H

#include "CQCGL1dRpo.hpp"

class CQCGL1dRpo_arpack : public CQCGL1dRpo {

public:

    typedef std::complex<double> dcp;

    ////////////////////////////////////////////////////////////
    // A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    CQCGL1dRpo_arpack(int N, double d,
		      double Mu, double Dr, double Di, double Br, double Bi, 
		      double Gr, double Gi, int dimTan);
    
    // A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
    CQCGL1dRpo_arpack(int N, double d, 
		      double b, double c, double dr, double di, 
		      int dimTan);
    
    // iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
    CQCGL1dRpo_arpack(int N, double d,
		      double delta, double beta, double D, double epsilon,
		      double mu, double nu, int dimTan);
    ~CQCGL1dRpo_arpack();
    CQCGL1dRpo_arpack & operator=(const CQCGL1dRpo_arpack &x);

    ////////////////////////////////////////////////////////////
    std::pair<VectorXcd, MatrixXd>
    evRpo(const ArrayXd &a0, double h, int nstp, 
	  double th, double phi, int ne);
    
    void 
    calEVParaSeq(std::string file, std::vector<double> Bis, 
		 std::vector<double> Gis, int ne, bool saveV);

    static
    std::pair< std::vector<double>, std::vector<double> >
    getMissIds(std::string file, double Bi0, double Gi0, 
	       double incB, double incG, int nB, int nG);
};


struct Jdotx {
    CQCGL1dRpo_arpack *rpo;
    ArrayXd a0;
    double h, th, phi;
    int Nt;
    
    Jdotx(CQCGL1dRpo_arpack *rpo, const ArrayXd &a0, double h, int Nt,
	  double th, double phi) 
	: rpo(rpo), a0(a0), h(h), Nt(Nt), th(th), phi(phi){}
    
    void mul(double *v, double *w){
	int Ndim = rpo->Ndim;
	Map<const ArrayXd> mv(v, Ndim);
	Map<ArrayXd> mw(w, Ndim);
	ArrayXXd tmp = rpo->intgv(a0, mv, h, Nt);
	mw = rpo->Rotate(tmp.rightCols(1), th, phi);
    }
    
};


#endif	/* CQCGL1dRpo_arpack */
<file_sep>#include <iostream>
#include <cstdio>
#include <Eigen/Dense>
#include <H5Cpp.h>
#include "ksFEFV.hpp"
#include "myH5.hpp"
#include "ksint.hpp"
#include "ped.hpp"

using namespace std;
using namespace Eigen;

/** @brief calculate Floquet exponents and Floquet vectors of KS system.
 *
 *  @param[in] ppType periodic type: ppo/rpo
 *  @param[in] ppId  id of the orbit
 *  @param[in] MaxN maximal number of PED iteration
 *  @param[in] tol tolerance of PED
 *  @param[in] nqr spacing
 *  @return FE and FV
 */
pair<MatrixXd, MatrixXd>
KScalFEFV(const string fileName,
	  const string ppType,
	  const int ppId,
	  const int L /* = 22 */,
	  const int MaxN /* = 80000 */,
	  const double tol /* = 1e-15 */,
	  const int nqr /* = 1 */,
	  const int trunc /* = 0 */){
    // get the initla condition of the orbit
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);

    const int N = a.rows();
    const int Nks = N + 2;
    
    // solve the Jacobian of this po.
    KS ks(Nks, L);
    std::pair<ArrayXXd, ArrayXXd> tmp2 = ks.intgj(a.col(0), T/nstp, nstp, nqr);
    MatrixXd daa = tmp2.second; 
    daa = daa.rightCols(daa.cols() - daa.rows()).eval();
  
    // calculate the Flqouet exponents and vectors.
    PED ped;
    ped.reverseOrder(daa); // reverse order.
    if(ppType.compare("ppo") == 0)
	daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
    else // R*J for rpo
	daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);
    pair<MatrixXd, MatrixXd> eigv = ped.EigVecs(daa, MaxN, tol, false, trunc);
    MatrixXd &eigvals = eigv.first; 
    eigvals.col(0) = eigvals.col(0).array()/T;
    MatrixXd &eigvecs = eigv.second;

    return make_pair(eigvals, eigvecs);
}


/** @brief calculate Floquet exponents of KS system.
 *
 *  @param[in] ppType periodic type: ppo/rpo
 *  @param[in] ppId  id of the orbit
 *  @param[in] MaxN maximal number of PED iteration
 *  @param[in] tol tolerance of PED
 *  @param[in] nqr spacing
 *  @return FE and FV
 */
MatrixXd
KScalFE(const string fileName,
	const string ppType,
	const int ppId,
	const int L /* = 22 */,
	const int MaxN /* = 80000 */,
	const double tol /* = 1e-15 */,
	const int nqr /* = 1 */){
    // get the initla condition of the orbit
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);

    const int N = a.rows();
    const int Nks = N + 2;
    
    // solve the Jacobian of this po.
    KS ks(Nks, L);
    pair<ArrayXXd, ArrayXXd> tmp2 = ks.intgj(a.col(0), T/nstp, nstp, nqr);
    MatrixXd daa = tmp2.second;
    daa = daa.rightCols(daa.cols() - daa.rows()).eval();
  
    // calculate the Flqouet exponents and vectors.
    PED ped;
    ped.reverseOrder(daa); // reverse order.
    if(ppType.compare("ppo") == 0)
	daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
    else // R*J for rpo
	daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);
    MatrixXd eigvals = ped.EigVals(daa, MaxN, tol, false);
    eigvals.col(0) = eigvals.col(0).array()/T;

    return eigvals;
}

MatrixXd
KSgetR(const string fileName,
       const string ppType,
       const int ppId,
       const int L /* = 22 */,
       const int MaxN /* = 80000 */,
       const double tol /* = 1e-15 */,
       const int nqr /* = 1 */){
    
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);

    const int N = a.rows();
    const int Nks = N + 2;
    
    // solve the Jacobian of this po.
    KS ks(Nks, L);
    pair<ArrayXXd, ArrayXXd> tmp2 = ks.intgj(a.col(0), T/nstp, nstp, nqr);
    MatrixXd daa = tmp2.second;
    daa = daa.rightCols(daa.cols() - daa.rows()).eval();
  
    // calculate the Flqouet exponents and vectors.
    PED ped;
    ped.reverseOrder(daa); // reverse order.
    if(ppType.compare("ppo") == 0)
	daa.leftCols(N) = ks.reflect(daa.leftCols(N)); // R*J for ppo
    else // R*J for rpo
	daa.leftCols(N) = ks.rotate(daa.leftCols(N), -s*2*M_PI/L);
    MatrixXd eigvals = ped.EigVals(daa, MaxN, tol, false);
    eigvals.col(0) = eigvals.col(0).array()/T;

    return daa;
}

void 
KScalWriteFE(const string inputfileName,
	     const string outputfileName,
	     const string ppType,
	     const int ppId,
	     const int L /* = 22 */,
	     const int MaxN /* = 80000 */,
	     const double tol /* = 1e-15 */,
	     const int nqr /* = 1 */){
    MatrixXd eigvals = KScalFE(inputfileName, ppType, ppId, L, MaxN, tol, nqr);  
    MyH5::KSwriteFE(outputfileName, ppType, ppId, eigvals);
}


void 
KScalWriteFEInit(const string inputfileName,
		 const string outputfileName,
		 const string ppType,
		 const int ppId,
		 const int L /* = 22 */,
		 const int MaxN /* = 80000 */,
		 const double tol /* = 1e-15 */,
		 const int nqr /* = 1 */){
    MatrixXd eigvals = KScalFE(inputfileName, ppType, ppId, L, MaxN, tol, nqr);  
    MyH5::KSwriteFE(outputfileName, ppType, ppId, eigvals);

    auto tmp = MyH5::KSreadRPO(inputfileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);
    MyH5::KSwriteRPO(outputfileName, ppType, ppId, a, T, nstp, r, s);
}


void 
KScalWriteFEFV(const string inputfileName,
	       const string outputfileName,
	       const string ppType,
	       const int ppId,
	       const int L /* = 22 */,
	       const int MaxN /* = 80000 */,
	       const double tol /* = 1e-15 */,
	       const int nqr /* = 1 */,
	       const int trunc /* = 0 */){
    pair<MatrixXd, MatrixXd> eigv = KScalFEFV(inputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
    MatrixXd &eigvals = eigv.first;
    MatrixXd &eigvecs = eigv.second; 
  
    MyH5::KSwriteFEFV(outputfileName, ppType, ppId, eigvals, eigvecs);
    
}


/**
 * @brief calculate FE and FV and save inital conditions and FE, FV to outputfile
 */
void 
KScalWriteFEFVInit(const string inputfileName,
		   const string outputfileName,
		   const string ppType,
		   const int ppId,
		   const int L /* = 22 */,
		   const int MaxN /* = 80000 */,
		   const double tol /* = 1e-15 */,
		   const int nqr /* = 1 */,
		   const int trunc /* = 0 */){
    pair<MatrixXd, MatrixXd> eigv = KScalFEFV(inputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
    MatrixXd &eigvals = eigv.first;
    MatrixXd &eigvecs = eigv.second; 
  
    MyH5::KSwriteFEFV(outputfileName, ppType, ppId, eigvals, eigvecs);
    
    auto tmp = MyH5::KSreadRPO(inputfileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);
    MyH5::KSwriteRPO(outputfileName, ppType, ppId, a, T, nstp, r, s);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//  Left eigenvector related 

std::pair<MatrixXd, MatrixXd>
KScalLeftFEFV(const std::string fileName, const std::string ppType, const int ppId,
	      const int L, const int MaxN, const double tol,
	      const int nqr, const int trunc){
    
    auto tmp = MyH5::KSreadRPO(fileName, ppType, ppId);
    MatrixXd &a = std::get<0>(tmp);
    double T = std::get<1>(tmp);
    int nstp = (int) std::get<2>(tmp);
    double r = std::get<3>(tmp);
    double s = std::get<4>(tmp);

    const int N = a.rows();
    const int Nks = N + 2;
    
    // solve the Jacobian of this po.
    KS ks(Nks, L);
    std::pair<ArrayXXd, ArrayXXd> tmp2 = ks.intgj(a.col(0), T/nstp, nstp, nqr);
    MatrixXd daa = tmp2.second;
    
    // get the order of J_1^T, J_2^T, ..., (R*J_M)^T 
    int M = daa.cols();
    daa.resize(N, N*M);
    if(ppType.compare("ppo") == 0)
	daa.rightCols(N) = ks.reflect(daa.rightCols(N)); // R*J for ppo
    else // R*J for rpo
	daa.rightCols(N) = ks.rotate(daa.rightCols(N), -s*2*M_PI/L);
    for(int i = 0; i < M; i++) {
	MatrixXd tmp = daa.middleCols(i*N, N).transpose();
	daa.middleCols(i*N, N) = tmp;
    }
    
    // calculate the Flqouet exponents and vectors.
    PED ped;
    pair<MatrixXd, MatrixXd> eigv = ped.EigVecs(daa, MaxN, tol, false, trunc);
    MatrixXd &eigvals = eigv.first; 
    eigvals.col(0) = eigvals.col(0).array()/T;
    MatrixXd &eigvecs = eigv.second;

    return make_pair(eigvals, eigvecs);
}

void 
KScalWriteLeftFEFV(const string inputfileName,
		   const string outputfileName,
		   const string ppType,
		   const int ppId,
		   const int L,
		   const int MaxN ,
		   const double tol ,
		   const int nqr ,
		   const int trunc ){
    std::pair<MatrixXd, MatrixXd> eigv = KScalLeftFEFV(inputfileName, ppType, ppId, L, MaxN, tol, nqr, trunc);
    MatrixXd &eigvals = eigv.first;
    MatrixXd &eigvecs = eigv.second; 
    
    MyH5::KSwriteFEFV(outputfileName, ppType, ppId, eigvals, eigvecs);
}
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3 -march=corei7 -msse4.2' MEXcqcgl1d.cpp cqcgl1d.cc -I../../include -I/usr/include/eigen3 -lm -lfftw3
 * */

#include "cqcgl1d.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>

using namespace Eigen;


static ArrayXXd gintgv(int N, double d, double h,
		       int Njacv,
		       double b, double c,
		       double dr, double di,
		       int threadNum,
		       double *a0, double *v, 
		       double th, double phi, int nstp){

    bool enableJacv = true;
    Cqcgl1d cgl(N, d, h, enableJacv, Njacv, b, c, dr, di, threadNum);
    Map<ArrayXd> tmpa(a0, cgl.Ndim);
    Map<ArrayXXd> tmpv(v, cgl.Ndim, cgl.trueNjacv);
    ArrayXXd av = cgl.gintgv(tmpa, tmpv, th, phi, nstp);
    return av;
}

void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    int N = mxGetScalar(prhs[0]);
    double d = mxGetScalar(prhs[1]);
    double h = mxGetScalar(prhs[2]);
    int Njacv = mxGetScalar(prhs[3]);
    double b = mxGetScalar(prhs[4]);
    double c = mxGetScalar(prhs[5]);
    double dr = mxGetScalar(prhs[6]);
    double di = mxGetScalar(prhs[7]);
    int threadNum = mxGetScalar(prhs[8]);

    double *a0 = mxGetPr(prhs[9]);
    double *v = mxGetPr(prhs[10]);
    double th = mxGetScalar(prhs[11]);
    double phi = mxGetScalar(prhs[12]);
    int nstp = mxGetScalar(prhs[13]);
    // mwSize isJ = mxGetScalar(prhs[14]);
    
    ArrayXXd av = gintgv(N, d, h, Njacv, b, c, dr, di, threadNum, a0, v, th, phi, nstp);
    plhs[0] = mxCreateDoubleMatrix(av.rows(), av.cols(), mxREAL);
    memcpy(mxGetPr(plhs[0]), av.data(), av.cols()*av.rows()*sizeof(double));
}
<file_sep>#include "ksrefine.hpp"
#include "iterMethod.hpp"
#include <iostream>
#include <fstream>

using namespace std; 
using namespace Eigen;

typedef Eigen::SparseMatrix<double> SpMat;
typedef Eigen::Triplet<double> Tri;

////////////////////////////////////////////////////////////
//                     class KSrefine                     //
////////////////////////////////////////////////////////////

/*------------          constructor        ---------------*/
KSrefine::KSrefine(int N /* = 32 */, double L /* = 22 */) : N(N), L(L) {}
KSrefine::KSrefine(const KSrefine &x) : N(x.N), L(x.L) {}
KSrefine & KSrefine::operator=(const KSrefine &x){ return *this;}
KSrefine::~KSrefine(){}

/* -----------         member functions    -------------- */
struct KeepDiag {
  inline bool operator() (const int& row, const int& col,
			  const double&) const
  { return row == col;  }
};

/* @brief transform a dense matrix into Triplet form, which should be used to
 *        initialize a spase matrix subblock.
 *
 * @param[in] M row position of the subblock
 * @param[in] N col position of the sbublock
 * @return the triplet representation of the dense matrix
 *
 */
vector<Tri> 
KSrefine::triMat(const MatrixXd &A, const size_t M /* = 0 */, 
		 const size_t N /* = 0 */){
  vector<Tri> tri; 
  size_t m = A.rows();
  size_t n = A.cols();
  tri.reserve(m*n);
  // for efficience, loop in the row wise.
  for(size_t j = 0; j < n; j++)
    for(size_t i = 0; i < m; i++)
      tri.push_back( Tri(M+i, N+j, A(i,j) ));

  return tri;
}


/* @brief transform a diagoal matrix (diagonal elements are the same) into Triplet
 *        form
 *        
 * @param[in] n size of the diagonal matrix
 * @param[in] x the diagonal elements
 * @param[in] M row position of the subblock
 * @param[in] N col position of the sbublock
 * @see triMat()
 */
vector<Tri> 
KSrefine::triDiag(const size_t n, const double x, const size_t M /* = 0 */, 
	const size_t N /* = 0 */ ){
  vector<Tri> tri;
  tri.reserve(n);
  for(size_t i = 0; i < n; i++) tri.push_back( Tri(M+i, N+i, x) );
  return tri;
}

/* @brief form the multishooting difference vector
 *        [ f(x_0)       - x_1,
 *          f(x_1)       - x_2,
 *          ...
 *          R*f(x_{m-1}) - x_0]
 *        Here R is rotation for rpo, reflection for ppo.
 *
 * @param[in] ks KS object used to integrate the system
 * @param[in] x [x_0, x_1, ..., x_{n-1}] state vectors
 * @param[in] nstp integratin steps
 * @param[in] ppType "ppo" or "rpo"
 * @param[in] th rotation angle for rpo. It is not used for ppo.
 */

VectorXd 
KSrefine::multiF(KS &ks, const ArrayXXd &x, const int nstp, 
		 const string ppType, const double th /* = 0.0 */){
  int n = x.rows();
  int m = x.cols();
  VectorXd F(m*n);

  // form the first m - 1 difference vectors
  for(size_t i = 0; i < m - 1; i++){
    ArrayXXd aa = ks.intg(x.col(i), nstp, nstp);
    F.segment(i*n, n) = aa.col(1) - x.col(i+1);
  }

  // the last difference vector
  ArrayXXd aa = ks.intg(x.col(m-1), nstp, nstp);
  if(ppType.compare("ppo") == 0)
    F.segment((m-1)*n, n) = ks.reflect(aa.col(1)) - x.col(0);
  else if(ppType.compare("rpo") == 0)
    F.segment((m-1)*n, n) = ks.rotate(aa.col(1), th)  - x.col(0);
  else
    fprintf(stderr, "please indicate the right PO type !\n");
  
  return F;
}

/** @brief calculate the column size of the multishooting matrix
 *
 */
int
KSrefine::calColSizeDF(const int &rows, const int &cols, const string ppType){
  int colsizeDF(0);
  
  if(ppType.compare("ppo") == 0) colsizeDF = rows*cols+1;
  else if(ppType.compare("rpo") == 0) colsizeDF = rows*cols+2;
  else fprintf(stderr, "please indicate the right PO type !\n");

  return colsizeDF;
}

/* @brief not only form the difference vector but also the multishooting matrix
 *
 * @return multishooting matrix and difference vector
 * @see multiF()
 */
pair<SpMat, VectorXd> 
KSrefine::multishoot(KS &ks, const ArrayXXd &x, const int nstp, 
		     const string ppType, const double th /* = 0.0 */,
		     const bool Print /* = false */){
  int n = x.rows();
  int m = x.cols();
  
  int colsizeDF = calColSizeDF(n, m, ppType); 
  SpMat DF(m*n, colsizeDF);
  VectorXd F(m*n);
  vector<Tri> nz; 
  nz.reserve(2*m*n*n+m*n);
  if(Print) printf("Forming multishooting matrix:");

  for(size_t i = 0 ; i < m; i++){
    if(Print) printf("%zd ", i);
    pair<ArrayXXd, ArrayXXd> tmp = ks.intgj(x.col(i), nstp, nstp, nstp); 
    ArrayXXd &aa = tmp.first;
    ArrayXXd &J = tmp.second;
    // assert(J.rows() == n*n && J.cols() == 1);
    J.resize(n, n);
    
    if(i < m-1)
      {
	// J
	vector<Tri> triJ = triMat(J, i*n, i*n);
	nz.insert(nz.end(), triJ.begin(), triJ.end());
	// velocity
	vector<Tri> triv = triMat(ks.velocity(aa.col(1)), i*n, m*n);
	nz.insert(nz.end(), triv.begin(), triv.end());
	// f(x_i) - x_{i+1}
	F.segment(i*n, n) = aa.col(1) - x.col(i+1);
      } 
    else
      {
	if(ppType.compare("ppo") == 0){
	  // R*J
	  vector<Tri> triJ = triMat(ks.reflect(J), i*n, i*n);  
	  nz.insert(nz.end(), triJ.begin(), triJ.end());
	  // R*velocity
	  vector<Tri> triv = 
	    triMat(ks.reflect(ks.velocity(aa.col(1))), i*n, m*n);
	  nz.insert(nz.end(), triv.begin(), triv.end());
	  // R*f(x_{m-1}) - x_0
	  F.segment(i*n, n) = ks.reflect(aa.col(1)) - x.col(0);
	} else if (ppType.compare("rpo") == 0){
	  // g*J
	  vector<Tri> triJ = triMat(ks.rotate(J, th), i*n, i*n);
	  nz.insert(nz.end(), triJ.begin(), triJ.end());  
	  // R*velocity
	  vector<Tri> triv = 
	    triMat(ks.rotate(ks.velocity(aa.col(1)), th), i*n, m*n);
	  nz.insert(nz.end(), triv.begin(), triv.end());
	  // T*g*f(x_{m-1})
	  VectorXd tx = ks.gTangent( ks.rotate(aa.col(1), th) );
	  vector<Tri> tritx = triMat(tx, i*n, m*n+1);
	  nz.insert(nz.end(), tritx.begin(), tritx.end());
	  // g*f(x_{m-1}) - x_0
	  F.segment(i*n, n) = ks.rotate(aa.col(1), th) - x.col(0);
	} else {
	  fprintf(stderr, "please indicate the right PO type !\n");
	}

      }
    
    // -I on subdiagonal
    vector<Tri> triI = triDiag(n, -1, i*n, ((i+1)%m)*n);
    nz.insert(nz.end(), triI.begin(), triI.end());

  }
  if(Print) printf("\n");
  
  DF.setFromTriplets(nz.begin(), nz.end());

  return make_pair(DF, F);
}


/** @brief find ppo/rpo in KS system
 *
 * @param[in] a0 guess of initial condition
 * @param[in] T guess of period
 * @param[in] h0 guess of time step
 * @param[in] Norbit number of pieces of the orbit, so each segment has Norbit/M.
 * @param[in] M number of pieces for multishooting method
 * @param[in] ppType ppo/rpo
 * @param[in] th0 guess of initial group angle. For ppo, it is zero.
 * @param[in] hinit: the initial time step to get a good starting guess.
 * @param[in] MaxN maximal number of iteration
 * @param[in] tol tolerance of convergence
 * @return initial conditions along the orbit, time step, shift, error
 *
 */
tuple<MatrixXd, double, double, double>
KSrefine::findPOmulti(const ArrayXd &a0, const double T, const int Norbit, 
		      const int M, const string ppType,
		      const double hinit /* = 0.1*/,
		      const double th0 /* = 0 */,
		      const int MaxN /* = 100 */, 
		      const double tol /* = 1e-14*/, 
		      const bool Print /* = false */,
		      const bool isSingle /* = false */){ 
  bool Terminate = false;
  assert(a0.rows() == N - 2 && Norbit % M == 0);
  const int nstp = Norbit/M;
  double h = T/Norbit;
  double th = th0;
  double lam = 1;
  SparseLU<SpMat> solver; // used in the pre-CG method

  // prepare the initial state sequence
  KS ks0(N, hinit, L);
  ArrayXXd tmpx = ks0.intg(a0, (int)ceil(T/hinit), 
			(int)floor(T/hinit/M));
  ArrayXXd x = tmpx.leftCols(M); 
  double err = 0; // error 
  
  for(size_t i = 0; i < MaxN; i++){
    if(Print && i%10 == 0) printf("******  i = %zd/%d  ****** \n", i, MaxN);
    KS ks(N, h, L);
    VectorXd F;
    if(!isSingle) F = multiF(ks, x, nstp, ppType, th);
    else F = multiF(ks, x.col(0), Norbit, ppType, th);
    err = F.norm(); 
    if(err < tol){
      fprintf(stderr, "stop at norm(F)=%g for iteration %zd\n", err, i);
      break;
    }
   
    pair<SpMat, VectorXd> p = multishoot(ks, x, nstp, ppType, th, false); 
    SpMat JJ = p.first.transpose() * p.first; 
    VectorXd JF = p.first.transpose() * p.second;
    SpMat Dia = JJ; 
    Dia.prune(KeepDiag());

    for(size_t j = 0; j < 20; j++){
      ////////////////////////////////////////
      // solve the update
      SpMat H = JJ + lam * Dia; 
      pair<VectorXd, vector<double> > cg = iterMethod::ConjGradSSOR<SpMat>
	(H, -JF, solver, VectorXd::Zero(H.rows()), H.rows(), 1e-6);
      VectorXd &dF = cg.first;
      
      ////////////////////////////////////////
      // print the CG infomation
      if(Print)
	printf("CG error %g after %lu iterations.\n", 
	       cg.second.back(), cg.second.size());

      ////////////////////////////////////////
      // update the state
      ArrayXXd xnew = x + Map<ArrayXXd>(&dF(0), N-2, M);
      double hnew = h + dF((N-2)*M)/nstp; // be careful here.
      double thnew = th;
      if(ppType.compare("rpo") == 0) thnew += dF((N-2)*M+1);
      
      // check the new time step positve
      if( hnew <= 0 ){ 
	fprintf(stderr, "new time step is negative\n");
	Terminate = true;
	break;
      }
      
      KS ks1(N, hnew, L);
      VectorXd newF;
      if(!isSingle) newF = multiF(ks1, xnew, nstp, ppType, thnew); 
      else newF = multiF(ks1, xnew.col(0), Norbit, ppType, thnew); 
      if(Print) printf("err = %g \n", newF.norm());
      if (newF.norm() < err){
	x = xnew; h = hnew; th = thnew; 
	lam = lam/10; 
	break;
      }
      else{
	lam *= 10; 
	if(Print) printf("lam = %g \n", lam);
	if( lam > 1e10) {
	  fprintf(stderr, "lam = %g too large.\n", lam); 
	  Terminate = true;
	  break; 
	}
      }
      
    }
    
    if( Terminate )  break;
  }
  
  return make_tuple(x, h, th, err);
}

std::tuple<VectorXd, double, double>
KSrefine::findPO(const Eigen::ArrayXd &a0, const double T, const int Norbit, 
		 const int M, const std::string ppType,
		 const double hinit /* = 0.1 */,
		 const double th0 /* = 0 */, 
		 const int MaxN /* = 100 */, 
		 const double tol /* = 1e-14 */, 
		 const bool Print /* = false */,
		 const bool isSingle /* = false */){
  tuple<MatrixXd, double, double, double> 
    tmp = findPOmulti(a0, T, Norbit, M, ppType, hinit, th0, MaxN, tol, Print, isSingle);
  return make_tuple(std::get<0>(tmp).col(0), std::get<1>(tmp), std::get<2>(tmp));
}

/*
pair<MatrixXd, VectorXd> newtonReq(Cqcgl1d &cgl, const ArrayXd &a0, const double w1, const double w2){
  MatrixXd DF(2*N+2, 2*N+2);
  ArrayXd t1 = cgl.TS1(a0);
  ArrayXd t2 = cgl.TS2(a0);
  DF.topLeftCorner(2*N, 2*N) = cgl.stab(a0) + w1*cgl.GS1() + w2*cgl.GS2();
  DF.col(2*N).head(2*N) = t1;
  DF.col(2*N+1).head(2*N) = t2;
  //DF.row(2*N).head(2*N) = t1.transpose();
  //DF.row(2*N+1).head(2*N) = t2.transpose();
  DF.row(2*N).head(2*N) = VectorXd::Zero(2*N);
  DF.row(2*N+1).head(2*N) = VectorXd::Zero(2*N);
  DF.bottomRightCorner(2,2) = MatrixXd::Zero(2,2);

  VectorXd F(2*N+2);
  F.head(2*N) = cgl.vel(a0) + w1*t1 + w2*t2;
  F(2*N) = 0;
  F(2*N+1) = 0;

  return make_pair(DF, F);
  
}
*/
/*
ArrayXd findReq(const ArrayXd &a0, const double w10, const double w20, const int MaxN, const double tol){

  ArrayXd a = a0;
  double w1 = w10;
  double w2 = w20;
  double lam = 1;
  ConjugateGradient<MatrixXd> CG;
  Cqcgl1d cgl(N, L);
  
  for(size_t i = 0; i < MaxN; i++){
    if (lam > 1e10) break;
    printf("********  i = %zd/%d   ******** \n", i, MaxN);
    VectorXd F = cgl.vel(a) + w1*cgl.TS1(a) + w2*cgl.TS2(a);
    double err = F.norm(); 
    if(err < tol){
      printf("stop at norm(F)=%g\n", err);
      break;
    }
   
    pair<MatrixXd, VectorXd> p = newtonReq(cgl, a, w1, w2); 
    MatrixXd JJ = p.first.transpose() * p.first;
    VectorXd JF = p.first.transpose() * p.second;
    
    for(size_t j = 0; j < 20; j++){
      printf("inner iteration j = %zd\n", j);
      //MatrixXd H = JJ + lam * JJ.diagonal().asDiagonal(); 
      MatrixXd H = JJ; H.diagonal() *= (1+lam);
      CG.compute(H);     
      VectorXd dF = CG.solve(-JF);
      printf("CG error %f, iteration number %d\n", CG.error(), CG.iterations());
      ArrayXd anew = a + dF.head(2*N).array();
      double w1new = w1 + dF(2*N); 
      double w2new = w2 + dF(2*N+1);
      printf("w1new = %f, w2new = %f\n", w1new, w2new);
      
      VectorXd Fnew = cgl.vel(anew) + w1new*cgl.TS1(anew) + w2new*cgl.TS2(anew);
      cout << "err = " << Fnew.norm() << endl;
      if (Fnew.norm() < err){
	a = anew; w1 = w1new; w2 = w2new;
	lam = lam/10; cout << "lam = "<< lam << endl;
	break;
      }
      else{
	lam *= 10; cout << "lam = "<< lam << endl;
	if( lam > 1e10) { printf("lam = %f too large.\n", lam); break; }
      }
      
    }
  }
  
  ArrayXd req(2*N+3);
  VectorXd err = cgl.vel(a) + w1*cgl.TS1(a) + w2*cgl.TS2(a);
  req << a, w1, w2, err.norm(); 
  return req;
}
*/
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CQCGL1dEIDc.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class pyCQCGL1dEIDc : public CQCGL1dEIDc {
  
public:

    pyCQCGL1dEIDc(int N, double d, double Mu, double Dr, double Di, 
		  double Br, double Bi, double Gr, double Gi):
	CQCGL1dEIDc(N, d, Mu, Dr, Di, Br, Bi, Gr, Gi) {}

    pyCQCGL1dEIDc(int N, double d,
		  double b, double c, double dr, double di) :
	CQCGL1dEIDc(N, d, b, c, dr, di) {}
    
    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }

    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

   /* wrap the integrator */
    bn::ndarray PYintgC(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intgC(tmpa, h, tend, skip_rate));
    }
    
    bn::ndarray PYintg(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), m*n);
	return copy2bn(intg(tmpa, h, tend, skip_rate));
    }

};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_CQCGL1dEIDc) {
    bn::initialize();
    
    // must provide the constructor
    bp::class_<CQCGL1dEIDc>("CQCGL1dEIDc", bp::init<
			    int, double, double, double, double,
			    double, double, double, double>())
	;
    
    // the EIDc class
    bp::class_<EIDc>("EIDc", bp::init<>())
	.def_readonly("NCalCoe", &EIDc::NCalCoe)
	.def_readonly("NReject", &EIDc::NReject)
	.def_readonly("NCallF", &EIDc::NCallF)
	.def_readonly("NSteps", &EIDc::NSteps)
	.def_readonly("TotalTime", &EIDc::TotalTime)
	.def_readonly("CoefficientTime", &EIDc::CoefficientTime)
	.def_readwrite("rtol", &EIDc::rtol)
	;

    // 
    bp::class_<pyCQCGL1dEIDc, bp::bases<CQCGL1dEIDc> >("pyCQCGL1dEIDc", bp::init<
						       int, double, double, double, double,
						       double, double, double, double>())
	.def(bp::init<int, double, double, double ,double, double>())
	.def_readonly("N", &pyCQCGL1dEIDc::N)
	.def_readonly("d", &pyCQCGL1dEIDc::d)
	.def_readonly("Mu", &pyCQCGL1dEIDc::Mu)
	.def_readwrite("Br", &pyCQCGL1dEIDc::Br)
	.def_readwrite("Bi", &pyCQCGL1dEIDc::Bi)
	.def_readonly("Dr", &pyCQCGL1dEIDc::Dr)
	.def_readonly("Di", &pyCQCGL1dEIDc::Di)
	.def_readwrite("Gr", &pyCQCGL1dEIDc::Gr)
	.def_readwrite("Gi", &pyCQCGL1dEIDc::Gi)
	.def_readonly("Ndim", &pyCQCGL1dEIDc::Ndim)
	.def_readonly("Ne", &pyCQCGL1dEIDc::Ne)
	.def_readonly("Omega", &pyCQCGL1dEIDc::Omega)
	.def_readwrite("eidc", &pyCQCGL1dEIDc::eidc)
	.def("Ts", &pyCQCGL1dEIDc::PYTs)
	.def("hs", &pyCQCGL1dEIDc::PYhs)
	.def("lte", &pyCQCGL1dEIDc::PYlte)

	.def("changeOmega", &pyCQCGL1dEIDc::changeOmega)
	.def("setScheme", &pyCQCGL1dEIDc::setScheme)
	.def("intgC", &pyCQCGL1dEIDc::PYintgC)
	.def("intg", &pyCQCGL1dEIDc::PYintg)
	;

}
<file_sep>/* to compile :
 * g++ test_iterMethod.cc  -O3 -march=corei7 -msse2 -msse4 -I $XDAPPS/eigen/include/eigen3 -std=c++11 -I ../../include -L ../../lib -literMethod -ldenseRoutines 
 */
#include "iterMethod.hpp"
#include <cmath>
#include <complex>
#include <iostream>
#include <time.h>       /* time */

#define cee(x) (cout << (x) << endl << endl)

using namespace std;
using namespace Eigen;
using namespace denseRoutines;
using namespace iterMethod;

typedef Eigen::Triplet<double> Tri;
typedef Eigen::SparseMatrix<double> SpMat; 

int main()
{
    cout.precision(16);
    switch (9)
	{
 
	case 1: // test ConjGrad() with dense matrix
	    {
		const int N = 10;
		MatrixXd A(N, N);
		VectorXd b(N);

		for (int i = 0; i < N; i++) {
		    for (int j = 0; j < N; j++) {
			A(i,j) = (i+j)%11;
		    }
		    b(i) = sin(i*i);
		}
  
		pair<VectorXd, vector<double> > 
		    tmp = iterMethod::ConjGrad<MatrixXd>(A, b, VectorXd::Zero(N), 100, 1e-6);
		cout << tmp.first << endl << endl;
		for (int i = 0; i < tmp.second.size(); i++) {
		    cout << tmp.second[i] << endl;
		}
		cout << tmp.second.size() << endl;

		break;
	    }
      
	case 2: //test ConjGrad() with sparse matrix
	    {
		const int N  = 10;
	
		vector<Tri> tri;
		for (int i = 0; i < N; i++) {
		    tri.push_back(Tri(i, i, 2));
		    if(i < N-1) {
			tri.push_back(Tri(i, i+1, -1));
			tri.push_back(Tri(i+1, i, -1));
		    }
		}
		SpMat A(N, N);
		A.setFromTriplets(tri.begin(), tri.end());
	
		VectorXd b(N);
		for (int i = 0; i < N; i++) b(i) = sin(i*i);  

		// perform CG method 
		pair<VectorXd, vector<double> > 
		    tmp = iterMethod::ConjGrad<SpMat>(A, b, VectorXd::Zero(N), 100, 1e-6);
		cout << tmp.first << endl << endl;
		for (int i = 0; i < tmp.second.size(); i++) {
		    cout << tmp.second[i] << endl;
		}
		cout << tmp.second.size() << endl;
	
	    }

	case 3 : // test ConjGradPre() with dense matrix
	    {
		// initialization 
		const int N  = 10;
	
		MatrixXd A(N, N);
		for (int i = 0; i < N; i++) {
		    A(i, i) = 2;
		    if(i < N-1) {
			A(i+1, i) = -1;
			A(i, i+1) = -1;
		    }
		}

		VectorXd b(N);
		for (int i = 0; i < N; i++) b(i) = sin(i*i);  

		// compute
		MatrixXd M(MatrixXd::Identity(N, N)); cout << A << endl;
		PartialPivLU<MatrixXd> solver;
		pair<VectorXd, vector<double> > 
		    tmp = iterMethod::ConjGradPre<MatrixXd, PartialPivLU<MatrixXd> >
		    (A, b, M, solver, VectorXd::Zero(N), 100, 1e-16);

		cout << tmp.first << endl << endl;
		for (int i = 0; i < tmp.second.size(); i++) {
		    cout << tmp.second[i] << endl;
		}
		cout << tmp.second.size() << endl;
	
		break;
	    }
      
	case 4: // test ConjGradPre() with sparse matrix
	    {
		const int N  = 10;
	
		vector<Tri> tri;
		for (int i = 0; i < N; i++) {
		    tri.push_back(Tri(i, i, 2));
		    if(i < N-1) {
			tri.push_back(Tri(i, i+1, -1));
			tri.push_back(Tri(i+1, i, -1));
		    }
		}
		SpMat A(N, N);
		A.setFromTriplets(tri.begin(), tri.end());
	
		VectorXd b(N);
		for (int i = 0; i < N; i++) b(i) = sin(i*i);  

		// compute
		SpMat M(N, N); 
		vector<Tri> triM; 
		for (int i = 0; i < N; i++) triM.push_back(Tri(i, i, 1));
		M.setFromTriplets(triM.begin(), triM.end());
		cout << M << endl;

		SparseLU<SpMat> solver;
		pair<VectorXd, vector<double> > 
		    tmp = iterMethod::ConjGradPre<SpMat, SparseLU<SpMat> >
		    (A, b, M, solver, VectorXd::Zero(N), 100, 1e-16);

		cout << tmp.first << endl << endl;
		for (int i = 0; i < tmp.second.size(); i++) {
		    cout << tmp.second[i] << endl;
		}
		cout << tmp.second.size() << endl;
	
		break;
	
	    }
      
	case 5 : // test SSOR preconditioning
	    {
		const int N  = 10;
	
		vector<Tri> tri;
		for (int i = 0; i < N; i++) {
		    tri.push_back(Tri(i, i, 2));
		    if(i < N-1) {
			tri.push_back(Tri(i, i+1, -1));
			tri.push_back(Tri(i+1, i, -1));
		    }
		}
		SpMat A(N, N);
		A.setFromTriplets(tri.begin(), tri.end());

		SpMat ssor = iterMethod::preSSOR<SpMat>(A);
		cout << ssor << endl;

		break;
	    }

	case 6: // test ConjGradSSOR() with sparse matrix
	    {
		const int N  = 10;
	
		vector<Tri> tri;
		for (int i = 0; i < N; i++) {
		    tri.push_back(Tri(i, i, 2));
		    if(i < N-1) {
			tri.push_back(Tri(i, i+1, -1));
			tri.push_back(Tri(i+1, i, -1));
		    }
		}
		SpMat A(N, N);
		A.setFromTriplets(tri.begin(), tri.end());
	
		VectorXd b(N);
		for (int i = 0; i < N; i++) b(i) = sin(i*i);  

		// compute
		SparseLU<SpMat> solver;
		pair<VectorXd, vector<double> > 
		    tmp = iterMethod::ConjGradSSOR<SpMat, SparseLU<SpMat> >
		    (A, b, solver, VectorXd::Zero(N), 100, 1e-16);

		cout << tmp.first << endl << endl;
		for (int i = 0; i < tmp.second.size(); i++) {
		    cout << tmp.second[i] << endl;
		}
		cout << tmp.second.size() << endl;
	
		break;
	
	    }

	case 7: // test Gmres() with dense matrix
	    {
		srand (time(NULL));
		const int N  = 10;

		MatrixXd A(N, N);
		VectorXd x(N);

		for (int i = 0; i < N; i++) {
		    for (int j = 0; j < N; j++) {
			A(i,j) = (double)rand() / RAND_MAX - 0.5; 
		    }
		    x(i) =  (double)rand() / RAND_MAX - 0.5; 
		}
		VectorXd b = A * x;
	
		//cout << A << endl << endl;
		cout << x << endl << endl;
		cout << b << endl << endl;

		// compute
		std::tuple<VectorXd, vector<double>, int> 
		    tmp = iterMethod::Gmres<MatrixXd>
		    (A, b, VectorXd::Zero(N), 20, 20, 1e-8);

		cout << std::get<0>(tmp) << endl << endl;
		for (int i = 0; i < std::get<1>(tmp).size(); i++) {
		    cout << std::get<1>(tmp)[i] << endl;
		}
		cout << std::get<2>(tmp) << endl << endl;;
		cout << std::get<1>(tmp).size() << endl << endl;
		cout << (A * std::get<0>(tmp) - b).norm() << endl;
		break;	
	    }

	case 8: // test findTrustRegion
	    {
		srand (time(NULL));
		const int N = 5;
		ArrayXd D(N), p(N);
		for(int i = 0; i < N; i++){
		    /* D(i) = i+1; */
		    /* p(i) = i+1; */
		    /* D(i) = (double)rand() / RAND_MAX - 0.5; */
		    /* p(i) = (double)rand() / RAND_MAX - 0.5; */
		    D(i) = rand() % 100;
		    p(i) = rand() % 100;
		}

		cout << D <<endl << endl;
		cout << p << endl << endl;
		cout << p / D << endl << endl;
		cout << p.matrix().norm() << endl << endl;
		
		auto tmp = iterMethod::findTrustRegion(D, p, 0.1, 1e-4, 20, 0);
		cout << std::get<0>(tmp) << endl;
		cout << std::get<1>(tmp).size() << endl;
		cout << std::get<2>(tmp) << endl;

		auto x = std::get<1>(tmp);
		for_each (x.begin(), x.end(), [](double i){cout << i << endl;});

		ArrayXd z = iterMethod::calz(D, p,  std::get<0>(tmp));
		cout << "z norm " << z.matrix().norm() << endl;
		cout << "Dz-p " << endl << (D*z - p).matrix().norm() << endl;

		break;
	    }

	case 9: // test GmresHook()/GmresHookPre() with dense matrix
	    {
		const int N  = 50;

		//MatrixXd A = MatrixXd::Random(N, N);
		//A.diagonal() *= 200;
		VectorXd t = VectorXd::Random(N) * 0.5 + 5*VectorXd::Ones(N);
		t(N-1) = 1e6;
		MatrixXd A = matE(t);
		VectorXd x(VectorXd::Random(N));
		VectorXd b = A * x;
		
		VectorXcd e = eEig(A); // cee(e);

		VectorXd bp;
		std::vector<double> errs;
		int flag;
		std::tie(bp, errs, flag) = iterMethod::GmresHook<MatrixXd>
		    (A, b, VectorXd::Zero(N), 1e-12, 1e-3, 20, 20, 1e-8, 100, 20, false, 1); 

		for (int i = 0; i < errs.size(); i++)   cout << errs[i] << endl;		
		cee( (A * bp - b).norm() );

		break;	
	    }

	case 10:		/* test LM() function */
	    {
		srand(time(NULL));
		const int N = 100;
		
		MatrixXd A(randM(N, N));
		A.col(10) *= 1e7;
		VectorXd x(randM(N, 1));
		VectorXd b = A * x;

		cout << x << endl << endl;
		cout << b << endl << endl;

		auto tmp = LM(A, b, VectorXd::Zero(N), 1e-13, 100, 20);
		
		cout << std::get<0>(tmp) << endl << endl;
		auto res = std::get<1>(tmp);
		for(int i = 0; i < res.size(); i++) cout << res[i] << endl;
		cout << std::get<2>(tmp) << endl << endl;
		

		break;
	    }


	}

    return 0;
}


<file_sep>/* g++ -std=c++11 -I$EIGEN test_EigenFFT.cc */
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include <iostream>

#define EIGEN_FFTW_DEFAULT

#define CE(x) cout << (x) << endl << endl

using namespace Eigen;
using namespace std;

int main(){
    
    VectorXcd A(4);
    A.real() << 2, 8, 3, 6;
    A.imag() << 3, 5, 7, 19;

    VectorXcd B(4);
    VectorXcd C(4);

    FFT<double> fft;
    fft.fwd(B, A);
    fft.inv(C, B);

    CE(A); CE(B); CE(C);
    
    return 0;
}

<file_sep>from personalFunctions import *

case = 20

if case == 10:
    """
    allocate all soliton solutions
    """
    ix = np.arange(0.09, 0.57, 0.01).tolist()
    ixf = [format(i, ".6f") for i in ix]
    fs = ['req09.h5', 'req1.h5', 'req11.h5', 'req12.h5', 'req13.h5',
          'req14.h5', 'req15.h5', 'req16.h5', 'req17.h5', 'req18.h5',
          'req19.h5', 'req2.h5', 'req21.h5', 'req22.h5', 'req23.h5',
          'req24.h5', 'req25.h5', 'req26.h5', 'req27.h5', 'req28.h5',
          'req29.h5', 'req3.h5', 'req31.h5', 'req32.h5', 'req33.h5',
          'req34.h5', 'req35.h5', 'req36.h5', 'req37.h5', 'req38.h5',
          'req39.h5', 'req4.h5', 'req41.h5', 'req42.h5', 'req43.h5',
          'req44.h5', 'req45.h5', 'req46.h5', 'req47.h5', 'req48.h5',
          'req49.h5', 'req5.h5', 'req51.h5', 'req52.h5', 'req53.h5',
          'req54.h5', 'req55.h5', 'req56.h5']
    inps = ['./req_different_di/' + i for i in fs]
    for i in range(len(ix)):
        cqcglMoveReqEV(inps[i], '1', 'reqDi.h5', ixf[i]+'/1')

if case == 20:
    """
    allocate all soliton solutions
    """
    ix = [0.57, 0.59, 0.61, 0.63, 0.65, 0.67, 0.69, 0.71, 0.74, 0.77,
          0.8, 0.83, 0.86, 0.9, 0.94, 0.96]
    ixf = [format(i, ".6f") for i in ix]
    fs = ['req57.h5', 'req59.h5', 'req61.h5', 'req63.h5', 'req65.h5',
          'req67.h5', 'req69.h5', 'req71.h5', 'req74.h5', 'req77.h5',
          'req8.h5', 'req83.h5', 'req86.h5', 'req9.h5', 'req94.h5',
          'req96.h5']
    inps = ['./req_different_di/' + i for i in fs]
    for i in range(len(ix)):
        cqcglMoveReqEV(inps[i], '1', 'reqDi.h5', ixf[i]+'/1')
<file_sep>/* to comiple:
 * h5c++ -O3 test_cqcgl1d.cc  -L../../lib -I../../include -I $XDAPPS/eigen/include/eigen3 -std=c++0x -lCQCGL1d -lsparseRoutines -ldenseRoutines -lmyH5 -lped -lmyfft -lfftw3 -lm 
 */
#include "CQCGL1d.hpp"
#include "myH5.hpp"
#include <iostream>
#include <fstream>
#include <eigen3/Eigen/Dense>
#include <complex>
#include <H5Cpp.h>

using namespace std;
using namespace Eigen;
using namespace MyH5;
using namespace denseRoutines;

typedef std::complex<double> dcp;


#define N10

int main(){

#ifdef N10
    //======================================================================
    /* test the new constructor */
    const int N = 1024;
    const int L = 50;
    // CQCGL1d cgl(N, L, 4.0, 0.8, 0.01, 0.06, -1);
    CQCGL1d cgl(N, L, -1, 1, 4.0, 1, 0.8, -0.01, -0.06, -1);
	
    int nstp = 1;
	
    VectorXcd A0 = Gaussian(N, N/2, N/10, 3) + Gaussian(N, N/4, N/10, 0.5);
    VectorXd a0 = cgl.Config2Fourier(A0);
	
    ArrayXXd aa = cgl.intg(a0, 0.0001, nstp, 1);
	
    cout << aa.rows() << 'x' << aa.cols() << endl;
    cout << aa << endl;
#endif

    
    return 0;
}
<file_sep>#ifndef KSFEFV_H
#define KSFEFV_H

#include <Eigen/Dense>


std::pair<Eigen::MatrixXd, Eigen::MatrixXd>
KScalFEFV(const std::string fileName,
	  const std::string ppType,
	  const int ppId,
	  const int L = 22 ,
	  const int MaxN = 80000,
	  const double tol = 1e-15,
	  const int nqr = 1,
	  const int trunc = 0);

Eigen::MatrixXd
KScalFE(const std::string fileName,
	const std::string ppType,
	const int ppId,
	const int L = 22,
	const int MaxN = 80000,
	const double tol = 1e-15,
	const int nqr = 1);

Eigen::MatrixXd
KSgetR(const std::string fileName,
       const std::string ppType,
       const int ppId,
       const int L /* = 22 */,
       const int MaxN /* = 80000 */,
       const double tol /* = 1e-15 */,
       const int nqr /* = 1 */);

void 
KScalWriteFE(const std::string inputfileName,
	     const std::string outputfileName,
	     const std::string ppType,
	     const int ppId,
	     const int L = 22,
	     const int MaxN = 80000,
	     const double tol = 1e-15,
	     const int nqr = 1);
void
KScalWriteFEInit(const std::string inputfileName,
		 const std::string outputfileName,
		 const std::string ppType,
		 const int ppId,
		 const int L = 22,
		 const int MaxN = 80000,
		 const double tol = 1e-15,
		 const int nqr = 1);

void 
KScalWriteFEFV(const std::string inputfileName,
	       const std::string outputfileName,
	       const std::string ppType,
	       const int ppId,
	       const int L = 22,
	       const int MaxN = 80000,
	       const double tol = 1e-15,
	       const int nqr = 1,
	       const int trunc = 0);

void 
KScalWriteFEFVInit(const std::string inputfileName,
		   const std::string outputfileName,
		   const std::string ppType,
		   const int ppId,
		   const int L = 22,
		   const int MaxN = 80000,
		   const double tol = 1e-15,
		   const int nqr = 1,
		   const int trunc = 0);


////////////////////////////////////////////////////////////////////////////////

std::pair<Eigen::MatrixXd, Eigen::MatrixXd>
KScalLeftFEFV(const std::string fileName, const std::string ppType, const int ppId,
	      const int L, const int MaxN, const double tol,
	      const int nqr, const int trunc);

void 
KScalWriteLeftFEFV(const std::string inputfileName,
		   const std::string outputfileName,
		   const std::string ppType,
		   const int ppId,
		   const int L,
		   const int MaxN ,
		   const double tol ,
		   const int nqr ,
		   const int trunc );

#endif	/* KSFEFV_H */

<file_sep>/* h5c++ test_CQCGL1dEIDc.cc -std=c++11 -lCQCGL1d -lmyfft -lmyH5 -ldenseRoutines -literMethod -lfftw3 -I $RESH/include/ -L $RESH/lib/ -I $XDAPPS/eigen/include/eigen3 -DEIGEN_FFTW_DEFAULT -O3 -o cgl1d.out && time ./cgl1d.out 
 */
#include <iostream>
#include <ctime>
#include "CQCGL1dEIDc.hpp"
#include "myH5.hpp"
// #include "CQCGL1d.hpp"
#include "denseRoutines.hpp"

#define cee(x) cout << (x) << endl << endl;
#define N5

using namespace MyH5;
using namespace std;
using namespace Eigen;
using namespace denseRoutines;

int main(){

    std::vector<std::string> scheme = {"IFRK43", "IFRK54",
				       "Cox_Matthews", "Krogstad", "Hochbruck_Ostermann", 
				       "Luan_Ostermann", "SSPP43"};
#ifdef N5
    //====================================================================================================
    // test the integrator
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);

#endif
#ifdef N10
    //====================================================================================================
    // test the performance of the EID compared with previous implementation.
    // The initial condition is the travelling wave, or a suppoposition of
    // two Gaussian waves. This asymmetric initial condition will result
    // asymmetric explosions.
    const int N = 1024; 
    const double d = 30;
    const double di = 0.06;
    CQCGL1dEIDc cgl(N, d, 4, 0.8, 0.01, di);
    CQCGL1d cgl2(N, d, 4, 0.8, 0.01, di, -1, 4);

    std::string file = "/usr/local/home/xiong/00git/research/data/cgl/reqDi.h5";
    std::string groupName = to_string(di) + "/1";
    VectorXd a0;
    double wth, wphi, err;
    std::tie(a0, wth, wphi, err) = CqcglReadReq(file, groupName);

    if (true) {
	VectorXcd A0 = Gaussian(N, N/2, N/10, 3) + Gaussian(N, N/4, N/10, 0.5);
	a0 = cgl2.Config2Fourier(A0);
    }
    
    double T = 4;

    time_t t = clock();
    ArrayXXd aa = cgl.intgC(a0, 0.001, T, 10);
    t = clock()-t;
    cout << static_cast<double>(t) / CLOCKS_PER_SEC << endl;

    t = clock();
    ArrayXXd aa2 = cgl2.intg(a0, 0.001, static_cast<int>(T/0.001), 10);
    t = clock()-t;
    cout << static_cast<double>(t) / CLOCKS_PER_SEC << endl;

    cout << aa.cols() << ' ' << aa2.cols() << ' '	 
	 << (aa-aa2.rightCols(aa.cols())).abs().maxCoeff() << ' '
	 << aa.abs().maxCoeff() << ' ' << cgl.lte.maxCoeff() << endl;

    savetxt("aa.dat", aa.transpose()); savetxt("aa2.dat", aa2.transpose()); 
    
    // Output:
    // 0.871511
    // 0.738813
    // 4000 4001 3197.97 3297.8 0.000316152
    
    // the performance are almost the same.

#endif
#ifdef N15
    //====================================================================================================
    // test a single method to see whether there is a bug
    // Also, save the state for orbits 
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 20;

    cgl.setScheme("Cox_Matthews");	
    ArrayXXd aa = cgl.intgC(a0, 0.002, T, 50);
    savetxt("aa.dat", aa.transpose());
    
    aa = cgl.intgC(a0, 0.002, T, 5);
    savetxt("a0NoAdapt.dat", aa.row(0).transpose());
    
    // save for time adaption integrated orbit
    if(true){
	cgl.eidc.rtol = 1e-10;

	cgl.setScheme("Cox_Matthews");
	ArrayXXd aaAdapt = cgl.intg(a0, T/(1<<15), T, 400);
	savetxt("aaAdapt_Cox_Matthews.dat", aaAdapt.transpose());
	savetxt("TsAdapt_Cox_Matthews.dat", cgl.Ts);

	cgl.setScheme("SSPP43");
	aaAdapt = cgl.intg(a0, T/(1<<15), T, 400);
	savetxt("aaAdapt_SSPP43.dat", aaAdapt.transpose());
	savetxt("TsAdapt_SSPP43.dat", cgl.Ts);
    }

    // save for time adaption orbit in comoving frame
    if(true){
	cgl.eidc.rtol = 1e-10;
	cgl.setScheme("Cox_Matthews");
	cgl.changeOmega(-17.667504892760448);
	ArrayXXd aaCom = cgl.intg(a0, T/(1<<15), T, 200);
	savetxt("aaCom.dat", aaCom.transpose());
	savetxt("TsCom.dat", cgl.Ts);

	aaCom = cgl.intgC(a0, 0.002, T, 5);
	savetxt("a0ComNoAdapt.dat", aaCom.row(0).transpose());
    }
#endif
#ifdef N20
    //====================================================================================================
    // Test the accuracy of constant stepping shemes.
    // Choose Luan-Ostermann method with a small time step as the base
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 20;

    double h0 = T / (1<<18);	// T / 2^18
    
    cgl.setScheme("Luan_Ostermann");
    ArrayXd x0 = cgl.intgC(a0, h0, T, 1000000).rightCols(1);

    int n = 8;

    MatrixXd erros(n, scheme.size()+1);
    for(int i = 0; i < scheme.size(); i++) {
	cgl.setScheme(scheme[i]);	
	for(int j = 0, k=2; j < n; j++, k*=2){
	    double h = k*h0;
	    if(i == 0) {
		erros(j, 0) = h; 
	    }
	    ArrayXXd aa = cgl.intgC(a0, h, T, 1000000);
	    double err = (aa.rightCols(1) - x0).abs().maxCoeff() / x0.abs().maxCoeff();
	    erros(j, i+1) = err; 
	    cout << err << ' ';
	}
	cout << endl;
    }
    savetxt("cqcgl1d_N20_err.dat", erros);
#endif
#ifdef N30
    //====================================================================================================
    // fix the time step. try to look at the estimated local error of all shemes
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;
    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 20;
    int n0 = 15, n1 = 6;
    double h0 = T / (1<<n0);	
    double w[] = {0, -17.667504892760448};

    MatrixXd ltes(1<<(n0-n1), 2*scheme.size());
    for(int k = 0; k < 2; k++){
	cgl.changeOmega(w[k]);
	for(int i = 0; i < scheme.size(); i++) {
	    cgl.setScheme(scheme[i]);	
	    ArrayXXd aa = cgl.intgC(a0, h0, T, 1<<n1);
	    ltes.col(k*scheme.size() + i) = cgl.lte;
	}
    }
    savetxt("cqcgl1d_N30_lte.dat", ltes);
#endif
#ifdef N40
    //====================================================================================================
    // compare static frame integration and comoving frame integration for a single method
    // by using different rtol so make the global error close
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    cgl.setScheme("Cox_Matthews");
    MatrixXd hs;
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double w[] = {0, -17.667504892760448};

    for(int i = 0; i < 2; i++){
	cgl.changeOmega(w[i]);
	cgl.eidc.rtol = i == 0 ? 1e-10 : 1e-11;
	ArrayXXd aa = cgl.intg(a0, T/(1<<12), T, 100);
	MatrixXd tmp(cgl.hs.size(), 2);
	tmp << cgl.Ts, cgl.hs;
	savetxt("cqcgl1d_N40_" + to_string(i) + ".dat", tmp);
	savetxt("aa_" + to_string(i) + ".dat", aa.transpose());
    }

#endif
#ifdef N50
    //====================================================================================================
    // static frame integration
    // set the rtol = 1e-10 and output time steps
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    cgl.eidc.rtol = 1e-10;

    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double h0 = T / (1<<12);	// T / 2^12
    
    for(int i = 0; i < scheme.size(); i++) {
	cgl.setScheme(scheme[i]);
	ArrayXXd aa = cgl.intg(a0, h0, T, 1<<5);
	savetxt("cqcgl1d_N50_hs_"+to_string(i)+".dat", cgl.hs);
    }
    
#endif
#ifdef N60
    //====================================================================================================
    // Comoving frame integration
    // set the rtol = 1e-10 and output time steps
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    cgl.eidc.rtol = 1e-10;
    cgl.changeOmega(-17.667504892760448);

    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double h0 = T / (1<<12);	// T / 2^12
    
    for(int i = 0; i < scheme.size(); i++) {
	cgl.setScheme(scheme[i]);
	ArrayXXd aa = cgl.intg(a0, h0, T, 1<<5);
	savetxt("cqcgl1d_N60_comoving_hs_"+to_string(i)+".dat", cgl.hs);
    }
#endif
#ifdef N65
    //====================================================================================================
    // comoving frame integration
    //       rtol vs global relative error for a single method
    //       
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    cgl.changeOmega(-17.667504892760448);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);

    VectorXcd A0 = Gaussian(N, N/2, N/20, 2.5) + Gaussian(N, N/3, N/20, 0.5);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 40;
    double h0 = T / (1 << 20);
    
    cgl.setScheme("Luan_Ostermann");
    ArrayXd x0 = cgl.intgC(a0, h0, T, 1000000).rightCols(1);

    int n = 10;
    time_t t;
    
    cgl.setScheme("Luan_Ostermann");
    VectorXd errors(n);
    for(int i = 0, k = 1; i < n; i++, k*=5){
	printf("i == %d\n", i);
	double rtol = k * 1e-15;
	cgl.eidc.rtol = rtol;
	ArrayXd lastState = cgl.intg(a0, T/(1<<12), T, 1000000).rightCols(1);
	double err = (lastState - x0).abs().maxCoeff() / x0.abs().maxCoeff();
	errors[i] = err;
    }
    cout << errors << endl;

#endif
#ifdef N70
    //====================================================================================================
    // static & comoving frame integration with time step adaption turned on.
    // choose different rtol to obtain
    //      rtol vs global relative error
    //      rtol vs integration steps, N(x) evaluation times
    //      
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 20;
    double h0 = T / (1<<18);	// T / 2^20    
    double w[] = {0, -17.667504892760448};

    int n = 10;
    time_t t; 
	
    for(int p = 0; p < 2; p++){
	cgl.changeOmega(w[p]);
	cgl.setScheme("IFRK54");
	ArrayXd x0 = cgl.intgC(a0, h0, T, 1000000).rightCols(1);

	MatrixXd erros(n, 6*scheme.size()+1);
	for(int i = 0; i < scheme.size(); i++) {
	    cgl.setScheme(scheme[i]);	
	    for(int j = 0, k=1; j < n; j++, k*=5){
		double rtol = k*1e-13;
		cgl.eidc.rtol = rtol;
		if(i == 0) {
		    erros(j, 0) = rtol; 
		}
		ArrayXd xf = cgl.intg(a0, T/(1<<12), T, 1000000).rightCols(1);
		double err = (xf - x0).abs().maxCoeff() / x0.abs().maxCoeff();
		erros.row(j).segment(6*i+1, 6) << 
		    err,  
		    cgl.eidc.NCalCoe, 
		    cgl.eidc.NCallF,
		    cgl.eidc.NReject,
		    cgl.eidc.TotalTime,
		    cgl.eidc.CoefficientTime;
		cout << err << ' ';
	    }
	    cout << endl;
	}
	savetxt("cqcgl1d_N70_stat" + to_string(p) + ".dat", erros);
    }
#endif
#ifdef N75
    //====================================================================================================
    // figure out why the Luan_Ostermann method produces large Nab
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    cgl.changeOmega(-17.667504892760448);
    CQCGL1d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1);
    
    VectorXcd A0 = Gaussian(N, N/2, N/30, 2.5) + Gaussian(N, 2*N/5, N/30, 0.2);
    VectorXd a0 = cgl2.Config2Fourier(A0);    
    double T = 20;
    double h0 = T / (1<<18);	// T / 2^20    
    
    int n = 10;
    time_t t; 

    cgl.setScheme("Luan_Ostermann");
    ArrayXd x0 = cgl.intgC(a0, h0, T, 1000000).rightCols(1);

    //cgl.setScheme("Hochbruck_Ostermann");
    //cgl.setScheme("IFRK54");
    for(int j = 0, k=1; j < n; j++, k*=5){
	double rtol = k*1e-13;
	cgl.eidc.rtol = rtol;
	t = clock();
	ArrayXd xf = cgl.intg(a0, T/(1<<12), T, 1000000).rightCols(1);
	t = clock() - t;
	double err = (xf - x0).abs().maxCoeff() / x0.abs().maxCoeff();
	cout << err << '\t'
	     << static_cast<double>(t) / CLOCKS_PER_SEC << '\t'
	     << cgl.eidc.NCallF << '\t'
	     << cgl.eidc.NCalCoe << '\t'
	     << cgl.eidc.NSteps << '\t'
	     << cgl.eidc.NReject << endl;
    }
#endif
#ifdef N80
    //====================================================================================================
    // test the accuracy of calculating coefficient
    // there is no problem with coefficients
    const int N = 1024; 
    const double d = 30;
    const double di = 0.06;
    CQCGL1dEIDc cgl(N, d, 4, 0.8, 0.01, di);
    cgl.changeOmega(-176.67504941219335);
    
    int n = 3;
    ArrayXXcd c(N, n);
    for (int i = 0; i < n; i++){
	cgl.eidc.M = 64 * (1<<i);
	cout << cgl.eidc.M << endl;
	cgl.eidc.calCoe(1e-3);
	c.col(i) = cgl.eidc.b[3];
	
    }
    
    MatrixXd err(n, n);
    for( int i = 0; i < n; i++) {
	for (int j = 0; j < n; j++){
	    err(i, j) = (c.col(i) - c.col(j)).abs().maxCoeff();
	}
    }
    
    cout << err << endl;

#endif
#ifdef N90
    //====================================================================================================
    // test the norm of b for estimating the local error
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL1dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    
    int bindex[] = {3, 3, 4, 7};

    ArrayXXcd bs1(N, 4);
    for (int i = 0; i < 4; i++){
	cgl.setScheme(scheme[i]);
	cgl.eidc.calCoe(1e-3);
	bs1.col(i) = cgl.eidc.b[bindex[i]];
    }
    savetxt("l1r.dat", cgl.L.real()); 
    savetxt("l1c.dat", cgl.L.imag());
    
    cgl.changeOmega(-17.667504892760448);
    
    ArrayXXcd bs2(N, 4);
    for (int i = 0; i < 4; i++){
	cgl.setScheme(scheme[i]);
	cgl.eidc.calCoe(1e-3);
	bs2.col(i) = cgl.eidc.b[bindex[i]];
    }
    savetxt("l2r.dat", cgl.L.real());
    savetxt("l2c.dat", cgl.L.imag());

    for(int i = 0; i < 4; i++) 
	cout << bs1.col(i).matrix().norm() << '\t';
    cout << endl;
    for(int i = 0; i < 4; i++)
	cout << bs2.col(i).matrix().norm() << '\t';
    cout << endl;

    savetxt("bs1r.dat", bs1.real()); 
    savetxt("bs1c.dat", bs1.imag());
    savetxt("bs2r.dat", bs2.real()); 
    savetxt("bs2c.dat", bs2.imag());

#endif
    
    return 0;
}
<file_sep>#ifndef CQCGL2DEIDC_H
#define CQCGL2DEIDC_H

#include "EIDc.hpp"
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>
#include "myH5.hpp"

using namespace MyH5;

///  integrator for 2d CQCGL
///
///  The domain layout is
///  
///           dx
///      *************
///      *           *
///   dy *           *  M
///      *           *
///      *           * 
///      *************
///            N
///
///    
///      
class CQCGL2dEIDc {
    
public :

    typedef std::complex<double> dcp;
    
    const int N, M;		/* dimension of FFT */
    const double dx, dy;	/* system domain size */
    int Ne, Me;
    int Nplus, Nminus, Nalias;
    int Mplus, Mminus, Malias;
    
    double Br, Bi, Gr, Gi, Dr, Di, Mu;
    double Omega = 0;
    ArrayXd Kx, QKx, Ky, QKy;
    ArrayXXcd L;
    ArrayXcd Lv;
	
    FFT<double> fft;

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 50;
    int IntPrint = 0;		// print frequency during integration. 
    
    struct NL {
	CQCGL2dEIDc *cgl;
	dcp B, G;
	MatrixXcd A;
	
	NL(CQCGL2dEIDc *cgl) : cgl(cgl), B(cgl->Br, cgl->Bi), G(cgl->Gr, cgl->Gi) {
	    A.resize(cgl->M, cgl->N);
	}
	~NL(){}	
	
	void operator()(ArrayXcd &x, ArrayXcd &dxdt, double t){
	    Map<MatrixXcd> xv(x.data(), cgl->M, cgl->N);
	    Map<MatrixXcd> dxdtv(dxdt.data(), cgl->M, cgl->N);
	    cgl->fft.inv2(A.data(), x.data(), cgl->N, cgl->M);
	    ArrayXXcd A2 = A.array() * A.array().conjugate();
	    A = B * A.array() * A2 + G * A.array() * A2.square();
	    cgl->fft.fwd2(dxdt.data(), A.data(), cgl->N, cgl->M);
	    dxdtv.middleRows(cgl->Mplus, cgl->Malias).setZero(); /* dealias */
	    dxdtv.middleCols(cgl->Nplus, cgl->Nalias).setZero(); /* dealias */
	}
    };
    
    NL nl;

    ArrayXcd Yv[10], Nv[10];
    EIDc eidc;

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    CQCGL2dEIDc(int N, int M, double dx, double dy,
		double Mu, double Dr, double Di,
		double Br, double Bi, double Gr,
		double Gi) :
	N(N), M(M), dx(dx), dy(dy), Mu(Mu), Dr(Dr), Di(Di), Br(Br), Bi(Bi), Gr(Gr), Gi(Gi),
	nl(this)
    {
	Ne = (N/3) * 2 - 1;
	Nplus = (Ne + 1) / 2;
	Nminus = (Ne - 1) / 2;
	Nalias = N - Ne;

	Me = (M/3) * 2 - 1;
	Mplus = (Me + 1) / 2;
	Mminus = (Me - 1) / 2;
	Malias = M - Me;

	// calculate the Linear part
	Kx.resize(N,1);
	Kx << ArrayXd::LinSpaced(N/2, 0, N/2-1), N/2, ArrayXd::LinSpaced(N/2-1, -N/2+1, -1);
	Ky.resize(M,1);
	Ky << ArrayXd::LinSpaced(M/2, 0, M/2-1), 0, ArrayXd::LinSpaced(M/2-1, -M/2+1, -1);        

	QKx = 2*M_PI/dx * Kx;  
	QKy = 2*M_PI/dy * Ky;
    
	L = dcp(Mu, -Omega) - dcp(Dr, Di) * (QKx.square().replicate(1, M).transpose() + 
					     QKy.square().replicate(1, N)); 
	L.middleRows(Mplus, Malias).setZero();
	L.middleCols(Nplus, Nalias).setZero();
	Lv = Map<VectorXcd>(L.data(), M*N);
	
	int nYN0 = eidc.names.at(eidc.scheme).nYN;
	for(int i = 0; i < nYN0; i++){
	    Yv[i].resize(M*N);
	    Nv[i].resize(M*N);
	}
	eidc.init(&Lv, Yv, Nv);
	eidc.CN = 8*M;
    }
    
    CQCGL2dEIDc(int N, double dx,
		double Mu, double Dr, double Di,
		double Br, double Bi, double Gr,
		double Gi) 
	: CQCGL2dEIDc(N, N, dx, dx, Mu, Dr, Di, Br, Bi, Gr, Gi) 
    { }
	

    CQCGL2dEIDc(int N, int M, double dx, double dy,
		double b, double c, double dr, double di)
	: CQCGL2dEIDc(N, M, dx, dy, -1, 1, b, 1, c, -dr, -di)
    { }

    CQCGL2dEIDc(int N, double d,
		double b, double c, double dr, double di)
	: CQCGL2dEIDc(N, N, d, d, b, c, dr, di)
    { }

    ~CQCGL2dEIDc(){}


    ////////////////////////////////////////////////////////////////////////////////////////////////////
    inline void 
    setScheme(std::string x){
	int nYN0 = eidc.names.at(eidc.scheme).nYN;
	eidc.scheme = x;
	int nYN1 = eidc.names.at(eidc.scheme).nYN;
	for (int i = nYN0; i < nYN1; i++) {
	    Yv[i].resize(M*N);
	    Nv[i].resize(M*N);
	}
    }

    inline void 
    changeOmega(double w){
	Omega = w;
	L = dcp(Mu, -Omega) - dcp(Dr, Di) * (QKx.square().replicate(1, M).transpose() + 
					     QKy.square().replicate(1, N)); 
	L.middleRows(Mplus, Malias) = ArrayXXcd::Zero(Malias, N); 
	L.middleCols(Nplus, Nalias) = ArrayXXcd::Zero(M, Nalias);
	Lv = Map<VectorXcd>(L.data(), M*N);
    }

    inline 
    ArrayXXcd
    intgC(const ArrayXXcd &a0, const double h, const double tend, const int skip_rate,
	  const int saveFlag, const string fileName){
	
	const int Nt = (int)round(tend/h);
	const int m = (Nt + skip_rate - 1) / skip_rate;
	lte.resize(m);

	ArrayXXcd aa;
	H5File file;
	if (0 == saveFlag) file = H5File(fileName, H5F_ACC_TRUNC); /* openFile fails */
	else if (1 == saveFlag) aa.resize(Me, Ne*m);
	
	ArrayXXcd tu0 = pad(a0); 
	ArrayXcd u0 = Map<ArrayXcd>(tu0.data(), M*N);

	int ks = 0;
	auto ss = [this, &ks, &aa, &file, &saveFlag, &tend](ArrayXcd &x, double t, double h, double err){
	    if( IntPrint > 0 && ks % IntPrint == 0) fprintf(stderr, "%f/%f\n", t, tend);

	    Map<ArrayXXcd> xv(x.data(), M, N);
	    ArrayXXcd uxv = unpad(xv);

	    lte(ks) = err;

	    if(0 == saveFlag){
		char groupName[10];
		sprintf (groupName, "%.6d", ks);
		std::string s = "/" + std::string(groupName);
		Group group(file.createGroup(s));
		std:: string DS = s + "/";
		
		writeMatrixXd(file, DS + "ar", uxv.real());
		writeMatrixXd(file, DS + "ai", uxv.imag());
	    }
	    else if (1 == saveFlag){
		aa.middleCols((ks)*Ne, Ne) = uxv;
	    }
	    else {
		// only try to get integeration information
	    }
	    	    
	    ks++;
	};
	
        eidc.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
	
	return aa;
    }

    inline 
    ArrayXXcd
    intg(const ArrayXXcd &a0, const double h, const double tend, const int skip_rate,
	 const int saveFlag, const string fileName){
	
	const int Nt = (int)round(tend/h);
	const int m = (Nt+skip_rate-1)/skip_rate;
	Ts.resize(m);
	hs.resize(m);
	lte.resize(m);

	ArrayXXcd aa;
	H5File file;
	if (0 == saveFlag) file = H5File(fileName, H5F_ACC_TRUNC); /* openFile fails */
	else if (1 == saveFlag) aa.resize(Me, Ne*m);
	
	ArrayXXcd tu0 = pad(a0); 
	ArrayXcd u0 = Map<ArrayXcd>(tu0.data(), M*N);
	
	int ks = 0;
	auto ss = [this, &ks, &aa, &file, &saveFlag, &tend](ArrayXcd &x, double t, double h, double err){

	    if( IntPrint > 0 && ks % IntPrint == 0 ) fprintf(stderr, "%f/%f\n", t, tend);

	    Map<ArrayXXcd> xv(x.data(), M, N);
	    ArrayXXcd uxv = unpad(xv);

	    int m = Ts.size();
	    if(ks >= m){
		Ts.conservativeResize(m+cellSize);
		hs.conservativeResize(m+cellSize);
		lte.conservativeResize(m+cellSize);
	    }
	    hs(ks) = h;
	    lte(ks) = err;
	    Ts(ks) = t;

	    if(0 == saveFlag){
		char groupName[10];
		sprintf (groupName, "%.6d", ks);
		std::string s = "/" + std::string(groupName);
		Group group(file.createGroup(s));
		std:: string DS = s + "/";
		
		writeMatrixXd(file, DS + "ar", uxv.real());
		writeMatrixXd(file, DS + "ai", uxv.imag());
	    }
	    else if (1 == saveFlag){
		if(ks >= m) aa.conservativeResize(Eigen::NoChange, m+cellSize*Ne);
		aa.middleCols(ks*Ne, Ne) = uxv;
	    }
	    else {
		// only try to get integeration information	
	    }

	    ks++;
	};
	
	eidc.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
	hs.conservativeResize(ks);
	lte.conservativeResize(ks);
	Ts.conservativeResize(ks);
	if(1 == saveFlag) aa.conservativeResize(Eigen::NoChange, ks);

	return aa;
    }

    ArrayXXcd unpad(const ArrayXXcd &v){
	int m = v.rows();
	int n = v.cols();
	assert(m == M && n % N == 0);
	int s = n / N;
    
	ArrayXXcd vt(Me, Ne*s);
	for (int i = 0; i < s; i++){
	
	    vt.middleCols(i*Ne, Ne) <<
	    
		v.block(0, i*N, Mplus, Nplus), 
		v.block(0, i*N+Nplus+Nalias, Mplus, Nminus),

		v.block(Mplus+Malias, i*N, Mminus, Nplus),
		v.block(Mplus+Malias, i*N+Nplus+Nalias, Mminus, Nminus)
		;
	}
    
	return vt;
    }

    ArrayXXcd pad(const ArrayXXcd &v){
	int m = v.rows();
	int n = v.cols();
	assert( n % Ne == 0 && m == Me);
	int s = n / Ne;
    
	ArrayXXcd vp(M, N*s);
	for (int i = 0; i < s; i++){
	
	    vp.middleCols(i*N, N) << 
	    
		v.block(0, i*Ne, Mplus, Nplus), 
		ArrayXXcd::Zero(Mplus, Nalias), 
		v.block(0, i*Ne+Nplus, Mplus, Nminus),
	    
		ArrayXXcd::Zero(Malias, N),
	    
		v.block(Mplus, i*Ne, Mminus, Nplus), 
		ArrayXXcd::Zero(Mminus, Nalias), 
		v.block(Mplus, i*Ne+Nplus, Mminus, Nminus)
		;
	}
    
	return vp;
    }

};

#endif	/* CQCGL2DEIDC_H */
<file_sep>import numpy as np
from numpy.linalg import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d

class Arrow3D(FancyArrowPatch):
    """
    The 3d arrow class
    """
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs)
        self._verts3d = xs, ys, zs

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
        FancyArrowPatch.draw(self, renderer)

    def setvalue(self, x, y, z):
        self._verts3d = x, y, z
##################################################

data = np.load('data.npz')

aaTilde1 = data['aaTilde1']
veTilde1 = data['veTilde1']
aaTilde2 = data['aaTilde2']
veTilde2 = data['veTilde2']
ee = data['ee']

i1 = 0
i2 = 1
i3 = 2

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.plot(aaTilde1[:, i1], aaTilde1[:, i2], aaTilde1[:, i3], 'r')
ax.plot(aaTilde2[:, i1], aaTilde2[:, i2], aaTilde2[:, i3], 'g')

spa = 60

ratio1 = 5
ah1 = aaTilde1
veIndex1 = 0
nor1 = norm(veTilde1[veIndex1::30], axis=1)
nor1.resize((nor1.size, 1))
ae1r = ah1 + veTilde1[veIndex1::30] / nor1 / ratio1
veIndex1 = 1
nor1 = norm(veTilde1[veIndex1::30], axis=1)
nor1.resize((nor1.size, 1))
ae1i = ah1 + veTilde1[veIndex1::30] / nor1 / ratio1

ratio2 = 5
ah2 = aaTilde2
veIndex2 = 0
nor2 = norm(veTilde2[veIndex2::30], axis=1)
nor2.resize((nor2.size, 1))
ae2r = ah2 + veTilde2[veIndex2::30] / nor2 / ratio2
veIndex2 = 1
nor2 = norm(veTilde2[veIndex2::30], axis=1)
nor2.resize((nor2.size, 1))
ae2i = ah2 + veTilde2[veIndex2::30] / nor2 / ratio2

for i in np.arange(0, aaTilde1.shape[0], spa):
    a1 = Arrow3D([ah1[i, i1], ae1r[i, i1]], [ah1[i, i2], ae1r[i, i2]],
                 [ah1[i, i3], ae1r[i, i3]],
                 mutation_scale=20, lw=1.0, arrowstyle="-|>", color="m")
    ax.add_artist(a1)
    a1 = Arrow3D([ah1[i, i1], ae1i[i, i1]], [ah1[i, i2], ae1i[i, i2]],
                 [ah1[i, i3], ae1i[i, i3]],
                 mutation_scale=20, lw=1.0, arrowstyle="-|>", color="b")
    ax.add_artist(a1)

for i in np.arange(0, aaTilde2.shape[0], spa):
    a2 = Arrow3D([ah2[i, i1], ae2r[i, i1]], [ah2[i, i2], ae2r[i, i2]],
                 [ah2[i, i3], ae2r[i, i3]],
                 mutation_scale=20, lw=1.0, arrowstyle="-|>", color="k")
    ax.add_artist(a2)
    a2 = Arrow3D([ah2[i, i1], ae2i[i, i1]], [ah2[i, i2], ae2i[i, i2]],
                 [ah2[i, i3], ae2i[i, i3]],
                 mutation_scale=20, lw=1.0, arrowstyle="-|>", color="c")
    ax.add_artist(a2)

ax.set_xlabel(r'$e_1$', fontsize=25)
ax.set_ylabel(r'$e_2$', fontsize=25)
ax.set_zlabel(r'$e_3$', fontsize=25)
plt.tight_layout(pad=0)
plt.show(block=False)
<file_sep>/* to comiple:
 * g++ -O3 test_lorenz.cc  -L../../lib -I../../include -I $XDAPPS/eigen/include/eigen3 -std=c++11 -llorenz -ldenseRoutines -lm && ./a.out
 */
#include "lorenz.hpp"
#include <iostream>
#include <fstream>

using namespace std;
using namespace Eigen;
using namespace denseRoutines;

typedef std::complex<double> dcp;

int main(){

    switch(1){
	
    case 1: {			/* test integrator */
	
	Vector3d x0(VectorXd::Random(3));
	Lorenz loz = Lorenz();
	// auto tmp = loz.intgj(x0, 0.01, 1000, 1, 1);
	// savetxt("xx.dat", tmp.first);
	loz.Rho = 487.115277;
	loz.B = 0.25;
	MatrixXd xx = loz.equilibriaIntg(1, 0, 1e-3, 0.001, 8000, 1);
	savetxt("xx.dat", xx);

	cout << loz.equilibria() << endl;
	break;
    }
		

    default: {
	fprintf(stderr, "please indicate a valid case number \n");
	
	}
    }

    return 0;
}
<file_sep>from py_CQCGL2d import *
from personalFunctions import *

case = 10

if case == 10:
    """
    test the plot function
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6

    cgl = pyCQCGL2d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4)
    Ns = 10000
    skip = 20
    cgl.constETDPrint = 200
    fileName = 'ex.h5'

    A0 = 3*centerRand2d(N, N, 0.2, 0.2, True)
    a0 = cgl.Config2Fourier(A0)
    aa = cgl.intg(a0, 0.005, Ns, skip, True, fileName)
    c2dp = CQCGL2dPlot(d, d)
    # c2dp.oneState(cgl, fileName, 100)
    c2dp.savePlots(cgl, fileName, range(Ns/skip+1), 'fig3',
                   plotType=2, size=[12, 6])

<file_sep>###################################################
# This file contains all the related functions to
# investigate the escape rate in Logistic map using
# cycle expansion.
# please complete the experimental part
###################################################
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import fsolve
import sympy as sp
from personalFunctions import *

class Logistic:
    def __init__(self, A):
        self.A = A

    def oneIter(self, x):
        return self.A * (1.0 - x) * x

    def multiIters(self, x, n):
        y = np.zeros(n+1)
        y[0] = x
        tmpx = x
        for i in range(n):
            tmpx = self.oneIter(tmpx)
            y[i+1]=tmpx
            
        return y

    def df(self, x):
        return self.A*(1-2*x)
    
    def dfn(self, x):
        n = np.size(x)
        multiplier = 1.0
        for i in range(n):
            multiplier *= self.df(x[i])

        return multiplier

    def plotIni(self):
        fig = plt.figure(figsize=[8, 8])
        ax = fig.add_subplot(111)
        ax.set_xlabel(r'$x_n$', fontsize=30)
        ax.set_ylabel(r'$x_{n+1}$', fontsize=30)
        ax.set_xlim([0, 1])
        ax.set_ylim([0, 1])
        plt.gca().set_aspect('equal', adjustable='box')
        ax.tick_params(axis='both', which='major', labelsize=20)
        
        x = np.linspace(0, 1, 200)
        y = self.oneIter(x)
        ax.plot(x, y, lw=2, c='b')
        ax.plot(x, x, lw=2, c='k', ls='--')
        
        return fig, ax
        

    def plotEnd(self, fig, ax):
        ax2d(fig, ax)

    def plotIter(self, ax, x0, n):
        x, y = x0, self.oneIter(x0)
        for i in range(n):
            print i
            newy = self.oneIter(y)
            ax.scatter(x, y, c='g', edgecolors='none', s=100)
            ax.plot([x, y], [y, y], lw=1.5, c='r')
            ax.plot([y, y], [y, newy], lw=1.5, c='r')
            x, y = y, newy

if __name__ == '__main__':
    """
    experiment
    """
    case = 10

    if case == 10:
        A = 5.0
        order = 4
        lm = Logistic(A)
        f = lambda x : lm.multiIters(x, order)[-1] - x
        x = fsolve(f, 0.2)
        xn = lm.multiIters(x, order-1)
        mp = lm.dfn(xn)
        np.set_printoptions(precision=16)
        print lm.multiIters(x, order), mp

    if case == 20:
        # Floquet multipliers for the periodic orbits up to length 4
        # { {0, 1}, {01}, {001, 011}, {0001, 0011, 0111} }
        mp = [[-4., 6.0], 
              [-20.0],    
              [-114.954535015, 82.9545350148],
              [ -684.424135353, 485.09371391, -328.669578465]
              ]
        lm = Logistic(6.0)
        z = sp.Symbol('z')
        zeta = 1 
        order = 4 # cycle expansion order
        for i in range(order):
            for j in range(np.size(mp[i])):
                zeta = zeta * (1 - z**(i+1)/np.abs(mp[i][j]))
                zeta = ( zeta.expand() + sp.O(z**(order+1)) ).removeO() # remove higher orders
        print "zeta function at order: ", order
        print zeta
        
        # for efficicy, we choose to use np.roots() instead sp.solve() to find the zero points
        coe = sp.Poly(zeta, z).coeffs() # get the coefficients => a_n, a_{n-1}, ..., a_0
        zps = np.roots(coe) # find the zeros points of zeta function
        leig = np.max(1.0 / zps),  # get the leading eigenvalues
        print leig, np.log(leig)

    if case == 30:
        # Floquet multipliers for the periodic orbits up to length 4
        # { 0, 1, 01, 001, 011, 0001, 0011, 0111 }
        
        # multipliers for A = 6.0
        mp = [[-4., 6.0],
              [-20.0],
              [-114.954535015, 82.9545350148],
              [ -684.424135353, 485.09371391, -328.669578465]
              ]
     
  
        lm = Logistic(6.0)
        z = sp.Symbol('z')
        trace = 0
        order = 4
        for i in range(order):
            for j in range(np.size(mp[i])):
                for r in range(order/(i+1)):
                    trace += (i+1) * z**((r+1)*(i+1))/(np.abs(mp[i][j]**(r+1)-1))
                
        
        C = sp.Poly(trace, z).coeffs() # obtain coefficients of trace: C_n, C_{n-1}, C_1
        C = C[::-1] # reverse the order => C_1, C_2,... C_n
        Q = np.zeros(np.size(C))
        Q[0] = C[0]
        for i in range(order):
            Q[i] = C[i]
            for j in range(i):
                Q[i] -= (C[j]*Q[i-1-j])  
            Q[i] = Q[i] / np.double(i+1) 
        
        det = np.append(1.0, -Q) # obtain the coefficients of spectral determinant
        print det
        zps = np.roots(det[::-1]) # find the zeros points of zeta function
        leig = np.max(1.0 / zps),  # get the leading eigenvalues
        print leig, np.log(leig)


    if case == 35:
        """
        periodic orbits for A = 5.0
        """
        

    if case == 40:
        # Floquet multipliers for the periodic orbits up to length 5
        # { {0, 1}, {01}, {001, 011}, {0001, 0011, 0111},
        # {00001, 00011, 00101, 00111, 01011, 01111} }     
        # multipliers for A = 5.0   
        mp = [[-3.0, 5.0],
              [-11.0],
              [-49.4264068712, 35.4264068712],
              [ -240.961389769, 167.507590647, -103.546200878],
              [-1198.49148617, 827.861204429, 547.72002265, -481.824783312 ,-386.519433432, 313.254476004]
              ]
        lm = Logistic(5.0)
        z = sp.Symbol('z')
        trace = 0
        order = 3
        for i in range(order):
            for j in range(np.size(mp[i])):
                for r in range(order/(i+1)):
                    trace += (i+1) * z**((r+1)*(i+1))/(np.abs(mp[i][j]**(r+1)-1))
                
        
        C = sp.Poly(trace, z).coeffs() # obtain coefficients of trace: C_n, C_{n-1}, C_1
        C = C[::-1] # reverse the order => C_1, C_2,... C_n
        Q = np.zeros(np.size(C))
        Q[0] = C[0]
        for i in range(order):
            Q[i] = C[i]
            for j in range(i):
                Q[i] -= (C[j]*Q[i-1-j])  
            Q[i] = Q[i] / np.double(i+1) 
        
        det = np.append(1.0, -Q) # obtain the coefficients of spectral determinant
        print det
        zps = np.roots(det[::-1]) # find the zeros points of zeta function
        leig = np.max(1.0 / zps),  # get the leading eigenvalues
        print leig, np.log(leig)
<file_sep>#ifndef KSSYM_H
#define KSSYM_H

#include <eigen3/Eigen/Dense>
using Eigen::MatrixXd; 
using Eigen::Matrix2d; 

class Kssym {
  
public:
  const int px; 

  /** @brief SO2 reduction of a sequence of column vectors stored in aa.
   *
   *  @param[in] aa matrix storing the vectors
   *  @param[out] ang pointer to the theta array. If you do not need
   *                  angle information, then just pass NULL to angle
   *  @return the group transformed vectors 
   * */
  MatrixXd redSO2(const MatrixXd &aa, double *ang);
  
  /** @brief calculate g(th) * aa
   *
   *  @param[in] aa [n,m] matrix
   *  @param[in] th SO2 group angle
   *  @return rotated matrix
   */
  MatrixXd rotate(const MatrixXd &aa, const double th);
  
  /* ------------   constructor/ destructor  ----------------- */
  Kssym(int p = 1): px(p) {}
  Kssym(const Kssym &k): px(k.px) {}
  Kssym & operator=(const Kssym &x ){ return *this; }
  ~Kssym(){}
};

#endif	/* KSSYM_H */
<file_sep>import numpy as np
import matplotlib.pyplot as plt
import h5py
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

N = 256;

f = h5py.File('/usr/local/home/xiong/svn/DOGS/blog/code/data/req.h5', 'r')
valr = f['/req1/valr']; n1= valr.shape[0]
vali = f['/req1/vali']
vr = np.zeros((n1,), np.double); 
vi = np.zeros((n1,), np.double);
valr.read_direct(vr); vali.read_direct(vi);
ve = vr+1j*vi

ia = ve

fig = plt.figure(figsize=(8,5));
ax = fig.add_subplot(111)
#ax.plot(range(1,2*N+1), ia.real, 'r.')
ax.scatter(range(1,2*N+1), ia.real, s=4, c = 'r', marker='o', edgecolor='none')
ax.locator_params(nbins=5)
ax.set_xlim((0,520))
ax.set_ylim((-35,1))
ax.grid('on')

ax2in=inset_axes(ax,width="45%",height="50%",loc=3)
ax2in.scatter(np.arange(1,11), ia[:10].real, c=(1,0,0), marker='o',
              s=22,edgecolors='none')
ax2in.set_xlim(0.5,10.5)
ax2in.set_ylim(-0.2,0.4)
ax2in.yaxis.set_ticks_position('right')
ax2in.xaxis.set_ticks_position('top')
ax2in.set_xticks((1,3,6,9))
#ax2in.set_yticks((-0.3,-0.2,-0.1,0,0.1))
ax2in.grid('on')

mark_inset(ax,ax2in,loc1=1,loc2=2,fc="none")


plt.tight_layout(pad=0)
plt.show()
f.close()
<file_sep>#ifndef CQCGL2dREQ_H		
#define CQCGL2dREQ_H

#include "CQCGL2d.hpp"

class CQCGL2dReq : public CQCGL2d {

public :
    
    double tol = 5e-8;
    double minRD = 0;
    int maxit = 10;
    int maxInnIt = 20;
    double GmresRtol = 1e-6;
    int GmresRestart = 100;
    int GmresMaxit = 4;
    int hookPrint = 1;

    ArrayXXcd Lu; 
    ArrayXXcd Tx;
    ArrayXXcd Ty;
    ArrayXXcd Tp;

    ////////////////////////////////////////////////////////////
    CQCGL2dReq(int N, int M, double dx, double dy,
	       double Mu, double Dr, double Di,
	       double Br, double Bi, double Gr,
	       double Gi,  
	       int threadNum);
    CQCGL2dReq(int N, double dx,
	       double Mu, double Dr, double Di,
	       double Br, double Bi, double Gr,
	       double Gi,  
	       int threadNum);
    CQCGL2dReq(int N, int M, double dx, double dy,
	       double b, double c, double dr, double di,
	       int threadNum);
    CQCGL2dReq(int N, double dx,
	       double b, double c, double dr, double di,
	       int threadNum);
    ~CQCGL2dReq();
    CQCGL2dReq & operator=(const CQCGL2dReq &x);

    ////////////////////////////////////////////////////////////
    
    void calPre();
    VectorXd Fx(const VectorXd &x);
    VectorXd DFx(const VectorXd &x, const VectorXd &dx);
    std::tuple<ArrayXXcd, double, double, double, double>
    findReq_hook(const ArrayXXcd &x0, const double wthx0, 
		 const double wthy0, const double wphi0);
    Eigen::Vector3d
    optReqTh(const ArrayXXcd &a0);
    
};

#endif	/* CQCGL2dREQ_H */
<file_sep># usage: make t=***
# or on pace cluster : make t=** pace=**

CC = g++
AR = ar

OPTIM = -O3 -msse2 -msse4 -march=corei7 
INCLUDE = ../../include
EIGEN = /usr/local/home/xiong/apps/eigen/include/eigen3
CFLAGS = -std=c++11 -DEIGEN_FFTW_DEFAULT
LIB = ../../lib

# for pace cluster 
ifdef pace
OPTIM = -O3
EIGEN = /nv/hp16/xding35/data/apps/eigen/include/eigen3
endif
####


ifndef t
t = int
endif

ifeq ($(t), int)		# for 1d integration
SOURCE = CQCGL1d.cc 

else ifeq ($(t), sub1d)		# sub1d integration
SOURCE = CQCGL1dSub.cc

else ifeq ($(t), req1d)		# for REQ code
SOURCE = CQCGL1dReq.cc

else ifeq ($(t), sub1dreq)	# sub1d req
SOURCE = CQCGL1dSubReq.cc

else ifeq ($(t), rpo1d)		# for RPO code
SOURCE = CQCGL1dRpo.cc 

else ifeq ($(t), rpo1dar)	# for 1d Rpo with arpack support
SOURCE = CQCGL1dRpo_arpack.cc
CFLAGS += -I$(XDAPPS)/arpackpp/include # -llapack -larpack -lsuperlu -lopenblas

else ifeq ($(t), int2d)		# for 2d CQCGL class
SOURCE = CQCGL2d.cc

else ifeq ($(t), req2d)
SOURCE = CQCGL2dReq.cc

else ifeq ($(t), ani)
SOURCE = CQCGL2dDislin.cc

else
SOURCE = CQCGL1d.cc 

endif

SHARED = $(addprefix lib, $(addsuffix .so, $(basename $(word 1, $(SOURCE)))))
STATIC = $(addprefix lib, $(addsuffix .a, $(basename $(word 1, $(SOURCE)))))


all : $(SHARED) # $(STATIC) 

$(SHARED): $(SOURCE)
	$(CC) -shared -fpic $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^ -o $@
$(SOURCE:.cc=.o) : $(SOURCE)
	$(CC) -c $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
$(STATIC): $(SOURCE:.cc=.o)
	$(AR) crs $@ $^

clean:
	rm -f *.so *.o *.a
move:
	mv *.so *.a $(LIB)
<file_sep>#ifndef CQCGL1DEIDC_H
#define CQCGL1DEIDC_H

#include "EIDc.hpp"
#include <Eigen/Dense>
#include <unsupported/Eigen/FFT>

class CQCGL1dEIDc {
    
public :

    typedef std::complex<double> dcp;
    
    const int N;		/* dimension of FFT */
    const double d;		/* system domain size */
    int Ne, Ndim, Nplus, Nminus, Nalias;
    
    double Br, Bi, Gr, Gi, Dr, Di, Mu;
    double Omega = 0;
    ArrayXd K, QK;
    ArrayXcd L;
	
    FFT<double> fft;		// support MatrixBase but not ArrayBase

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 500;
    
    struct NL {
	CQCGL1dEIDc *cgl;
	dcp B, G;
	VectorXcd A;
	
	NL(CQCGL1dEIDc *cgl) : cgl(cgl), B(cgl->Br, cgl->Bi), G(cgl->Gr, cgl->Gi) {
	    A.resize(cgl->N);
	}
	~NL(){}	

	void operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t){
	    Map<VectorXcd> xv(x.data(), x.size());
	    Map<VectorXcd> dxdtv(dxdt.data(), dxdt.size());
	    cgl->fft.inv(A, xv);
	    ArrayXcd A2 = A.array() * A.array().conjugate();
	    A = B * A.array() * A2 + G * A.array() * A2.square();
	    cgl->fft.fwd(dxdtv, A);
	    dxdtv.segment(cgl->Nplus, cgl->Nalias).setZero(); /* dealias */
	}
    };
    
    NL nl;

    ArrayXXcd Yv[10], Nv[10];
    EIDc eidc;

    ////////////////////////////////////////////////////////////////////////////////////////////////////
    CQCGL1dEIDc(int N, double d, double Mu, double Dr, double Di, 
		double Br, double Bi, double Gr, double Gi):
	N(N), d(d), Mu(Mu), Dr(Dr), Di(Di), Br(Br), Bi(Bi), Gr(Gr), Gi(Gi),
	nl(this)
    {
	Ne = (N/3) * 2 - 1;
	Ndim = 2 * Ne;
	Nplus = (Ne + 1) / 2;
	Nminus = (Ne - 1) / 2;
	Nalias = N - Ne;

	// calculate the Linear part
	K.resize(N,1);
	K << ArrayXd::LinSpaced(N/2, 0, N/2-1), N/2, ArrayXd::LinSpaced(N/2-1, -N/2+1, -1);       
	QK = 2*M_PI/d * K; 
	L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square(); 
	L.segment(Nplus, Nalias).setZero();
	
	int nYN0 = eidc.names.at(eidc.scheme).nYN; // do not call setScheme here. Different.
	for(int i = 0; i < nYN0; i++){
	    Yv[i].resize(N, 1);
	    Nv[i].resize(N, 1);
	}
	eidc.init(&L, Yv, Nv);
    }
    
    CQCGL1dEIDc(int N, double d,
		double b, double c,
		double dr, double di)
	: CQCGL1dEIDc(N, d, -1, 1, b, 1, c, -dr, -di)
    { }

   ~CQCGL1dEIDc(){}


    ////////////////////////////////////////////////////////////////////////////////////////////////////
    inline void 
    setScheme(std::string x){
	int nYN0 = eidc.names.at(eidc.scheme).nYN;
	eidc.scheme = x;
	int nYN1 = eidc.names.at(eidc.scheme).nYN;
	for (int i = nYN0; i < nYN1; i++) {
	    Yv[i].resize(N, 1);
	    Nv[i].resize(N, 1);
	}
    }

    inline void 
    changeOmega(double w){
	Omega = w;
	L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square();
	L.segment(Nplus, Nalias).setZero();
    }

    inline 
    ArrayXXd
    intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
	assert( Ndim == a0.size());
	
	ArrayXXcd u0 = R2C(a0); 
	const int Nt = (int)round(tend/h);
	const int M = (Nt + skip_rate - 1) / skip_rate;
	ArrayXXcd aa(N, M);
	lte.resize(M);
	int ks = 0;
	auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	    aa.col(ks) = x;
	    lte(ks++) = err;
	};
	
        eidc.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
	
	return C2R(aa);
    }

    inline 
    ArrayXXd
    intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
	assert( Ndim == a0.size());

	ArrayXXcd u0 = R2C(a0); 
	const int Nt = (int)round(tend/h);
	const int M = (Nt+skip_rate-1)/skip_rate;
	ArrayXXcd aa(N, M);
	Ts.resize(M);
	hs.resize(M);
	lte.resize(M);
	int ks = 0;
	auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	    int m = Ts.size();
	    if (ks >= m ) {
		Ts.conservativeResize(m+cellSize);
		aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
		hs.conservativeResize(m+cellSize);
		lte.conservativeResize(m+cellSize);
	    }
	    hs(ks) = h;
	    lte(ks) = err;
	    aa.col(ks) = x;
	    Ts(ks++) = t;
	};
	
	eidc.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
	hs.conservativeResize(ks);
	lte.conservativeResize(ks);
	Ts.conservativeResize(ks);
	aa.conservativeResize(Eigen::NoChange, ks);

	return C2R(aa);
    }

    /** @brief transform conjugate matrix to its real form */
    ArrayXXd C2R(const ArrayXXcd &v){
	int n = v.rows();
	int m = v.cols();
	assert(N == n);
	ArrayXXcd vt(Ne, m);
	vt << v.topRows(Nplus), v.bottomRows(Nminus);

	return Map<ArrayXXd>((double*)(vt.data()), 2*vt.rows(), vt.cols());
    }

    ArrayXXcd R2C(const ArrayXXd &v){
	int n = v.rows();
	int m = v.cols();
	assert( n == Ndim);
    
	Map<ArrayXXcd> vp((dcp*)&v(0,0), Ne, m);
	ArrayXXcd vpp(N, m);
	vpp << vp.topRows(Nplus), ArrayXXcd::Zero(Nalias, m), vp.bottomRows(Nminus);

	return vpp;
    }


};

#endif	/* CQCGL1DEIDC_H */
<file_sep>#ifndef EIDR_H
#define EIDR_H

#include "EID.hpp"

class EIDr : public EID<double> {

public :
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    // constructor and destructor
    
    EIDr(){}
    EIDr(ArrayXd *L, ArrayXXcd *Y, ArrayXXcd *N) : EID<double>(L, Y, N){}
    EIDr & operator=(const EIDr &x){
	return *this;
    }
    ~EIDr(){}
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////
    inline 
    ArrayXXcd 
    MUL(const ArrayXd &C, const ArrayXXcd &Y){ 
	return C.matrix().asDiagonal() * Y.matrix();
    }
    
    inline
    ArrayXd
    mean(const Ref<const ArrayXXcd> &x){ 
	return x.rowwise().mean().real();
    }

    /**
     * @brief calcuate the matrix to do averge of phi(z). 
     */
    inline
    ArrayXXcd 
    ZR(ArrayXd &z){
    	int M1 = z.size();
	ArrayXd K = ArrayXd::LinSpaced(M, 1, M); // 1,2,3,...,M 
	ArrayXXcd r = R * ((K-0.5)/M * dcp(0, M_PI)).exp().transpose();
	return z.template cast<std::complex<double>>().replicate(1, M) + r.replicate(M1, 1);
    }

}; 


#endif	/* EIDR_H */
<file_sep>import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
from mpl_toolkits.mplot3d import Axes3D
from personalFunctions import *
from py_ks import *


def statisAverage(dis, ang, cell):
    dis = np.floor(np.log10(dis)/cell)
    N = len(dis)
    minD = np.min(dis)
    maxD = np.max(dis)
    sumAng = np.zeros((maxD-minD+1, ang.shape[1]))
    sumNum = np.zeros(maxD - minD + 1)
    for i in range(N):
        ix = dis[i] - minD
        sumNum[ix] += 1
        sumAng[ix, :] += ang[i, :]

    # calcuate the mean value
    average = np.zeros([maxD-minD+1, ang.shape[1]])
    for i in range(len(sumNum)):
        if sumNum[i] != 0:
            average[i, :] = sumAng[i, :] / sumNum[i]

    # form x coordinate
    x = np.arange(minD, maxD+1) + 0.5

    return 10**(x*cell), average


def calSpacing(fileName, ppType, ppId, nqr):
    """
    calculate the spacing of points in a rpo/ppo
    """
    a, T, nstp, r, s = KSreadPO(fileName, ppType, ppId)
    h = T / nstp
    ks = pyKS(64, h, 22)
    aa = ks.intg(a, np.int(nstp), nqr)
    aa = aa[:-1, :]
    if ppType == 'ppo':
        aaWhole = ks.half2whole(aa)
    else:
        aaWhole = aa
    aaHat = ks.orbitToSlice(aaWhole)[0]
    M = aaHat.shape[0]
    dis = np.zeros(M)
    for i in range(M):
        dis[i] = np.linalg.norm(aaHat[(i+1) % M] - aaHat[i])
    return dis


def setAxis(ax, xl, xr, yl, yr, px, py):
    ax.set_yscale('log')
    ax.set_xscale('log')
    ax.set_ylim([yl, yr])
    ax.set_xlim([xl, xr])
    # ax.legend(loc='upper left')
    # ax.set_title('(a)')

    ax.text(px, py, r'$\sin(\theta)$', fontsize=18)
    # ax.set_ylabel(r'$\sin(\theta)$', size='large')
    # ax.set_xlabel(r'$||\Delta \hat{u}||_2$', fontsize=15, labelpad=0)


def setAxis2(ax):
    ax.set_yscale('log')
    ax.set_xscale('log')
    # ax.text(px, py, r'$\langle \sin(\theta) \rangle$', fontsize=15)
    # ax.set_ylabel(r'$< \sin(\theta) >$', size='large')
    # ax.set_xlabel(r'$||\Delta \hat{u}||_2$', size='large')

    
if __name__ == "__main__":

    case = 6

    if case == 1:
        """
        compare the truncated and untruncated
        """
        fig = plt.figure(figsize=(6, 5))
        ax = fig.add_subplot(111)

        folder = 'cases32modes/case4rpo8x10sT40/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')
        sps = np.loadtxt('cases32modes/spacing/spacing_rpo8.txt')

        ax.scatter(dis, ang[:, 4], s=7, c='b', marker='o', edgecolor='none')
        ii = [i for i in range(np.size(dis)) if dis[i] > 4*sps[idx[i]]]
        ax.scatter(dis[ii], ang[ii, 4], s=7, c='r', marker='s', edgecolor='none')

        ax.set_yscale('log')
        ax.set_xscale('log')
        ax.set_ylim([1e-4, 1e-1])
        ax.set_xlim([1e-3, 1e-1])

        ax.set_ylabel(r'$\sin(\theta)$', size='large')
        ax.set_xlabel(r'$||\Delta x||_2$', size='large')

        fig.tight_layout(pad=0)
        plt.show()

    if case == 2:
        """
        plot one good truncated statistic figure
        """
        folder = 'cases32modes/case4rpo4x10sT30/'
        sps = np.loadtxt('cases32modes/spacing/spacing_rpo4.txt')
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')

        ii = [i for i in range(np.size(dis)) if dis[i] > 4*sps[idx[i]]]

        cix = [3, 4, 5]             # column index
        spix = [6, 7, 8, 15]        # subspace index
        colors = ['r', 'b', 'c', 'm']
        markers = ['o', 's', 'v', '*']
        Num = np.size(cix)

        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        for i in range(Num):
            ax.scatter(dis[ii], ang[ii, cix[i]], s=7, c=colors[i], marker=markers[i],
                       edgecolor='none', label='1-'+str(spix[i]))

        ax.set_yscale('log')
        ax.set_xscale('log')
        ax.set_ylim([1e-4, 1e-0])
        ax.set_xlim([1e-3, 1e-1])
        # ax.legend(loc='upper left')
        # ax.set_title('(a)')

        ax.text(1.2e-3, 2e-1, r'$\sin(\theta)$', fontsize=18)
        # ax.set_ylabel(r'$\sin(\theta)$', size='large')
        # ax.set_xlabel(r'$||\Delta x||_2$', size='large')
        fig.tight_layout(pad=0)
        plt.show()

    if case == 3:
        """
        plot only one shadowing incidence
        """
        folder = 'cases32modes/case4ppo3x10sT30/'
        sps = np.loadtxt('cases32modes/spacing/spacing_ppo3.txt')
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')
        No = np.loadtxt(folder + 'No')

        midx = np.argmax(No)
        i1 = np.int(np.sum(No[:midx]))
        i2 = np.int(np.sum(No[:midx+1]))
        ii = [i for i in range(i1, i2) if dis[i] > 4*sps[idx[i]]]

        cix = [3, 4, 5]             # column index
        spix = [6, 7, 8, 15]        # subspace index
        colors = ['r', 'b', 'c', 'm']
        markers = ['o', 's', 'v', '*']
        Num = np.size(cix)

        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        for i in range(Num):
            ax.scatter(dis[ii], ang[ii, cix[i]], s=10, c=colors[i], marker=markers[i],
                       edgecolor='none', label='1-'+str(spix[i]))

        ax.set_yscale('log')
        ax.set_xscale('log')
        ax.set_ylim([5e-4, 2e-1])
        ax.set_xlim([5e-3, 1e-1])
        # ax.legend(loc='upper left')
        # ax.set_title('(a)')

        ax.text(6e-3, 9e-2, r'$\sin(\theta)$', fontsize=18)
        # ax.set_ylabel(r'$\sin(\theta)$', size='large')
        # ax.set_xlabel(r'$||\Delta \hat{u}||_2$', fontsize=15, labelpad=0)
        fig.tight_layout(pad=0)
        plt.show()

    if case == 4:
        """
        plot spacing along periodic orbit
        """
        sps = np.loadtxt('spacing/spacing_rpo6.txt')
        fig = plt.figure(figsize=(8, 6))
        ax = fig.add_subplot(111)
        ax.semilogy(sps)

        ax.set_xlabel('index of points along the orbit')
        ax.set_ylabel('spacing')
        ax.set_title('rpo6')
        # ax.set_xlim([0, 2100])
        ax.set_ylim([4e-4, 1e-1])

        plt.tight_layout(pad=0)
        plt.show()

    if case == 5:
        """
        plot the distance structure
        """
        fig = plt.figure(figsize=(6, 4))
        ax = fig.add_subplot(111)

        dis = np.loadtxt('./cases32modes/case4rpo6x10sT30/dis')
        No = np.loadtxt('./cases32modes/case4rpo6x10sT30/No', dtype=int)
        ix = 13                 # shadowing incidence.
        h = 0.1

        start = No[:ix].sum()   # number of point before what we want
        x = h*np.arange(No[ix])
        y = dis[start:start+No[ix]]

        ax.plot(x, y, c='b', lw=1)
        # ax.quiver(22, 2e-3, 0, 0.1)
        # ax.quiver(18, 2e-3, 0, 0.1)
        ax.text(8.5, 6e-3, 'B')
        ax.text(16.5, 1.6e-2, 'C')

        ax.set_ylim([4e-3, 1e-1])
        ax.set_yscale('log')

        ax.set_xlabel('t')
        ax.set_ylabel(r'$||\Delta x||_2$')

        fig.tight_layout(pad=0)
        plt.show()

    ############################################################
    #                 The new set of data : x5                 #
    ############################################################
    if case == 6:
        """
        plot one good truncated statistic figure
        """
        ppType = 'ppo'
        ppId = 4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        folder = 'cases32modes_x5/case4ppo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle2')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')

        ii = [i for i in range(np.size(dis)) if dis[i] > 4*sps[idx[i]]]
        """
        cix = [3, 4, 5]             # column index
        spix = [6, 7, 8, 15]        # subspace index
        colors = ['r', 'b', 'c', 'm']
        markers = ['o', 's', 'v', '*']
        Num = np.size(cix)

        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        for i in range(Num):
            ax.scatter(dis[ii], ang[ii, cix[i]], s=7, c=colors[i], marker=markers[i],
                       edgecolor='none', label='1-'+str(spix[i]))

        ax.set_yscale('log')
        ax.set_xscale('log')
        ax.set_ylim([1e-4, 1e-0])
        ax.set_xlim([1e-3, 1e-1])
        # ax.legend(loc='upper left')
        # ax.set_title('(a)')

        ax.text(1.2e-3, 2e-1, r'$\sin(\theta)$', fontsize=18)
        # ax.set_ylabel(r'$\sin(\theta)$', size='large')
        # ax.set_xlabel(r'$||\Delta x||_2$', size='large')
        fig.tight_layout(pad=0)
        plt.show()
        # savez_compressed('rpo4Scatter.npz', dis=dis[ii], ang=ang[ii][:, cix])
        """
    if case == 7:
        """
        plot only one shadowing incidence
        """
        ppType = 'rpo'
        ppId = 4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        folder = 'cases32modes_x5/case4rpo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')
        No = np.loadtxt(folder + 'No')

        # midx = 1 for rpo4; midx = 6 for ppo4;
        # midx = np.argmax(No)
        midx = 1
        i1 = np.int(np.sum(No[:midx]))
        i2 = np.int(np.sum(No[:midx+1]))
        ii = [i for i in range(i1, i2) if dis[i] > 4*sps[idx[i]]]

        cix = [3, 4, 5]             # column index
        spix = [6, 7, 8, 15]        # subspace index
        colors = ['r', 'b', 'c', 'm']
        markers = ['o', 's', 'v', '*']
        Num = np.size(cix)

        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        for i in range(Num):
            ax.scatter(dis[ii], ang[ii, cix[i]], s=10, c=colors[i], marker=markers[i],
                       edgecolor='none', label='1-'+str(spix[i]))

        setAxis(ax, 7e-3, 1e-1, 1e-3, 5e-1, 8e-3, 2e-1)  # for rpo4
        # setAxis(ax, 7e-3, 1e-1, 5e-4, 8e-2, 8e-3, 4e-2)  # for ppo4

        fig.tight_layout(pad=0)
        plt.show()

        # savez_compressed('rpo4OneShadow.npz', dis=dis[ii], ang=ang[ii][:, cix])

    if case == 8:
        """
        plot the statistic avaerage
        """
        ppType = 'rpo'
        ppId = 4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        folder = 'cases32modes_x5/case4rpo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')

        ii = [i for i in range(np.size(dis)) if dis[i] > 4*sps[idx[i]]]

        cell = 0.2
        x, aver = statisAverage(dis[ii], ang[ii], 0.2)

        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        
        for i in range(aver.shape[1]):
            ax.plot(x, aver[:, i], '-o')

        setAxis2(ax)
        fig.tight_layout(pad=0)
        plt.show()

    if case == 9:
        """
        calcuate and save the full angle points.
        modify : ppType, folder, gTpos
        """
        ppType = 'ppo'
        ppId = 4
        gTpos = 3               # work both for ppo4 and rpo4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        a, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', ppType, ppId)
        h = T / nstp
        veAll = KSreadFV('../ks22h001t120x64EV.h5', ppType, ppId)
        ks = pyKS(64, h, 22)
        aaHat, veHat = ks.orbitAndFvWholeSlice(a, veAll, nstp, ppType, gTpos)
        
        folder = 'cases32modes_x5/case4ppo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')
        difv = np.loadtxt(folder + 'difv')

        M = len(idx)
        NFV = 29
        ang2 = np.zeros((M, NFV))
        for i in range(M):
            if i % 100 == 0:
                print "i = ", i
            d = idx[i]
            fvs = veHat[d*NFV:(d+1)*NFV, :]
            for j in range(NFV):
                ang2[i, j] = pAngle(difv[i], fvs[:j+1].T)

        ang3 = np.cos(ang2)
        np.savetxt('ang2.dat', ang3)

    if case == 10:
        """
        plot the statistic avarage also use more subspaces
        change: ppType, folder
        """
        ppType = 'ppo'
        ppId = 4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        folder = 'cases32modes_x5/case4ppo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle2')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')

        ii = [i for i in range(np.size(dis)) if dis[i] > 4*sps[idx[i]]]
        
        cell = 0.2
        x, aver = statisAverage(dis[ii], ang[ii], 0.2)
        """
        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111)
        
        for i in range(3, 6) + range(6, 11, 2)+range(16, 25, 4):
            ax.plot(x, aver[:, i], '-o')

        setAxis2(ax)
        ax.set_yticks([1e-6, 1e-4, 1e-2, 1e0])
        fig.tight_layout(pad=0)
        plt.show()
        """
        # savez_compressed('rpo4Average.npz', x=x, aver=aver)

    if case == 11:
        """
        plot the shadowing configuration for one shadowing incidence
        change : ppType, folder, midx
        """
        ppType = 'ppo'
        ppId = 4
        sps = calSpacing('../ks22h001t120x64EV.h5', ppType, ppId, 5)

        folder = 'cases32modes_x5/case4ppo4x5sT30/'
        ang = np.sin(np.arccos(np.loadtxt(folder + 'angle')))
        dis = np.loadtxt(folder + 'dis')
        idx = np.loadtxt(folder + 'indexPo')
        No = np.loadtxt(folder + 'No')
        difv = np.loadtxt(folder + 'difv')

        # midx = 1 for rpo4; midx = 6 for ppo4;
        # midx = np.argmax(No)
        midx = 6
        i1 = np.int(np.sum(No[:midx]))
        i2 = np.int(np.sum(No[:midx+1]))
        # ii = [i for i in range(i1, i2) if dis[i] > 4*sps[idx[i]]]
        ii = range(i1, i2)

        cix = [3, 4, 5]             # column index
        spix = [6, 7, 8, 15]        # subspace index
        colors = ['r', 'b', 'c', 'm']
        markers = ['o', 's', 'v', '*']
        Num = np.size(cix)

        a, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', ppType, ppId)
        h = T / nstp
        ks = pyKS(64, h, 22)
        aa = ks.intg(a, nstp, 5)
        aa = aa[:-1, :]
        if ppType == 'ppo':
            aaWhole = ks.half2whole(aa)
        else:
            aaWhole = aa
        aaHat = ks.orbitToSlice(aaWhole)[0]

        aaErgHat = np.zeros((len(ii), difv.shape[1]))
        for i in range(len(ii)):
            aaErgHat[i] = difv[ii[i]] + aaHat[idx[ii[i]]]
            
        """
        fig = plt.figure(figsize=(3, 2))
        ax = fig.add_subplot(111, projection='3d')
        f1 = 0
        f2 = 2
        f3 = 3
        ax.plot(aaHat[:, f1], aaHat[:, f2], aaHat[:, f3])
        ax.plot(aaErgHat[:, f1], aaHat[:, f2], aaHat[:, f3])
        for i in range(Num):
            ax.scatter(dis[ii], ang[ii, cix[i]], s=10, c=colors[i], marker=markers[i],
                       edgecolor='none', label='1-'+str(spix[i]))

        setAxis(ax, 7e-3, 1e-1, 1e-3, 5e-1, 8e-3, 2e-1)  # for rpo4
        # setAxis(ax, 7e-3, 1e-1, 5e-4, 8e-2, 8e-3, 4e-2)  # for ppo4

        fig.tight_layout(pad=0)
        plt.show()
        """
<file_sep>import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

N = 1024; M = 10000;
AA = np.fromfile('aa.bin', np.double, 2*N*M).reshape(M,2*N).T;
Ar = AA[0::2,:]; Ai = AA[1::2, :]; Ama = abs(Ar+1j*Ai);

fig = plt.figure(figsize=(8,6));
ax = fig.add_subplot(111)
ax.set_ylim((-0.5, 3.5))
ax.set_xlabel('L'); 
ax.set_ylabel('|A|');
ax.grid('on', color ='w', lw = 1); fig.tight_layout(pad = 0)
ax.patch.set_facecolor('black')

x = np.linspace(0, 50, N, endpoint=False)
line, = ax.plot(x, Ama[:,0], c=(0,1,0) ,lw=1.5, label = '0');

Maxf = 7000 ;
def animate(i):
    y = Ama[:,i];
    line.set_ydata(y);
    # only use the integer part to get rid of flashes of legend.
    line.set_label('time : ' + str( int((i*0.005+500)*10)/10.0 ) ); 
    ax.legend(fancybox=True)
    return line, ax; # ax also needs be updated in order to update legend.

anim = animation.FuncAnimation(fig, animate, frames=Maxf,
                               interval=0 , blit=False, repeat=False);
anim.save('cqcgl1d.mp4', dpi=100, fps=30, extra_args=['-vcodec', 'libx264'])
#plt.show()
<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' intg2M1.cpp ../ksint.cc ../ksintM1.cc -I../../../include  -I$XDAPPS/eigen/include/eigen3 -lfftw3
 * */
#include "ksintM1.hpp"
#include "mex.h"
#include "matrix.h"
#include <cmath>
#include <cstring>
#include <cassert>
#include <Eigen/Dense>

using namespace Eigen;

/* ks 1st mode slice integrator without Jacobian */
static std::pair<ArrayXXd, ArrayXd>
intg2M1(double *a0, int N, double h, double T, int np, double d){
  KSM1 ks(N+2, h, d);
  Map<ArrayXd> v0(a0, N);
  return ks.intg2(v0, T, np);
}

void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    int np = 1;
    double d = 22;
    
    switch (nrhs) 
	{
	case 5 :
	    d =  mxGetScalar(prhs[4]); 
	case 4 :
	    np = mxGetScalar(prhs[3]); 
	case 3 : {
	    // get the pointer and the size of input 
	    double *a0 = mxGetPr(prhs[0]);
	    mwSize N = mxGetM(prhs[0]);
	    mwSize M = mxGetN(prhs[0]);
	    assert( N % 2 == 0 && M = 1 );	
	    double h = mxGetScalar(prhs[1]);
	    double T = mxGetScalar(prhs[2]);

	    std::pair<ArrayXXd, ArrayXd> tmp = intg2M1(a0, N, h, T, np, d);
	    int m = tmp.first.cols();
	    plhs[0] = mxCreateDoubleMatrix(N, m, mxREAL);
	    plhs[1] = mxCreateDoubleMatrix(m, 1, mxREAL);
	    
	    memcpy(mxGetPr(plhs[0]), &tmp.first(0,0), m*N*sizeof(double));
	    memcpy(mxGetPr(plhs[1]), &tmp.second(0), m*sizeof(double));

	    break; // very import
	}
	default:
	    mexErrMsgIdAndTxt( "KS_integrator:inputMismatch", 
			       " 3 =< #input <=5. Example: intg(a0, h, nstp, np, d) \n");
	}
   
}
<file_sep>from personalFunctions import *


def setAxis(ax, xr, xlabel=r'$t$', ylabel=r'$\lambda_k(t)$'):
    # ax.get_yaxis().set_tick_params(which='both', direction='in', pad = -20)
    # ax.get_xaxis().set_tick_params(which='both', direction='in', pad = -20)

    # ax.set_xlabel(xlabel, fontsize=20)
    # ax.set_ylabel(ylabel, fontsize=20)
    ax.set_xlim([0, xr])
    ax.set_xticks([0, xr-1])
    ax.set_xticklabels([0, r'$T_p$'], fontsize=13)


if __name__ == '__main__':

    case = 10

    if case == 1:
        """
        plot the local Flouqet exponents of ppo1
        """
        # load data
        ksp = KSplot()
        a, T, nstp, r, s = ksp.readPO('../ks22h001t120x64EV.h5', 'ppo', 1)
        expand = np.log(np.loadtxt('./ppo/FVexpand1.dat')) / (5 * T / nstp)
        
        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ax.plot(expand[0], lw=1.5, ls='-')
        ax.plot(expand[2], lw=1.5, ls='-')
        ax.plot(expand[3], lw=1.5, ls='-')
        ax.plot(expand[4], lw=1.5, ls='-')
        ax.plot(expand[5], lw=1.5, ls='-')
        ax.plot(expand[7], lw=1.5, ls='-')

        ax.plot(expand[8], lw=1.5, ls='-')
        ax.plot(expand[9], lw=1.5, ls='-')

        ax.text(expand.shape[1]/50, 0.4, r'$\lambda_k(t)$', fontsize=18)
        ax.text(expand.shape[1]/3, -0.8, r'$k=1, 3, 4, 5, 6, 8$', fontsize=18)
        ax.text(expand.shape[1]/2, -1.8, r'$k=9, 10$', fontsize=18)
        
        setAxis(ax, expand.shape[1])
        ax.set_ylim([-2.5, 1])
        ax.set_yticks([-2, -1, 0, 1])
        fig.tight_layout(pad=0)
        plt.show()

    if case == 10:
        """
        plot the local Flouqet exponents of rpo1
        """
        ksp = KSplot()
        a, T, nstp, r, s = ksp.readPO('../ks22h001t120x64EV.h5', 'rpo', 1)
        expand = np.log(np.loadtxt('./rpo/FVexpand1.dat')) / (5 * T / nstp)
        
        fig, ax = pl2d(labs=[r'$t$', r'$\lambda_j(u(t))$'], axisLabelSize=25, tickSize=20)
        ax.plot(expand[0], lw=1.5, ls='-', label=r'$j=1$')
        ax.plot(expand[1], lw=1.5, ls='-', label=r'$j=2$')
        ax.plot(expand[2], lw=1.5, ls='-', label=r'$j=3$')
        ax.plot(expand[3], lw=1.5, ls='-', label=r'$j=4$')
        ax.plot(expand[4], lw=1.5, ls='-')
        ax.plot(expand[5], lw=1.5, ls='-', label=r'$j=5, 6$')
        ax.plot(expand[6], lw=1.5, ls='-', label=r'$j=7$')
        ax.plot(expand[7], lw=1.5, ls='-', label=r'$j=8$')

        ax.plot(expand[8], lw=1.5, ls='-')
        ax.plot(expand[9], lw=1.5, ls='-', label=r'$j=9, 10$')
        
        xr = expand.shape[1]
        ax.set_xlim([0, xr])
        ax.set_xticks([0, xr-1])
        ax.set_xticklabels([0, r'$T_p$'], fontsize=20)
        # ax.set_ylim([-2.5, 1])
        ax.set_yticks([-2.5, -1, 0, 0.5])

        ax.legend(loc='best', ncol=3, fontsize=20)
        fig.tight_layout(pad=0)
        plt.show(block=False)
        
        
    if case == 2:
        """
        plot $\lambda_i(t) -\lambda$ for a small subset
        """
        a, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', 'ppo', 1)
        expand = np.log(np.loadtxt('./ppo/FVexpand1.dat')) / (5 * T / nstp)
        fe = KSreadFE('../ks22h001t120x64EV.h5', 'ppo', 1)[0]

        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ix = [8, 9, 10, 11]
        for i in ix:
            ax.plot(expand[i]-fe[i], lw=1.5, ls='-', label='k='+str(i+1))

        setAxis(ax, expand.shape[1], ylabel=r'$\lambda_k(t) - \lambda_k$')
        ax.set_yticks([-0.03, 0, 0.03, 0.06])
        ax.legend(loc='best', fontsize=13, frameon=False)
        fig.tight_layout(pad=0)
        plt.show()

        # savez_compressed('ppo1', T=T, nstp=nstp, fe=fe)

    if case == 3:
        """
        plot $\lambda_i(t) -\lambda$ for the remaining set
        """
        a, T, nstp, r, s = KSreadPO('../ks22h001t120x64EV.h5', 'ppo', 1)
        expand = np.log(np.loadtxt('./ppo/FVexpand1.dat')) / (5 * T / nstp)
        fe = KSreadFE('../ks22h001t120x64EV.h5', 'ppo', 1)[0]

        fig = plt.figure(figsize=[3, 2])
        ax = fig.add_subplot(111)
        ix = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
        for i in ix:
            ax.plot(expand[i]-fe[i], lw=1.5, ls='-')

        ax.arrow(expand.shape[1]/20, 0.009, 0, -0.003,
                 width=20, head_length=0.001, head_width=80,
                 fc='k')
        setAxis(ax, expand.shape[1], ylabel=r'$\lambda_k(t) - \lambda_k$')
        ax.set_yticks([-0.008, -0.002, 0.004, 0.01])
        fig.tight_layout(pad=0)
        plt.show()

    if case == 4:
        """
        The partial hyperbolicity degree
        """
        pn = np.zeros(29)
        for i in range(1, 201):
            print i
            expand = np.loadtxt('./ppo/FVexpand' + str(i) + '.dat')
            for j in range(1, 30):
                x = np.amin(expand[:j], axis=0) - np.amax(expand[j:], axis=0)
                if np.amin(x) > 0:
                    pn[j-1] += 1

        rn = np.zeros(29)
        for i in range(1, 201):
            print i
            expand = np.loadtxt('./rpo/FVexpand' + str(i) + '.dat')
            for j in range(1, 30):
                x = np.amin(expand[:j], axis=0) - np.amax(expand[j:], axis=0)
                if np.amin(x) > 0:
                    rn[j-1] += 1

        ph = pn + rn

        # np.savetxt('ph.dat', ph)

        fig = plt.figure(figsize=[3, 3])
        ax = fig.add_subplot(111)
        ax.scatter(range(1, 30), ph, s=30, facecolor='b', edgecolors='none')
        ax.set_xticks(range(0, 31, 4))
        ax.set_xlim([0, 30])
        ax.set_ylim([-50, 450])
        # ax.set_xlabel('k', fontsize=20)
        ax.grid('on')
        fig.tight_layout(pad=0)
        plt.show()

    
<file_sep>#include "ksintM1.hpp"
#include <cmath>

using Eigen::NoChange;

/* ================================================== 
 *                    Class : KS 1st mode integrator
 * ==================================================*/

/* --------------------    constructors  -------------------- */
KSM1::KSM1(int N, double h, double d) : KS(N, h, d) {}
KSM1::KSM1(const KSM1 &x) : KS(x) {}
KSM1 & KSM1::operator=(const KSM1 &x) { return *this; }


/* -------------------- member functions -------------------- */

/** @brief calculate the nonlinear term
 * (a_1 - 1)*(q_k^2 - q_k^4)a_k - iq_k/2 fft(ifft^2(a)) + iq_k/2*a*real(fft(ifft(a))_1) 
 **/
void KSM1::NL(KSfft &f){
  double a1hat = f.vc1(1).real();  
  ifft(f);
  f.vr2 = f.vr2 * f.vr2;
  fft(f);
  f.vc3 = (a1hat - 1)*L*f.vc1 + a1hat*G*f.vc3 - f.vc3(1).real()*G*f.vc1;
}

#if 0
void KSM1::jNL(KSfft &f){
  double a1 = f.vc1(1,0).real();
  ArrayXd y1 = f.vc1.block(1,1,1,N-2).real();
  ifft(f);
  ArrayXd tmp = f.vr2.col(0);
  f.vr2 = tmp.matrix().asDiagonal()*f.vr2.matrix();
  fft(f);
  double fv1 = f.vc3.row(1).real();
  /* (q_k^2-q_k^4)*a - iq_k/2*\sum a_m a_{k-m} */
  f.vc3.col(0) = L*f.vc1.col(0) + G*f.vc3.col(0);
  /* (q_k^2-q_k^4)*y - iq_k/2*\sum a_m y_{k-m} */
  f.vc3.rightCols(N-2) = L*f.vc1.rightCols(N-2) + 2.0*G*f.vr3.rightCols(N-2);
  
  f.vc3.rightCols(N-2) = (a1-1)*f.vc3.rightCols(N-2) - G * f.vc1.rightCols(N-2)*fv1(0)
    +y1*f.vr3.col(0) - 2.0*G*fv1.tail(N-2);
  f.vc3.col(0) = a1*f.vc3.col(0) - L*f.vc1.col(0) -fv1(0)*G*f.vc1;
}
#endif

/** @brief Integrator on the 1st mode slice.
 *
 *  @return the trajectory (first element of the return pair) and the time
 *          in the full state space (second element of the return pair)
 */
std::pair<ArrayXXd, ArrayXd>
KSM1::intg(const ArrayXd &a0, size_t nstp, size_t np){
  if( N-2 != a0.rows() ) {printf("dimension error of a0\n"); exit(1);} 
  Fv.vc1 = R2C(a0); 
  Fv.vc1(1) = dcp(Fv.vc1(1).real(), 0.0); //force the imag of 1st mode to be zero
  ArrayXXd aa(N-2, nstp/np+1);  aa.col(0) = a0;
  ArrayXd tt(nstp/np+1); tt(0) = 0.0;

  double t = 0;
  for(size_t i = 1; i < nstp +1; i++){
    NL(Fv); Fa.vc1 = E2*Fv.vc1 + Q*Fv.vc3;
    NL(Fa); Fb.vc1 = E2*Fv.vc1 + Q*Fa.vc3;
    NL(Fb); Fc.vc1 = E2*Fa.vc1 + Q*(2.0*Fb.vc3 - Fv.vc3);
    NL(Fc);
    Fv.vc1 = E*Fv.vc1 + Fv.vc3*f1 + 2.0*(Fa.vc3+Fb.vc3)*f2 + Fc.vc3*f3;    
    t += Fv.vc1(1).real() * h;

    if( 0 == i%np ) {
      aa.col(i/np) = C2R(Fv.vc1);
      tt(i/np) = t;
    }
  }
  
  return std::make_pair(aa, tt);
}

/** @brief Integrator on the 1st mode slice. It will integrate KS on slice
 *         until the corresponding time lapse in full state is approximate T.
 *         Therefore, the result's dimension depends.
 *
 * @param[in] T time to be integrated in the full state space.
 *
 */
std::pair<ArrayXXd, ArrayXd>
KSM1::intg2(const ArrayXd &a0, double T, size_t np){
  const size_t cell = 1000;
  if( N-2 != a0.rows() ) {printf("dimension error of a0\n"); exit(1);} 
  Fv.vc1 = R2C(a0); 
  Fv.vc1(1) = dcp(Fv.vc1(1).real(), 0.0); //force the imag of 1st mode to be zero
  ArrayXXd aa(N-2, cell);  aa.col(0) = a0;
  ArrayXd tt(cell); tt(0) = 0.0;
  
  double t = 0;
  size_t i = 1; // record the integration steps.
  size_t ix = 1; // record the #columns of aa.
  double lastT = 0; // record the last time recorded in tt.
  while(lastT < T){
    NL(Fv); Fa.vc1 = E2*Fv.vc1 + Q*Fv.vc3;
    NL(Fa); Fb.vc1 = E2*Fv.vc1 + Q*Fa.vc3;
    NL(Fb); Fc.vc1 = E2*Fa.vc1 + Q*(2.0*Fb.vc3 - Fv.vc3);
    NL(Fc);
    Fv.vc1 = E*Fv.vc1 + Fv.vc3*f1 + 2.0*(Fa.vc3+Fb.vc3)*f2 + Fc.vc3*f3;    
    t += Fv.vc1(1).real() * h;


    if( 0 == i%np ) {
      int m = aa.cols();
      if(i/np > m - 1) {
	aa.conservativeResize(NoChange, m+cell); // rows not change, just extend cols
	tt.conservativeResize(m+cell);
      }
      aa.col(i/np) = C2R(Fv.vc1);
      tt(i/np) = t; lastT = t;
      ix++;
    }
    
    i++;
  }
  
  return std::make_pair(aa.leftCols(ix), tt.head(ix));
}

#if 0
KSM1::intgj(const ArrayXd a0,  size_t nstp, size_t np, size_t nqr){
  if( N-2 != a0.rows() ) {printf("dimension error of a0\n"); exit(1);}
  ArrayXXd v0(N-2, N-1);
  v0 << a0, MatrixXd::Identity(N-2, N-2);
  jFv.vc1 = R2C(v0);
  ArrayXXd aa(N-2, nstp/np+1); aa.col(0) = a0;
  ArrayXXd daa((N-3)*(N-3), nstp/nqr);
  for(size_t i = 1; i < nstp + 1; i++){
    
  }
}

#endif
<file_sep>from py_CQCGL1dSub import *
from py_CQCGL1d import *
from cglHelp import *

################################################################################
#   compare req in subspace and in full space
################################################################################

case = 10

if case == 10:
    """
    compare eigenvalues for symmetric subspace and full space
    """
    N, d = 1024, 50
    Bi, Gi = 2, -5
    index = 1

    cgl = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)
    
    a0, wth0, wphi0, err0, e0, v0 = req.read('../../data/cgl/reqBiGiEV.h5',
                                             req.toStr(Bi, Gi, index), flag=2)
    e1 = e0

    a0, wth0, wphi0, err0, e0, v0 = req.read('../../data/cgl/reqsubBiGiEV.h5',
                                             req.toStr(Bi, Gi, index), flag=2,
                                             sub=True)
    e2 = e0

    print e1[:10]
    print e2[:10]

if case == 20:
    """
    compare eigenvectors
    """
    N, d = 1024, 50
    Bi, Gi = 2, -2
    index = 1
    
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    cglsub = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, reqsub = CQCGLreq(cgl), CQCGLreq(cglsub), 
    cp, cpsub = CQCGLplot(cgl), CQCGLplot(cglsub)

    a0, wth0, wphi0, err0, e0, v0 = req.read('../../data/cgl/reqBiGiEV.h5',
                                           req.toStr(Bi, Gi, index),
                                           flag=2)
    cp.oneConfig(v0[0].real * cgl.N)
    cp.oneConfig(v0[0].imag * cgl.N)
    cp.oneConfig(v0[1].real * cgl.N)
    cp.oneConfig(v0[1].imag * cgl.N)

    a1, wth1, wphi1, err1, e1, v1 = reqsub.read('../../data/cgl/reqsubBiGiEV.h5',
                                                req.toStr(Bi, Gi, index),
                                                sub=True,flag=2)
    cpsub.oneConfig(v1[0].real * cgl.N)
    cpsub.oneConfig(v1[0].imag * cgl.N)

if case == 30:
    """
    same as case 20, but sperate real/imag part
    """
    N, d = 1024, 50
    Bi, Gi = 2, -2
    index = 1
    
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    cglsub = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req, reqsub = CQCGLreq(cgl), CQCGLreq(cglsub), 
    cp, cpsub = CQCGLplot(cgl), CQCGLplot(cglsub)

    a0, wth0, wphi0, err0, e0, v0 = req.read('../../data/cgl/reqBiGiEV.h5',
                                           req.toStr(Bi, Gi, index),
                                           flag=2)
    plot1dfig(cgl.Fourier2Config(v0[0].real * cgl.N).real)
    plot1dfig(cgl.Fourier2Config(v0[0].real * cgl.N).imag)
    plot1dfig(cgl.Fourier2Config(v0[0].imag * cgl.N).real)
    plot1dfig(cgl.Fourier2Config(v0[0].imag * cgl.N).imag)
    plot1dfig(cgl.Fourier2Config(v0[2].real * cgl.N).real)
    plot1dfig(cgl.Fourier2Config(v0[2].real * cgl.N).imag)
    plot1dfig(cgl.Fourier2Config(v0[2].imag * cgl.N).real)
    plot1dfig(cgl.Fourier2Config(v0[2].imag * cgl.N).imag)
    

    a1, wth1, wphi1, err1, e1, v1 = reqsub.read('../../data/cgl/reqsubBiGiEV.h5',
                                                req.toStr(Bi, Gi, index),
                                                sub=True,flag=2)
    plot1dfig(cglsub.Fourier2Config(v1[0].real * cglsub.N).real)
    plot1dfig(cglsub.Fourier2Config(v1[0].real * cglsub.N).imag)
    plot1dfig(cglsub.Fourier2Config(v1[0].imag * cglsub.N).real)
    plot1dfig(cglsub.Fourier2Config(v1[0].imag * cglsub.N).imag)

<file_sep>from py_ks import *
from personalFunctions import *


def magvalue(x):
    return np.abs(x[0::2] + 1j * x[1::2])

case = 4

if case == 1:
    f = h5py.File('../../data/myN32/ks22h02t100EV.h5')
    ve = np.array(f['/ppo/1/ve']).T
    N, M = ve.shape
    N = np.int(np.sqrt(N))
    ve = ve[:, 0]
    ve.resize(N, N)

    fig = plt.figure(figsize=(8, 4))
    ax = fig.add_subplot(111)
    ax.plot(range(1, N/2+1), magvalue(ve[:, 0]), '-o', c='r', label=r'$V_{1r}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 1]), '-s', c='b', label=r'$V_{1i}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 7]), '-^', c='g', label=r'$V_{8}$')
    ax.plot([4.5, 4.5], [0, 0.7], '--', c='k', lw=3)
    ax.grid('on')
    ax.set_xlabel('Fourier mode index')
    ax.set_ylabel('amplitute')
    ax.legend()
    plt.tight_layout(pad=0)
    plt.show()

    # The black dashed line separate the physical (first 8) and transient modes ( 9 to 30). 
    # since 
    # $$
    # u(x_{n},t)=\!\!\sum_{k=-N/2+1}^{N/2}\!\!a_{k}(t)e^{iq_{k}x_{n}}
    # $$
    # Denote $a_k = b_k + ic_k$, so we has state space $[b_1, c_1, b_2, c_2, \cdots]$.  X-axis is the exponent index of this state space

    ### Plot the unphysical Floquet vectors

    # In[63]:
    
    fig = plt.figure(figsize=(8,4))
    ax = fig.add_subplot(111)
    ax.plot(range(1, N/2+1), magvalue(ve[:, 8]), '-o', c='r', label=r'$V_{9}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 17]), '-s', c='b', label=r'$V_{18}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 24]), '-v', c='c', label=r'$V_{25}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 29]), '-^', c='g', label=r'$V_{30}$')
    ax.plot([4.5, 4.5], [0,1], '--', c='k', lw=3)
    ax.grid('on')
    ax.set_xlabel('Fourier mode index')
    ax.set_ylabel('amplitute')
    ax.legend(loc='best')
    plt.tight_layout(pad=0)
    plt.show()

if case == 2:
    """
    plot Fvs for N = 64
    """        
    f = h5py.File('../../data/myN32/ks22h02t100EV.h5')
    ve = np.array(f['/ppo/1/ve']).T
    N, M = ve.shape
    N = np.int(np.sqrt(N))
    ve = ve[:, 0]
    ve.resize(N, N)
    
    fig = plt.figure(figsize=(8, 4))
    ax = fig.add_subplot(111)
    ax.plot(range(1, N/2+1), magvalue(ve[:, 0]), '-o', c='r', label=r'$V_{1r}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 1]), '-s', c='b', label=r'$V_{1i}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 7]), '-^', c='g', label=r'$V_{8}$')
    ax.plot([4.5, 4.5], [0, 0.7], '--', c='k', lw=3)
    ax.grid('on')
    ax.set_xlabel('Fourier mode index')
    ax.set_ylabel('amplitute')
    ax.legend()
    plt.tight_layout(pad=0)
    plt.show()
    
    # The black dashed line separate the physical (first 8) and transient modes ( 9 to 30). 
    # since 
    # $$
    # u(x_{n},t)=\!\!\sum_{k=-N/2+1}^{N/2}\!\!a_{k}(t)e^{iq_{k}x_{n}}
    # $$
    # Denote $a_k = b_k + ic_k$, so we has state space $[b_1, c_1, b_2, c_2, \cdots]$.  X-axis is the exponent index of this state space
    
    ### Plot the unphysical Floquet vectors
    
    # In[63]:
    
    fig = plt.figure(figsize=(8,4))
    ax = fig.add_subplot(111)
    ax.plot(range(1, N/2+1), magvalue(ve[:, 8]), '-o', c='r', label=r'$V_{9}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 17]), '-s', c='b', label=r'$V_{18}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 24]), '-v', c='c', label=r'$V_{25}$')
    ax.plot(range(1, N/2+1), magvalue(ve[:, 29]), '-^', c='g', label=r'$V_{30}$')
    ax.plot([4.5, 4.5], [0,1], '--', c='k', lw=3)
    ax.grid('on')
    ax.set_xlabel('Fourier mode index')
    ax.set_ylabel('amplitute')
    ax.legend(loc='best')
    plt.tight_layout(pad=0)
    plt.show()


if case == 3:
    """
    plot the orbit ppo1 for N = 64
    """
    N = 64
    f = h5py.File('../../data/ks22h001t120x64EV.h5')
    pp = '/ppo/1/'
    T = np.array(f[pp + 'T'])[0]
    nstp = np.int(np.array(f[pp + 'nstp'])[0])
    a0 = np.array(f[pp + 'a'])
    h = T / nstp

    ks = pyKS(N, h, 22)
    aa = ks.intg(a0, nstp*4, 10)
    KSplotColorMapOrbit(aa, [0, 22, 0, 10.25*4])


if case == 4:
    """
    plot the orbit rpo1 for N = 64
    """
    N, L = 64, 22
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    poFile = '../../data/ks22h001t120x64EV.h5'
    a0, T, nstp, r, s = ksp.readPO(poFile, 'rpo', 1)

    h = T / nstp

    aa = ks.intg(a0, h, nstp*2, 10)
    ksp.config(aa, [0, 22, 0, 16.31*2])

if case == 5:

    """
    plot the Fv of ppo1 for N = 64
    """
    N = 64
    Ndim = N - 2
    f = h5py.File('../../data/ks22h001t120x64EV.h5')
    pp = '/ppo/1/'
    T = np.array(f[pp + 'T'])[0]
    nstp = np.int(np.array(f[pp + 'nstp'])[0])
    a0 = np.array(f[pp + 'a'])
    h = T / nstp

    veAll = np.array(f[pp + 've'])
    Nve = 30
    veid = 30
    ve = veAll[:, (veid-1)*Ndim:veid*Ndim]

    KSplotColorMapOrbit(ve, [0, 22, 0, 10.25],
                        size=[2.5, 6],
                        save=True,
                        name='ppo1Fv30_64', axisOn=False, barOn=False)
    
if case == 6:
    """
    plot the Fv of rpo1 for N = 64
    """
    N = 64
    Ndim = N - 2
    f = h5py.File('../../data/ks22h001t120x64EV.h5')
    pp = '/rpo/1/'
    T = np.array(f[pp + 'T'])[0]
    nstp = np.int(np.array(f[pp + 'nstp'])[0])
    a0 = np.array(f[pp + 'a'])
    h = T / nstp

    veAll = np.array(f[pp + 've'])
    Nve = 30
    veid = 30
    ve = veAll[:, (veid-1)*Ndim:veid*Ndim]

    KSplotColorMapOrbit(ve, [0, 22, 0, 16.31],
                        size=[2.5, 6],
                        save=True,
                        name='rpo1Fv30_64', axisOn=False, barOn=False)

if case == 7:
    """
    plot the Fv power graph of ppo1/rpo1 for N = 64
    """
    N = 64
    Ndim = N - 2
    f = h5py.File('../../data/ks22h001t120x64EV.h5')
    pp = '/ppo/1/'
    T = np.array(f[pp + 'T'])[0]
    nstp = np.int(np.array(f[pp + 'nstp'])[0])
    a0 = np.array(f[pp + 'a'])
    h = T / nstp

    veAll = np.array(f[pp + 've'])
    Nve = 30
    ve = veAll[0]
    
    fig = plt.figure(figsize=(5, 4))
    ax = fig.add_subplot(111)
    ax.set_xlabel('k')
    ax.set_ylabel('power')
    for i in range(Nve):
            x = range(1, Nve/2+1)
            y = ve[Ndim*i:Ndim*(i+1)]
            y = y[::2]**2 + y[1::2]**2
            y = y[:Nve/2]
            if i < 8:
                    ax.plot(x, y, 'r-o', lw=1)
            if i >= 8:
                    ax.plot(x, y, 'b-o', lw=1)

    # ax.set_yscale('log')
    fig.tight_layout(pad=0)
    plt.show()

if case == 20:
    """
    Have a look at the Floquet vectors obtained from PED for N = 64 KS.
    Some of them do not converge, so maybe I can visulize the error
    """
    N = 64
    Ndim = N - 2
    ppId = 33
    poType = 'rpo'
    # fe, fv = KSreadFEFV('../../data/ks22h001t120x64EV.h5', 'rpo', ppId)
    fe, fv = KSreadFEFV('../../data/ex.h5', 'rpo', ppId)
    vs = fv[0].reshape(30, Ndim)
    plot1dfig(vs[29])
    

if case == 30:
    """
    Have a look at some left eigenvector of periodic orbits of KS.
    """
    N = 64
    Ndim = N - 2
    ppId = 1
    poType = 'ppo'
    
    f1 = '../../data/ks22h001t120x64EV.h5'
    fe1, fv1 = KSreadFEFV(f1, poType, ppId)
    fe, fv = KSreadFEFV('../../data/left.h5', poType, ppId)
    vs1 = fv1[0].reshape(30, Ndim)
    vs = fv[0].reshape(30, Ndim)
    plot1dfig(vs1[9])
    plot1dfig(vs[9])
    
    a0, T, nstp, r, s = KSreadPO(f1, poType, ppId)
    h = T / nstp
    ks = pyKS(N, h, 22)
    aa = ks.intg(a0, nstp, 5)
    KSplotColorMapOrbit(aa, [0, 22, 0, T])

    ix = 3
    v1 = fv1[:, 62*ix:62*(ix+1)]
    v = fv[:, 62*ix:62*(ix+1)]
    KSplotColorMapOrbit(v, [0, 22, 0, T])
    KSplotColorMapOrbit(v1, [0, 22, 0, T])
<file_sep>#ifndef KSPO_H
#define KSPO_H

#include <vector>
#include <tuple>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include "ksint.hpp"
#include "myH5.hpp"
#include "ped.hpp"

using namespace H5;

class KSPO : public KS{

public:
    //////////////////////////////////////////////////
    typedef Eigen::SparseMatrix<double> SpMat;
    typedef Eigen::Triplet<double> Tri;
    
    //////////////////////////////////////////////////
    KSPO(int N, double d);
    KSPO & operator=(const KSPO &x);
    ~KSPO();
    
    //////////////////////////////////////////////////
    static
    std::string 
    toStr(string ppType, int id);
    
    static
    std::string
    toStr(double domainSize, string ppType, int id);

    static
    std::tuple<VectorXd, double, int, double, double>
    read(H5File &file, const std::string groupName, const bool isRPO); 

    static
    void 
    write(H5File &file, const std::string groupName, const bool isRPO,
	  const ArrayXd &a, const double T, const int nstp, 
	  const double theta, const double err);
    
    static
    MatrixXd
    readE(H5File &file, const std::string groupName);

    static
    MatrixXd 
    readV(H5File &file, const std::string groupName);
    
    static
    void 
    writeE(H5File &file, const std::string groupName, 
	   const MatrixXd &e);
    
    static
    void 
    writeV(H5File &file, const std::string groupName, 
	   const MatrixXd &v);
    
    static
    void 
    move(H5File &fin, std::string gin, H5File &fout, std::string gout,
	 int flag = 0);
    //////////////////////////////////////////////////
    VectorXd
    MFx(const VectorXd &x, const int nstp, const bool isRPO);
    std::tuple<SpMat, SpMat, VectorXd>
    multiCalJJF(const VectorXd &x, int nstp, const bool isRPO);
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    calJJF(const VectorXd &x, int nstp, const bool isRPO);
    std::tuple<ArrayXXd, double, int>
    findPO_LM(const ArrayXXd &a0, const bool isRPO, const int nstp,		      
	      const double tol, const int maxit, const int innerMaxit);

    std::pair<MatrixXd, MatrixXd>
    calEV(const bool isRPO, const ArrayXd &a0,  const double T, const int nstp, const double theta,
	  const double tol, const int MaxN, const int trunc);
    
};

template<class Mat>
class KSPO_JJF {    
public :
    KSPO *ks;
    bool isRPO;
    int nstp;
    KSPO_JJF(KSPO *ks, int nstp, bool isRPO) : ks(ks), nstp(nstp), isRPO(isRPO){}
    
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    operator()(const VectorXd &x) {
	return ks->calJJF(x, nstp, isRPO);
    }    
};

template<class Mat>
class KSPO_MULTIJJF {    
public:
    KSPO *ks;
    bool isRPO;
    int nstp;
    KSPO_MULTIJJF(KSPO *ks, int nstp, bool isRPO) : ks(ks), nstp(nstp), isRPO(isRPO) {}
    
    std::tuple<KSPO::SpMat, KSPO::SpMat, VectorXd>
    operator()(const VectorXd &x) {
	return ks->multiCalJJF(x, nstp, isRPO);
    }    
};
    

#endif	/* KSPO_H */
<file_sep>import matplotlib.pyplot as plt
import matplotlib.cm as cm
from numpy import *
import scipy.io as sio
from mpl_toolkits.mplot3d import Axes3D

##################################################
# function to add embedded plot
# rect = [ x of left corner, y of left corner, width, height ] in 
# percentage
def add_subplot_axes(ax,rect,axisbg='w'):
    fig = plt.gcf()
    box = ax.get_position()
    width = box.width
    height = box.height
    inax_position  = ax.transAxes.transform(rect[0:2])
    transFigure = fig.transFigure.inverted()
    infig_position = transFigure.transform(inax_position)    
    x = infig_position[0]
    y = infig_position[1]
    width *= rect[2]
    height *= rect[3]  # <= Typo was here
    subax = fig.add_axes([x,y,width,height],axisbg=axisbg)
    x_labelsize = subax.get_xticklabels()[0].get_size()
    y_labelsize = subax.get_yticklabels()[0].get_size()
    x_labelsize *= rect[2]**0.5
    y_labelsize *= rect[3]**0.5
    subax.xaxis.set_tick_params(labelsize=x_labelsize)
    subax.yaxis.set_tick_params(labelsize=y_labelsize)
    return subax
##################################################
# load data
ixRange = range(22,29); #ixRange.insert(0, 0);
N = len(ixRange)

fileName = ['ang'+ str(i) + '.txt' for i in ixRange]

a = []; b = []; angNum = []; angSpan = [];
ns = 1000;
for i in range(N):
    print i
    ang = arccos(loadtxt(fileName[i]))
    angNum.append(ang.shape[0])
    angSpan.append(max(ang)-min(ang))
    at, bt = histogram(ang, ns);
    a.append(at); b.append(bt);
##################################################
# plot 
fig = plt.figure(figsize = (7,5))
ax = fig.add_subplot(111)

ReverseAngle = False;

colors = cm.rainbow(linspace(0, 1, N))
labs = ['(1-' + str(i+1) + ',' + str(i+2) + '-30)' for i in ixRange]
labx =[pi/16, pi/8*1.1, pi/8*0.9, pi/8*3*0.9, pi/2*0.8]
laby =[0.9, 0.02, 0.1, 0.05, 0.005]

if(ReverseAngle):
    for i in range(N):
        b[i] = 1/b[i]
    ax2 = add_subplot_axes(ax, [0.6, 0.1, 0.4, 0.5])
    ax2.set_xlim(0,200)
    ax.set_xlabel(r'$1/\theta$',size='large')
else:
    ax.set_xlabel(r'$\theta$',size='large')
    ax.set_xticks([0., .125*pi, 0.25*pi, 0.375*pi])
    ax.set_xticklabels(["$0$", r"$\frac{1}{8}\pi$", r"$\frac{2}{8}\pi$",
                        r"$\frac{3}{8}\pi$"])

for i in range(N):
    ax.scatter(b[i][:-1], a[i]*ns/(angSpan[i]*angNum[i]), s = 7, 
               c = colors[i], edgecolor='none', label=labs[i])
    #if(not ReverseAngle):
        #ax.text(labx[i], laby[i], labs[i])

ax.legend(fontsize='small', loc='upper center', ncol = 2,
          bbox_to_anchor=(1.11, 1), fancybox=True)
ax.set_yscale('log')
ax.set_ylim([0.001, 1000])
#ax.set_title('(a)')
ax.set_ylabel(r'$\rho(\theta)$',size='large')

if(ReverseAngle):
    ax2.scatter(b[0][:-1], a[0]*ns/max(ang[0])/ang[0].shape[0], s = 7, 
               c = colors[0], edgecolor='none')
    #ax2.scatter(b[2][:-1], a[2]*ns/max(ang[2])/ang[2].shape[0], s = 7, 
    #           c = colors[2], edgecolor='none')
    ax2.set_yscale('log')

plt.tight_layout(pad=0)
plt.show()

<file_sep>from cglHelp import *
from py_CQCGL1d import *

case = 44

labels = ["IF4(3)", "IF5(4)",
          "ERK4(3)2(2)", "ERK4(3)3(3)", "ERK4(3)4(3)", "ERK5(4)5(4)",
          "SS4(3)"]
mks = ['o', 's', '+', '^', 'x', 'v', 'p']
Nscheme = len(labels)
lss = ['--', '-.', ':', '-', '-', '-', '-']

if case == 10:
    lte = np.loadtxt('data/N10_lte.dat')
    T = 10.25
    n = lte.shape[0]
    fig, ax = pl2d(labs=[r'$t$', r'$LTE$'], yscale='log', xlim=[0, 2*T])
    for i in range(6):
        ax.plot(np.linspace(0, 2*T, n), lte[:, i], lw=2, label=labels[i])
    ax2d(fig, ax)
        
if case == 20:
    ltes = []
    for i in range(3):
        k = 10**i
        lte = np.loadtxt('data/KS_N20_lte' + str(k) + '.dat')
        ltes.append(lte)
    T = 10.25
    
    fig, ax = pl2d(labs=[r'$t$', r'$LTE$'], yscale='log', xlim=[0, T])
    k = 5
    for i in range(3):
        n = len(ltes[i][:, k])
        ax.plot(np.linspace(0, T, n), ltes[i][:, k], lw=2)
    ax2d(fig, ax)

    fig, ax = pl2d(labs=[r'$t$', r'$LTE$'], yscale='log', xlim=[0, 2*T])
    k = 1
    for i in range(Nscheme):
        n = len(ltes[k][:, i])
        ax.plot(np.linspace(0, 2*T, n), ltes[k][:, i], lw=2, label=labels[i])
    ax2d(fig, ax)

if case == 30:
    err = np.loadtxt('data/KS_N30_err.dat')
    h = err[:, 0]
    fig, ax = pl2d(size=[6, 5], labs=[r'$h$', 'relative error'],
                   axisLabelSize=20, tickSize=15,
                   xlim=[5e-5, 4e-1],
                   xscale='log', yscale='log')
    for i in range(Nscheme):
        ax.plot(h, err[:, i+1], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.plot([1e-2, 1e-1], [1e-10, 1e-6], lw=2, c='k', ls='--')
    ax.plot([4e-2, 4e-1], [1e-11, 1e-6], lw=2, c='k', ls='--')
    # ax.grid(True, which='both')
    ax.locator_params(axis='y', numticks=4)
    ax2d(fig, ax)

###############################################################################
# 1d cqcgl
if case == 40:
    """
    plot 1d cqcgl of heat map / configuration figure for the const time step,
    time step adaption and comoving frame methods
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    cp = CQCGLplot(cgl)

    ###################
    # the case with constant time step
    ################### 
    aa = np.loadtxt('data/aa.dat')

    # plot the heat map
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    fig, ax = pl2d(size=[4, 5], labs=[r'$x$', r'$t$'], axisLabelSize=25, tickSize=18)
    im = ax.imshow(Aamp, cmap=plt.get_cmap('jet'), extent=[0, d, 0, 20],
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    ax2d(fig, ax)

    # plot a single state
    numOfState = aa.shape[0]
    fig, ax = pl2d(size=[6, 5], labs=[r'$x$', r'$|A|$'], 
                   ylim=[0, 3.5],
                   axisLabelSize=25, tickSize=18)
    A = cgl.Fourier2Config(aa[int(10./20 * numOfState)])
    Aamp = np.abs(A)
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=3, ls='--', c='r')
    A = cgl.Fourier2Config(aa[int(7.0/20 * numOfState)])
    Aamp = np.abs(A)
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2, ls='-', c='b')
    ax.locator_params(axis='y', nbins=4)
    ax2d(fig, ax)

    ###################
    # the case with static frame time step adaption
    ################### 
    aa = np.loadtxt('data/aaAdapt_Cox_Matthews.dat')
    Ts = np.loadtxt('data/TsAdapt_Cox_Matthews.dat')
    
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    fig, ax = pl2d(size=[4, 5], labs=[r'$x$', r'$t$'], axisLabelSize=25, tickSize=18)
    im = ax.imshow(Aamp, cmap=plt.get_cmap('jet'), extent=[0, d, 0, 20],
                   aspect='auto', origin='lower')
    yls = [0, 5, 10, 15, 20]
    ids = [bisect_left(Ts, yl) for yl in yls]
    yts = [x / float(Ts.size) * 20 for x in ids]
    ax.set_yticks(yts)
    ax.set_yticklabels(yls)
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    ax2d(fig, ax)

    aa = np.loadtxt('data/aaAdapt_SSPP43.dat')
    Ts = np.loadtxt('data/TsAdapt_SSPP43.dat')
    
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    fig, ax = pl2d(size=[4, 5], labs=[r'$x$', r'$t$'], axisLabelSize=25, tickSize=18)
    im = ax.imshow(Aamp, cmap=plt.get_cmap('jet'), extent=[0, d, 0, 20],
                   aspect='auto', origin='lower')
    yls = [0, 5, 10, 15, 20]
    ids = [bisect_left(Ts, yl) for yl in yls]
    yts = [x / float(Ts.size) * 20 for x in ids]
    ax.set_yticks(yts)
    ax.set_yticklabels(yls)
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    ax2d(fig, ax)

    ###################
    # the case with comoving frame time step adaption
    ################### 
    aa = np.loadtxt('data/aaCom.dat')
    Ts = np.loadtxt('data/TsCom.dat')
    
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    fig, ax = pl2d(size=[4, 5], labs=[r'$x$', r'$t$'], axisLabelSize=25, tickSize=18)
    im = ax.imshow(Aamp, cmap=plt.get_cmap('jet'), extent=[0, d, 0, 20],
                   aspect='auto', origin='lower')
    yls = [0, 5, 10, 15, 20]
    ids = [bisect_left(Ts, yl) for yl in yls]
    yts = [x / float(Ts.size) * 20 for x in ids]
    ax.set_yticks(yts)
    ax.set_yticklabels(yls)
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size='5%', pad=0.05)
    plt.colorbar(im, cax=cax, ticks=[0, 1, 2, 3])
    ax2d(fig, ax)
    
    ####################
    # plot the high frequency phase rotation
    ####################
    aa = np.loadtxt('data/a0NoAdapt.dat')
    fig = plt.figure(figsize=[6, 5])
    ax = fig.add_subplot('111')
    ax.set_xlabel(r'$t$', fontsize=25)
    ax.set_ylabel(r'$Re(a_0)$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    ax.plot(np.linspace(0, 20, aa.size), aa, lw=1, c='r')
    plt.tight_layout(pad=0)
    plt.show(block=False)

    ####################
    # plot the phase rotation and the profile of req
    ####################
    aa = np.loadtxt('data/a0ComNoAdapt.dat')
    req = CQCGLreq(cgl)
    a0, wth0, wphi0, err0 = req.readReqBiGi('../../data/cgl/reqBiGi.h5',
                                            Bi, Gi, 1)
    AA = cgl.Fourier2Config(a0)
    Aamp = np.abs(AA)    
    
    fig = plt.figure(figsize=[12, 5])
    ax = fig.add_subplot('121')
    ax.text(0.1, 0.9, '(a)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xlabel(r'$x$', fontsize=25)
    ax.set_ylabel(r'$|A|$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    ax.plot(np.linspace(0, d, Aamp.shape[0]), Aamp, lw=2)

    ax = fig.add_subplot('122')
    ax.text(0.1, 0.9, '(b)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xlabel(r'$t$', fontsize=25)
    ax.set_ylabel(r'$Re(\tilde{a}_0)$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    ax.plot(np.linspace(0, 20, aa.size), aa, lw=1, c='r')

    plt.tight_layout(pad=0)
    plt.show(block=False)

if case == 44:
    """
    transform  data in case 40 
    """
    N, d = 1024, 50
    
    # 1st
    cgl = pyCQCGL1d(N, d, -0.1, 0.08, 0.5, 0.782, 1, -0.1, -0.08, -1)
    pulsate = np.load('data/pulsatingSoliton.npz')
    aa, aa2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    AA2 = cgl.Fourier2Config(aa2)
    Aamp2 = np.abs(AA2)
    np.savez_compressed('data/pulsatingSolitonAmp.npz', states=Aamp, statesAdapt=Aamp2, Ts=Ts, T=T)

    # 2nd
    Bi, Gi = 3.5, -5.0
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    pulsate = np.load('data/extremeSoliton.npz')
    aa, aa2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    AA2 = cgl.Fourier2Config(aa2)
    Aamp2 = np.abs(AA2)
    np.savez_compressed('data/extremeSolitonAmp.npz', states=Aamp, statesAdapt=Aamp2, Ts=Ts, T=T)

    # 3rd
    Bi, Gi = 0.8, -0.6
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    aa = np.loadtxt('data/aa.dat')
    aa2 = np.loadtxt('data/aaAdapt_Cox_Matthews.dat')
    Ts = np.loadtxt('data/TsAdapt_Cox_Matthews.dat')
    T = 20
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    AA2 = cgl.Fourier2Config(aa2)
    Aamp2 = np.abs(AA2)
    np.savez_compressed('data/explodingSolitonAmp.npz', states=Aamp, statesAdapt=Aamp2, Ts=Ts, T=T)

if case == 45:
    """
    plot fence instead of heat
    """
    N, d = 1024, 50
    fig = plt.figure(figsize=[15, 4])
    
    # 1st
    ax = ax3dinit(fig, num=131, labs=[r'$x$', r'$t$', r'$|A|$'], axisLabelSize=20, tickSize=12)
    ax.text2D(0.3, 0.9, '(a)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=18)
    cgl = pyCQCGL1d(N, d, -0.1, 0.08, 0.5, 0.782, 1, -0.1, -0.08, -1)
    skipRate = 1
    pulsate = np.load('data/pulsatingSoliton.npz')
    aa, aa2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    Aamp = Aamp[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_yticks([0, 30, 60])
    ax.set_zticks([0, 3])
    ax.view_init(75, -50)
    
    # 2nd
    ax = ax3dinit(fig, num=132, labs=[r'$x$', r'$t$', r'$|A|$'], axisLabelSize=20, tickSize=12)
    ax.text2D(0.3, 0.9, '(b)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=18)
    Bi, Gi = 3.5, -5.0
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    skipRate = 1
    pulsate = np.load('data/extremeSoliton.npz')
    aa, aa2, Ts, T = pulsate['states'], pulsate['statesAdapt'], pulsate['Ts'], pulsate['T']
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    Aamp = Aamp[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_ylim([0, 13])
    ax.set_yticks([0, 5, 10])
    ax.set_zticks([0, 1])
    ax.view_init(60, -40)

    # 3rd
    ax = ax3dinit(fig, num=133, labs=[r'$x$', r'$t$', r'$|A|$'], axisLabelSize=20, tickSize=12)
    ax.text2D(0.3, 0.9, '(c)', horizontalalignment='center',
              transform=ax.transAxes, fontsize=18)
    Bi, Gi = 0.8, -0.6
    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    skipRate = 5
    aa = np.loadtxt('data/aa.dat')
    T = 20
    AA = cgl.Fourier2Config(aa)
    Aamp = np.abs(AA)
    Aamp = Aamp[::skipRate, :]
    rows, cols = Aamp.shape
    X = np.linspace(0, d, cols)
    Y = np.linspace(0, T, rows)
    for i in range(Aamp.shape[0]):
        ax.plot(X, np.ones(cols) * Y[i], Aamp[i], c='k', alpha=1)
    
    ax.set_ylim([0, 13])
    ax.set_yticks([0, 5, 10])
    ax.set_zticks([0, 3])
    ax.view_init(75, -80)
    
    ############
    ax3d(fig, ax)
    

if case == 50:
    """
    plot the relative errors of 1d cgcgl by constant schemes
    """
    err = np.loadtxt('data/cqcgl1d_N20_err.dat')
    h = err[:, 0]
    fig, ax = pl2d(size=[6, 5], labs=[r'$h$', None],
                   axisLabelSize=20, tickSize=15,
                   xlim=[3e-5, 3e-2],
                   ylim=[1e-11, 1e1],
                   xscale='log', yscale='log')
    for i in range(Nscheme):
        ax.plot(h, err[:, i+1], lw=1.5, marker=mks[i], mfc='none',
                label=labels[i])
    ax.plot([1e-4, 1e-2], [1e-8, 1e0], lw=2, c='k', ls='--')
    ax.plot([2e-3, 2e-2], [1e-9, 1e-4], lw=2, c='k', ls='--')
    # ax.grid(True, which='both')
    ax.locator_params(axis='y', numticks=5)
    ax2d(fig, ax, loc='upper left')

if case == 60:
    """
    plot the estimated local error of 1d cgcgl by constant schemes
    """
    err = np.loadtxt('data/cqcgl1d_N30_lte.dat')
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    n = err.shape[0]
    T = 20.0
    x = np.arange(1, n+1) * T/n
    
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'estimated local error'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   ylim=[1e-17, 1e-7],
                   yscale='log')
    for i in range(Nscheme):
        ax.plot(x, err[:, i], lw=1.5, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='lower right')

    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'estimated local error'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   ylim=[1e-30, 1e-8],
                   yscale='log')
    for i in range(Nscheme):
        ax.plot(x, err[:, Nscheme+i], lw=2, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=4)
    ax.locator_params(axis='x', nbins=5)
    ax2d(fig, ax, loc='lower right')

if case == 70:
    """
    plot the time steps used in the process
    """
    hs = []
    for i in range(Nscheme):
        x = np.loadtxt('data/cqcgl1d_N50_hs_' + str(i) + '.dat')
        hs.append(x)
    
    T = 20.0
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'$h$'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   ylim=[2e-5, 2e-3],
                   yscale='log')
    for i in range(Nscheme):
        n = len(hs[i])
        x = np.arange(1, n+1) * T/n
        ax.plot(x, hs[i], lw=2, ls=lss[i], label=labels[i])
    # ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='upper left')
    
if case == 80:
    """
    same as case 70 but in comoving frame
    plot the time steps used in the process
    """
    hs = []
    for i in range(Nscheme):
        x = np.loadtxt('data/cqcgl1d_N60_comoving_hs_' + str(i) + '.dat')
        hs.append(x)
    
    T = 20.0
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'$h$'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   ylim=[8e-6, 2e-2],
                   yscale='log')
    for i in range(Nscheme):
        n = len(hs[i])
        x = np.arange(1, n+1) * T/n
        ax.plot(x, hs[i], lw=1.5, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='upper left')

if case == 90:
    """
    static & comoving frame
    plot the relative error, Nab, Nn vs rtol
    """
    loadFlag = 0

    err = np.loadtxt('data/cqcgl1d_N70_stat' + ('0' if loadFlag == 0 else '1') + '.dat')
    rtol = err[:, 0]
    
    fig = plt.figure(figsize=[12, 15])
    
    # plot relative error
    ax = fig.add_subplot('321')
    ax.text(0.5, 0.9, '(a)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel('relative error', fontsize=15)
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 6*i+1], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='bottem right', fontsize=12)
    
    # plot Nab
    ax = fig.add_subplot('322')
    ax.text(0.5, 0.9, '(b)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Nab$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(2, 6):
        ax.plot(rtol, err[:, 6*i+2], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', nbins=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='right', fontsize=12)

    # plot Nn
    ax = fig.add_subplot('323')
    ax.text(0.1, 0.9, '(c)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Nn$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 6*i+3], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper right', fontsize=12)

    # plot NReject
    ax = fig.add_subplot('324')
    ax.text(0.9, 0.9, '(d)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    # ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'number of rejections', fontsize=15)
    ax.set_ylim([0, 80] if loadFlag == 0 else [0, 250])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 6*i+4], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper left', ncol=2, fontsize=12)

    # plot Wt
    ax = fig.add_subplot('325')
    ax.text(0.1, 0.9, '(e)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Wt$', fontsize=20)
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 6*i+5], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper right', fontsize=12)

    # plot time of calculating coefficients / Wt
    ax = fig.add_subplot('326')
    ax.text(0.07, 0.9, '(f)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'time ratio', fontsize=15)
    ax.set_ylim([1e-6, 2e0])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 6*i+6]/err[:, 6*i+5], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='lower right', fontsize=12)

    ## 
    fig.tight_layout(pad=1)
    plt.show(block=False)

if case == 68:
    """
    comoving frame
    plot the relative error, Nab, Nn vs rtol
    """
    err = np.loadtxt('data/cqcgl1d_N70_comoving.dat')
    rtol = err[:, 0]
    
    # plot relative error
    fig, ax = pl2d(size=[6, 5], labs=[r'$rtol$', 'relative error'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   ylim=[1e-9, 4e-0],
                   xscale='log',
                   yscale='log')
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 4*i+1], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax2d(fig, ax, loc='lower right')
    
    # plot Nab
    fig, ax = pl2d(size=[6, 5], labs=[r'$rtol$', r'$Nab$'],
                   axisLabelSize=20, tickSize=15,
                   ylim=[500, 4000],
                   # yscale='log',
                   xscale='log')
    for i in range(4):
        ax.plot(rtol, err[:, 4*i+2], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', nbins=5)
    ax.locator_params(axis='x', numticks=5)
    ax2d(fig, ax, loc='upper left')

    # plot Nn
    fig, ax = pl2d(size=[6, 5], labs=[r'$rtol$', r'$Nn$'],
                   axisLabelSize=20, tickSize=15,
                   ylim=[4e4, 1e9],
                   xscale='log', yscale='log')
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 4*i+3], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax2d(fig, ax, loc='upper right')

    # plot Wt
    fig, ax = pl2d(size=[6, 5], labs=[r'$rtol$', r'$Wt$'],
                   axisLabelSize=20, tickSize=15,
                   ylim=[2e0, 1e4],
                   xscale='log', yscale='log')
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 4*i+4], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax2d(fig, ax, loc='upper right')

if case == 120:
    """
    Compare the accuracy of static and comoving frames
    """
    err = np.loadtxt('data/cqcgl1d_N70_stat0.dat')
    err2 = np.loadtxt('data/cqcgl1d_N70_stat1.dat')
    rtol = err[:, 0]

    for i in range(2, 6):
        fig, ax = pl2d(size=[6, 5], labs=[r'$rtol$', 'relative error'],
                       axisLabelSize=20, tickSize=15,
                       # xlim=[1e-8, 5e-3],
                       ylim=[1e-9, 4e-0],
                       xscale='log',
                       yscale='log')
        ax.plot(rtol, err[:, 4*i+1], lw=1.5, marker=mks[0], mfc='none',
                ms=8, label='static')
        ax.plot(rtol, err2[:, 4*i+1], lw=1.5, marker=mks[1], mfc='none',
                ms=8, label='comoving')
        ax.locator_params(axis='y', numticks=5)
        ax.locator_params(axis='x', numticks=5)
        ax.text(0.3, 0.9, labels[i], fontsize=15, horizontalalignment='center',
                verticalalignment='center',  bbox=dict(ec='black', fc='none'),
                transform=ax.transAxes)
        ax2d(fig, ax, loc='upper right')

<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "ksint.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


class pyKS : public KS {
  
public:
    pyKS(int N, double d) : KS(N, d) {}
    
    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }
    
    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

    /* wrap the integrator */
    bn::ndarray PYintgC(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);

	return copy2bn(intgC(tmpa, h, tend, skip_rate));
    }

    /* wrap the integrator with Jacobian */
    bp::tuple PYintgjC(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	auto tmpav = intgjC(tmpa, h, tend, skip_rate);
	
	return bp::make_tuple(copy2bn(tmpav.first), copy2bn(tmpav.second));
    }

    bn::ndarray PYintg(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	return copy2bn(intg(tmpa, h, tend, skip_rate));
    }

    bp::tuple PYintgj(bn::ndarray a0, double h, double tend, int skip_rate){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	auto result = intgj(tmpa, h, tend, skip_rate);
	
	return bp::make_tuple(copy2bn(result.first), copy2bn(result.second));
    }

    /* wrap the velocity */
    bn::ndarray PYvelocity(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);

	return copy2bn(velocity(tmpa));
    }
    
    bn::ndarray PYvelReq(bn::ndarray a0, double theta){
	int m, n;
	getDims(a0, m, n);
	Map<VectorXd> tmpa((double*)a0.get_data(), n*m);
	
	return copy2bn(velReq(tmpa, theta));
    }
    
    /* stab */
    bn::ndarray PYstab(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXd> tmpa((double*)a0.get_data(), n*m);
	
	return copy2bn(stab(tmpa));
    }

    bn::ndarray PYstabReq(bn::ndarray a0, double theta){
	int m, n;
	getDims(a0, m, n);
	Map<VectorXd> tmpa((double*)a0.get_data(), n*m);
	
	return copy2bn(stabReq(tmpa, theta));
    }
    
    /* reflection */
    bn::ndarray PYreflect(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);	
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(reflect(tmpaa));
    }

    /* half2whole */
    bn::ndarray PYhalf2whole(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(half2whole(tmpaa));
    }

    /* Rotation */
    bn::ndarray PYrotate(bn::ndarray aa, const double th){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXd> tmpaa((double*)aa.get_data(), n, m);
	return copy2bn(rotate(tmpaa, th));
    }
        
    bp::tuple PYredSO2(bn::ndarray aa, int p, bool toY){
	int m, n;
	getDims(aa, m, n);
	Map<MatrixXd> tmpaa((double*)aa.get_data(), n, m);
	
	auto tmp = redSO2(tmpaa, p, toY);
	return bp::make_tuple(copy2bn(tmp.first), copy2bn(tmp.second));
    }

    bp::tuple PYfundDomain(bn::ndarray aa, int pSlice, int pFund){
	int m, n;
	getDims(aa, m, n);
	Map<MatrixXd> tmpaa((double*)aa.get_data(), n, m);
	
	auto tmp = fundDomain(tmpaa, pSlice, pFund);
	return bp::make_tuple( copy2bn(tmp.first), copy2bn<ArrayXXi, int>(tmp.second));
    }
    
    bp::tuple PYredO2f(bn::ndarray aa, int pSlice, int pFund){
	int m, n;
	getDims(aa, m, n);
	Map<MatrixXd> tmpaa((double*)aa.get_data(), n, m);
	
	auto tmp = redO2f(tmpaa, pSlice, pFund);
	return bp::make_tuple( copy2bn(std::get<0>(tmp)),
			       copy2bn<ArrayXXi, int>(std::get<1>(tmp)),
			       copy2bn(std::get<2>(tmp))
			       );
    }
    
    bn::ndarray PYredV(bn::ndarray v, bn::ndarray a, int p, bool toY){
	int m, n;
	getDims(v, m, n);
	Map<MatrixXd> tmpv((double*)v.get_data(), n, m);
	getDims(a, m, n);
	Map<VectorXd> tmpa((double*)a.get_data(), n * m);

	return copy2bn( redV(tmpv, tmpa, p, toY) );
    }
    
    bn::ndarray PYcalMag(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<MatrixXd> tmpaa((double*)aa.get_data(), n, m);
	
	return copy2bn(calMag(tmpaa));
    }

    bp::tuple PYtoPole(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<MatrixXd> tmpaa((double*)aa.get_data(), n, m);

	auto tmp = toPole(tmpaa);
	return bp::make_tuple(copy2bn(tmp.first), 
			      copy2bn(tmp.second)
			      );
    }

};

//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////


BOOST_PYTHON_MODULE(py_ks) {
    bn::initialize();    
    bp::class_<KS>("KS", bp::init<int, double>()) ;

    // the EIDr class
    bp::class_<EIDr>("EIDr", bp::init<>())
	.def_readonly("NCalCoe", &EIDr::NCalCoe)
	.def_readonly("NReject", &EIDr::NReject)
	.def_readonly("NCallF", &EIDr::NCallF)
	.def_readonly("NSteps", &EIDr::NSteps)
	.def_readonly("TotalTime", &EIDr::TotalTime)
	.def_readonly("CoefficientTime", &EIDr::CoefficientTime)
	.def_readwrite("rtol", &EIDr::rtol)
	;
    
    bp::class_<pyKS, bp::bases<KS> >("pyKS", bp::init<int, double>())
	.def_readonly("N", &pyKS::N)
	.def_readonly("d", &pyKS::d)
	.def_readwrite("eidr", &pyKS::eidr)
	.def_readwrite("eidr2", &pyKS::eidr2)
	.def("Ts", &pyKS::PYTs)
	.def("hs", &pyKS::PYhs)
	.def("lte", &pyKS::PYlte)
	.def("intgC", &pyKS::PYintgC)
	.def("intgjC", &pyKS::PYintgjC)
	.def("intg", &pyKS::PYintg)
	.def("intgj", &pyKS::PYintgj)
	.def("velocity", &pyKS::PYvelocity)
	.def("velReq", &pyKS::PYvelReq)
	.def("stab", &pyKS::PYstab)
	.def("stabReq", &pyKS::PYstabReq)
	.def("reflect", &pyKS::PYreflect)
	.def("half2whole", &pyKS::PYhalf2whole)
	.def("rotate", &pyKS::PYrotate)
	.def("redSO2", &pyKS::PYredSO2)
	.def("fundDomain", &pyKS::PYfundDomain)
	.def("redO2f", &pyKS::PYredO2f)
	.def("redV", &pyKS::PYredV)
	.def("calMag", &pyKS::PYcalMag)
	.def("toPole", &pyKS::PYtoPole)
	;

}
<file_sep># usage: make t=***

CC = g++
AR = ar

OPTIM = -O3 -msse2 -msse4 -march=corei7
INCLUDE = ../../include
EIGEN = /usr/local/home/xiong/apps/eigen/include/eigen3
CFLAGS = -std=c++11 -DEIGEN_FFTW_DEFAULT # -Wfatal-errors

ifndef t
t = int
endif

ifeq ($(t), int)
SOURCE = ksint.cc 

else ifeq ($(t), po)
SOURCE = KSPO.cc

else ifeq ($(t), dim)
SOURCE = ksdim.cc

else ifeq ($(t), fefv)
SOURCE = ksFEFV.cc

else ifeq ($(t), refine)
SOURCE = ksrefine.cc

endif

SHARED = $(addprefix lib, $(addsuffix .so, $(basename $(word 1, $(SOURCE)))))
STATIC = $(addprefix lib, $(addsuffix .a, $(basename $(word 1, $(SOURCE)))))

all : $(SHARED) # $(STATIC) 

$(SHARED): $(SOURCE)
	$(CC) -shared -fpic $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^ -o $@
$(SOURCE:.cc=.o) : $(SOURCE)
	$(CC) -c $(CFLAGS) $(OPTIM) -I$(INCLUDE) -I$(EIGEN) $^
$(STATIC): $(SOURCE:.cc=.o)
	$(AR) crs $@ $^

clean:
	rm -f *.so *.o *.a
move:
	mv *.so *.a /usr/local/home/xiong/00git/research/lib
<file_sep>from personalFunctions import *
from personalPlotly import *

case = 2

if case == 1:
    x, y, z = np.random.rand(3, 10)
    trace1 = go.Scatter3d(
        x=x,
        y=y,
        z=z,
        mode='lines+markers',
        marker=dict(
            size=12,
            line=dict(
                color='rgba(217, 217, 217, 0.14)',
                width=0.5
            ),
            opacity=0.8
        ),
        name='$\\theta$'
    )

    layout = go.Layout(
        scene=go.Scene(
            xaxis=dict(
                title='$\\theta$',
                showbackground=True,
                backgroundcolor='rgb(230, 230,230)'
            ),
            yaxis=dict(
                title='$Y$',
                showbackground=True,
                backgroundcolor='rgb(230, 230,230)'
            ),
            zaxis=go.ZAxis(title='z axis title')
        ),
        margin=dict(
            b=0,
            l=0,
            r=0,
            t=0
        ),
        showlegend=True,
    )
    fig = go.Figure(data=[trace1], layout=layout)
    py.plot(fig, filename='ex1', fileopt='overwrite')
    # plot_url = py.plot_mpl(fig, filename='ex1', fileopt='overwrite')

if case == 2:
    x, y, z = rand(3, 10)
    ptly3d(0, 1, 2, 'ex2', plotType=2, ls='dot')
    # ptly3d(x, y, z, 'ex2', plotType=2, ls='dot')
<file_sep># This makefile tries to compile the shared library for matlab
# You should note the difference with the ordinary C/C++ complilation procedure.
# 
#  1) As with Boost.Python, mex cannot deal with shared linkages, so except the bottom
#     library, all other source files must be compiled.
#     

CC = mex
CXX = '/usr/bin/g++-4.7'
CXXFLAGS = '-std=c++11 -fPIC -O3'
CXXFLAGS_THREADS = '-std=c++11 -fPIC -O3 -DTFFT'


INCLUDE = -I../../../include -I/usr/local/home/xiong/apps/eigen/include/eigen3
LIB = -L../../../lib -L/usr/lib/x86_64-linux-gnu
LINK = -lm -lfftw3_threads -lfftw3 -lped -lsparseRoutines -ldenseRoutines -literMethod


SOURCE = ../cqcgl1d.cc ../../myfft/myfft.cc


all : cqcglIntgv cqcglNdim cqcglGintgv

cqcglIntgv : cqcglIntgv.cpp $(SOURCE)
	$(CC) CXX=$(CXX) CXXFLAGS=$(CXXFLAGS_THREADS) $(INCLUDE) $(LIB) $(LINK) $^
	mv $@.mexa64 $@_threads.mexa64
	$(CC) CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) $(INCLUDE) $(LIB) $(LINK) $^

cqcglNdim : cqcglNdim.cpp $(SOURCE)
	$(CC) CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) $(INCLUDE) $(LIB) $(LINK) $^

cqcglGintgv : cqcglGintgv.cpp $(SOURCE)
	$(CC) CXX=$(CXX) CXXFLAGS=$(CXXFLAGS_THREADS) $(INCLUDE) $(LIB) $(LINK) $^
	mv $@.mexa64 $@_threads.mexa64
	$(CC) CXX=$(CXX) CXXFLAGS=$(CXXFLAGS) $(INCLUDE) $(LIB) $(LINK) $^

clean:
	rm -f *.mexa64
move:
	mv *.mexa64  /usr/local/home/xiong/00git/research/lib/mex
<file_sep>import sympy as sp

sp.init_printing()
ap, am = sp.symbols('a_+, a_-')
print sp.Integral(1/ap, ap)
<file_sep>#include <iostream>
#include <functional>
#include "CQCGL2dReq.hpp"
#include "iterMethod.hpp"

#define cee(x) (cout << (x) << endl << endl)

namespace ph = std::placeholders;

using namespace std;
using namespace Eigen;
using namespace iterMethod;
using namespace denseRoutines;
using namespace MyH5;

//////////////////////////////////////////////////////////////////////
//                      constructor                                 //
//////////////////////////////////////////////////////////////////////
CQCGL2dReq::CQCGL2dReq(int N, int M, double dx, double dy,
		       double Mu, double Dr, double Di,
		       double Br, double Bi, double Gr,
		       double Gi,  
		       int threadNum)
    :CQCGL2d(N, M, dx, dy, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum)
{
    calPre();
}


CQCGL2dReq::CQCGL2dReq(int N, double dx,
		       double Mu, double Dr, double Di,
		       double Br, double Bi, double Gr,
		       double Gi,  
		       int threadNum)
    : CQCGL2d(N, dx, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) 
{
    calPre();
}

CQCGL2dReq::CQCGL2dReq(int N, int M, double dx, double dy,
		       double b, double c, double dr, double di,
		       int threadNum) 
    : CQCGL2d(N, M, dx, dy, b, c, dr, di, threadNum) 
{
    calPre();
}

CQCGL2dReq::CQCGL2dReq(int N, double dx,
		       double b, double c, double dr, double di,
		       int threadNum)
    : CQCGL2d(N, dx, b, c, dr, di, threadNum)
{
    calPre();
}

CQCGL2dReq & CQCGL2dReq::operator=(const CQCGL2dReq &x){
    return *this;
}

CQCGL2dReq::~CQCGL2dReq(){}

//////////////////////////////////////////////////////////////////////
//                      member functions                            //
//////////////////////////////////////////////////////////////////////

void 
CQCGL2dReq::calPre(){    
    Lu = unpad(L);
    Tx = (dcp(0, 1) * Kx2).replicate(1, Me).transpose();
    Ty = (dcp(0, 1) * Ky2).replicate(1, Ne);
    Tp = dcp(0, 1) * ArrayXXd::Ones(Me, Ne);
}

VectorXd
CQCGL2dReq::Fx(const VectorXd &x){
    assert(x.size() == 2*Ne*Me + 3);

    Vector3d th = x.tail<3>();	// wthx, wthy, wphi
    VectorXd ra = x.head(2*Me*Ne); // use matrix type for resizing
    ArrayXXcd a = r2c(ra);

    ArrayXXcd v = velocityReq(a, th(0), th(1), th(2));

    VectorXd F(2*Ne*Me+3);
    F << c2r(v), 0, 0, 0;
    
    return F;
}

VectorXd
CQCGL2dReq::DFx(const VectorXd &x, const VectorXd &dx){
    assert(x.size() == 2*Ne*Me + 3 && dx.size() == 2*Ne*Me + 3);
    
    Vector3d th = x.tail<3>();	// wthx, wthy, wphi
    Vector3d dth = dx.tail<3>();
    VectorXd ra = x.head(2*Me*Ne);
    VectorXd rda = dx.head(2*Me*Ne); 
    ArrayXXcd a = r2c(ra);
    ArrayXXcd da = r2c(rda); 
    
    ArrayXXcd t1 = tangent(a, 1);
    ArrayXXcd t2 = tangent(a, 2);
    ArrayXXcd t3 = tangent(a, 3);

    ArrayXXcd Ax = stabReq(a, da, th(0), th(1), th(2)) +
	dth(0) * t1 + dth(1) * t2 + dth(2) * t3;

    double t1x = (t1 * da.conjugate()).sum().real();
    double t2x = (t2 * da.conjugate()).sum().real();
    double t3x = (t3 * da.conjugate()).sum().real();

    VectorXd DF(2*Ne*Me+3);
    DF << c2r(Ax), t1x, t2x, t3x; 

    return DF;
}

std::tuple<ArrayXXcd, double, double, double, double>
CQCGL2dReq::findReq_hook(const ArrayXXcd &x0, const double wthx0, 
			 const double wthy0, const double wphi0){
    HOOK_PRINT_FREQUENCE = hookPrint;
    
    assert(x0.rows() == Me && x0.cols() == Ne);
    
    auto fx = std::bind(&CQCGL2dReq::Fx, this, ph::_1);
    auto dfx = std::bind(&CQCGL2dReq::DFx, this, ph::_1, ph::_2);
    
    VectorXd x(2*Me*Ne+3);
    x << c2r(x0), wthx0, wthy0, wphi0;

    VectorXd xnew;
    std::vector<double> errs;
    int flag;
    auto Pre = [this](const VectorXd &x, const VectorXd &dx){
	Vector3d th = x.tail<3>();
	Vector3d dth = dx.tail<3>();
	VectorXd dra = dx.head(2*Me*Ne);
	ArrayXXcd da = r2c(dra);

	ArrayXXcd px = 1/(Lu + Tx*th(0) + Ty*th(1) + Tp*th(2)) * da;
	VectorXd p(2*Ne*Me+3);
	p << c2r(px), dth;

	return p; 
    };
    std::tie(xnew, errs, flag) = Gmres0HookPre(fx, dfx, Pre, x, tol, minRD, maxit, maxInnIt, 
					       GmresRtol, GmresRestart, GmresMaxit,
					       false, 1); 
    if(flag != 0) fprintf(stderr, "Req not converged ! \n");
    
    Vector3d th = xnew.tail<3>();
    VectorXd y = xnew.head(2*Me*Ne); 
    
    return std::make_tuple(r2c(y), th(0), th(1), th(2), errs.back());
}


/** @brief find the optimal guess of wthx, wthy and wphi for a candidate req
 * 
 *  Let $V = [t1, t2, t3]$ the matrix of group tangent, and $V = QR$.
 *  Then expansion coefficient of vector $x$ is $a = Q^T x$.
 *  So The subtraction should be $Q a$, which is $V R^{-1} a$. Therefore, the
 *  optimal expansion coefficients in V basis is $R^{-1}a$.
 *  
 *  @return    [wthx, wthy, wphi] such that velocityReq(a0, wthx, wthy, wphi) minimal
 */
Vector3d
CQCGL2dReq::optReqTh(const ArrayXXcd &a0){
    ArrayXXcd t1 = tangent(a0, 1);
    ArrayXXcd t2 = tangent(a0, 2);
    ArrayXXcd t3 = tangent(a0, 3);
    ArrayXXcd x = velocity(a0);

    MatrixXd V(2*Me*Ne, 3);
    V << c2r(t1), c2r(t2), c2r(t3);
    MatrixXd Q, R;
    std::tie(Q, R) = QR(V);
    
    Vector3d a = Q.transpose() * c2r(x).matrix();
    Vector3d b =  R.inverse() * a;
    
    return b;
}

<file_sep>from personalFunctions import *
from py_CQCGL1d import *
from py_CQCGL2d import *

labels = ["IFRK4(3)", "IFRK5(4)",
          "ERK4(3)2(2)", "ERK4(3)3(3)", "ERK4(3)4(3)", "ERK5(4)5(4)",
          "SSPP4(3)"]
mks = ['o', 's', '+', '^', 'x', 'v', 'p']
Nscheme = len(labels)
lss = ['--', '-.', ':', '-', '-', '-', '-']

case = 10

if case == 10:
    """
    plot the integration process
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6

    cgl = pyCQCGL2d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4)
    fileName = 'aaSS.h5'
    c2dp = CQCGL2dPlot(d, d)

    c2dp.savePlots(cgl, fileName, 'fig3', plotType=2, size=[12, 6])
    c2dp.makeMovie('fig3')
<file_sep>from personalFunctions import *
from py_ks import *


def getEnoughN(x, nb):
    ma = max(x)
    mi = min(x)
    l = ma - mi
    id = np.floor(nb * (x - mi) / l)
    s = 0
    for i range(len(id)):
        
case = 10

if case == 10:
    N = 64
    d = 22
    h = 0.01

    ks = pyKS(N, d)
    fileName = '../../data/ks22h001t120x64EV.h5'
    poType = 'rpo'
    poId = 1
    
    a0, T, nstp, r, s = KSreadPO(fileName, poType, poId)
    a0H = ks.orbitToSlice(a0)[0]
    FE, FV = KSreadFEFV(fileName, poType, poId)
    FV = FV[0].reshape((30, N-2))
    FVH = ks.veToSlice(FV, a0)
    fv = FVH[[0, 1] + range(3, 30)]  # get rid of group tengent

    aa = ks.aintg(rand(N-2), h, T, 1000000)
    vd = np.zeros((0, N-2))
    for i in range(100):
        if i % 10 == 0:
            print i, vd.shape
        a0E = aa[-1]
        aa = ks.aintg(a0E, h, 500, 1)
        aaH = ks.orbitToSlice(aa)[0]
        div = aaH-a0H
        dis = norm(div, axis=1)
        ix = dis < 0.1
        vd = np.vstack((vd, div[ix]))
        
    x = fv[0] / norm(fv[0])
    x = vd.dot(x)
<file_sep>/* How to compile this program:
 * h5c++ readks.cc ../ped/ped.cc ../ksint/ksint.cc
 * -std=c++0x -I$XDAPPS/eigen/include/eigen3 -I../../include -lfftw3
 * -march=corei7 -msse4 -O3
 */
#ifndef READKS_H
#define READKS_H

#include "ksint.hpp"
#include "ped.hpp"
#include <Eigen/Dense>
#include <tuple>
#include <string>

class ReadKS {

public:
  //////////////////////////////////////////////////
  const std::string fileName; // intial condition H5 file
  const std::string fileNameE; // exponents H5 file
  const std::string fileNameEV; // vectors H5 file
  const int N;	// dimension of eigenvectors. default N = 30
  const int Nks; // truncation number of KS. default Nks = 32
  const double L; // size of KS. default L = 22
  //////////////////////////////////////////////////

  //////////////////////////////////////////////////
  ReadKS(std::string s1, std::string s2, std::string s3, int N = 30,
	 int Nks = 32, double L = 22);
  explicit ReadKS(const ReadKS &x);
  ReadKS & operator=(const ReadKS &x);
  ~ReadKS();
  //////////////////////////////////////////////////

  //////////////////////////////////////////////////
  Eigen::MatrixXi 
  checkExistEV(const std::string &ppType, const int NN);  
  std::tuple<Eigen::ArrayXd, double, double>
  readKSorigin(const std::string &ppType, const int ppId);
  std::tuple<Eigen::ArrayXd, double, double, double, double>
  readKSinit(const std::string &ppType, const int ppId);
  std::tuple<MatrixXd, double, double, double, double>
  readKSinitMulti(const std::string fileName, const std::string &ppType, const int ppId);
  void 
  writeKSinit(const std::string fileName, const std::string ppType, 
	      const int ppId,
	      const std::tuple<ArrayXd, double, double, double, double> ksinit
	      );
  void 
  writeKSinitMulti(const std::string fileName, const std::string ppType, 
		   const int ppId,
		   const std::tuple<MatrixXd, double, double, double, double> ksinit
		   );
  Eigen::MatrixXd
  readKSe(const std::string &ppType, const int ppId);
  Eigen::MatrixXd
  readKSve(const std::string &ppType, const int ppId);
  void 
  writeKSe(const std::string &ppType, const int ppId, 
	   const Eigen::MatrixXd &eigvals, const bool rewrite = false);
  void 
  writeKSev(const std::string &ppType, const int ppId,
	    const Eigen::MatrixXd &eigvals, const Eigen::MatrixXd &eigvecs, 
	    const bool rewrite = false);
  std::pair<MatrixXd, MatrixXd>
  calKSFloquet(const std::string ppType, const int ppId, 
	       const int MaxN = 80000, const double tol = 1e-15,
	       const int nqr = 1, const int trunc = 0);
  std::pair<MatrixXd, MatrixXd>
  calKSFloquetMulti(const std::string fileName, 
		    const std::string ppType, const int ppId, 
		    const int MaxN = 80000, const double tol = 1e-15,
		    const int nqr = 1, const int trunc = 0);
  MatrixXd
  calKSFloquetOnlyE(const std::string ppType, const int ppId, 
		    const int MaxN = 80000, const double tol = 1e-15,
		    const int nqr = 1);
  void 
  calKSOneOrbit( const std::string ppType, const int ppId,
		 const int MaxN  = 80000, const double tol = 1e-15,
		 const bool rewrite = false, const int nqr = 1,
		 const int trunc = 0);
  void 
  calKSOneOrbitOnlyE( const std::string ppType, const int ppId,
		      const int MaxN = 80000, const double tol = 1e-15,
		      const bool rewrite = false, const int nqr = 1);
  std::vector< std::pair<double, int> > 
  findMarginal(const Eigen::Ref<const Eigen::VectorXd> &Exponent);
  Eigen::MatrixXi 
  indexSubspace(const Eigen::Ref<const Eigen::VectorXd> &RCP, 
		const Eigen::Ref<const Eigen::VectorXd> &Exponent);

  //////////////////////////////////////////////////
  
};

#endif	/* READKS_H */
<file_sep>/* to comiple:
 * h5c++ -O3 test_CQCGL2dDislin.cc  -L../../lib -I../../include -I $XDAPPS/eigen/include/eigen3 -std=c++11 -lCQCGL2d -lsparseRoutines -ldenseRoutines -lmyH5 -lmyfft -lfftw3 -lm -lCQCGL2dDislin -ldiscpp
 */
#include "CQCGL2dDislin.hpp"
#include "myH5.hpp"
#include "denseRoutines.hpp"
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <H5Cpp.h>

#define cee(x) (cout << (x) << endl << endl)

#define CASE10


using namespace std;
using namespace Eigen;
using namespace MyH5;
using namespace denseRoutines;

typedef std::complex<double> dcp;

int main(){

    switch(0){
	
    case 1 : {			/* test integrator */
	int N = 1024; 
	double L = 100;
	double di = 0.05;
	CQCGL2dDislin cgl(N, L, 4.0, 0.8, 0.01, di, 4);
	
	VectorXd xs(2); xs << N/4, 3*N/4;
	VectorXd as(2); as << 0.1, 0.1;
	ArrayXXcd A0 = dcp(3, 3)*solitons(N, N, xs, xs, as, as);
	// ArrayXXcd A0 = dcp(3, 3)*soliton(N, N, N/2, N/2, 0.1, 0.1);
	//ArrayXXcd A0 = dcp(3, 0) * center2d(N, N, 0.2, 0.2);
	ArrayXXcd a0 = cgl.Config2Fourier(A0);
	
	cgl.constAnim(a0, 0.001, 10);
	
	break;
    }

    case 2 : { 
	int N = 1024; 
	double L = 100;
	double di = 0.05;
	CQCGL2dDislin cgl(N, L, 4.0, 0.8, 0.01, di, 4);
	
	VectorXd xs(4); xs << N/4, N/4, 3*N/4, 3*N/4;
	VectorXd ys(4); ys << N/4, 3*N/4, N/4, 3*N/4;
	VectorXd as(4); as << 0.1, 0.1, 0.1, 0.1;
	ArrayXXcd A0 = dcp(3, 3)*solitons(N, N, xs, ys, as, as);
	ArrayXXcd a0 = cgl.Config2Fourier(A0);
	
	cgl.constAnim(a0, 0.001, 10);
	break;
    }

	
    case 3 : { 
	int N = 1024; 
	double L = 100;
	double di = 0.05;
	CQCGL2dDislin cgl(N, L, 4.0, 0.8, 0.01, di, 4);
	
	ArrayXXcd A0 = dcp(3, 3)*solitonMesh(N, N, 3, 3, 0.05);
	ArrayXXcd a0 = cgl.Config2Fourier(A0);
	
	cgl.constAnim(a0, 0.001, 10);
	break;
    }

    case 4 : {


    }

    default: {
	fprintf(stderr, "please indicate a valid case number \n");
	}
    }
    
#ifdef CASE10
    // ====================================================================================================
    int N = 1024; 
    double L = 30;
    double di = 0.05;
    CQCGL2dDislin cgl(N, L, 4.0, 0.8, 0.01, di, 4);
	
    ArrayXXcd A0 = Gaussian2d(N, N, N/2, N/2, N/10, N/10, 3) 
	    + Gaussian2d(N, N, N/2, N/4, N/10, N/10, 0.5);
    ArrayXXcd a0 = cgl.Config2Fourier(A0);
	
    cgl.constAnim(a0, 0.001, 10);
    
#endif

    return 0;
}
<file_sep>from py_ks import *
from personalFunctions import *

case = 20

if case == 10:
    """
    use a larger domain size for simulation
    """
    N, L = 128*2, 100
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    T, h = 100, 0.001

    a0 = rand(N-2)
    aa = ks.intg(a0, h, np.int(100/h), 1000000)
    a0 = aa[-1]
    aa = ks.intg(a0, h, np.int(T/h), 5)
    
    ksp.config(aa, [0, L, 0, T], size=[3.6, 6], axisLabelSize=25, tickSize=16)
    ksp.config(aa, [0, L, 0, T], size=[3.4, 6], labs=[None, None], axisLabelSize=25, tickSize=16)

if case == 20:
    """
    use a larger domain size for simulation
    """
    N, L = 128*2, 200
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    T, h = 100, 0.001

    a0 = rand(N-2)
    aa = ks.intg(a0, h, np.int(400/h), 1000000)
    a0 = aa[-1]
    aa = ks.intg(a0, h, np.int(T/h), 5)
    
    ksp.config(aa, [0, L, 0, T], size=[6, 6], axisLabelSize=25, tickSize=16)
    ksp.config(aa, [0, L, 0, T], size=[6, 6], labs=[None, None], axisLabelSize=25, tickSize=16)
    

<file_sep>#!/bin/bash

make && make move

perl -pe 's/CLEANUP = no/CLEANUP = yes/' Makefile > tmp
make -f tmp && mv libmyfft.so libmyfft_clean.so \
&& mv libmyfft.a libmyfft_clean.a && make move

rm tmp
<file_sep>import numpy as np
import matplotlib.pyplot as plt

N = 1024; M = 10000;
AA = np.fromfile('aa.bin', np.double, 2*N*M).reshape(M,2*N).T;
Ar = AA[0::2,:]; Ai = AA[1::2, :]; Ama = abs(Ar+1j*Ai); Ama=Ama.T;
Maxf = 7000 ;
mag = 2;
h = 0.005;

fig = plt.figure(figsize=(6,8));
ax = fig.add_subplot(111)
ax.set_xlabel('x')
ax.set_ylabel('t')
ax.set_yticks([0, h*mag*Maxf])
ax.set_yticklabels(["$0$", "35"])
#ax.set_ylim((-0.5, 3.5))


ax.imshow(Ama[:,0:Maxf], cmap=plt.get_cmap('seismic'), extent=(0,50,0,h*mag*Maxf));
ax.grid('on')
fig.tight_layout(pad=0)
plt.show()
<file_sep>from ksHelp import *
from py_ks import *

case = 10

if case == 10:
    N, L = 64, 21.7
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    
    a0 = rand(N-2)
    a0 = ks.intgC(a0, 0.01, 100, 1000000)
    for i in range(10):
        aa = ks.intgC(a0, 0.01, 100, 10)
        a0 = aa[-1]
        # raa, ths = ks.redSO2(aa, 1, False)
        ksp.config(aa, [0, L, 0, 100])
    
if case == 20:
    """
    visulize rpo with different L
    """
    N = 64
    L0, dL = 21.95, 0.05
    ppType = 'rpo'
    isRPO = ppType == 'rpo'
    ppId = 2
    fileName = '../../data/ksh01x64.h5'
    
    Ts, ths = [], []
    for i in range(20):
        L = L0 - i * dL
        ks = pyKS(N, L)
        ksp = KSplot(ks)
        groupName = ksp.toStr(ppType, ppId, L, flag=1)
        if ksp.checkExist(fileName, groupName):
            a, T, nstp, theta, err = ksp.readPO(fileName, groupName, isRPO)[:5]
            Ts.append(T)
            ths.append(theta)
            if i%1 == 0:
                aa = ks.intgC(a, T/nstp, 4*T, 5)
                ksp.config(aa, [0, L, 0, 4*T])
    print Ts
    print ths

if case == 30:
    """
    visulize the state space for small L
    """
    N, L = 64, 21.95
    ks = pyKS(N, L)
    ksp = KSplot(ks)

    ppType = 'ppo'
    isRPO = ppType == 'rpo'
    ppId = 1
    
    a, T, nstp, theta, err = ksp.readPO('../../data/ksh01x64.h5', ksp.toStr(ppType, ppId, L, flag=1),
                                        isRPO)[:5]
    ap = ks.intgC(a, T/nstp, T, 10)
    apH = ks.redSO2(ap, 2, True)[0]

    aE = rand(N-2)*0.1
    aE = ks.intgC(aE, 0.01, 100, 100000)
    aa = ks.intgC(aE, 0.01, 1000, 10)
    aaH = ks.redSO2(aa, 2, True)[0]

    fig, ax = pl3d(size=[8, 6])
    ax.plot(apH[:, 1], apH[:, 5], apH[:, 3], c='r', lw=3)
    ax.plot(aaH[:, 1], aaH[:, 5], aaH[:, 3], c='b')
    ax3d(fig, ax)

if case == 40:
    """
    have a look at stability of rpo/ppo for different L
    """
    N = 64
    L0, dL = 21.95, 0.05
    ppType = 'rpo'
    isRPO = ppType == 'rpo'
    ppId = 2
    fileName = '../../data/ksh01x64EV.h5'
    
    Ls, Es, Ts = [], [], []
    for i in range(20):
        L = L0 - i * dL
        ksp = KSplot()
        groupName = ksp.toStr(ppType, ppId, L, flag=1)
        if ksp.checkExist(fileName, groupName):
            a, T, nstp, theta, err, e = ksp.readPO(fileName, groupName, isRPO, flag=1)[:6]
            Ts.append(T)
            Ls.append(L)
            Es.append(e)

    print Ts
    print Ls
    print Es
<file_sep>#!/bin/bash
for f in ./*.eps; do
    epspdf $f $(basename $f .eps).pdf
done
<file_sep>from py_CQCGL_threads import *
from personalFunctions import *

case = 60

if case == 10:
    """
    save the same initial condition
    """
    N = 1024
    d = 30
    di = 0.06
    T = 8
    
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)

    Ndim = cgl.Ndim
    A0 = 3*centerRand(N, 0.2, True)
    a0 = cgl.Config2Fourier(A0)

    aa = cgl.aintg(a0, 0.001, T, 100000)
    print aa.shape
    np.savetxt('init.dat', aa[-1])

if case == 20:
    """
    constant time step result
    """
    N = 1024
    d = 30
    di = 0.06
    T = 8
    h = 1e-4
    nstp = np.int(T/h)
    
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    cgl.Method = 1

    a0 = np.loadtxt('init.dat')
    aa = cgl.intg(a0, h, nstp, 10)
    lte1 = cgl.lte()

    # plot 3d and heat profiles
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T],
                               tickSize=15, axisLabelSize=25)
    plotConfigWireFourier(cgl, aa[::40].copy(), [0, d, 0, T])

    # plot single soliton profile
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$x$', r'$|A|$'],
                   axisLabelSize=25, tickSize=15)
    A1 = cgl.Fourier2Config(aa[0])
    A2 = cgl.Fourier2Config(aa[2100])    # t = 2.1
    ax.plot(np.linspace(0, d, len(A1)), np.abs(A1), lw=1.5, ls='-', c='b')
    ax.plot(np.linspace(0, d, len(A2)), np.abs(A2), lw=1.5, ls='-', c='r')
    ax2d(fig, ax)

    cgl.Method = 2
    aa2 = cgl.intg(a0, h, nstp, 10)
    lte2 = cgl.lte()
    
    # plot lte
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$t$', r'$LTE$'],
                   axisLabelSize=25, tickSize=15,
                   yscale='log')
    ax.plot(np.linspace(0, T, len(lte1)), lte1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(lte2)), lte2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

if case == 30:
    """
    time step adaption in static frame
    """
    N = 1024
    d = 30
    di = 0.06
    T = 8
    
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    a0 = np.loadtxt('init.dat')
    cgl.changeOmega(-176.67504941219335)
    
    cgl.Method = 1
    aa = cgl.aintg(a0, 1e-3, T, 40)
    Ts1 = cgl.Ts()
    lte1 = cgl.lte()
    hs1 = cgl.hs()
    print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe

    cgl.Method = 2
    aa2 = cgl.aintg(a0, 1e-3, T, 40)
    Ts2 = cgl.Ts()
    lte2 = cgl.lte()
    hs2 = cgl.hs()
    print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe

    # plot heat map
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T],
                               tt=Ts1, yls=range(0, T+1),
                               tickSize=15, axisLabelSize=25)
    
    # plot the accumlated time.
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$t$'],
                   axisLabelSize=25, tickSize=15)
    ax.plot(np.linspace(0, T, len(Ts1)), Ts1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(Ts2)), Ts2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot lte
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$LTE$'],
                   axisLabelSize=25, tickSize=15,
                   ylim=[1e-11, 1e-10],
                   yscale='log')
    ax.plot(np.linspace(0, T, len(lte1)), lte1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(lte2)), lte2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot hs
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$h$'],
                   axisLabelSize=25, tickSize=18,
                   ylim=[8e-6, 1e-4],
                   yscale='log')
    ax.plot(np.linspace(0, T, len(hs1)), hs1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(hs2)), hs2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot the real part of the zeros mode
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$Re(a_0)$'],
                   axisLabelSize=25, tickSize=18)
    n = aa.shape[0]
    ids = np.arange(3*n/4, n)
    ax.plot(np.linspace(3*T/4, T, len(ids)), aa[ids, 0], lw=1, ls='-', c='r')
    ax2d(fig, ax)

if case == 40:
    """
    time step adaption in co-moving frame
    """
    N = 1024
    d = 30
    di = 0.06
    T = 8
    
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    a0 = np.loadtxt('init.dat')
    cgl.changeOmega(-176.67504941219335)
    
    cgl.Method = 1
    aa = cgl.aintg(a0, 1e-3, T, 40)
    Ts1 = cgl.Ts()
    lte1 = cgl.lte()
    hs1 = cgl.hs()
    print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe

    cgl.Method = 2
    aa2 = cgl.aintg(a0, 1e-3, T, 40)
    Ts2 = cgl.Ts()
    lte2 = cgl.lte()
    hs2 = cgl.hs()
    print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe

    # plot heat map
    plotConfigSpaceFromFourier(cgl, aa, [0, d, 0, T],
                               tt=Ts1, yls=range(0, T+1),
                               tickSize=15, axisLabelSize=25)
    
    # plot the accumlated time.
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$t$'],
                   axisLabelSize=25, tickSize=15)
    ax.plot(np.linspace(0, T, len(Ts1)), Ts1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(Ts2)), Ts2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot lte
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$LTE$'],
                   axisLabelSize=25, tickSize=15,
                   ylim=[1e-11, 1e-10],
                   yscale='log')
    ax.plot(np.linspace(0, T, len(lte1)), lte1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(lte2)), lte2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot hs
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$h$'],
                   axisLabelSize=25, tickSize=18,
                   ylim=[8e-6, 1e-3],
                   yscale='log')
    ax.plot(np.linspace(0, T, len(hs1)), hs1, lw=1.5, ls='-', c='r',
            label='Cox-Matthews')
    ax.plot(np.linspace(0, T, len(hs2)), hs2, lw=2, ls='--', c='b',
            label='Krogstad')
    ax2d(fig, ax)

    # plot the real part of the zeros mode
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\tau$', r'$Re(a_0)$'],
                   axisLabelSize=25, tickSize=18)
    n = aa.shape[0]
    ids = np.arange(3*n/4, n)
    ax.set_ylim([-1000, 1000])
    ax.plot(np.linspace(3*T/4, T, len(ids)), aa[ids, 0], lw=1, ls='-', c='r')
    ax2d(fig, ax)


if case == 50:
    """
    plot the relative equilibrium
    """
    N = 1024
    d = 30
    di = 0.06
   
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          di, 1)
    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)

    # plot the solition profile
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$x$', r'$|A(x)|$'],
                   axisLabelSize=25, tickSize=18)
    A1 = cgl.Fourier2Config(a0)
    ax.plot(np.linspace(0, d, len(A1)), np.abs(A1), lw=1.5, ls='-', c='r')
    ax2d(fig, ax)

if case == 60:
    """
    collect the performance of static and co-moving frames
    """
    N = 1024
    d = 30
    di = 0.06
    T = 8

    cgl = pyCQCGL(N, d, 4.0, 0.8, 0.01, di, 0, 4)
    a0 = np.loadtxt('init.dat')
    rtols = [1e-6, 1e-7, 1e-8, 1e-9, 1e-10, 1e-11]
    
    R1 = np.zeros((2, len(rtols)))
    N1 = np.zeros((2, len(rtols)))
    for i in range(len(rtols)):
        cgl.rtol = rtols[i]
        print i, cgl.rtol

        cgl.Method = 1
        aa = cgl.aintg(a0, 1e-3, T, 1000000)
        print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe
        R1[0, i] = cgl.NReject
        N1[0, i] = cgl.NSteps
        
        cgl.Method = 2
        aa2 = cgl.aintg(a0, 1e-3, T, 1000000)
        print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe
        R1[1, i] = cgl.NReject
        N1[1, i] = cgl.NSteps
       
    cgl.changeOmega(-176.67504941219335)
    R2 = np.zeros((2, len(rtols)))
    N2 = np.zeros((2, len(rtols)))
    for i in range(len(rtols)):
        cgl.rtol = rtols[i]
        print i, cgl.rtol

        cgl.Method = 1
        aa = cgl.aintg(a0, 1e-3, T, 1000000)
        print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe
        R2[0, i] = cgl.NReject
        N2[0, i] = cgl.NSteps
        
        cgl.Method = 2
        aa2 = cgl.aintg(a0, 1e-3, T, 1000000)
        print cgl.NSteps, cgl.NReject, cgl.NCallF, cgl.NCalCoe
        R2[1, i] = cgl.NReject
        N2[1, i] = cgl.NSteps
        
    # save result
    # np.savez_compressed('perf', R1=R1, N1=N1, R2=R2, N2=N2)

    # plot the number of integration steps
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\epsilon$', r'$N_s$'],
                   axisLabelSize=25, tickSize=18, yscale='log')
    ax.set_xscale('log')
    ax.plot(rtols, N1[0], lw=1.5, ls='-', marker='o', ms=7,
            mew=2, mfc='none', mec='r', c='r', label='Static Cox-Matthews')
    ax.plot(rtols, N1[1], lw=1.5, ls='-', marker='s', ms=10,
            mew=2, mfc='none', mec='g', c='g', label='Static Krogstad')
    ax.plot(rtols, N2[0], lw=1.5, ls='--', marker='o', ms=7,
            mew=2, mfc='none', mec='c', c='c', label='Co-moving Cox-Matthews')
    ax.plot(rtols, N2[1], lw=1.5, ls='--', marker='s', ms=10,
            mew=2, mfc='none', mec='k', c='k', label='Co-moving Krogstad')
    ax.grid(True, which='both')
    ax2d(fig, ax)

    # plot the number of rejections
    fig, ax = pl2d(size=[6, 4.5], labs=[r'$\epsilon$', r'$N_r$'],
                   axisLabelSize=25, tickSize=18)
    ax.set_xscale('log')
    ax.plot(rtols, R1[0], lw=1.5, ls='-', marker='o', ms=7,
            mew=2, mfc='none', mec='r', c='r', label='Static Cox-Matthews')
    ax.plot(rtols, R1[1], lw=1.5, ls='-', marker='s', ms=10,
            mew=2, mfc='none', mec='g', c='g', label='Static Krogstad')
    ax.plot(rtols, R2[0], lw=1.5, ls='--', marker='o', ms=7,
            mew=2, mfc='none', mec='c', c='c', label='Co-moving Cox-Matthews')
    ax.plot(rtols, R2[1], lw=1.5, ls='--', marker='s', ms=10,
            mew=2, mfc='none', mec='k', c='k', label='Co-moving Krogstad')
    ax.grid(True, which='both')
    ax2d(fig, ax)
<file_sep>#include<iostream>
#include <cmath>
#include "lorenz.hpp"

using namespace std;
using namespace Eigen;
using namespace denseRoutines;

Lorenz::Lorenz(){
}

Lorenz::~Lorenz(){
}

Lorenz & Lorenz::operator=(const Lorenz &x){
    return *this;
}

/* ====================================================================== */

/* velocity field of Lorenz flow
 *        
 *        | sigma * (y -x)     |
 * v(x) = | rho * y - y - x*z  |
 *        | x*y - b*z          |
 */

Vector3d
Lorenz::vel(const Ref<const Vector3d> &x){
    Vector3d v;
    v <<
	Sigma * (x(1) - x(0)),
	Rho * x(0) - x(1) - x(0)*x(2),
	x(0)*x(1) - B * x(2);

    return v;
}

/* stability matrix  */
Matrix3d
Lorenz::stab(const Ref<const Vector3d> &x){
    Matrix3d A;
    A << 
	-Sigma,    Sigma,   0,
	Rho-x(2),   -1,     -x(0),
	x(1),       x(0),   -B;
    
    return A;
}

MatrixXd
Lorenz::velJ(const Ref<const MatrixXd> &x){
    MatrixXd vJ(3, 4);
    vJ << 
	vel(x.col(0)),
	stab(x.col(0)) * x.rightCols(3);

    return vJ;
}

MatrixXd
Lorenz::intg(const Ref<const Vector3d> &x0, const double h, 
	     const int nstp, const int nq){

    int M = nstp/nq + 1;
    MatrixXd xx(3, M);
    xx.col(0) = x0;

    Vector3d x(x0);


    for (int i = 0; i < nstp; i++){
	Vector3d k1 = vel(x); 
	Vector3d k2 = vel(x + h/2*k1);
	Vector3d k3 = vel(x + h/2*k2);
	Vector3d k4 = vel(x + h*k3);
	
	x += h/6 * (k1 + 2*k2 + 2*k3 + k4);
	
	if((i+1)%nq == 0) xx.col((i+1)/nq) = x;
    }

    return xx;
}

std::pair<MatrixXd, MatrixXd>
Lorenz::intgj(const Ref<const Vector3d> &x0, const double h,
	      const int nstp, const int xs, const int js){
    int M1 = nstp / xs + 1;
    int M2 = nstp / js;
    
    MatrixXd xx(3, M1);
    MatrixXd JJ(3, 3*M2);
    xx.col(0) = x0;

    MatrixXd x(3, 4);
    x << x0, MatrixXd::Identity(3,3);  

    for (int i = 0; i < nstp; i++){
	MatrixXd k1 = velJ(x); 
	MatrixXd k2 = velJ(x + h/2*k1);
	MatrixXd k3 = velJ(x + h/2*k2);
	MatrixXd k4 = velJ(x + h*k3);
	
	x += h/6 * (k1 + 2*k2 + 2*k3 + k4);
	
	if ((i+1)%xs == 0) xx.col((i+1)/xs) = x.col(0);
	if ((i+1)%js == 0) JJ.middleCols((i+1)/js-1, 3) = x.rightCols(3);
    }

    return std::make_pair(xx, JJ);
}


/* ============================================================ */

/**
 * If rho > 1 there are 3 equilibria :
 *  Eq0 = [0, 0, 0]
 *  Eq1 = [\sqrt{b(rho-1)}, \sqrt{b(rho-1)}, rho-1]
 *  Eq2 = [-\sqrt{b(rho-1)}, -\sqrt{b(rho-1)}, rho-1]
 *
 *  @return each column is an equilibrium
 */
Matrix3d
Lorenz::equilibria(){
    double z = Rho - 1;
    double x = sqrt(B*z);
    
    Matrix3d E;
    E << 
	0, x, -x,
	0, x, -x,
	0, z, z;

    return E;
}

/* obtain the stability matrix of the ith equilibrium */
Matrix3d
Lorenz::equilibriaStab(const int i){
    Matrix3d E = equilibria();
    return stab(E.col(i));
}

/* obtain the eigenvalues/eigenvectors of the stability matrix of
 * the ith equilibrium 
 */
std::pair<VectorXcd, MatrixXcd>
Lorenz::equilibriaEV(const int i){
    Matrix3d A = equilibriaStab(i);
    return evEig(A);
}


MatrixXd
Lorenz::equilibriaIntg(const int i, const int j, const double eps,
		       const double h, const int nstp, 
		       const int nq){
    Vector3d x0 = equilibria().col(i);
    auto e = equilibriaEV(i);
    Vector3d v = e.second.col(j).real();
    
    return intg(x0 + eps*v, h, nstp, nq); 
}
<file_sep>/* Requirement: >= g++4.6, >=eigen3.1
 * compile command:
 *  g++ -o libks2py.so ksintM1.cc ksint.cc ksint2py.cc
 *  -shared -fpic -lm  -lfftw3 -std=c++0x -march=corei7 -O3 -msse2 -msse4
 *  -I../../include -I/path/to/eigen3
 */
#include "ksintM1.hpp"
#include <Eigen/Dense>
#include <cstring>
#include <cstdlib>

using Eigen::ArrayXXd;
using Eigen::ArrayXd;
using Eigen::Map;

typedef struct {
  double *aa;
  double *tt;
} at;

const int N = 32;

extern "C"
void ksf(double *aa, double *a0, double d, double h, int nstp, int np){
  KS ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  ArrayXXd vv = ks.intg(v0, nstp, np);
  memcpy(aa, &vv(0,0), (nstp/np+1)*(N-2)*sizeof(double));
}

extern "C"
void ksfM1(double *aa, double *tt, double *a0, double d, double h,
	   int nstp, int np){
  KSM1 ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  std::pair<ArrayXXd, ArrayXd> vv = ks.intg(v0, nstp, np);
  memcpy(aa, &(vv.first(0,0)), (nstp/np+1)*(N-2)*sizeof(double));
  memcpy(tt, &(vv.second(0)), (nstp/np+1)*sizeof(double));
}

extern "C"
int ksf2M1(at *at, double *a0, double d, double h,
	    double T, int np){
  KSM1 ks(N, h, d);
  Map<ArrayXd> v0(a0, N-2);
  std::pair<ArrayXXd, ArrayXd> vv = ks.intg2(v0, T, np);
  int m = vv.first.cols();
  
  double *aa = new double[m*(N-2)];
  double *tt = new double[m];
  memcpy(aa, &(vv.first(0,0)), m*(N-2)*sizeof(double));
  memcpy(tt, &(vv.second(0)), m*sizeof(double));
  
  at->aa = aa;
  at->tt = tt;
  
  return m;
}

extern "C"
void freeks(at *at){
  delete[] at->aa;
  delete[] at->tt;
}
<file_sep>#ifndef KSDIM_H
#define KSDIM_H

#include <Eigen/Dense>
#include <iostream>
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h> 		/* for create folder */

std::pair<Eigen::MatrixXd, Eigen::MatrixXi> 
anglePO(const std::string fileName, const std::string ppType,
	const int ppId, const Eigen::MatrixXi subspDim);

void
anglePOs(const std::string fileName, const std::string ppType,
	const int N, const int NN,
	const std::string saveFolder,
	const std::string spType, const int M = 29);
void
anglePOs(const std::string fileName, const std::string ppType,
	 const int N, const std::vector<int> ppIds,
	 const std::string saveFolder,
	 const std::string spType, const int M);

Eigen::MatrixXd partialHyperb(const std::string fileName,
			      const std::string ppType,
			      const int ppId);
void partialHyperbOneType(const std::string fileName,
			  const std::string ppType,
			  const int NN, const std::string saveFolder);
void partialHyperbAll(const std::string fileName,
		      const int NNppo, const int NNrpo,
		      const std::string saveFolder);
Eigen::MatrixXd
localFE(const std::string fileName, const std::string ppType, const int ppId);
void localFEOneType(const std::string fileName, const std::string ppType,
		    const int NN, const std::string saveFolder);
void localFEAll(const std::string fileName, const int NNppo, const int NNrpo,
		const std::string saveFolder);

#endif	/* KSDIM_H */

<file_sep>/* compile command: 
 * mex CXXFLAGS='-std=c++0x -fPIC -O3' half2whole.cc ../ksint.cc  -I../../../include -I$XDAPPS/eigen/include/eigen3 -lfftw3
 * */
#include "ksint.hpp"
#include "mex.h"
#include <cmath>
#include <cstring>
#include <Eigen/Dense>

using namespace Eigen;

/* transform trajectory into 1st mode slice */
static MatrixXd
orbitToSlice(double *aa, const int N, const int M){
    KS ks(N+2);
    Map<MatrixXd> aa2(aa, N, M);
    return ks.half2whole(aa2);
}


void
mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    // get the pointer and the size of input 
    double *aa = mxGetPr(prhs[0]);
    mwSize N = mxGetM(prhs[0]);
    mwSize M = mxGetN(prhs[0]);
  
    MatrixXd tmp = orbitToSlice(aa, N, M);
    mwSize N2 = tmp.rows();
    mwSize M2 = tmp.cols();
    plhs[0] = mxCreateDoubleMatrix(N2, M2, mxREAL);
    memcpy(mxGetPr(plhs[0]), &tmp(0,0), N2*M2*sizeof(double));
}
<file_sep>from time import time
from py_cqcgl1d import pyCqcgl1d, pyCqcglRPO
from personalFunctions import *


def cqcglFindReq(fileName, frac=0.3, MaxIter=300, Ntrial=1000):
    N = 512
    d = 50
    h = 0.005
    cgl = pyCqcgl1d(N, d, h, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)

    ReqNum = 1
    for i in range(Ntrial):
        A0 = 3*centerRand(2*N, frac)
        a0 = cgl.Config2Fourier(A0).squeeze()
        wth0 = rand()
        wphi0 = rand()
        a, wth, wphi, err = cgl.findReq(a0, wth0, wphi0, MaxIter,
                                        1e-12, True, False)
        if err < 1e-12:
            print "found : " + str(ReqNum)
            cqcglSaveReq(fileName, str(ReqNum), a, wth, wphi, err)
            ReqNum += 1


def cqcglConvertReq(N2, inputFile, outputFile, indices,
                    MaxIter=300, tol=1e-12, doesPrint=False):
    """
    convert the relative equilibria found for some truncation number N to
    a finer resolution N2 = 2*N.

    parameters:
    N2          the dimension of the finer system
    inputFile   file storing reqs with N
    outputFile  file is about to create to store reqs with 2*N
    indices     the indices of reqs needed to be converted
    """
    # N = 512
    d = 50
    h = 0.005                   # time step is not used acturally
    cgl = pyCqcgl1d(N2, d, h, True, 0,
                    -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
                    4)

    for i in indices:
        a0, wth0, wphi0, err0 = cqcglReadReq(inputFile, str(i))
        a0unpad = 2 * cgl.generalPadding(a0)
        a, wth, wphi, err = cgl.findReq(a0unpad, wth0, wphi0,
                                        MaxIter, tol, True, doesPrint)
        print err
        cqcglSaveReq(outputFile, str(i), a, wth, wphi, err)


case = 9

if case == 1:
    """
    find the relative equlibria after changing dimension
    """
    N = 512
    d = 50
    h = 0.005
    cgl = pyCqcgl1d(N, d, h, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)
    Ndim = cgl.Ndim

    a0, wth0, wphi0, err0 = cqcglReadReq('../../data/cgl/req.h5', '10')

    a0unpad = 2*cgl.generalPadding(a0)
    a, wth, wphi, err = cgl.findReq(a0unpad, 0, wphi0,
                                    100, 1e-12, True, True)
    # cqcglSaveReq("req.hdf5", '1', a, wth, wphi, err)
    nstp = 10000
    aa = cgl.intg(a, nstp, 1)
    plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h])

if case == 2:
    """
    try different guesses to find relative equilibria
    Just for test purpose
    """
    N = 1024
    d = 30
    h = 0.0002
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, -0.01, -0.08, 4)

    A0 = 5*centerRand(2*N, 0.2)
    # A0 = 5*centerOne(2*N, 0.25)
    a0 = cgl.Config2Fourier(A0)
    wth0 = rand()
    wphi0 = rand()
    a, wth, wphi, err = cgl.findReq(a0, wth0, wphi0, 100, 1e-12, True, True)
    nstp = 10000
    aa = cgl.intg(a, nstp, 1)
    plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h])
    plot1dfig(a)
    plotOneConfigFromFourier(cgl, a)
    print wth, wphi
    # cqcglSaveReq("req2.h5", '1', a, wth, wphi, err)

if case == 9:
    """
    load the guess from file and then find req
    """
    N = 1024
    d = 30
    h = 0.0002

    di = 0.05
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqTmp.h5',
                                          di, 1)
    a, wth, wphi, err = cgl.findReq(a0, wth0, wphi0, 100, 1e-12, True, True)

    nstp = 10000
    aa = cgl.intg(a, nstp, 1)
    plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h])
    plotOneConfigFromFourier(cgl, a)
    print wth, wphi
    # cqcglSaveReq("req2.h5", '1', a, wth, wphi, err)


if case == 10:
    """
    use existing req to find the req with slightly different di
    """
    N = 1024
    d = 30
    h = 0.0002
    diOld = 0.41
    di = diOld + 0.001
    cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)
    
    a0, wth0, wphi0, err = cqcglReadReqdi('../../data/cgl/reqDi.h5',
                                          diOld, 1)
    a, wth, wphi, err = cgl.findReq(a0, wth0, wphi0, 40, 1e-12, True, True)
    nstp = 10000
    aa = cgl.intg(a, nstp, 1)
    plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h])
    plot1dfig(a)
    plotOneConfigFromFourier(cgl, a)
    print wth, wphi
    # cqcglSaveReq("req98.h5", '1', a, wth, wphi, err)
    eigvalues, eigvectors = eigReq(cgl, a, wth, wphi)
    print eigvalues[:10]

if case == 11:
    """
    use existing req to find the req with slightly different di
    and do this for a sequence of di s.
    """
    N = 1024
    d = 30
    h = 0.0002

    diOld = 0.94
    diInc = 0.02
    for i in range(1):
        di = diOld + diInc
        print di

        cgl = pyCqcgl1d(N, d, h, True, 0, 4.0, 0.8, 0.01, di, 4)

        fileName = '../../data/cgl/reqDi.h5'
        a0, wth0, wphi0, err0 = cqcglReadReqdi(fileName, diOld, 2)
        a, wth, wphi, err = cgl.findReq(a0, wth0, wphi0, 20, 1e-12, True, True)

        plotOneConfigFromFourier(cgl, a, save=True, name=str(di)+'.png')
        print wth, wphi, err
        e, v = eigReq(cgl, a, wth, wphi)
        print e[:8]
        cqcglSaveReqEVdi(fileName, di, 2, a, wth, wphi, err,
                         e.real, e.imag, v[:, :10].real, v[:, :10].imag)

        diOld += diInc


if case == 3:
    """
    run a long time to collect relative equilibria
    """
    cqcglFindReq("req3.h5", 0.3, 300, 1000)


if case == 4:
    """
    have a look at these relative equilibrium and remove the duplicates.
    All kinds of manipulations to build the final data base.
    """
    N = 256
    d = 50
    h = 0.005
    cgl = pyCqcgl1d(N, d, h, -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6)

    # Num = 851
    # wthAll = np.zeros(Num)
    # wphiAll = np.zeros(Num)
    # errAll = np.zeros(Num)
    # aAll = np.zeros((Num, 2*N))
    # for i in range(Num):
    #     a, wth, wphi, err = cqcglReadReq("req3.hdf5", str(i+1))
    #     aAll[i] = a
    #     wthAll[i] = wth
    #     wphiAll[i] = wphi
    #     errAll[i] = err

    # dup = []
    # groups = []
    # for i in range(Num):
    #     for j in range(i):
    #         if (np.abs(np.abs(wthAll[i]) - np.abs(wthAll[j])) < 1e-6 and
    #             np.abs(wphiAll[i] - wphiAll[j]) < 1e-6):
    #             dup.append([i, j])
    #             groups.append(i+1)
    #             break

    # cqcglRemoveReq("req3.hdf5", "req4.hdf5", Num, groups)

    # Num2 = 567
    # for i in range(Num2):
    #     a, wth, wphi, err = cqcglReadReq("req4.hdf5", str(i+1))
    #     plotOneConfigFromFourier(cgl, a, save=True,
    #                              name=str(i+1)+'.png')
    #     print wth, wphi, err
    #     wait = raw_input("press enter to continue")

    # groups = [1, 2, 3, 10, 12, 18, 62, 138, 141, 212, 214, 221, 265,
    #           270, 276, 292, 330, 351, 399, 414, 425]
    # cqcglExtractReq('req4.hdf5', 'req5.h5', groups, 2)

    # for i in range(21):
    #     a, wth, wphi, err = cqcglReadReq("req5.h5", str(i+2))
    #     print wth, wphi, err
    #     plotOneConfigFromFourier(cgl, a, save=True,
    #                              name=str(i+2)+'.png')

if case == 5:
    """
    change the existing reqs to different dimension
    """
    # cqcglConvertReq('../../data/cgl/req.h5', 'req2.h5', range(1, 23))
    # cqcglConvertReq(2048, '../../data/cgl/reqN1024.h5', 'req2.h5', range(1, 23))
    cqcglConvertReq(4096, '../../data/cgl/reqN2048.h5', 'req2.h5',
                    range(1, 23), tol=1.5e-11, doesPrint=True)

if case == 6:
    """
    plot the interesting relative equilibria that I have found
    """
    N = 1024
    d = 50
    h = 0.005
    cgl = pyCqcgl1d(N, d, h, True, 0,
                    -0.1, 1.0, 0.8, 0.125, 0.5, -0.1, -0.6,
                    4)

    Num = 22
    nstp = 18000
    for i in range(Num):
        a, wth, wphi, err = cqcglReadReq('../../data/cgl/reqN1024.h5', str(i+1))
        aa = cgl.intg(a, nstp, 1)
        plotConfigSpace(cgl.Fourier2Config(aa), [0, d, 0, nstp*h],
                        save=True, name='cqcglReq'+str(i+1)+'T90'+'.png')
        plotOneConfigFromFourier(cgl, a, save=True,
                                 name='cqcglReq'+str(i+1)+'.png')
<file_sep>from personalFunctions import *
from py_ks import *

case = 10

if case == 10:
    N, L = 64, 22
    ks = pyKS(N, L)
    t_init = time();
    a0 = np.ones(N-2)*0.1
    for i in range(100):
        aa = ks.intgC(a0, 0.01, 30, 10)
    print time() - t_init
    t_init = time()
    for i in range(1):
        aa, daa = ks.intgjC(a0, 0.01, 30, 100000)
    print time() - t_init

if case == 15:
    ks = pyKSM1(32, 0.1, 22)
    t_init = time()
    for i in range(1000):
        a0 = np.ones(30)*0.1
        a0[1] = 0
        aa, tt = ks.intg(a0, 2000, 1)
    print time() - t_init

    t_init = time()
    for i in range(10):
        a0 = np.ones(30)*0.1
        a0[1] = 0
        aa, tt = ks.intg2(a0, 20, 1)
    print time() - t_init

if case == 20:
    ks = pyKS(32, 0.1, 22)
    aa = ks.intg(np.ones(30)*0.1, 20, 1)
    aaHat, ang = ks.orbitToSlice(aa)
    aaTilde = ks.reduceReflection(aaHat)

    # check p2
    print np.sqrt(aaHat[:, 2]**2 + aaHat[:, 5]**2)
    print aaTilde[:, 2]
    # check the last transformed term
    print aaHat[:, 26] * aaHat[:, 29] / np.sqrt(aaHat[:, 26]**2 + aaHat[:, 29]**2)
    print aaTilde[:, 29]
    # check the unchanged terms
    print aaHat[:, 3]
    print aaTilde[:, 3]

    x = 0.1*np.arange(30)
    ve = np.sin(range(30))
    veTilde = ks.reflectVe(ve, x)

if case == 30:
    """
    test the redSO2 and fundDomain() functions
    """
    N = 64
    d = 22
    ks = pyKS(N, d)
    
    a0 = rand(N-2)
    aa = ks.aintg(a0, 0.01, 100, 1000000)
    aa = ks.aintg(aa[-1], 0.01, 200, 1)
    plot3dfig(aa[:, 0], aa[:, 1], aa[:, 2])

    raa1, ang1 = ks.redSO2(aa, 1, True)
    faa1, dids1 = ks.fundDomain(raa1, 2)
    print norm(raa1[:, 0])
    plot3dfig(raa1[:, 3], raa1[:, 1], raa1[:, 2])
    plot3dfig(faa1[:, 3], faa1[:, 1], faa1[:, 2])
    plot1dfig(dids1)
    
    raa2, ang2 = ks.redSO2(aa, 2, True)
    faa2, dids2 = ks.fundDomain(raa2, 1)
    print norm(raa2[:, 2])
    plot3dfig(raa2[:, 0], raa1[:, 1], raa1[:, 3])
    plot3dfig(faa2[:, 0], faa2[:, 1], faa2[:, 3])
    plot1dfig(dids2)

if case == 40:
    """
    test the 2nd slice
    """
    N = 64
    d = 22
    ks = pyKS(N, d)

    x = rand(N-2)-0.5
    y = ks.Reflection(x)
    th0 = np.pi*2.47
    th1 = np.pi*4.22
    x1, t1 = ks.redO2(x)
    x2, t2 = ks.redO2(ks.Rotation(x, th0))
    y1, r1 = ks.redO2(y)
    y2, r2 = ks.redO2(ks.Rotation(y, th1))
    print norm(x2-x1), norm(y2-y1), norm(y2-x2)

if case == 50:
    """
    test the 2nd slice with fundamental domain
    """
    N = 64
    d = 22
    ks = pyKS(N, d)

    x = rand(N-2)-0.5
    y = ks.Reflection(x)
    th0 = np.pi*2.47
    th1 = np.pi*4.22
    x1, id1, t1 = ks.redO2f(x, 2)
    x2, id2, t2 = ks.redO2f(ks.Rotation(x, th0), 2)
    y1, id3, r1 = ks.redO2f(y, 2)
    y2, id4, r2 = ks.redO2f(ks.Rotation(y, th1), 2)
    print norm(x2-x1), norm(y2-y1), norm(y2-x2)

if case == 60:
    """
    test ks.stab() function
    """
    N = 64
    d = 22
    ks = pyKS(N, d)

    fileName = '/usr/local/home/xiong/00git/research/data/ks22Reqx64.h5'
    a0, err = KSreadEq(fileName, 3)
    print norm(ks.velocity(a0))

    A = ks.stab(a0)
    e, v = eig(A.T)
    idx = argsort(e.real)[::-1]
    e = e[idx]
    v = v[:, idx]
    print e

if case == 70:
    """
    visualize heat map of ppo/rpo
    """
    N = 64
    L = 22
    ks = pyKS(N, L)
    
    fileName = '/usr/local/home/xiong/00git/research/data/ks22h001t120x64EV.h5'
    poType = 'ppo'
    poId = 2
    
    KSplotPoHeat(ks, fileName, poType, poId, NT=2, Ts=100, fixT=True)

if case == 80:
    """
    print the period
    """
    fileName = '/usr/local/home/xiong/00git/research/data/ks22h001t120x64EV.h5'
    Ts = []
    for poId in range(1, 31):
        a0, T, nstp, r, s = KSreadPO(fileName, 'rpo', poId)
        print '%0.2f\n' % T,
        Ts.append(T)

    
<file_sep>from cglHelp import *
from py_CQCGL2d import *


case = 90

labels = ["IF4(3)", "IF5(4)",
          "ERK4(3)2(2)", "ERK4(3)3(3)", "ERK4(3)4(3)", "ERK5(4)5(4)",
          "SS4(3)"]
mks = ['o', 's', '+', '^', 'x', 'v', 'p']
Nscheme = len(labels)
lss = ['--', '-.', ':', '-', '-', '-', '-']

if case == 40:
    """
    plot one instance of explosion in heat map.
    Also plot the req in heat map
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -0.6

    cgl = pyCQCGL2d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4)
    cglp = CQCGL2dPlot(d, d)

    fig = plt.figure(figsize=[12, 15])

    states = []
    # load explosion data
    ts = [3, 5, 8, 10, 12]
    for i in range(len(ts)):
        t = ts[i]
        index = np.int(t / 20.0 * 256)
        a = cglp.load('aaCox.h5', index)
        states.append(a)
    # load req data
    a, wthx, wthy, wphi, err = cglp.loadReq('../../data/cgl/req2dBiGi.h5', cglp.toStr(Bi, Gi, 1))
    states.append(a)
    
    for i in range(6):
        ax = fig.add_subplot('32' + str(i+1))
        ax.set_axis_off()
        # ax.tick_params(axis='both', which='major', labelsize=18)
        ax.text(0.1, 0.9, '('+ chr(ord('a') + i) +')', horizontalalignment='center',
                transform=ax.transAxes, fontsize=18, color='white')

        A = cgl.Fourier2Config(states[i])
        aA = np.abs(A).T

        im = ax.imshow(aA, cmap=plt.get_cmap('jet'), aspect='equal',
                       origin='lower', extent=[0, d, 0, d])
        dr = make_axes_locatable(ax)
        cax = dr.append_axes('right', size=0.08, pad=0.05)
        cax.tick_params(labelsize=18)
        plt.colorbar(im, cax=cax, ticks=[1, 2, 3])
        
    ####
    fig.tight_layout(pad=1)
    plt.show(block=False)


if case == 60:
    """
    plot the estimated local error of 2d cgcgl by constant schemes
    """
    err = np.loadtxt('data/cqcgl2d_N30_lte.dat')
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    n = err.shape[0]
    T = 20.0
    x = np.arange(1, n+1) * T/n
    
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'estimated local error'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   # ylim=[1e-17, 1e-7],
                   yscale='log')
    for i in range(Nscheme):
        ax.plot(x, err[:, i], lw=1.5, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='lower right')

    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'estimated local error'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   # ylim=[1e-30, 1e-8],
                   yscale='log')
    for i in range(Nscheme):
        ax.plot(x, err[:, Nscheme+i], lw=2, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=4)
    ax.locator_params(axis='x', nbins=5)
    ax2d(fig, ax, loc='lower right')

if case == 70:
    """
    plot the time steps used in the process
    """
    hs = []
    for i in range(Nscheme):
        x = np.loadtxt('data/cqcgl2d_N50_hs_' + str(i) + '.dat')
        hs.append(x)
    
    T = 20.0
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'$h$'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   # ylim=[2e-5, 2e-3],
                   yscale='log')
    for i in range(Nscheme):
        n = len(hs[i])
        x = np.arange(1, n+1) * T/n
        ax.plot(x, hs[i], lw=2, ls=lss[i], label=labels[i])
    # ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='upper left')
    
if case == 80:
    """
    same as case 70 but in comoving frame
    plot the time steps used in the process
    """
    hs = []
    for i in range(Nscheme):
        x = np.loadtxt('data/cqcgl2d_N60_comoving_hs_' + str(i) + '.dat')
        hs.append(x)
    
    T = 20.0
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    fig, ax = pl2d(size=[6, 5], labs=[r'$t$', r'$h$'],
                   axisLabelSize=20, tickSize=15,
                   # xlim=[1e-8, 5e-3],
                   # ylim=[8e-6, 2e-2],
                   yscale='log')
    for i in range(Nscheme):
        n = len(hs[i])
        x = np.arange(1, n+1) * T/n
        ax.plot(x, hs[i], lw=1.5, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    fig.tight_layout(pad=0)
    ax.legend(loc='lower right', ncol=2)
    plt.show(block=False)
    # ax2d(fig, ax, loc='upper left')

if case == 90:
    """
    static & comoving frame
    plot the relative error, Nab, Nn vs rtol
    """
    loadFlag = 1

    err = np.loadtxt('data/new_cqcgl2d_N70_stat' + ('0' if loadFlag == 0 else '1') + '.dat')
    rtol = err[:, 0]

    hs = []
    for i in range(Nscheme):
        s = '50' if loadFlag == 0 else '60_comoving'
        x = np.loadtxt('data/cqcgl2d_N' + s + '_hs_' + str(i) + '.dat')
        hs.append(x)
    
    fig = plt.figure(figsize=[12, 15])

    #plot time step
    T = 20.0
    lss = ['--', '-.', ':', '-', '-', '-', '-']
    ax = fig.add_subplot('321')
    ax.text(0.5, 0.9, '(a)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_yscale('log')
    ax.set_xlabel(r'$t$', fontsize=20)
    ax.set_ylabel(r'$h$', fontsize=20)
    ax.set_ylim([3e-5, 2e-2] if loadFlag == 0 else [2e-5, 4e-2])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        n = len(hs[i])
        x = np.arange(1, n+1) * T/n
        ax.plot(x, hs[i], lw=1.5, ls=lss[i], label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', nbins=5)
    ax.legend(loc='lower right', ncol=2, fontsize=12)

        
    # plot Nab
    ax = fig.add_subplot('322')
    ax.text(0.5, 0.9, '(b)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Nab$', fontsize=20)
    ax.set_ylim([0, 5000] if loadFlag == 0 else [0, 7000])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(2, 6):
        ax.plot(rtol, err[:, 5*i+1], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', nbins=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='right', fontsize=12)

    # plot Nn
    ax = fig.add_subplot('323')
    ax.text(0.1, 0.9, '(c)', horizontalalignment='center',
         transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Nn$', fontsize=20)
    ax.set_ylim([8e3, 1e7])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 5*i+2], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper right', fontsize=12)

    # plot NReject
    ax = fig.add_subplot('324')
    ax.text(0.9, 0.9, '(d)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    # ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'number of rejections', fontsize=15)
    ax.set_ylim([0, 180] if loadFlag == 0 else [0, 250])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 5*i+3], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper left', ncol=2, fontsize=12)

    # plot Wt
    ax = fig.add_subplot('325')
    ax.text(0.1, 0.9, '(e)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'$Wt$', fontsize=20)
    ax.set_ylim([1e3, 1e6])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 5*i+4], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=5)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='upper right', fontsize=12)

    # plot time of calculating coefficients / Wt
    ax = fig.add_subplot('326')
    ax.text(0.07, 0.9, '(f)', horizontalalignment='center',
            transform=ax.transAxes, fontsize=18, color='black')
    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set_xlabel(r'$rtol$', fontsize=20)
    ax.set_ylabel(r'time ratio', fontsize=15)
    ax.set_ylim([1e-6, 2e0])
    ax.tick_params(axis='both', which='major', labelsize=15)
    for i in range(Nscheme):
        ax.plot(rtol, err[:, 5*i+5]/err[:, 5*i+4], lw=1.5, marker=mks[i], mfc='none',
                ms=8, label=labels[i])
    ax.locator_params(axis='y', numticks=4)
    ax.locator_params(axis='x', numticks=5)
    ax.legend(loc='lower right', ncol=2, fontsize=12)

    ## 
    fig.tight_layout(pad=1)
    plt.show(block=False)
<file_sep>/* to compile:
 * g++ test_ksintM1.cc -std=c++0x -lksint -lfftw3 -I ../../include/ -L ../../lib/ -I $XDAPPS/eigen/include/eigen3
 */

#include "ksintM1.hpp"
#include <Eigen/Dense>
#include <iostream>
using namespace std;
using namespace Eigen;

int main(){
    /* ------------------------------------------------------- */
    switch (2) {
    case 1: {
	ArrayXd a0 = ArrayXd::Ones(30) * 0.1; a0(1) = 0.0;
	KSM1 ks(32, 0.1, 22);
	std::pair<ArrayXXd, ArrayXd> at = ks.intg(a0, 2000, 2000);
	cout << at.first << endl;
	cout << at.second << endl;

	break;
    }

    case 2: {
	ArrayXd a0 = ArrayXd::Ones(30) * 0.1; a0(1) = 0.0;
	KSM1 ks(32, 0.1, 22);
	std::pair<ArrayXXd, ArrayXd> at = ks.intg2(a0, 2, 1);
	cout << at.first.cols()<< endl;
	cout << at.first.rows() << endl;
	cout << at.second.tail(1) << endl;

	break;
    }
    
    default : {
	cout << "please indicate the correct index." << endl;
    }
	
    }

    return 0;
}
<file_sep>from ksHelp import *
from py_ks import *
from personalFunctions import *


class Sym():
    """
    Parameters
    ==========
    N      : number of Fourier modes in KS
    L      : domain size of KS
    pSlice : Fourier mode index used to define slice
    pFund  : Fourier mode index used to define fundamental domain
    toY    : whether rotate to the positive Y axis
    """
    N, L = 64, 22
    ks = pyKS(N, L)
    ksp = KSplot(ks)

    def __init__(self, pSlice, toY, pFund):
        self.pSlice = pSlice
        self.pFund = pFund
        self.toY = toY

    def getMuFullState(self, x0, v0, v1=None, T=200, r0=1e-5, nn=30, b=1):
        """
        get the unstable mainifold in the full state space
        
        case 1:
        -------
        For a complex pair (the case of E1 and E2), we use distribution
        a0 = x0 + r0 * exp(s) * v0
        Here, s = np.arange(0, nn, b). For real case, b = 1. For complex case,
        b = 2 * pi * |mu / nv| with (mu + i * nv) the stability exponent.
        
        case 2:
        -------
        For two degerate real unstable directions (the case of E3), we use distribution
        a0 = x0 + r0 * (v1*cos + v2*sin)
        Here, we v1 and v2 are orthornormal.
        
        ---------
        return :
        aars : orbits in reduced fundamental domain
        dom : domain indices
        jumps : jumping indices
        """
        aars = []
        dom = []
        jumps = []

        
        if v1 is not None:
            v0 = v0 / LA.norm(v0)
            v1p = v1 - np.dot(v0, v1) * v0
            v1p = v1p / LA.norm(v1p)

        for i in range(nn):
            if v1 is None:      # case 1
                s = np.double(i) / nn * b
                a0 = x0 + r0 * np.exp(s) * v0
            else:               # case 2
                th = i * 2 * np.pi / nn 
                a0 = x0 + r0 * (np.cos(th) * v0 + np.cos(th) * v1p)
                
            aa = self.ks.aintg(a0, 0.01, T, 1)
            raa, dids, ths = self.ks.redO2f(aa, self.pSlice, self.pFund)
            aars.append(raa)
            dom.append(dids)
            jumps.append(getJumpPts(dids))
        
        return aars, dom, jumps


class Eq(Sym):
    """
    equilibrium class
    """
    def __init__(self, a0, r, pSlice, toY, pFund, 
                 DoGetSliceState=True, DoCalculateEsEv=True, DoGetGroupOrbit=True):
        Sym.__init__(self, pSlice, toY, pFund)

        self.a0 = a0
        self.r = r              # error
        
        self.go = None          # group orbit
        self.so = None          # state in the slice
        self.es = None          # stability exponents
        self.ev = None          # stability eigenvectors
        self.evr = None         # stability eigenvectors in real format
        self.rev = None         # in-slice stability eigenvectors
       
        # ev is in cloumn format. While evr and rev are in row format

        if DoGetSliceState:
            self.so = self.ks.redO2f(self.a0, pSlice, pFund)[0]

        # E2 and E3 may be in the slice border, so
        # just obtain their group orbits  
        if DoGetGroupOrbit:
            n = 100
            self.go = np.zeros((n, self.N-2))
            for i in range(n):
                th = 2*i*np.pi / n
                self.go[i] = self.ks.Rotation(a0, th)

        # get the eigenvector of eq/req
        if DoCalculateEsEv:
            self.es, self.ev = self.getEsEv()
            self.evr = Tcopy(realve(self.ev))
            self.rev = self.ks.redV(self.evr, self.a0, self.pSlice, True)

    def getEsEv(self):
        es, ev = self.ksp.stabEig(self.a0)
        return es, ev
            

    def getMu(self, vId, T=200, r0=1e-5, nn=30):
        """
        obtain the unstable manifold of eq

        Some properties:
        1) unstable manifold of E2 is in the antisymmetric subspace.
        2) When we check the the correctness of rev of E3. rev[2]
           does not vanish becuase E3 is in the slice border.
        """
        v0, v1 = self.evr[vId], self.evr[vId+1]  # default case 2
        b = 1
        if np.iscomplex(self.es[vId]):  # case 1
            v1 = None
            b = 2 * np.pi * np.abs(self.es[vId].real / self.es[vId].imag)
        return self.getMuFullState(self.a0, v0, v1, T=T, r0=r0, nn=nn, b=b)

    
class Req(Eq):
    """
    relative equilibrium class
    """
    def __init__(self, a0, w, r, pSlice, toY, pFund,
                 DoGetSliceState=True, DoCalculateEsEv=True, DoGetGroupOrbit=True):
        self.w = w
        Eq.__init__(self, a0, r, pSlice, toY, pFund, DoGetSliceState, DoCalculateEsEv, DoGetGroupOrbit)

    def getEsEv(self):
         es, ev = self.ksp.stabReqEig(self.a0, self.w)
         return es, ev

class PPO(Sym):
    """
   ppo class
    """
    def __init__(self, a0, T, nstp, r, pSlice, toY, pFund,
                 DoGetFullOrbit=True, DoGetInsliceOrbit=True,
                 DoGetFundOrbit=True):
        Sym.__init__(self, pSlice, toY, pFund)

        self.a0 = a0
        self.T = T
        self.nstp = nstp
        self.r = r              # error

        self.fo = None          # full state space orbit
        self.so = None          # slice orbit
        self.fdo = None         # fundamental domain orbit
        self.po = None          # projected orbit

        self.pp = None          # Poincare point
        self.ppp = None         # Projected Poincare point

        self.dids = None        # domain ids
        self.jumps = None       # domain jump index
        self.ths = None         # slice angles
        
        ##########
        if DoGetFullOrbit:
            h = T / nstp
            self.fo = self.ks.intg(a0, h, nstp, 5)
            if DoGetInsliceOrbit:
                self.so, self.ths = self.ks.redSO2(self.fo, pSlice, toY)
                if DoGetFundOrbit:
                    self.fdo, self.dids = self.ks.fundDomain(self.so, pSlice, pFund)
                    self.jumps = getJumpPts(self.dids)

        

class RPO(PPO):
    """
    rpo class
    """
    def __init__(self, a0, T, nstp, r, s, pSlice, toY, pFund,
                 DoGetFullOrbit=True, DoGetInsliceOrbit=True,
                 DoGetFundOrbit=True):
        PPO.__init__(self, a0, T, nstp, r, pSlice, toY, pFund, 
                     DoGetFullOrbit, DoGetInsliceOrbit, DoGetFundOrbit)
        self.s = s              # shift
        
    

class Inv(Sym):
    """
    This class is designed to study the structure of KS
    system in the symmetry reduced fundamental state space.
    "Inv" means invariant structures in this system.
    
    Slice is chosen to make the pth mode's real part zero.
    Note, for 1st mode slice, E2 and E3 are on the slice border,
    it makes no sence to reduce symmetry for them, nor for the projection of
    vectors.
    """
    
    def __init__(self, reqFile, poFile, pSlice, toY, pFund, ppoIds=[], rpoIds=[]):
        """
        reqFile : the file storing reqs
        poFile: the file storing ppo/rpo and Floquet vectors
        -------
        Es      : the 3 equilibria 
        TWs     : the 2 relative equilibria
        ppos    : a list of ppo
        rpos    : a list of rpo
        ppoIds  : indices of ppo
        rpoIds  : indices of rpo
        """
        Sym.__init__(self, pSlice, toY, pFund)
        self.reqFile = reqFile
        self.poFile = poFile
        self.ppoIds = ppoIds
        self.rpoIds = rpoIds

        self.Es, self.TWs, self.ppos, self.rpos = [], [], [], []

        self.loadRE()
        self.loadPO()

    def loadRE(self):
        """
        load all req and eq and their corresponding
        symmetry reduced states in the fundamental
        domain.

        reqFile : path to the req data file
        p : the fourier mode used to reduce symmetry
        """
        
        # load req
        for i in range(2):
            a, w, err = self.ksp.readReq(self.reqFile, i+1)
            self.TWs.append(Req(a, w, err, self.pSlice, self.toY, self.pFund, self.ksp))
        
        # load eq
        for i in range(3):
            a, err = self.ksp.readEq(self.reqFile, i+1)
            self.Es.append(Eq(a, err, self.pSlice, self.toY, self.pFund, self.ksp))

        
    def loadPO(self):
        """
        Load rpo and ppo and reduce the symmetry.
        If bases and orgin x0 are given, then also return the
        projection.
        
        This functions is called in the constructor, but it can also 
        be called afterwards so as to refresh the rpo/ppo set        
        """
        self.ppos, self.rpos = [], []
        for i in self.ppoIds:
            a0, T, nstp, r, s = self.ksp.readPO(self.poFile, 'ppo', i)
            self.ppos.append(PPO(a0, T, nstp, r, self.pSlice, self.toY, self.pFund))
             
        for i in self.rpoIds:
            a0, T, nstp, r, s =  self.ksp.readPO(self.poFile, 'rpo', i)
            self.rpos.append(RPO(a0, T, nstp, r, s, self.pSlice, self.toY, self.pFund))


    def poPoincProject(self, bases, x0):
        for i in range(len(self.ppos)):
            self.ppos[i].ppp = (self.ppos[i].pp - x0).dot(bases.T)
        for i in range(len(self.rpos)):
            self.rpos[i].ppp = (self.rpos[i].pp - x0).dot(bases.T)

    def savePoPoincProject(self):
        ppo = []
        rpo = []
        for i in range(len(self.ppos)):
            ppo.append(self.ppos[i].ppp)
        for i in range(len(self.rpos)):
            rpo.append(self.rpos[i].ppp)
        np.savez_compressed('PoPoincare', ppo=ppo, rpo=rpo)

    def poFvPoinc(self, poType, poId, ptsId, p, ii, reflect=False):
        """
        get the in-slice Floquet vector
        """
        a0, T, nstp, r, s = KSreadPO(self.poFile, poType, poId)
        h = T / nstp
        aa = self.ks.intg(a0, h, nstp, 5)
        fe = KSreadFE(self.poFile, poType, poId)
        fv = KSreadFV(self.poFile, poType, poId)[ptsId].reshape(30, self.N-2)

        x0 = aa[ptsId]
        if reflect:
            x0 = self.ks.Reflection(x0)
            fv = self.ks.Reflection(fv)

        rfv = self.ks.redV(fv, x0, p, True)
        
        v1, v2, v3 = orthAxes(rfv[ii[0]], rfv[ii[1]], rfv[ii[2]])
        bases = np.vstack((v1, v2, v3))

        return fe, fv, rfv, bases
        


    def getMuAll(self, p, T=200, r0=1e-5, nn=30):
        """
        get the unstable manifolds af all eq/req
        """
        MuE = []
        for i in range(3):
            a0 = self.eqr[i]
            v0 = ksreq.Ev['e'][i][0]
            aars, dom, jumps = self.getMu(a0, v0, p, T=T, r0=r0, nn=nn)
            MuE.append([aars, dom, jumps])
            if i == 0:
                v0 = ksreq.Ev['e'][i][2]
                aars, dom, jumps = self.getMu(a0, v0, p, T=T, r0=r0, nn=nn)
                MuE.append([aars, dom, jumps])
            if i == 2:
                v0 = ksreq.Ev['e'][i][1]
                aars, dom, jumps = self.getMu(a0, v0, p, T=T, r0=r0, nn=nn)
                MuE.append([aars, dom, jumps])

        MuTw = []
        for i in range(2):
            a0 = self.reqr[i]
            v0 = ksreq.Ev['tw'][i][0]
            aars, dom, jumps = self.getMu(a0, v0, p, T=T, r0=r0, nn=nn)
            MuTw.append([aars, dom, jumps])
            if i == 0:
                v0 = ksreq.Ev['tw'][i][2]
                aars, dom, jumps = self.getMu(a0, v0, p, T=T, r0=r0, nn=nn)
                MuTw.append([aars, dom, jumps])

        return MuE, MuTw

    def plotRE(self, ax, ii, doProject=False, do3d=True):
        """
        construct the plotting block for req/eq
        """
        c1 = ['r', 'b']
        for i in range(2):
            x = self.TWs[i].so
            if do3d:
                ax.scatter(x[ii[0]], x[ii[1]], x[ii[2]],
                           c=c1[i], s=70,
                           edgecolors='none', label='TW'+str(i+1))
            else:
                ax.scatter(x[ii[0]], x[ii[1]], c=c1[i], s=70,
                           edgecolors='none', label='TW'+str(i+1))

        c2 = ['c', 'k', 'y']
        for i in range(3):
            x = self.Es[i].so
            if do3d:
                ax.scatter(x[ii[0]], x[ii[1]], x[ii[2]],
                           c=c2[i], s=70,
                           edgecolors='none', label='E'+str(i+1))
            else:
                ax.scatter(x[ii[0]], x[ii[1]], c=c2[i], s=70,
                           edgecolors='none', label='E'+str(i+1))

    def plotFundOrbit(self, ax, faa, jumps, ii, c=None, alpha=0.5, lw=1,
                      label=None):
        """
        plot orbit in the fundamental domain. sudden jumps are avoided.
        
        faa : a single orbit in the fundamental domain
        jumps : indices where orbit jumps from one domain to another
        ii : the plot index
        """
        if c is None:
            c = rand(3, 1)

        x = np.concatenate(([-1], jumps, [len(faa)-1]))
        for i in range(len(x)-1):
            r = range(x[i]+1, x[i+1]+1)
            if i == 0:
                ax.plot(faa[r, ii[0]], faa[r, ii[1]], faa[r, ii[2]],
                        c=c, alpha=alpha, lw=lw, label=label)
            else:
                ax.plot(faa[r, ii[0]], faa[r, ii[1]], faa[r, ii[2]],
                        c=c, alpha=alpha, lw=lw)

    def getBases(self, etype, eId, ii):
        """
        get projection bases

        x0 : origin
        bases : selected bases
        """
        v = self.Evr[etype][eId]
        v1, v2, v3 = orthAxes(v[ii[0]], v[ii[1]], v[ii[2]])
        bases = np.vstack((v1, v2, v3))

        x0 = self.Eqr[etype][eId].dot(bases.T)

        self.EqrP['e'] = self.Eqr['e'].dot(bases.T) - x0
        self.EqrP['tw'] = self.Eqr['tw'].dot(bases.T) - x0
        
        E2 = self.Eg['E2'].dot(bases.T) - x0
        E3 = self.Eg['E3'].dot(bases.T) - x0
        self.EgP = {'E2': E2, 'E3': E3}

        return x0, bases

    def getPoinc(self, raa, jumps, first):
        """
        get the poincare intersection points. Poincare section is
        b_2 = 0 from negative to positive. Note it is very important to
        record the point after crossing Poincare section. Also both
        crossings are recorded due to reflection symmetry, but the
        order should be shuffled.
        --------
        Paramters
        raa : orbit in the fundamental domain
        dids : indices of regions
        jumps : indices when orbit crosses Poincare section
        
        Return
        borderIds : indices of intersection points which are in the 1st region
        borderPts : the corresponding points
        start : starting index from negative to positive
        """
        case = 1
        if case == 1:
            """
            Poincare section is the reflection border
            """
            n = len(jumps)
            borderPts = np.zeros((n, raa.shape[1]))
            # for i in range(n):
            #     j = jumps[i]
            #     if j < 0:
            #         # interp1d works for every row
            #         f = interp1d(raa[j-1:j+2, 2], raa[j-1:j+2].T, kind='quadratic')
            #     else:
            #         f = interp1d(raa[j:j+2, 2], raa[j:j+2].T, kind='linear')
            #     borderPts[i] = f(0)
            
            for i in range(n):
                j = jumps[i]
                x1, x2 = raa[j], raa[j+1]
                x1 = self.ks.Reflection(x1)
                p = np.vstack((x1, x2))
                f = interp1d(p[:, 2], p.T, kind='linear')
                borderPts[i] = f(0)

        if case == 2:
            """
            c_1 = 0.3 is the Poincare section
            """
            n = raa.shape[0]
            borderPts = np.zeros((0, raa.shape[1]))
            for i in range(n-1):
                if raa[i, 6] < 0 and raa[i+1, 6] > 0:
                    borderPts = np.vstack((borderPts, raa[i]))
            
        return borderPts
<file_sep>#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <Eigen/Dense>
#include <cstdio>

#include "CQCGL2dReq.hpp"
#include "myBoostPython.hpp"

using namespace std;
using namespace Eigen;
namespace bp = boost::python;
namespace bn = boost::numpy;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class pyCQCGL2dReq : public CQCGL2dReq {
  
public:

    pyCQCGL2dReq(int N, int M, double dx, double dy,
		 double Mu, double Dr, double Di,
		 double Br, double Bi, double Gr,
		 double Gi,  
		 int threadNum) :
	CQCGL2dReq(N, M, dx, dy, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) {}
    
    pyCQCGL2dReq(int N, double dx,
		 double Mu, double Dr, double Di,
		 double Br, double Bi, double Gr,
		 double Gi,  
		 int threadNum) :
	CQCGL2dReq(N, dx, Mu, Dr, Di, Br, Bi, Gr, Gi, threadNum) {}

    pyCQCGL2dReq(int N, int M,  double dx, double dy, 
		 double b, double c, double dr, double di, 
		 int threadNum) :
	CQCGL2dReq(N, M, dx, dy, b, c, dr, di, threadNum) {}
    
    pyCQCGL2dReq(int N, double dx,
		 double b, double c, double dr, double di,
		 int threadNum) :
	CQCGL2dReq(N, dx, b, c, dr, di, threadNum) {}
    
    bn::ndarray PYTs(){
	return copy2bn(Ts);
    }

    bn::ndarray PYlte(){
	return copy2bn(lte);
    }

    bn::ndarray PYhs(){
	return copy2bn(hs);
    }

    /* Kx */
    bn::ndarray PYKx(){
	return copy2bn(Kx);
    }

    /* Ky */
    bn::ndarray PYKy(){
	return copy2bn(Ky);
    }
    
    /* L */
    bn::ndarray PYL(){
	return copy2bnc(L);
    }

   /* wrap the integrator */
    bn::ndarray PYintg(bn::ndarray a0, double h, int Nt, int skip_rate, 
		       bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(intg(tmpa, h, Nt, skip_rate, doSaveDisk, fileName));
    }
    
    bn::ndarray PYaintg(bn::ndarray a0, double h, double tend, int skip_rate,
			bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(aintg(tmpa, h, tend, skip_rate, doSaveDisk, fileName));
    }

    bn::ndarray PYintgv(bn::ndarray a0, bn::ndarray v0, double h, int Nt, int skip_rate,
			bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);
	return copy2bnc(intgv(tmpa, tmpv, h, Nt, skip_rate, doSaveDisk, fileName));
    }    

    bn::ndarray PYaintgv(bn::ndarray a0, bn::ndarray v0, double h, double tend, int skip_rate,
			 bool doSaveDisk, string fileName){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	getDims(v0, m, n);
	Map<ArrayXXcd> tmpv((dcp*)v0.get_data(), n, m);
	return copy2bnc(aintgv(tmpa, tmpv, h, tend, skip_rate, doSaveDisk, fileName));
    }

    bn::ndarray PYFourier2Config(bn::ndarray aa){
	int m, n;
	getDims(aa, m, n);
	Map<ArrayXXcd> tmpaa((dcp*)aa.get_data(), n, m);
	return copy2bnc( Fourier2Config(tmpaa) );
    }

    bn::ndarray PYConfig2Fourier(bn::ndarray AA){
	int m, n;
	getDims(AA, m, n);
	Map<ArrayXXcd> tmpAA((dcp*)AA.get_data(), n, m);
	return copy2bnc( Config2Fourier(tmpAA) );
    }

    bn::ndarray PYvelocity(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(velocity(tmpa));
    }

    bn::ndarray PYvelocityReq(bn::ndarray a0, double wthx, 
			      double wthy, double wphi){
	int m, n;
	getDims(a0, m, n);	
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	return copy2bnc(velocityReq(tmpa, wthx, wthy, wphi));
    }

    bp::tuple PYfindReq_hook(bn::ndarray x0, double wthx0, double wthy0, double wphi0){
	int m, n;
	getDims(x0, m, n);
	Map<ArrayXXcd> tmpx0((dcp*)x0.get_data(), n, m);
	
	auto result = findReq_hook(tmpx0, wthx0, wthy0, wphi0);
	return bp::make_tuple(copy2bnc(std::get<0>(result)),
			      std::get<1>(result),
			      std::get<2>(result),
			      std::get<3>(result),
			      std::get<4>(result)
			      );
    }
    
    bn::ndarray PYoptReqTh(bn::ndarray a0){
	int m, n;
	getDims(a0, m, n);
	Map<ArrayXXcd> tmpa((dcp*)a0.get_data(), n, m);
	
	return copy2bn(optReqTh(tmpa));
    }
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



BOOST_PYTHON_MODULE(py_CQCGL2dReq) {
    bn::initialize();
    
    // must provide the constructor
    bp::class_<CQCGL2dReq>("CQCGL2dReq", bp::init<
			   int, double, 
			   double, double, double, double, 
			   int>())
	;
    
    
    bp::class_<pyCQCGL2dReq, bp::bases<CQCGL2dReq> >("pyCQCGL2dReq", bp::init<
						     int, double, 
						     double, double, double, double,
						     int>())
	.def(bp::init<int, int, double, double,
	     double, double, double,
	     double, double, double,
	     double,
	     int>())
	.def(bp::init<int, double,
	     double, double, double,
	     double, double, double,
	     double,
	     int>())
	.def(bp::init<int, int, double, double,
	     double, double, double, double, 
	     int>())
	.def_readonly("N", &pyCQCGL2dReq::N)
	.def_readonly("M", &pyCQCGL2dReq::M)
	.def_readonly("dx", &pyCQCGL2dReq::dx)
	.def_readonly("dy", &pyCQCGL2dReq::dy)
	.def_readonly("Mu", &pyCQCGL2dReq::Mu)
	.def_readonly("Br", &pyCQCGL2dReq::Br)
	.def_readonly("Bi", &pyCQCGL2dReq::Bi)
	.def_readonly("Dr", &pyCQCGL2dReq::Dr)
	.def_readonly("Di", &pyCQCGL2dReq::Di)
	.def_readonly("Gr", &pyCQCGL2dReq::Gr)
	.def_readonly("Gi", &pyCQCGL2dReq::Gi)
	.def_readonly("Ne", &pyCQCGL2dReq::Ne)
	.def_readonly("Me", &pyCQCGL2dReq::Me)
	// .def_readonly("b", &pyCQCGL2dReq::b)
	// .def_readonly("c", &pyCQCGL2dReq::c)
	// .def_readonly("dr", &pyCQCGL2dReq::dr)
	// .def_readonly("di", &pyCQCGL2dReq::di)
	.def_readonly("Omega", &pyCQCGL2dReq::Omega)
	.def_readwrite("rtol", &pyCQCGL2dReq::rtol)
	.def_readwrite("nu", &pyCQCGL2dReq::nu)
	.def_readwrite("mumax", &pyCQCGL2dReq::mumax)
	.def_readwrite("mumin", &pyCQCGL2dReq::mumin)
	.def_readwrite("mue", &pyCQCGL2dReq::mue)
	.def_readwrite("muc", &pyCQCGL2dReq::muc)
	.def_readwrite("NCalCoe", &pyCQCGL2dReq::NCalCoe)
	.def_readwrite("NReject", &pyCQCGL2dReq::NReject)
	.def_readwrite("NCallF", &pyCQCGL2dReq::NCallF)
	.def_readwrite("NSteps", &pyCQCGL2dReq::NSteps)
	.def_readwrite("Method", &pyCQCGL2dReq::Method)
	.def_readwrite("constETDPrint", &pyCQCGL2dReq::constETDPrint)

	.def_readwrite("tol", &pyCQCGL2dReq::tol)
	.def_readwrite("minRD", &pyCQCGL2dReq::minRD)
	.def_readwrite("maxit", &pyCQCGL2dReq::maxit)
	.def_readwrite("maxInnIt", &pyCQCGL2dReq::maxInnIt)
	.def_readwrite("GmresRtol", &pyCQCGL2dReq::GmresRtol)
	.def_readwrite("GmresRestart", &pyCQCGL2dReq::GmresRestart)
	.def_readwrite("GmresMaxit", &pyCQCGL2dReq::GmresMaxit)

	.def("Ts", &pyCQCGL2dReq::PYTs)
	.def("hs", &pyCQCGL2dReq::PYhs)
	.def("lte", &pyCQCGL2dReq::PYlte)
	.def("Kx", &pyCQCGL2dReq::PYKx)
	.def("Ky", &pyCQCGL2dReq::PYKy)
	.def("L", &pyCQCGL2dReq::PYL)

	.def("changeOmega", &pyCQCGL2dReq::changeOmega)
	.def("intg", &pyCQCGL2dReq::PYintg)
	.def("aintg", &pyCQCGL2dReq::PYaintg)
	.def("intgv", &pyCQCGL2dReq::PYintgv)
	.def("aintgv", &pyCQCGL2dReq::PYaintgv)
	.def("Fourier2Config", &pyCQCGL2dReq::PYFourier2Config)
	.def("Config2Fourier", &pyCQCGL2dReq::PYConfig2Fourier)
	.def("velocity", &pyCQCGL2dReq::PYvelocity)
	.def("velocityReq", &pyCQCGL2dReq::PYvelocityReq)
	.def("findReq_hook", &pyCQCGL2dReq::PYfindReq_hook)
	.def("optReqTh", &pyCQCGL2dReq::PYoptReqTh) 
	;

}
<file_sep>##################################################
# Functions tool set 
##################################################
from time import time
import h5py
import matplotlib
#matplotlib.use('Qt4Agg')
#matplotlib.use('Qt5Agg')
#from pylab import *
import numpy as np
from numpy.random import rand
from scipy.spatial.distance import pdist, cdist, squareform
import numpy.linalg as LA
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d
import matplotlib.animation as animation
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import os
import subprocess as sps

from numpy.linalg import norm
from matplotlib.ticker import AutoMinorLocator

from bisect import bisect_left

##################################################
#               Plot related                     #
##################################################


class Arrow3D(FancyArrowPatch):
    """
    The 3d arrow class
    """
    def __init__(self, xs, ys, zs, *args, **kwargs):
        FancyArrowPatch.__init__(self, (0, 0), (0, 0), *args, **kwargs)
        self._verts3d = xs, ys, zs

    def draw(self, renderer):
        xs3d, ys3d, zs3d = self._verts3d
        xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
        self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
        FancyArrowPatch.draw(self, renderer)

    def setvalue(self, x, y, z):
        self._verts3d = x, y, z


def plinit(size=[8, 6]):
    fig = plt.figure(figsize=size)
    return fig


def ax3dinit(fig, num=111, labs=[r'$x$', r'$y$', r'$z$'], axisLabelSize=25,
             tickSize=None,
             xlim=None, ylim=None, zlim=None, isBlack=False):
    ax = fig.add_subplot(num, projection='3d')

    if labs[0] is not None:
        ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    if labs[1] is not None:
        ax.set_ylabel(labs[1], fontsize=axisLabelSize)
    if labs[2] is not None:
        ax.set_zlabel(labs[2], fontsize=axisLabelSize)

    if tickSize is not None:
        ax.tick_params(axis='both', which='major', labelsize=tickSize)

    if xlim is not None:
        ax.set_xlim(xlim)
    if ylim is not None:
        ax.set_ylim(ylim)
    if zlim is not None:
        ax.set_zlim(zlim)

    if isBlack:
        fig.patch.set_facecolor('black')
        ax.patch.set_facecolor('black')

    return ax


def pl3d(size=[8, 6], labs=[r'$x$', r'$y$', r'$z$'], axisLabelSize=25,
         tickSize=None,
         xlim=None, ylim=None, zlim=None, isBlack=False):
    fig = plinit(size=size)
    ax = ax3dinit(fig, labs=labs, axisLabelSize=axisLabelSize,
                  tickSize=tickSize,
                  xlim=xlim, ylim=ylim, zlim=zlim, isBlack=isBlack)
    return fig, ax


def ax3d(fig, ax, doBlock=False, save=False, name='output.png',
         angle=None, title=None,
         loc='best', alpha=0.2, picForm='png'):
    fig.tight_layout(pad=0)

    if angle is not None:
        ax.view_init(angle[0], angle[1])
    
    if title is not None:
        ax.set_title(title)

    ax.legend(loc=loc, framealpha=alpha)
    if save:
        plt.savefig(name, format=picForm)
        plt.close()
    else:
        plt.show(block=doBlock)


def add3d(fig, ax, x, y, z, maxShow=5, c='r', s=70):
    i = 0
    pts = []
    while raw_input(i) == '':
        if i >= len(x):
            for p in pts:
                p.remove()
            break
        
        if len(pts) > maxShow:
            p = pts.pop(0)
            p.remove()
           
        if len(pts) > 0:
            pts[-1].set_sizes([2*s])
        if len(pts) > 1:
            pts[-2].set_sizes([s])

        tmp = ax.scatter(x[i], y[i], z[i], c=c, s=s,
                         edgecolors='none')
        pts.append(tmp)
        fig.canvas.draw()
        # plt.show(block=False)
        i += 1
    

def ax2dinit(fig, num=111, labs=[r'$x$', r'$y$'], axisLabelSize=25,
             xscale=None,
             yscale=None, xlim=None, ylim=None, tickSize=None,
             isBlack=False, ratio='auto'):
    ax = fig.add_subplot(num)
    
    if labs[0] is not None:
        ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    if labs[1] is not None:
        ax.set_ylabel(labs[1], fontsize=axisLabelSize)

    if xscale is not None:
        ax.set_xscale(xscale)

    if yscale is not None:
        ax.set_yscale(yscale)

    if tickSize is not None:
        ax.tick_params(axis='both', which='major', labelsize=tickSize)
        
    if xlim is not None:
        ax.set_xlim(xlim)
    if ylim is not None:
        ax.set_ylim(ylim)

    if isBlack:
        fig.patch.set_facecolor('black')
        ax.patch.set_facecolor('black')

    ax.set_aspect(ratio)
    
    return ax


def pl2d(size=[8, 6], num=111, labs=[r'$x$', r'$y$'], axisLabelSize=25,
         xscale=None, yscale=None, xlim=None, ylim=None, tickSize=None,
         isBlack=False, ratio='auto'):
    fig = plt.figure(figsize=size)
    ax = ax2dinit(fig, num=111, labs=labs, axisLabelSize=axisLabelSize, xscale=xscale,
                  yscale=yscale, xlim=xlim, ylim=ylim, tickSize=tickSize,
                  isBlack=isBlack, ratio=ratio)
    return fig, ax


def ax2d(fig, ax, doBlock=False, save=False, name='output',
         title=None, loc='best', alpha=0.2):
    fig.tight_layout(pad=0)
    if title is not None:
        print "aaa"
        ax.set_title(title)

    ax.legend(loc=loc, framealpha=alpha)
    if save:
        plt.savefig(name + '.png', format='png')
        # plt.savefig(name + '.eps', format='eps')
        plt.close()
    else:
        plt.show(block=doBlock)


def makeMovie(data):
    fig, ax = pl3d()
    frame, = ax.plot([], [], [], c='red', ls='-', lw=1, alpha=0.5)
    pts, = ax.plot([], [], [], 'co', lw=3)

    def anim(i):
        j = min(i, data.shape[0])
        frame.set_data(data[:j, 0], data[:j, 1])
        frame.set_3d_properties(data[:j, 2])
        pts.set_data(data[j, 0], data[j, 1])
        pts.set_3d_properties(data[j, 2])
        
        ax.view_init(30, 0.5 * i)
        return frame, pts

    ani = animation.FuncAnimation(fig, anim, frames=data.shape[0],
                                  interval=0, blit=False, repeat=False)
    # ax3d(fig, ax)
    ax.legend()
    fig.tight_layout(pad=0)
    # ani.save('ani.mp4', dpi=200, fps=30, extra_args=['-vcodec', 'libx264'])
    plt.show()


def plot1dfig(x, c='r', lw=1, ls='-', marker=None, labs=[r'$x$', r'$y$'],
              size=[8, 6], axisLabelSize=25, yscale=None):
    """
    plot 2d figures in genereal
    """
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    ax.plot(x, c=c, lw=lw, ls=ls, marker=marker)
    if labs[0] is not None:
        ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    if labs[1] is not None:
        ax.set_ylabel(labs[1], fontsize=axisLabelSize)
    if yscale is not None:
        ax.set_yscale(yscale)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def plot2dfig(x, y, c='r', lw=1, ls='-', labs=[r'$x$', r'$y$'],
              size=[8, 6], axisLabelSize=25):
    """
    plot 2d figures in genereal
    """
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    ax.plot(x, y, c=c, lw=lw, ls=ls)
    ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    ax.set_ylabel(labs[1], fontsize=axisLabelSize)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def scatter2dfig(x, y, s=20, marker='o', fc='r', ec='none',
                 labs=[r'$x$', r'$y$'],
                 size=[8, 6], axisLabelSize=25, ratio='auto'):
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    ax.scatter(x, y, s=s, marker=marker,
               facecolor=fc, edgecolors=ec)
    ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    ax.set_ylabel(labs[1], fontsize=axisLabelSize)
    ax.set_aspect(ratio)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def plot3dfig(x, y, z, c='r', lw=1, labs=[r'$x$', r'$y$', r'$z$'],
              size=[8, 6], axisLabelSize=25):
    """
    plot 3d figures in genereal
    """
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(x, y, z, c=c, lw=lw)
    ax.set_xlabel(labs[0], fontsize=axisLabelSize)
    ax.set_ylabel(labs[1], fontsize=axisLabelSize)
    ax.set_zlabel(labs[2], fontsize=axisLabelSize)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def plotMat(y, colortype='jet', percent='5%', colorBar=True,
            save=False, name='out.png'):
    """
    plot a matrix
    """
    fig = plt.figure()
    ax = fig.add_subplot(111)
    im = ax.matshow(y, cmap=plt.get_cmap(colortype))
    ax.grid('on')
    if colorBar:
        dr = make_axes_locatable(ax)
        cax = dr.append_axes('right', size=percent, pad=0.05)
        plt.colorbar(im, cax=cax)
    if save:
        plt.savefig(name)
        plt.close()
    else:
        plt.show(block=False)


def plotIm(y, ext, size=[4, 5], labs=[r'$x$', r'$y$'], colortype='jet', percent='5%',
           axisLabelSize=25, barTicks=None, tickSize=None, save=False, name='out.png'):
    """
    plot the imag color map of a matrix. It has more control compared with plotMat
    """
    fig, ax = pl2d(size=size, labs=labs, axisLabelSize=axisLabelSize)
    im = ax.imshow(y, cmap=plt.get_cmap(colortype), extent=ext,
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size=percent, pad=0.05)

    if barTicks is not None:
        plt.colorbar(im, cax=cax, ticks=barTicks)
    else:
        plt.colorbar(im, cax=cax)

    if tickSize is not None:
        ax.tick_params(axis='both', which='major', labelsize=tickSize)
    
    ax2d(fig, ax, save=save, name=name)


def plotContour(z, x=None, y=None, size=[8, 6], labs=[r'$x$', r'$y$'],
                axisLabelSize=25,
                save=False, name='output.png', title=None, loc='best'):
    fig, ax = pl2d(size=size, labs=labs, axisLabelSize=axisLabelSize)
    if x is None or y is None:
        m, n = z.shape
        x = np.arange(n)
        y = np.arange(m)
    X, Y = np.meshgrid(x, y)
    CS = ax.contour(X, Y, z)
    ax.clabel(CS, inline=1, fontsize=10)
    ax2d(fig, ax, save=save, name=name, title=title, loc=loc)

############################################################
#                        Common functions                  #
############################################################

def sortByReal(eigvalue, eigvector=None):
    indx = np.argsort(eigvalue.real)
    indx = indx[::-1]
    if eigvector is None:
        return eigvalue[indx]
    else:
        return eigvalue[indx], eigvector[:, indx]


def pAngleVQ(V, Q):
    """
    compute the angle between a vector V and set of vectors Q
    Q is an orthonormal matrix
    """
    assert V.ndim == 1
    V = V / LA.norm(V)
    c = LA.norm(np.dot(Q.T, V))
    if (c > 1):
        c = 1
    return np.arccos(c)


def pAngle(V, U):
    """
    compute the principle angle between a vector V and a subspace U
    """
    q = LA.qr(U)[0]
    return pAngleVQ(V, q)

def vecAngle(v, u):
    """
    compute the angle between two vectors
    """
    return np.arccos(v.dot(u) / norm(v) / norm(u))


def seqAng(seqDifv, U):
    """
    seqDifv is a sequence of row vector
    """
    q = LA.qr(U)[0]
    M, N = seqDifv.shape
    ang = np.zeros(M)
    for i in range(M):
        ang[i] = pAngle(seqDifv[i, :], q)
    return ang


def findMarginal(e, k):
    """
    find the position of marginal exponents
    """
    ix = argsort(abs(e))
    return ix[:k]


def removeMarginal(e, k):
    ix = findMarginal(e, k)
    ep = [i for i in e if i not in e[ix]]
    return ep


def centerRand(N, frac, isComplex=True):
    """
    generate a localized random vector.
    frac: the fraction of the nonzero center in the totol size
    """
    if isComplex:
        a = rand(N) + 1j*rand(N)
    else:
        a = rand(N)
        
    N2 = np.int((1-frac)*0.5*N)
    a[:N2] = 0
    a[-N2:] = 0
    return a


def centerRand2d(M, N, f1, f2, isComplex=True):
    """
    generatate a localized random MxN matrix
    """
    if isComplex:
        a = rand(M, N) + 1j*rand(M, N) + 0.5
    else:
        a = rand(M, N)
    
    M2 = np.int((1-f1)*0.5*M)
    N2 = np.int((1-f2)*0.5*N)
    a[:M2, :] = 0
    a[-M2:, :] = 0
    a[:, :N2] = 0
    a[:, -N2:] = 0
    return a


def centerOne(N, frac):
    """
    generate a localized random vector.
    frac: the fraction of the nonzero center in the totol size
    """
    a = ones(N)
    N2 = np.int((1-frac)*0.5*N)
    a[:N2] = 0
    a[-N2:] = 0
    return a


def Tcopy(x):
    """
    transpose and change the memory layout
    """
    m, n = x.shape
    y = np.zeros((n, m))
    for i in range(n):
        y[i] = x[:, i]

    return y


def realve(ve):
    """
    transform complex vectors to real format
    """
    n, m = ve.shape
    rve = np.zeros((n, m))
    i = 0
    while i < m:
        if np.sum(np.iscomplex(ve[:, i])) > 0:
            rve[:, i] = ve[:, i].real
            rve[:, i+1] = ve[:, i].imag
            i = i+2
        else:
            rve[:, i] = ve[:, i].real
            i = i+1

    return rve


def orthAxes2(e1, e2):
    """
    construct an orthogonal two vectors from 2 general vectors.
    """
    n = e1.shape[0]
    x = np.zeros((n, 2))
    x[:, 0] = e1
    x[:, 1] = e2
    q, r = LA.qr(x)

    return q[:, 0], q[:, 1]


def orthAxes(e1, e2, e3):
    n = e1.shape[0]
    x = np.zeros((n, 3))
    x[:, 0] = e1
    x[:, 1] = e2
    x[:, 2] = e3
    q, r = LA.qr(x)             # q is a [N x 3] matrix

    # return q[:, 0], q[:, 1], q[:, 2]
    return q                    


def mag2vec(v1, v2):
    return np.sqrt(v1**2 + v2**2)


def normR(x):
    """
    the norm of each row of a matrix
    """
    return norm(x, axis=1)


def int2p(x, y, k=0):
    """
    interpolate two points
    """
    c1 = y[k] / (y[k] - x[k])
    c2 = -x[k] / (y[k] - x[k])
    return c1 * x + c2 * y, c1


def rotz(x, y, th):
    """
    rotate by z axis
    """
    c = np.cos(th)
    s = np.sin(th)
    return c * x - s * y, s * x + c * y


def difMap(x, farSize, size=[6, 6], percent='5%', colortype='jet'):
    m, n = x.shape
    y = np.zeros((m, farSize))
    for i in range(m-farSize):
        y[i] = norm(x[i]-x[i:i+farSize], axis=1)
    
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    # ax.set_xlabel('x', fontsize=axisLabelSize)
    # ax.set_ylabel('t', fontsize=axisLabelSize)
    im = ax.imshow(y, cmap=plt.get_cmap(colortype),
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size=percent, pad=0.05)
    plt.colorbar(im, cax=cax)
    fig.tight_layout(pad=0)
    plt.show(block=False)


def difMap2(x1, x2, size=[6, 4], percent='5%', colortype='jet'):
    """
    try to locate the possible po
    """
    y = cdist(x1, x2)
    
    fig = plt.figure(figsize=size)
    ax = fig.add_subplot(111)
    # ax.set_xlabel('x', fontsize=axisLabelSize)
    # ax.set_ylabel('t', fontsize=axisLabelSize)
    im = ax.imshow(y, cmap=plt.get_cmap(colortype),
                   aspect='auto', origin='lower')
    ax.grid('on')
    dr = make_axes_locatable(ax)
    cax = dr.append_axes('right', size=percent, pad=0.05)
    plt.colorbar(im, cax=cax)
    fig.tight_layout(pad=0)
    plt.show(block=False)

    
def getJumpPts(x):
    """
    for a sequence of integers x, try to get the
    locations when it jumps
    """
    n = x.shape[0]
    d = x[1:] - x[:-1]
    y = np.arange(n-1)
    y = y[d != 0]
    return y

def numStab(e, nmarg=2, tol=1e-8, flag=0):
    """
    get the number of unstable exponents. Assume e is sorted by its
    real part. 

    Parameters
    ======
    nmarg : number of marginal eigenvalues of expolents
    flag :  flag = 0 => exponents; flag = 1 => eigenvalues
    tol :  tolerance to judge marginal exponents

    Return
    ======
    m : number of unstable exponents or starting index for marginal
        exponent
    ep : exponents without marginal ones
    """
    accu = True
    if flag == 0:
        x = e.real
    else:
        x = np.log(np.abs(e))

    n = len(x)
    m = n-1
    for i in range(n):
        if abs(x[i]) < tol:
            m = i
            break

    if m >= n-1:
        accu = False
    else:
        for i in range(m+1, min(m+nmarg, n)):
            if abs(x[i]) > tol:
                accu = False
                break

    ep = np.delete(e, range(m, m+nmarg))
    return m, ep, accu

<file_sep>import h5py
import numpy as np
from numpy.linalg import norm
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import scipy.io as sio
# from IPython.display import display
# from IPython.html.widgets import interact
from py_ks import *
from personalFunctions import *

##################################################
# load data
f = h5py.File('../../data/myN32/ks22h02t100EV.h5', 'r')

dataName1 = '/ppo/1/'
a1 = f[dataName1 + 'a'].value
T1 = f[dataName1 + 'T'].value[0]
nstp1 = np.int(f[dataName1 + 'nstp'].value[0])
h1 = T1 / nstp1
e1 = f[dataName1 + 'e'].value
ve1 = f[dataName1 + 've'].value

dataName2 = '/rpo/2/'
a2 = f[dataName2 + 'a'].value
T2 = f[dataName2 + 'T'].value[0]
nstp2 = np.int(f[dataName2 + 'nstp'].value[0])
h2 = T2 / nstp2
e2 = f[dataName2 + 'e'].value
ve2 = f[dataName2 + 've'].value

##################################################
# different experimental cases

case = 3

if case == 1:
    """
    visualize the orbit after reduce reflection symmetry
    projected into Fourier space
    """
    ks1 = pyKS(32, h1, 22)
    aa1 = ks1.intg(a1, nstp1, 1)
    aa1 = aa1[:-1]
    # aaWhole1 = ks1.half2whole(aa1)
    aaWhole1 = aa1
    aaHat1, ang1 = ks1.orbitToSlice(aaWhole1)
    aaTilde1 = ks1.reduceReflection(aaHat1)
    plot3dfig(aaHat1[:, 0], aaHat1[:, 2], aaHat1[:, 3])
    plot3dfig(aaTilde1[:, 0], aaTilde1[:, 2], aaTilde1[:, 3])

if case == 2:
    """
    see how ppo2 is shadowed by rpo1 after reducing O2 symmetry.
    Note: only integrate one period
    """
    ks1 = pyKS(32, h1, 22)
    aa1 = ks1.intg(a1, nstp1, 1)[:-1]
    aaWhole1 = aa1
    aaHat1, ang1 = ks1.orbitToSlice(aaWhole1)
    aaTilde1 = ks1.reduceReflection(aaHat1)

    ks2 = pyKS(32, h2, 22)
    aa2 = ks2.intg(a2, nstp2, 1)
    aa2 = aa2[:-1]
    aaHat2, ang2 = ks2.orbitToSlice(aa2)
    aaTilde2 = ks2.reduceReflection(aaHat2)

    plot3dfig2lines(aaTilde1[:, 0], aaTilde1[:, 2], aaTilde1[:, 3],
                    aaTilde2[:, 0], aaTilde2[:, 2], aaTilde2[:, 3])
    
if case == 3:
    """
    visualize how Floquet vectors are aligned along ppo/rpo
    """
    ks1 = pyKS(32, h1, 22)
    aa1 = ks1.intg(a1, nstp1, 1)
    aa1 = aa1[:-1]
    aaWhole1 = ks1.half2whole(aa1)
    veWhole1 = ks1.half2whole(ve1)
    aaHat1, ang1 = ks1.orbitToSlice(aaWhole1)
    vep1 = ks1.veToSliceAll(veWhole1, aaWhole1, 0)

    ks2 = pyKS(32, h2, 22)
    aa2 = ks2.intg(a2, nstp2, 1)
    aa2 = aa2[:-1]
    aaHat2, ang2 = ks2.orbitToSlice(aa2)
    vep2 = ks2.veToSliceAll(ve2, aa2, 0)

    i1 = 0
    i2 = 2
    i3 = 3

    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aaHat1[:, i1], aaHat1[:, i2], aaHat1[:, i3], 'r')
    ax.plot(aaHat2[:, i1], aaHat2[:, i2], aaHat2[:, i3], 'g')

    spa = 70

    ratio1 = 5
    veIndex1 = 1
    ah1 = aaHat1
    nor1 = norm(vep1[veIndex1::30], axis=1)
    nor1.resize((nor1.size, 1))
    ae1 = aaHat1 + vep1[veIndex1::30] / nor1 / ratio1

    ratio2 = 5
    veIndex2 = 1
    ah2 = aaHat2
    nor2 = norm(vep2[veIndex2::30], axis=1)
    nor2.resize((nor2.size, 1))
    ae2 = aaHat2 + vep2[veIndex2::30] / nor2 / ratio2

    shift = 900
    ah1 = np.vstack((ah1[shift:], ah1[:shift]))
    ae1 = np.vstack((ae1[shift:], ae1[:shift]))

    for i in np.arange(0, aaHat1.shape[0]/2, spa):
        a1 = Arrow3D([ah1[i, i1], ae1[i, i1]], [ah1[i, i2], ae1[i, i2]],
                     [ah1[i, i3], ae1[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="m")
        ax.add_artist(a1)

    for i in np.arange(0, aaHat2.shape[0], spa):
        a2 = Arrow3D([ah2[i, i1], ae2[i, i1]], [ah2[i, i2], ae2[i, i2]],
                     [ah2[i, i3], ae2[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="k")
        ax.add_artist(a2)

    ax.set_xlabel(r'$b_1$')
    ax.set_ylabel(r'$b_2$')
    ax.set_zlabel(r'$c_2$')
    plt.tight_layout(pad=0)
    plt.show(block=False)

if case == 4:
    """
    visualize how Floquet vectors are aligned along ppo/rpo
    afeter reducing both rotation and reflection
    """
    ks1 = pyKS(32, h1, 22)
    aa1 = ks1.intg(a1, nstp1, 1)[:-1]
    aaHat1, ang1 = ks1.orbitToSlice(aa1)
    vep1 = ks1.veToSliceAll(ve1, aa1, 0)
    aaTilde1 = ks1.reduceReflection(aaHat1)
    veTilde1 = ks1.reflectVeAll(vep1, aaHat1, 0)

    ks2 = pyKS(32, h2, 22)
    aa2 = ks2.intg(a2, nstp2, 1)[:-1]
    aaHat2, ang2 = ks2.orbitToSlice(aa2)
    vep2 = ks2.veToSliceAll(ve2, aa2, 0)
    aaTilde2 = ks2.reduceReflection(aaHat2)
    veTilde2 = ks2.reflectVeAll(vep2, aaHat2, 0)

    # load Burak's axes.
    # comment out this part if using Fourier modes projection
    ee = sio.loadmat('ee.mat')['ee'][:3].T
    aaTilde1 = np.dot(aaTilde1, ee)
    veTilde1 = np.dot(veTilde1, ee)
    aaTilde2 = np.dot(aaTilde2, ee)
    veTilde2 = np.dot(veTilde2, ee)
    i1 = 0
    i2 = 1
    i3 = 2

    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111, projection='3d')
    ax.plot(aaTilde1[:, i1], aaTilde1[:, i2], aaTilde1[:, i3], 'r')
    ax.plot(aaTilde2[:, i1], aaTilde2[:, i2], aaTilde2[:, i3], 'g')

    spa = 60

    ratio1 = 5
    ah1 = aaTilde1
    veIndex1 = 0
    nor1 = norm(veTilde1[veIndex1::30], axis=1)
    nor1.resize((nor1.size, 1))
    ae1r = ah1 + veTilde1[veIndex1::30] / nor1 / ratio1
    veIndex1 = 1
    nor1 = norm(veTilde1[veIndex1::30], axis=1)
    nor1.resize((nor1.size, 1))
    ae1i = ah1 + veTilde1[veIndex1::30] / nor1 / ratio1

    ratio2 = 5
    ah2 = aaTilde2
    veIndex2 = 0
    nor2 = norm(veTilde2[veIndex2::30], axis=1)
    nor2.resize((nor2.size, 1))
    ae2r = ah2 + veTilde2[veIndex2::30] / nor2 / ratio2
    veIndex2 = 1
    nor2 = norm(veTilde2[veIndex2::30], axis=1)
    nor2.resize((nor2.size, 1))
    ae2i = ah2 + veTilde2[veIndex2::30] / nor2 / ratio2

    for i in np.arange(0, aaTilde1.shape[0], spa):
        a1 = Arrow3D([ah1[i, i1], ae1r[i, i1]], [ah1[i, i2], ae1r[i, i2]],
                     [ah1[i, i3], ae1r[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="m")
        ax.add_artist(a1)
        a1 = Arrow3D([ah1[i, i1], ae1i[i, i1]], [ah1[i, i2], ae1i[i, i2]],
                     [ah1[i, i3], ae1i[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="b")
        ax.add_artist(a1)

    for i in np.arange(0, aaTilde2.shape[0], spa):
        a2 = Arrow3D([ah2[i, i1], ae2r[i, i1]], [ah2[i, i2], ae2r[i, i2]],
                     [ah2[i, i3], ae2r[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="k")
        ax.add_artist(a2)
        a2 = Arrow3D([ah2[i, i1], ae2i[i, i1]], [ah2[i, i2], ae2i[i, i2]],
                     [ah2[i, i3], ae2i[i, i3]],
                     mutation_scale=20, lw=1.0, arrowstyle="-|>", color="c")
        ax.add_artist(a2)

    ax.set_xlabel(r'$e_1$', fontsize=25)
    ax.set_ylabel(r'$e_2$', fontsize=25)
    ax.set_zlabel(r'$e_3$', fontsize=25)
    plt.tight_layout(pad=0)
    plt.show(block=False)

<file_sep>import plotly.plotly as py
import plotly.offline as pyoff
import plotly.graph_objs as go


def ptlyTrace3d(x, y, z, plotType=0, lw=2, lc='blue', ls='solid',
                mc='red', ms=5, mt='circle', label=None):
    
    if plotType == 0:
        mode = 'lines'
    elif plotType == 1:
        mode = 'markers'
    else:
        mode = 'lines' + 'markers'

    trace = go.Scatter3d(
        x=x,
        y=y,
        z=z,
        mode=mode,
        marker=dict(
            size=ms,
            color=mc,
            symbol=mt,  # "circle" | "square" | "diamond" | "cross" | "x"
        ),
        line=dict(
            color=lc,
            width=lw,
            dash=ls,            # solid, dot, dash
        ),
        name=label
    )
    return trace


def ptlyLayout3d(labs=['$x$', '$y$', '$z$'], showLegend=False):
    layout = go.Layout(
        scene=go.Scene(
            xaxis=dict(
                title=labs[0],
                showbackground=True,
                backgroundcolor='rgb(230, 230,230)'
            ),
            yaxis=dict(
                title=labs[1],
                showbackground=True,
                backgroundcolor='rgb(230, 230,230)'
            ),
            zaxis=dict(
                title=labs[2],
                showbackground=True,
                backgroundcolor='rgb(230, 230,230)'
            )
        ),
        margin=dict(
            b=0,
            l=0,
            r=0,
            t=0
        ),
        showlegend=showLegend,
    )

    return layout


def ptly3d(trace, fileName, off=True, labs=['$x$', '$y$', '$z$'],
           showLegend=False):
    layout = ptlyLayout3d(labs=labs, showLegend=showLegend)
    fig = go.Figure(data=trace, layout=layout)
    if off:
        pyoff.plot(fig, filename=fileName)
    else:
        py.plot(fig, filename=fileName, fileopt='overwrite')


def ptlyPlot3d(x, y, z, fileName, off=True, plotType=0, lw=2, lc='blue',
               ls='solid',
               mc='red', ms=5,  mt='circle', label=None,
               labs=['$x$', '$y$', '$z$'], showLegend=False):
    trace = ptlyTrace3d(x, y, z, plotType=plotType, lw=lw, lc=lc, ls=ls,
                        mc=mc, ms=ms, mt=mt, label=label)
    ptly3d([trace], fileName, off=off, labs=labs, showLegend=showLegend)


<file_sep>    std::pair<ArrayXXd, ArrayXXd>    
    intgjMulti(const MatrixXd aa0, size_t nstp, size_t np, size_t nqr);
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    calReqJJF(const Ref<const VectorXd> &x);
    std::tuple<VectorXd, double, double>
    findReq(const Ref<const VectorXd> &x, const double tol, 
	    const int maxit, const int innerMaxit);
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    calEqJJF(const Ref<const VectorXd> &x);
    std::pair<VectorXd, double>
    findEq(const Ref<const VectorXd> &x, const double tol,
	   const int maxit, const int innerMaxit);



/*============================================================
 *                       Class : Calculate KS Req LM 
 *============================================================*/
template<class Mat>
struct KSReqJJF {
    KS &ks;
    KSReqJJF(KS &ks_) : ks(ks_){}
    
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    operator()(const VectorXd &x) {
	return ks.calReqJJF(x);
    }	
};

/*============================================================
 *                       Class : Calculate KS Eq LM 
 *============================================================*/
template<class Mat>
struct KSEqJJF {
    KS &ks;
    KSEqJJF(KS &ks_) : ks(ks_){}
    
    std::tuple<MatrixXd, MatrixXd, VectorXd>
    operator()(const VectorXd &x) {
	return ks.calEqJJF(x);
    }	
};

<file_sep>/* to comiple:
 * h5c++ -O3 test_CQCGL2d.cc  -L../../lib -I../../include -I $XDAPPS/eigen/include/eigen3 -std=c++11 -lCQCGL2d -lsparseRoutines -ldenseRoutines -lmyH5 -lmyfft -lfftw3 -lm 
 */
#include "CQCGL2d.hpp"
#include "myH5.hpp"
#include "denseRoutines.hpp"
#include <iostream>
#include <fstream>
#include <Eigen/Dense>
#include <complex>
#include <H5Cpp.h>

#define CE(x) (cout << (x) << endl << endl)

using namespace std;
using namespace Eigen;
using namespace MyH5;
using namespace denseRoutines;

typedef std::complex<double> dcp;

int main(){

    switch(2){
	
    case 1: {			/* test integrator */
	int N = 1024; 
	double L = 30;
	double di = 0.3;
	CQCGL2d cgl(N, L, 4.0, 0.8, 0.05, di, 4);
	
	ArrayXXcd A0 = 3*center2d<dcp>(N, N, 0.2, 0.2, 2);
	ArrayXXcd a0 = cgl.Config2Fourier(A0);
	ArrayXXcd A2 = cgl.Fourier2Config(a0);
	
	ArrayXXcd aa = cgl.intg(a0, 0.001, 10, 1, true, "ex.h5");
	CE(a0.rows()); CE(a0.cols()); CE(aa.rows()); CE(aa.cols());
	
	break;
    }

    case 2:{ 			/* test r2c and c2r */
	int N = 1024; 
	double L = 30;
	double di = 0.3;
	CQCGL2d cgl(N, L, 4.0, 0.8, 0.05, di, 4);

	ArrayXXcd x(ArrayXXcd::Random(3, 4));
	ArrayXXd y = cgl.c2r(x);
	ArrayXXcd z = cgl.r2c(y);
	CE(x);
	CE(y);
	CE(z);

	break;
    }

#if 0	
    case 3 :{ 			/* test Fourier2Config */
	const int N = 256; 
	const int L = 50;
	int nstp = 2;
	int nqr = 1;
	double h = 0.01; 
	
	ArrayXd A0(2*N) ;
	// prepare Gaussian curve initial condition
	for(int i = 0; i < N; i++) {
	    double x = (double)i/N*L - L/2.0; 
	    A0(2*i) =  exp(-x*x/8.0);
	}
	Cqcgl1d cgl(N, L, h);
	ArrayXXd aa = cgl.intg(A0, nstp, nqr);
	ArrayXXd AA = cgl.Fourier2Config(aa);
	
	cout << AA.rows() << 'x' << AA.cols() << endl << "--------------" << endl;
	//cout << AA.col(2) << endl;
	//cout << A0 << endl;
	break;
    }

    case 4:{			/* test the new constructor */
	const int N = 512;
	const int L = 50;
	double h = 0.001;
	Cqcgl1d cgl(N, L, h, false, 0, 0.1, 0.1, 0.1, 0.1, 4);
	const int Ndim = cgl.Ndim;
	
	int nstp = 1000;
	
	ArrayXd A0(2*N) ; 
	// prepare Gaussian curve initial condition
	for(int i = 0; i < N; i++) {
	    double x = (double)i/N*L - L/2.0; 
	    A0(2*i) =  exp(-x*x/8.0);
	} 
	ArrayXd a0 = cgl.Config2Fourier(A0).col(0);

	ArrayXXd AA = cgl.intg(a0, nstp, 1);
	
	cout << AA.rows() << 'x' << AA.cols() << endl << "--------------" << endl;
	cout << cgl.trueNjacv << endl;
	
	break;
    }

    case 5:{			/* test the cgl constructor */
	const int N = 512;
	const int L = 50;
	double h = 0.001;
	Cgl1d cgl(N, L, h, false, 0, 0.1, 0.2, 4);
	const int Ndim = cgl.Ndim;

	cout << cgl.Mu << endl;
	cout << cgl.Br << endl;
	cout << cgl.Bi << endl;
	cout << cgl.Dr << endl;
	cout << cgl.Di << endl;
	cout << cgl.Gr << endl;
	cout << cgl.Gi << endl;
	cout << cgl.trueNjacv << endl;
	
	break;
    }

    case 6: {			
	/* test reflectVe()
	 * Find the reason why discrete symmetry reduction will produce NAN elements.
	 * I find the answer is that my transformation is singular at point (0, 0).
	 */
	const int N = 1024;
	const int L = 30;
	const double h = 0.0002;
	const double di = 0.0799;

	std::string file("/usr/local/home/xiong/00git/research/data/cgl/req_different_di/req0799.h5");
	VectorXd a0;
	double wth, wphi, err;
	CqcglReadReq(file, "1", a0, wth, wphi, err);
	    
	Cqcgl1d cgl(N, L, h, true, 0, 4.0, 0.8, 0.01, di, 4);
	
	auto tmp = cgl.evReq(a0, wth, wphi);
	VectorXcd &e = tmp.first;
	MatrixXd v = realv(tmp.second);
	cout << e.head(10) << endl;
	
	ArrayXd a0Hat = cgl.orbit2sliceSimple(a0);
	ArrayXd a0Tilde = cgl.reduceReflection(a0Hat);
	MatrixXd vHat = cgl.ve2slice(v, a0);
	MatrixXd vTilde = cgl.reflectVe(vHat, a0Hat);
	
	MatrixXd G = cgl.refGradMat(a0Hat);
	MatrixXd G1 = cgl.refGrad1();
	ArrayXd step1 = cgl.reduceRef1(a0Hat);
	ArrayXd step2 = cgl.reduceRef2(step1);
	MatrixXd G2 = cgl.refGrad2(step1);
	MatrixXd G3 = cgl.refGrad3(step2);

	cout << G.maxCoeff() << endl;
	cout << G.minCoeff() << endl << endl;
	MatrixXd tmp2(step1.size(), 4);
	tmp2 << a0Hat, step1, step2, a0Tilde;
	cout << tmp2 << endl << endl;
	// cout << G3.row(42) << endl << endl;
	// cout << (G * vHat.col(0)).head(50) << endl;
	// cout << vTilde.col(0).head(60) << endl;
	break;

    }
    case 7:{
	/* see the spacing along a orbit
	 *   I find h = 0.0002 seems too large
	 */
	const int N = 1024;
	const int L = 30;
	const double h = 0.0002;
	const double di = 0.4;
	
	Cqcgl1d cgl(N, L, h, true, 0, 4.0, 0.8, 0.01, di, 4);

	std::string file("rpot.h5");
	int nstp;
	double T, th, phi, err;
	MatrixXd x;
	CqcglReadRPO(file, "1", x, T, nstp, th, phi, err);
	printf("T %g, nstp %d, th %g, phi %g, err %g\n", T, nstp, th, phi, err);

	ArrayXXd aa = cgl.intg(x.col(0), nstp*10, 1);
	VectorXd sp = spacing(aa);
	
	cout << sp.maxCoeff() << endl;
	cout << aa.rightCols(1).matrix().norm() << endl;
	break;
	
    }
#endif
    default: {
	fprintf(stderr, "please indicate a valid case number \n");
	}
    }
    
    return 0;
}
<file_sep>#include "CQCGL1d.hpp"

using namespace denseRoutines;

// implementation notes
// 1) not use fft.fwd(MatrixBase, MatrixBase) but use
//    fft.fwd(Complex * dst, const Complex * src, Index nfft)
//    becuase the former cannot work with Map<VectorXcd> type.
// 2) In C++, initialization list will be evaluated in the order they were
//    declared in the class definition

//////////////////////////////////////////////////////////////////////
//                     Inner Class CQCGL1d                          //
//////////////////////////////////////////////////////////////////////
CQCGL1d::NL::NL(){}
CQCGL1d::NL::NL(CQCGL1d *cgl, int cols) : 
    cgl(cgl), N(cgl->N), B(cgl->Br, cgl->Bi), G(cgl->Gr, cgl->Gi) {
    AA.resize(cgl->N, cols);
}
CQCGL1d::NL::~NL(){}

void CQCGL1d::NL::operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t){
    int cs = x.cols();
    assert(cs == dxdt.cols() && N == x.rows() && N == dxdt.rows());
    
    for(int i = 0; i < cs; i++)
	cgl->fft.inv(AA.data() + i*N, x.data() + i*N, N);
    
    ArrayXcd A = AA.col(0); 
    ArrayXcd aA2 = A * A.conjugate();

    if (cgl->IsQintic)
	AA.col(0) = B * A * aA2 + G * A * aA2.square();
    else 
	AA.col(0) = B * A * aA2;

    if(cs > 1){
	int M = cs - 1;
	ArrayXcd A2 = A.square();
	if (cgl->IsQintic)
	    AA.rightCols(M) = AA.rightCols(M).conjugate().colwise() *  ((B+G*2.0*aA2) * A2) +
		AA.rightCols(M).colwise() * ((2.0*B+3.0*G*aA2)*aA2);
	else
	    AA.rightCols(M) = AA.rightCols(M).conjugate().colwise() *  (B * A2) +
		AA.rightCols(M).colwise() * (2.0*B*aA2);	
    }
    
    for(int i = 0; i < cs; i++)
	cgl->fft.fwd(dxdt.data() + i*N, AA.data() + i*N, N);
    
    dxdt.middleRows(cgl->Nplus, cgl->Nalias).setZero(); // dealiaze
}

//////////////////////////////////////////////////////////////////////
//                        Class CQCGL1d                             //
//////////////////////////////////////////////////////////////////////

/* ------------------------------------------------------ */
/* ----                constructor/destructor     ------- */
/* ------------------------------------------------------ */

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
 *
 * @param[in] N            the number of Fourier modes
 * @param[in] d            the spacial period, size
 * @param[in] dimTan       the dimension of tangent space
 *                         dimTan > 0 => dimTan
 *                         dimTan = 0 => Ndim
 *                         dimTan < 0 => 0
 *              
 * Dealiasing is the method to calculate correct convolution term. For centralized
 * FFT, it works as set Fourier modes a_k = 0 for wave number |k| > 2/3 * N.
 * More specifically, in this code, the middle part of modes
 * is set to zero.
 *
 *    |<---------------------------------------------------------->|
 *                             FFT length: N
 *               
 *    |<--------------->|<--------------------->|<---------------->|
 *        (Ne + 1) / 2         N - Ne                (Ne - 1) /2
 *         = Nplus             = Nalias               = Nminus
 *
 *    @Note each term has real and imaginary part, so the indices are
 *          0, 1, 2,... Nplus*2, Nplus*2+1,... 2*Ne-1
 */
CQCGL1d::CQCGL1d(int N, double d,
		 double Mu, double Dr, double Di, double Br, double Bi,
		 double Gr, double Gi, int dimTan)
    : N(N), d(d), Mu(Mu), Dr(Dr), Di(Di), Br(Br), Bi(Bi), Gr(Gr), Gi(Gi),
      Ne((N/3) * 2 - 1),	// make it an odd number
      Ndim(2 * Ne),
      Nplus((Ne + 1) / 2),
      Nminus((Ne - 1) / 2),
      Nalias(N - Ne),
      DimTan(dimTan == 0 ? Ndim : (dimTan > 0 ? dimTan : 0)),
      nl(this, 1), nl2(this, DimTan+1)
{
    // calculate the Linear part
    K.resize(N,1);
    K << ArrayXd::LinSpaced(N/2, 0, N/2-1), N/2, ArrayXd::LinSpaced(N/2-1, -N/2+1, -1); 
    K2.resize(Ne, 1);
    K2 << ArrayXd::LinSpaced(Nplus, 0, Nplus-1), ArrayXd::LinSpaced(Nminus, -Nminus, -1); 
      
    QK = 2*M_PI/d * K; 
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square(); 
    L.segment(Nplus, Nalias).setZero();

    int nYN0 = eidc.names.at(eidc.scheme).nYN; // do not call setScheme here. Different.
    for(int i = 0; i < nYN0; i++){
	Yv[i].resize(N, 1);
	Nv[i].resize(N, 1);
	Yv2[i].resize(N, DimTan+1);
	Nv2[i].resize(N, DimTan+1);
    }
    eidc.init(&L, Yv, Nv);
    eidc2.init(&L, Yv2, Nv2);
}

/**
 * Constructor of cubic quintic complex Ginzburg-Landau equation
 * A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
 */
CQCGL1d::CQCGL1d(int N, double d, 
		 double b, double c, double dr, double di, 
		 int dimTan)
    : CQCGL1d::CQCGL1d(N, d, -1, 1, b, 1, c, -dr, -di, dimTan) {}


CQCGL1d::CQCGL1d(int N, double d,
		 double delta, double beta, double D, double epsilon,
		 double mu, double nu, int dimTan)
    : CQCGL1d::CQCGL1d(N, d, delta, beta, D/2, epsilon, 1, mu, nu, dimTan) {}

CQCGL1d::~CQCGL1d(){}

CQCGL1d & CQCGL1d::operator=(const CQCGL1d &x){
    return *this;
}

/* ------------------------------------------------------ */
/* ----                 Integrator                ------- */
/* ------------------------------------------------------ */

void CQCGL1d::setScheme(std::string x){
    int nYN0 = eidc.names.at(eidc.scheme).nYN;
    eidc.scheme = x;
    int nYN1 = eidc.names.at(eidc.scheme).nYN;
    for (int i = nYN0; i < nYN1; i++) {
	Yv[i].resize(N, 1);
	Nv[i].resize(N, 1);
	Yv2[i].resize(N, DimTan+1);
	Nv2[i].resize(N, DimTan+1);
    }
}

void CQCGL1d::changeOmega(double w){
    Omega = w;
    L = dcp(Mu, -Omega) - dcp(Dr, Di) * QK.square();
    L.segment(Nplus, Nalias).setZero();
}

/** @brief Integrator of 1d cqCGL equation.
 *
 *  The intial condition a0 should be coefficients of the intial state:
 *  [b0, c0 ,b1, c1,...] where bi, ci the real and imaginary parts of Fourier modes.
 *  
 * @param[in] a0 initial condition of Fourier coefficents. Size : [2*N,1]
 * @return state trajectory. Each column is the state followed the previous column. 
 */
ArrayXXd 
CQCGL1d::intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert( Ndim == a0.size());
    
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N, M);
    lte.resize(M);
    int ks = 0; 
    auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	aa.col(ks) = x;
	lte(ks++) = err;
    }; 
	
    eidc.intgC(nl, ss, 0, u0, tend, h, skip_rate); 
	
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
CQCGL1d::intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(v0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N, M), daa(N, Ndim*M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	aa.col(ks) = x.col(0);
	daa.middleCols(ks*Ndim, Ndim) = x.rightCols(Ndim);
	lte(ks++) = err;
	x.rightCols(Ndim) = R2C(MatrixXd::Identity(Ndim, Ndim));
    };
    
    eidc2.intgC(nl2, ss, 0, u0, tend, h, skip_rate);
    
    return std::make_pair(C2R(aa), C2R(daa));
}

/**
 * @brief integrate the state and a subspace in tangent space
 */
ArrayXXd
CQCGL1d::intgvC(const ArrayXd &a0, const ArrayXXd &v, const double h,
		const double tend){
    assert( Ndim == a0.size() && Ndim == v.rows() && DimTan == v.cols());
    ArrayXXd v0(Ndim, DimTan+1);
    v0 << a0, v;
    ArrayXXcd u0 = R2C(v0);

    const int Nt = (int)round(tend/h);
    ArrayXXcd aa(N, DimTan+1);
    auto ss = [this, &aa](ArrayXXcd &x, double t, double h, double err){
	aa = x;
    };
    
    eidc2.intgC(nl2, ss, 0, u0, tend, h, Nt);
    
    return C2R(aa);	   //both the final orbit and the perturbation
}

ArrayXXd
CQCGL1d::intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate){
    assert( Ndim == a0.size());
    
    ArrayXXcd u0 = R2C(a0); 
    const int Nt = (int)round(tend/h);
    const int M = (Nt+skip_rate-1)/skip_rate;
    ArrayXXcd aa(N, M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (ks >= m ) {
	    Ts.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	}
	hs(ks) = h;
	lte(ks) = err;
	aa.col(ks) = x;
	Ts(ks++) = t;
    };
    
    eidc.intg(nl, ss, 0, u0, tend, h, skip_rate);
	
    hs.conservativeResize(ks);
    lte.conservativeResize(ks);
    Ts.conservativeResize(ks);
    aa.conservativeResize(Eigen::NoChange, ks);
    
    return C2R(aa);
}

std::pair<ArrayXXd, ArrayXXd>
CQCGL1d::intgj(const ArrayXd &a0, const double h, const double tend, 
	       const int skip_rate){
    
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(a0);
    
    const int Nt = (int)round(tend/h);
    const int M = (Nt + skip_rate - 1) / skip_rate;
    ArrayXXcd aa(N, M), daa(N, Ndim*M);
    Ts.resize(M);
    hs.resize(M);
    lte.resize(M);
    int ks = 0;
    auto ss = [this, &ks, &aa, &daa](ArrayXXcd &x, double t, double h, double err){
	int m = Ts.size();
	if (ks >= m ) {
	    Ts.conservativeResize(m+cellSize);	    
	    hs.conservativeResize(m+cellSize);
	    lte.conservativeResize(m+cellSize);
	    aa.conservativeResize(Eigen::NoChange, m+cellSize); // rows not change, just extend cols
	    daa.conservativeResize(Eigen::NoChange, (m+cellSize)*Ndim);
	}
	hs(ks) = h;
	lte(ks) = err;
	Ts(ks) = t;
	aa.col(ks) = x.col(0);
	daa.middleCols(ks*Ndim, Ndim) = x.rightCols(Ndim);
	x.rightCols(Ndim) = R2C(MatrixXd::Identity(Ndim, Ndim));
	ks++;
    };

    eidc2.intg(nl2, ss, 0, u0, tend, h, skip_rate);
    return std::make_pair(C2R(aa), C2R(daa));
}
 

ArrayXXd 
CQCGL1d::intgv(const ArrayXXd &a0, const ArrayXXd &v, const double h,
	       const double tend){
    assert( Ndim == a0.size() && Ndim == v.rows() && DimTan == v.cols());
    ArrayXXd v0(Ndim, DimTan+1);
    v0 << a0, v;
    ArrayXXcd u0 = R2C(v0);

    ArrayXXcd aa(N, DimTan+1); 
    auto ss = [this, &aa](ArrayXXcd &x, double t, double h, double err){
	aa = x;
    };

    eidc2.intg(nl2, ss, 0, u0, tend, h, 1000000);
    return C2R(aa);
}

/** @brief transform conjugate matrix to its real form */
ArrayXXd CQCGL1d::C2R(const ArrayXXcd &v){
    int n = v.rows();
    int m = v.cols();
    assert(N == n);
    ArrayXXcd vt(Ne, m);
    vt << v.topRows(Nplus), v.bottomRows(Nminus);

    return Map<ArrayXXd>((double*)(vt.data()), 2*vt.rows(), vt.cols());
}

ArrayXXcd CQCGL1d::R2C(const ArrayXXd &v){
    int n = v.rows();
    int m = v.cols();
    assert( n == Ndim);
    
    Map<ArrayXXcd> vp((dcp*)&v(0,0), Ne, m);
    ArrayXXcd vpp(N, m);
    vpp << vp.topRows(Nplus), ArrayXXcd::Zero(Nalias, m), vp.bottomRows(Nminus);

    return vpp;
}

ArrayXXd CQCGL1d::c2r(const ArrayXXcd &v){
    return Map<ArrayXXd>((double*)&v(0,0), 2*v.rows(), v.cols());
}

ArrayXXcd CQCGL1d::r2c(const ArrayXXd &v){
    assert( 0 == v.rows() % 2);
    return Map<ArrayXXcd>((dcp*)&v(0,0), v.rows()/2, v.cols());
}

/* -------------------------------------------------- */
/* -------  Fourier/Configure transformation -------- */
/* -------------------------------------------------- */

/**
 * @brief back Fourier transform of the states. 
 */
ArrayXXcd CQCGL1d::Fourier2Config(const Ref<const ArrayXXd> &aa){
    int cs = aa.cols(), rs = aa.rows();
    assert(Ndim == rs);
    ArrayXXcd aac = R2C(aa);
    ArrayXXcd AA(N, cs);
    
    for(size_t i = 0; i < cs; i++)
	fft.inv(AA.data() + i*N, aac.data() + i*N, N);
    
    return AA;
}


/**
 * @brief Fourier transform of the states. Input and output are both real.
 */
ArrayXXd CQCGL1d::Config2Fourier(const Ref<const ArrayXXcd> &AA){
    int cs = AA.cols(), rs = AA.rows();
    assert(N == rs);
    ArrayXXcd aac(N, cs);
    
    for(size_t i = 0; i < cs; i++)
	fft.fwd(aac.data() + i*N, AA.data() + i*N, N);
    
    return C2R(aac);
}

ArrayXXd CQCGL1d::Fourier2ConfigMag(const Ref<const ArrayXXd> &aa){
    return Fourier2Config(aa).abs();
}

ArrayXXd CQCGL1d::calPhase(const Ref<const ArrayXXcd> &AA){
    int m = AA.cols();
    int n = AA.rows();
    assert(N == n);
    ArrayXXd phase(n, m);
    for(size_t i = 0; i < m; i++)
	for(size_t j =0; j < n; j++)
	    phase(j, i) = atan2(AA(j, i).imag(), AA(j, i).real());

    return phase;
}

ArrayXXd CQCGL1d::Fourier2Phase(const Ref<const ArrayXXd> &aa){
    return calPhase(Fourier2Config(aa));
}

/**
 * @brief calculate the mean energy density
 * \frac{\int |A|^2  dx}{\int dx} = 1/N \sum |A_i|^2 = 1/N^2 \sum |a_i|^2
 * = 1/N^2 \sum (a_r^2 + a_i^2)
 */
VectorXd 
CQCGL1d::calQ(const Ref<const ArrayXXd> &aa){
    const int n = aa.cols();
    VectorXd Q(n);
    for (int i = 0; i < n; i++){
	Q(i) = aa.col(i).matrix().squaredNorm() / (N*N);
    }

    return Q;
}

VectorXd
CQCGL1d::calMoment(const Ref<const ArrayXXd> &aa, const int p){
    const int n = aa.cols();
    VectorXd mom(n);
    
    ArrayXd x = ArrayXd::LinSpaced(N, 0, N-1) * d / N;
    ArrayXd xp = x;
    for(int i = 0; i < p-1; i++) xp *= x;

    ArrayXXcd AA = Fourier2Config(aa);
    for (int i = 0; i < n; i++){
	ArrayXd A2 = (AA.col(i) * AA.col(i).conjugate()).real();
	mom(i) = (A2 * xp).sum() / A2.sum();
    }

    return mom;
}


/* -------------------------------------------------- */
/* --------            velocity field     ----------- */
/* -------------------------------------------------- */

/**
 * @brief velocity field
 */
ArrayXd CQCGL1d::velocity(const ArrayXd &a0){
    assert( Ndim == a0.rows() );
    ArrayXXcd A = R2C(a0);
    ArrayXXcd v(N, 1);
    nl(A, v, 0);
    return C2R(L*A + v);
}

/**
 * @brief the generalized velociyt for relative equilibrium
 *
 *   v(x) + \omega_\tau * t_\tau(x) + \omega_\rho * t_\rho(x)
 */
ArrayXd CQCGL1d::velocityReq(const ArrayXd &a0, const double wth,
			     const double wphi){
    return velocity(a0) + wth*transTangent(a0) + wphi*phaseTangent(a0);    
}

/**
 * velocity in the slice
 *
 * @param[in]  aH  state in the slice
 */
VectorXd CQCGL1d::velSlice(const Ref<const VectorXd> &aH){
    VectorXd v = velocity(aH);
    
    Vector2d c;
    c << v(Ndim-1), v(3);
    
    Matrix2d Linv;
    Linv << 0.5/aH(Ndim-2), 0.5/aH(2),
	-0.5/aH(Ndim-2), 0.5/aH(2); 

    VectorXd tp = phaseTangent(aH);
    VectorXd tt = transTangent(aH);
    MatrixXd vs(Ndim, 2);
    vs << tp, tt;

    return v - vs * (Linv * c);
}

VectorXd CQCGL1d::velPhase(const Ref<const VectorXd> &aH){
    VectorXd v = velocity(aH);
 
    VectorXd tp = phaseTangent(aH);   
    double c = v(Ndim-1) / aH(Ndim-2);

    return v - c * tp;
}

/* -------------------------------------------------- */
/* --------          stability matrix     ----------- */
/* -------------------------------------------------- */
MatrixXd CQCGL1d::stab(const ArrayXd &a0){
    assert(a0.size() == Ndim && DimTan == Ndim);
    ArrayXXd v0(Ndim, Ndim+1); 
    v0 << a0, MatrixXd::Identity(Ndim, Ndim);
    ArrayXXcd u0 = R2C(v0);
    
    ArrayXXcd v(N, Ndim+1); 
    nl2(u0, v, 0); 
	
    ArrayXXcd j0 = R2C(MatrixXd::Identity(Ndim, Ndim));
    MatrixXcd Z = j0.colwise() * L + v.rightCols(Ndim);
  
    return C2R(Z);
}

/**
 * @brief stability for relative equilbrium
 */
MatrixXd CQCGL1d::stabReq(const ArrayXd &a0, double wth, double wphi){
    MatrixXd z = stab(a0);
    return z + wth*transGenerator() + wphi*phaseGenerator();
}

/**
 * @brief stability exponents of req
 */
VectorXcd CQCGL1d::eReq(const ArrayXd &a0, double wth, double wphi){
    return eEig(stabReq(a0, wth, wphi), 1);
}

/**
 * @brief stability vectors of req
 */
MatrixXcd CQCGL1d::vReq(const ArrayXd &a0, double wth, double wphi){
    return vEig(stabReq(a0, wth, wphi), 1);
}

/**
 * @brief stability exponents and vectors of req
 */
std::pair<VectorXcd, MatrixXcd>
CQCGL1d::evReq(const ArrayXd &a0, double wth, double wphi){
    return evEig(stabReq(a0, wth, wphi), 1);
}


/* -------------------------------------------------- */
/* ------           symmetry related           ------ */
/* -------------------------------------------------- */

/**
 * @brief reflect the states
 *
 * Reflection : a_k -> a_{-k}. so a_0 keeps unchanged
 */
ArrayXXd CQCGL1d::reflect(const Ref<const ArrayXXd> &aa){
    ArrayXXcd raa = R2C(aa);
    const int n = raa.rows(); // n is an odd number
    for(size_t i = 1; i < (n+1)/2; i++){
	ArrayXcd tmp = raa.row(i);
	raa.row(i) = raa.row(n-i);
	raa.row(n-i) = tmp;
    }
    return C2R(raa);
}

/**
 * @ brief calculate (x^2 - y^2) / \sqrt{x^2 + y^2}
 */
inline ArrayXd CQCGL1d::rcos2th(const ArrayXd &x, const ArrayXd &y){
    ArrayXd x2 = x.square();
    ArrayXd y2 = y.square();
    return (x2 - y2) / (x2 + y2).sqrt();
}

/**
 * @ brief calculate x * y / \sqrt{x^2 + y^2}
 */
inline ArrayXd CQCGL1d::rsin2th(const ArrayXd &x, const ArrayXd &y){
    return x * y / (x.square() + y.square()).sqrt();
}

/**
 * @brief calculate the gradient of rcos2th()
 *
 *        partial derivative over x :   (x^3 + 3*x*y^2) / (x^2 + y^2)^{3/2}
 *        partial derivative over y : - (y^3 + 3*y*x^2) / (x^2 + y^2)^{3/2}
 */
inline double CQCGL1d::rcos2thGrad(const double x, const double y){
    // only return derivative over x. Derivative over y can be obtained
    // by exchange x and y and flip sign
    double denorm = sqrt(x*x + y*y);
    double denorm3 = denorm * denorm * denorm;
    return x * (x*x + 3*y*y) / denorm3;
}

/**
 * @brief calculate the gradient of rsin2th()
 *
 *        partial derivative over x :   y^3 / (x^2 + y^2)^{3/2}
 *        partial derivative over y :   x^3 / (x^2 + y^2)^{3/2}
 */
inline double CQCGL1d::rsin2thGrad(const double x, const double y){
    // only return derivative over x. Derivative over y can be obtained
    // by exchange x and y
    double denorm = sqrt(x*x + y*y);
    double denorm3 = denorm * denorm * denorm;
    return y*y*y / denorm3;
}

/**
 * @brief the first step to reduce the discrete symmetry
 *
 * @param[in] aaHat   states after reducing continous symmetries
 */
ArrayXXd CQCGL1d::reduceRef1(const Ref<const ArrayXXd> &aaHat){
    const int m = aaHat.cols(); 
    const int n = aaHat.rows(); 
    assert(n == Ndim);
    
    ArrayXXd step1(n, m);
    step1.topRows<2>() = aaHat.topRows<2>();
    for(size_t i = 1; i < Nplus; i++){
	step1.row(2*i) = 0.5*(aaHat.row(2*i) - aaHat.row(n-2*i));
	step1.row(n-2*i) = 0.5*(aaHat.row(2*i) + aaHat.row(n-2*i));
	step1.row(2*i+1) = 0.5*(aaHat.row(2*i+1) - aaHat.row(n+1-2*i));
	step1.row(n+1-2*i) = 0.5*(aaHat.row(2*i+1) + aaHat.row(n+1-2*i));
    }

    return step1;
}

ArrayXXd CQCGL1d::reduceRef2(const Ref<const ArrayXXd> &step1){
    ArrayXXd step2(step1);
    ArrayXd p1s = step1.row(2).square(); 
    ArrayXd q1s = step1.row(3).square();
    ArrayXd denorm = (p1s + q1s).sqrt();
    step2.row(2) = (p1s - q1s) / denorm;
    step2.row(3) = step1.row(2) * step1.row(3) / denorm.transpose(); 
    
    for(size_t i = 4; i < 2*Nplus; i++){
	ArrayXd denorm = (step1.row(i-1).square() +  step1.row(i).square()).sqrt();
	step2.row(i) = step1.row(i-1) * step1.row(i) / denorm.transpose() ;
    }

    return step2;
}

/**
 * @brief get the indices which reflect sign in the 3rd step of reflection
 *        reduction
 *
 *        1, 4, 6, ...
 */
std::vector<int> CQCGL1d::refIndex3(){
    std::vector<int> index; // vector storing indices which flip sign
    index.push_back(1);
    for(size_t i = 2; i < Nplus; i++) index.push_back(2*i);
    for(size_t i = Nplus; i < Ne; i++) {
	if(i%2 != 0){		// the last mode a_{-1} has index Ne-1 even
	    index.push_back(2*i);
	    index.push_back(2*i+1);
	}
    }
    return index;
}


/**
 * @brief the 3rd step to reduce the discrete symmetry
 *
 */
ArrayXXd CQCGL1d::reduceRef3(const Ref<const ArrayXXd> &aa){

    ArrayXXd aaTilde(aa);
    aaTilde.row(0) = rcos2th(aa.row(0), aa.row(1));
    aaTilde.row(1) = rsin2th(aa.row(0), aa.row(1));
    
    std::vector<int> index = refIndex3();
    for(size_t i = 1; i < index.size(); i++){
	aaTilde.row(index[i]) = rsin2th(aa.row(index[i-1]), aa.row(index[i]));
    }

    return aaTilde;
}

ArrayXXd CQCGL1d::reduceReflection(const Ref<const ArrayXXd> &aaHat){
    return reduceRef3(reduceRef2(reduceRef1(aaHat)));
}

/**
 * @brief The gradient of the reflection reduction transformation for the
 *        firt step.
 *
 * step 1: ---------------------------------------
 *         | 1					 |
 *         |   1				 |
 *         |     1/2                   -1/2	 |
 *         |         1/2                   -1/2	 |
 *         |                   ...		 |
 *         |             1/2   -1/2		 |
 *         |                1/2    -1/2		 |
 *         |             1/2    1/2		 |
 *         |                1/2     1/2		 |
 *         |                   ...		 |
 *         |     1/2                   1/2 	 |
 *         |         1/2                   1/2   |
 *         ---------------------------------------
 */
MatrixXd CQCGL1d::refGrad1(){
    MatrixXd Gamma(MatrixXd::Zero(Ndim, Ndim));
    Gamma(0, 0) = 1;
    Gamma(1, 1) = 1;
    for (size_t i = 1; i < Nplus; i++){
	Gamma(2*i, 2*i) = 0.5;
	Gamma(2*i+1, 2*i+1) = 0.5;
	Gamma(2*i, Ndim - 2*i) = -0.5;
	Gamma(2*i+1, Ndim - 2*i + 1) = -0.5;
    }
    for(size_t i = Nplus; i < Ne; i++){
	Gamma(2*i, 2*i) = 0.5;
	Gamma(2*i, Ndim - 2*i) = 0.5;
	Gamma(2*i+1, 2*i+1) = 0.5;
	Gamma(2*i+1, Ndim - 2*i + 1) = 0.5;
    }
    return Gamma;
}

/**
 * @brief The gradient of the reflection reduction transformation for the
 *        2nd step.
 *        
 * step 2: ------------------------------------
 *         | 1				      |
 *         |   1			      |
 *         |     *  *                         |
 *         |     *  *                         |
 *         |        *  *         	      |
 *         |           *  *      	      |
 *         |               ...  	      |
 *         |                  *  *            |
 *         |                       1          |
 *         |                         1        |
 *         |                           ...    |
 *         |                               1  |
 *         ------------------------------------
 *               
 */
MatrixXd CQCGL1d::refGrad2(const ArrayXd &x){
    assert (x.size() == Ndim);
    MatrixXd Gamma(MatrixXd::Zero(Ndim, Ndim));
    Gamma(0, 0) = 1;
    Gamma(1, 1) = 1;
    Gamma(2, 2) = rcos2thGrad(x(2), x(3));
    Gamma(2, 3) = - rcos2thGrad(x(3), x(2));
    for (size_t i = 3; i < 2*Nplus; i++){
	Gamma(i, i) = rsin2thGrad(x(i), x(i-1));
	Gamma(i, i-1) = rsin2thGrad(x(i-1), x(i));
    }
    for (size_t i = 2*Nplus; i < Ndim; i++){
	Gamma(i, i) = 1;
    }
    return Gamma;
}

/**
 * @brief The gradient of the reflection reduction transformation for the
 *        3rd step.
 */
MatrixXd CQCGL1d::refGrad3(const ArrayXd &x){
    assert(x.size() == Ndim);
    MatrixXd Gamma(MatrixXd::Identity(Ndim, Ndim));
    std::vector<int> index = refIndex3();
    Gamma(0, 0) = rcos2thGrad(x(0), x(1));
    Gamma(0, 1) = - rcos2thGrad(x(1), x(0));
    Gamma(1, 1) = rsin2thGrad(x(1), x(0));
    Gamma(1, 0) = rsin2thGrad(x(0), x(1));
    
    for(size_t i = 1; i < index.size(); i++){
	Gamma(index[i], index[i]) = rsin2thGrad(x(index[i]), x(index[i-1]));
	Gamma(index[i], index[i-1]) = rsin2thGrad(x(index[i-1]), x(index[i]));
    }
    return Gamma;
}

/**
 * @brief calculate the tranformation matrix for reflection reduction
 */
MatrixXd CQCGL1d::refGradMat(const ArrayXd &x){
    ArrayXd step1 = reduceRef1(x); 
    ArrayXd step2 = reduceRef2(step1);
    return refGrad3(step2) * refGrad2(step1) * refGrad1();
}

/**
 * @brief transform covariant vectors after reducing reflection
 *
 * @param[in] veHat    covariant vectors after reducing the continuous symmetries.
 * @param[in] xHat     orbit point after reducing continuous symmetries.
 */
MatrixXd CQCGL1d::reflectVe(const MatrixXd &veHat, const Ref<const ArrayXd> &xHat){
    MatrixXd Gamma = refGradMat(xHat);
    return Gamma * veHat;
}

/** @beief reduce reflection symmetry of all the Floquet vectors along a po
 *
 *  Usaully, aaHat has one more column the the Floquet vectors, so you can
 *  call this function like:
 *  \code
 *      reflectVeAll(veHat, aaHat.leftCols(aa.cols()-1))
 *  \endcode
 *  
 *  @param[in] veHat   Floquet vectors along the orbit in the 1st mode slice.
 *                     Dimension: [N, M*Trunc]
 *  @param[in] aaHat   the orbit in the  slice
 *  @param[in] trunc   the number of vectors at each orbit point.
 *                     trunc = 0 means full set of vectors
 *  @return            transformed to the reflection invariant space.
 *                     Dimension [N, M*Trunc]
 *
 *  @note vectors are not normalized
 */
MatrixXd CQCGL1d::reflectVeAll(const MatrixXd &veHat, const MatrixXd &aaHat,
			       const int trunc /* = 0*/){
    int Trunc = trunc;
    if(trunc == 0) Trunc = veHat.rows();

    assert(veHat.cols() % Trunc == 0);
    const int n = veHat.rows();  
    const int m = veHat.cols()/Trunc;
    const int n2 = aaHat.rows();
    const int m2 = aaHat.cols();

    assert(m == m2 && n == n2);
    MatrixXd veTilde(n, Trunc*m);
    for(size_t i = 0; i < m; i++){
	veTilde.middleCols(i*Trunc, Trunc) =
	    reflectVe(veHat.middleCols(i*Trunc, Trunc), aaHat.col(i));
    }

    return veTilde;
}


/** @brief group rotation for spatial translation of set of arrays.
 *  th : rotation angle
 *  */
ArrayXXd CQCGL1d::transRotate(const Ref<const ArrayXXd> &aa, const double th){
    ArrayXcd R = ( dcp(0,1) * th * K2 ).exp(); // e^{ik\theta}
    ArrayXXcd raa = r2c(aa); 
    raa.colwise() *= R;
  
    return c2r(raa);
}

/** @brief group tangent in angle unit.
 *
 *  x=(b0, c0, b1, c1, b2, c2 ...) ==> tx=(0, 0, -c1, b1, -2c2, 2b2, ...)
 */
ArrayXXd CQCGL1d::transTangent(const Ref<const ArrayXXd> &aa){
    ArrayXcd R = dcp(0,1) * K2;
    ArrayXXcd raa = r2c(aa);
    raa.colwise() *= R;
  
    return c2r(raa);
}

/** @brief group generator. */
MatrixXd CQCGL1d::transGenerator(){
    MatrixXd T = MatrixXd::Zero(Ndim, Ndim);
    for(size_t i = 0; i < Ne; i++){
	T(2*i, 2*i+1) = -K2(i);
	T(2*i+1, 2*i) = K2(i);
    }
    return T;
}


/** @brief group transform for complex rotation
 * phi: rotation angle
 * */
ArrayXXd CQCGL1d::phaseRotate(const Ref<const ArrayXXd> &aa, const double phi){
    return c2r( r2c(aa) * exp(dcp(0,1)*phi) ); // a0*e^{i\phi}
}

/** @brief group tangent.  */
ArrayXXd CQCGL1d::phaseTangent(const Ref<const ArrayXXd> &aa){
    return c2r( r2c(aa) * dcp(0,1) );
}

/** @brief group generator  */
MatrixXd CQCGL1d::phaseGenerator(){
    MatrixXd T = MatrixXd::Zero(Ndim, Ndim);
    for(size_t i = 0; i < Ne; i++){
	T(2*i, 2*i+1) = -1;
	T(2*i+1, 2*i) = 1;
    }
    return T;
}

/**
 * @brief apply both continous symmetries
 *
 * @note     for performance purpose, this function is not written as the
 *           superposition of 2 functions
 */
ArrayXXd CQCGL1d::Rotate(const Ref<const ArrayXXd> &aa, const double th,
			 const double phi){
    ArrayXcd R = ( dcp(0,1) * (th * K2 + phi) ).exp(); // e^{ik\theta + \phi}
    ArrayXXcd raa = r2c(aa); 
    raa.colwise() *= R;
  
    return c2r(raa);
}

/**
 * @brief rotate the whole orbit with different phase angles at different point
 */
ArrayXXd CQCGL1d::rotateOrbit(const Ref<const ArrayXXd> &aa, const ArrayXd &th,
			      const ArrayXd &phi){
    const int m = aa.cols();
    const int n = aa.rows();
    const int m2 = th.size();
    const int m3 = phi.size();
    assert( m == m2 && m2 == m3);

    ArrayXXd aaHat(n, m);
    for( size_t i = 0; i < m; i++){
	aaHat.col(i) = Rotate(aa.col(i), th(i), phi(i));
    }

    return aaHat;
}


/**
 * @brief reduce the continous symmetries
 * 
 * @param[in] aa       states in the full state space
 * @return    aaHat, theta, phi
 * 
 * @note  g(theta, phi)(x+y) is different from gx+gy. There is no physical
 *        meaning to transform the sum/subtraction of two state points.
 */
std::tuple<ArrayXXd, ArrayXd, ArrayXd>
CQCGL1d::orbit2slice(const Ref<const ArrayXXd> &aa, const int method){
    int n = aa.rows();
    int m = aa.cols();
    assert(Ndim == n);
    ArrayXXd raa(n, m);
    ArrayXd th(m);
    ArrayXd phi(m);
    
    switch (method){

    case 1: {
	// a0 -> positive real. a1 -> positive real
	for(int i = 0; i < m; i++){
	    double x = atan2(aa(1, i), aa(0, i));
	    double y = atan2(aa(3, i), aa(2, i));
	    phi(i) = x;
	    th(i) = y - x;
	}
	break;
    }

    case 2: {
	// a0 -> positive imag. a1 -> positive real
	for (int i = 0; i < m; i++){
	    double x = atan2(aa(1, i), aa(0, i));
	    double y = atan2(aa(3, i), aa(2, i));
	    phi(i) = x - M_PI/2;
	    th(i) = y - x + M_PI/2;
	}
	break;
    }

    case 3: {
	// a0 -> positive real. a1 -> positive imag
	for (int i = 0; i < m; i++){
	    double x = atan2(aa(1, i), aa(0, i));
	    double y = atan2(aa(3, i), aa(2, i));
	    phi(i) = x;
	    th(i) = y - x - M_PI/2;
	}
	break;
    }
	
    case 4: {
	// a0 -> positive imag. a1 -> positive imag
	for (int i = 0; i < m; i++){
	    double x = atan2(aa(1, i), aa(0, i));
	    double y = atan2(aa(3, i), aa(2, i));
	    phi(i) = x - M_PI/2;
	    th(i) = y - x;
	}
	break;
    }

    case 5: {
	// a1 -> positive real. a-1 -> positive real
	// phase is wrapped. 
	for(size_t i = 0; i < m; i++){
	    double am1 = atan2(aa(n-1, i), aa(n-2, i));
	    double a1 = atan2(aa(3, i), aa(2, i));
	    phi(i) = 0.5 * (a1 + am1);
	    th(i) = 0.5 * (a1 - am1);
	    raa.col(i) = Rotate(aa.col(i), -th(i), -phi(i));
	}
	break;
    }

    case 6: {
	// a1 -> positive real. a-1 -> positive real
	// phase is unwrapped. 
	for(size_t i = 0; i < m; i++){
	    double am1 = atan2(aa(n-1, i), aa(n-2, i));
	    double a1 = atan2(aa(3, i), aa(2, i));
	    phi(i) = 0.5 * (a1 + am1);
	    th(i) = 0.5 * (a1 - am1);
	}

	const double M_2PI = 2 * M_PI;
	for(size_t i = 1; i < m; i++){
	    double t0 = th(i) - th(i-1);
	    double t1 = t0 - M_PI;
	    double t2 = t0 + M_PI;
	    double t0WrapAbs = fabs(remainder(t0, M_2PI));
	    if(fabs(t1) < t0WrapAbs) { // theta jump pi up
		th(i) = remainder(th(i) - M_PI, M_2PI);
		phi(i) = remainder(phi(i) - M_PI, M_2PI);
		continue;
	    }
	    if(fabs(t2) < t0WrapAbs) { // theta jump pi down
		th(i) = remainder(th(i) + M_PI, M_2PI);
		phi(i) = remainder(phi(i) + M_PI, M_2PI);
	    }
	}
	break;
    }
		
    default:
	fprintf(stderr, "orbit to slice error\n");
    }
	

    for(size_t i = 0; i < m; i++){
	raa.col(i) = Rotate(aa.col(i), -th(i), -phi(i));
    }

    return std::make_tuple(raa, th, phi);
}


/** @brief project covariant vectors to 1st mode slice
 *
 * @note vectors are not normalized
 */
MatrixXd CQCGL1d::ve2slice(const ArrayXXd &ve, const Ref<const ArrayXd> &x, int flag){
    int n = x.size();
    ArrayXXd xhat;
    ArrayXd th, phi;
    std::tie(xhat, th, phi) = orbit2slice(x, flag);
    VectorXd tx_rho = phaseTangent(xhat);
    VectorXd tx_tau = transTangent(xhat);
    VectorXd x0_rho(n), x0_tau(n);
    x0_rho.setZero();
    x0_tau.setZero();
    
    switch (flag){
    case 1 : {
	x0_rho(0) = 1;
	x0_tau(2) = 1;
	break;
    }
	
    case 2 : {
	x0_rho(1) = 1;
	x0_tau(2) = 1;
	break;
    }
    
    case 3 : {
	x0_rho(0) = 1;
	x0_tau(3) = 1;
	break;
    }
	
    case 4 : {
	x0_rho(1) = 1;
	x0_tau(3) = 1;
	break;
    }
	
    case 5 : {
	x0_rho(n-2) = 1;
	x0_tau(3) = 1;
	break;
    }
	
    case 6 : {
	x0_rho(n-2) = 1;
	x0_tau(2) = 1;
	break;
    }

    default:
	fprintf(stderr, "orbit to slice error\n");
    
    }

    VectorXd tp_rho = phaseTangent(x0_rho);
    VectorXd tp_tau = transTangent(x0_tau);

    Matrix2d L;
    L << tx_rho.dot(tp_rho), tx_tau.dot(tp_rho),
	tx_rho.dot(tp_tau), tx_tau.dot(tp_tau);

    MatrixXd tx(n, 2);
    tx.col(0) = tx_rho;
    tx.col(1) = tx_tau;

    MatrixXd t0(n, 2);
    t0.col(0) = tp_rho;
    t0.col(1) = tp_tau;

    MatrixXd vep = Rotate(ve, -th(0), -phi(0));
    vep = vep - tx * L.inverse() * t0.transpose() * vep;

    return vep;

}

/**
 * @brief a wrap function => reduce all symmetries of an orbit
 */
std::tuple<ArrayXXd, ArrayXd, ArrayXd>
CQCGL1d::reduceAllSymmetries(const Ref<const ArrayXXd> &aa, int flag){
    std::tuple<ArrayXXd, ArrayXd, ArrayXd> tmp = orbit2slice(aa, flag);
    return std::make_tuple(reduceReflection(std::get<0>(tmp)),
			   std::get<1>(tmp), std::get<2>(tmp));
}

/**
 * @brief a wrap function => reduce all the symmetries of covariant vectors
 */
MatrixXd CQCGL1d::reduceVe(const ArrayXXd &ve, const Ref<const ArrayXd> &x, int flag){
    std::tuple<ArrayXXd, ArrayXd, ArrayXd> tmp = orbit2slice(x, flag);
    return reflectVe(ve2slice(ve, x, flag), std::get<0>(tmp).col(0));
}


////////////////////////////////////////////////////////////////////////////////////////////////////
//                                   Abandoned                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////////

#if 0
/* -------------------------------------------------- */
/* --------         Lyapunov functional   ----------- */
/* -------------------------------------------------- */

/**
 * @brief calculate the Lyapunov functional
 *
 *  L = \int dx [ -\mu |A|^2 + D |A_x|^2 - 1/2 \beta |A|^4 - 1/3 \gamma |A|^6 ]
 *  Here FFT[ A_{x} ]_k = iq_k a_k, so 
 *          \int dx |A_x|^2 = 1/N \sum (q_k^2 |a_k|^2)
 *  The rest term can be obtained by invere FFT
 *  =>
 *  L = \sum_{k=1}^N [ -\mu |A_k|^2 - 1/2 \beta |A_k|^4 - 1/3 \gamma |A_k|^6]
 *     +\sum_{k=1}^N 1/N D [ q_k^2 |a_k|^2 ]
 *
 *  Note, there are may be pitfalls, but there is indeed asymmetry here:
 *  \sum_n |A_n|^2 = 1/N \sum_k |a_k|^2
 */
ArrayXcd
CQCGL1d::Lyap(const Ref<const ArrayXXd> &aa){
    int M = aa.cols();
    VectorXcd lya(M);
    for (size_t i = 0; i < M; i++){
	ArrayXcd a = R2C(aa.col(i));
	ArrayXcd a2 = a * a.conjugate();
	F[0].v1 = a;
	F[0].ifft();
	ArrayXcd A = F[0].v2;
	ArrayXcd A2 = A * A.conjugate();
	lya(i) =  -Mu * A2.sum()
	    - 1.0/2 * dcp(Br, Bi) * (A2*A2).sum()
	    - 1.0/3 * dcp(Gr, Gi) * (A2*A2*A2).sum()
	    + 1.0/N * dcp(Dr, Di) * (QK.square() * a2).sum();
    }
    
    return lya;
}

/**
 * @brief calculate the time derivative of Lyapunov functional
 *
 * The time derivative of Lyapunov functional is L_t = -2 \int dx |A_t|^2
 * 
 * @see Lyap(), velocity()
 */
ArrayXd
CQCGL1d::LyapVel(const Ref<const ArrayXXd> &aa){
    int M = aa.cols();
    VectorXd lyavel(M);
    for (size_t i = 0; i < M; i++){
	ArrayXd vel = velocity(aa.col(i)); // Fourier mode of velocity
	ArrayXcd cvel = R2C(vel);
	Fv.v1 = cvel;
	Fv.ifft();		// Fv.v2 is A_t
	lyavel(i) = -2 * (Fv.v2 * Fv.v2.conjugate()).sum().real();
    }
    return lyavel;
}

#endif

/**************************************************************/
/*                plane wave related                          */
/**************************************************************/

/**
 * @brief Return plane waves.
 *
 * @param[in] k            the wave index of the plane wave
 * @paran[in] isPositive   whether the sign in amplitude is positive or not
 * @return [a0, a, w]     Fourier state, amplitude, omega
 * 
 * @note This function only works for the b, c, dr, di construction
 */
std::tuple<ArrayXd, double, double>
CQCGL1d::planeWave(int k, bool isPositve){
    double b = Di, c = Bi, dr = -Gr, di = -Gi;
    double qk, a2, w;
    
    qk = 2 * M_PI * k / d;
    if(isPositve) a2 = 1/(2*dr) * (1 + sqrt(1-4*dr*(qk*qk+1)));
    else a2 = 1/(2*dr) * (1 - sqrt(1-4*dr*(qk*qk+1)));
    w = b*qk*qk - c*a2 + di*a2*a2;
    
    ArrayXd a0(ArrayXd::Zero(Ndim));
    if(k >= 0) a0(2*k) = sqrt(a2) * N;
    else a0(Ndim + 2*k) = sqrt(a2) * N; // please check
    
    return std::make_tuple(a0, sqrt(a2), w);
}


/**
 * @brief Stability exponents of plane wave
 *
 * @see planeWave(), eReq()
 */
VectorXcd 
CQCGL1d::planeWaveStabE(int k, bool isPositve){
    auto tmp = planeWave(k, isPositve);
    return eReq(std::get<0>(tmp), 0, std::get<2>(tmp));
}

std::pair<VectorXcd, MatrixXcd>
CQCGL1d::planeWaveStabEV(int k, bool isPositve){
    auto tmp = planeWave(k, isPositve);
    return evReq(std::get<0>(tmp), 0, std::get<2>(tmp));
}



<file_sep>from py_CQCGL1d import *
from cglHelp import *

################################################################################
# IN the parameter domain (Bi, Gi), we have a transition line which seperates
# stable relative equilibria and unstalbe equilibria. Hopf bifurcation happens
# close to this transition line.
#
# This file contains all case studies related to this Hopf bifurcation.
################################################################################

case = 10

if case == 10:
    """
    have a look at how unstable relative equilibrium turns to
    a limit cycle.
    """
    N, d = 1024, 50
    h = 2e-3

    Bi, Gi = 0.6, -3.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    req = CQCGLreq(cgl)
    cp = CQCGLplot(cgl)

    a0, wth0, wphi0, err0, e, v = req.readBiGi('../../data/cgl/reqBiGiEV.h5', Bi, Gi, index, flag=2)
    print e[:20]
    
    nstp = 30000
    a0 += 0.1*norm(a0)*v[0].real
    for i in range(5):
        aa = cgl.intg(a0, h, nstp, 10)
        a0 = aa[-1]
        cp.config(aa, [0, d, 0, nstp*h])
        
    
    # save candidate limit cycle
    if False:        
        rpo = CQCGLrpo(cgl)
        # be careful that the skip_rate is 10
        # rpo.saveBiGi('p.h5', Bi, Gi, 1, aa[200], 3000*h, 3000, 0, 0, 0)

if case == 30:
    """
    have a look at the limit cycle
    """
    N, d = 1024, 50
    Bi, Gi = 0.8, -3.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    rpo = CQCGLrpo(cgl)
    cp = CQCGLplot(cgl)
    
    x, T, nstp, th, phi, err = rpo.read('../../data/cgl/rpoHopfBiGi.h5', rpo.toStr(Bi, Gi, 1))
    a0 = x[:-3]
    h = T / nstp
    
    aa = cgl.intg(a0, h, nstp*4, 10)
    cp.config(aa, [0, d, 0, nstp*h])

    # check it is not a req
    vel = cgl.velocity(a0)
    velRed = cgl.ve2slice(vel, a0, 1)
    print norm(velRed)

if case == 40:
    """
    move rpo 
    """
    inFile = '../../data/cgl/rpoBiGi2.h5'
    outFile = '../../data/cgl/rpoHopfBiGi.h5'
    rpo = CQCGLrpo()
    gName = rpo.toStr(1.4, -3.9, 1)

    rpo.move(inFile, gName, outFile, gName, flag=0)
    
<file_sep>import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio
from mpl_toolkits.axes_grid1 import make_axes_locatable

aa = sio.loadmat('../mat/travelingWaveEvolution.mat')

h = 0.01

taa = aa['aa']; taa = taa[::2,:]+1j*taa[1::2,:];# change taa to plot differnt types.
#################### fig 1 ##########
fig = plt.figure(figsize=(4,5));
ax = fig.add_subplot(111)
ax.set_xlabel('x')
ax.set_ylabel('t')
im = ax.imshow(abs(np.fft.ifft(taa, axis=0)).T, cmap=plt.get_cmap('get'),
                extent=(0,50,0, h*taa.shape[1]), aspect='auto',
                origin ='lower')
ax.grid('on')
dr = make_axes_locatable(ax)
cax = dr.append_axes('right', size = '5%', pad =0.05)
bar = plt.colorbar(im, cax=cax, ticks=[0, 3])
########################################
fig.tight_layout(pad=0)
plt.show()
<file_sep>import numpy  as np 
from numpy.fft import rfft, irfft
from pdb import set_trace

def ksintIm(a0, h, nstp, d = 22, osp = 1, jsp = 1, isJ = False):
     N = len(a0); 
     a0p = np.zeros(N*2)
     a0p[1::2] = a0
     if isJ == True:
         tt, aa, daa = ksfjaco(a0p, h, nstp, osp, jsp, d, isJ)
         aa = aa[1::2, :]
         daa = daa.T.reshape(-1, 30)[1::2, 1::2]
         return aa.T, daa
     else :
         tt, aa = ksfjaco(a0p, h, nstp, osp, jsp, d, isJ)
         aa = aa[1::2, :]
         return aa.T
         
def ksfjaco(a0, h, nstp, osp = 1, jsp = 1, d =22, isJ = True):
    """
    KS integrator.

    Parameters
    ----------
    a0: one dimensional array or a list
    initial condition. It shoud be a one dimensional array or a list.
    h : double
    time step.
    nstp: int
    number of integration steps.
    osp: int, optional
    spacing for storing state vectors. If not given, osp = 1.
    jsp: int, optional
    spacing for Jacobian matrix. If not given, jsp = 1.
    d: int, optional
    length of KS system. If not given, d = 22.
    isJ: bool, optional
    Whethe to calculate the Jacobian matrix. If not given, isJ = True.

    Returns
    -------
    tt: one dimensional array
    (n,) time samples
    aa: narray
    (n,m) each column represent a state vector.
    daa: narray (only if isJ = True)
    (n**2, m) each column represent a row-stacked Jacobian.

    Examples
    --------
    >>> from numpy inport ones
    >>> tt, aa, daa= ksjaco(ones(30)*0.1, 0.25, 1000)
    >>> tt, aa = ksjaco(ones(30)*0.1, 0.25, 1000, isJ = False)
    >>> tt.shape
    (1000,)
    >>> aa.shape
    (30, 1000)
    >>> daa.shape
    (900, 1000)

    """
    N = len(a0)+2; Nh = N/2;
    a0=np.array(a0);

    if isJ:
        v = np.zeros((Nh+1, N-1), np.complex128);
        v[1:Nh, 0] = a0[::2] + 1j*a0[1::2];
        iniJ(v[:,1:]); 
    else:
        v = np.zeros([Nh+1,1], np.complex128);
        v[1:Nh, 0] = a0[::2] + 1j*a0[1::2];

    k, E, E2, Q, f1, f2, f3 = calCoe(h, Nh, d);
    g = 0.5j * np.r_[k[:-1], 0] * N; g = g[:, np.newaxis];
    E = E[:,np.newaxis]; E2 = E2[:,np.newaxis]; Q = Q[:,np.newaxis];
    f1 = f1[:,np.newaxis]; f2 = f2[:,np.newaxis]; f3 = f3[:,np.newaxis];
    if isJ:
        g = np.hstack((g, np.tile(2.*g, N-2)));
        daa = np.empty([(N-2)**2, nstp/jsp]);

    aa = np.empty([N-2, nstp/osp+1]); tt = np.empty([1, nstp/osp+1]);
    aa[:,0]=a0; tt[0,0]=0; 

    for n in range(1, nstp+1):
        t = n*h; rfv = irfft(v, axis=0); 
        Nv = g*rfft(rfv[:,0:1] * rfv, axis = 0); 

        a = E2*v + Q*Nv; rfv = irfft(a, axis=0); 
        Na = g*rfft(rfv[:,0:1] * rfv, axis = 0);

        b = E2*v + Q*Na; rfv =irfft(b, axis = 0);
        Nb = g*rfft(rfv[:,0:1] * rfv, axis = 0);

        c = E2*a + Q*(2*Nb - Nv); rfv =irfft(c, axis = 0);
        Nc = g*rfft(rfv[:,0:1] * rfv, axis = 0);

        v = E*v + Nv*f1 + 2*(Na+Nb)*f2 + Nc*f3; 

        if n % osp == 0:
            y1 = np.c_[v[1:Nh,0].real, v[1:Nh,0].imag];
            aa[:, n/osp] = y1.reshape(-1); tt[0,n/osp] =t;
        #set_trace();  
        if isJ and n % jsp == 0: 
            da = np.zeros((N-2, N-2)); da[::2,:]= v[1:Nh, 1:].real
            da[1::2,:] = v[1:Nh, 1:].imag; daa[:,n/jsp-1] = da.reshape(-1);
            iniJ(v[:,1:]);

    if isJ:
        return tt, aa, daa
    else:
        return tt, aa

def iniJ(J):
    """
    initialize the Jacobian matrix to be
    [ 0, 0, 0, ...
    1, 1j,0, ...
    0, 0, 1, 1j, ..
    ...
    0, 0, .... 1, 1j
    0, 0, 0, ...
    ]

    Parameters
    ----------
    J : array_like
    Jacobian matrix with size (Nh+1) x (N-2).

    """
    J[:,:]=0;
    for i in range(1, J.shape[0]-1):
        J[i, 2*i-2] = 1;
        J[i, 2*i-1] = 1j;

    return None

def calCoe(h, Nh, d, M = 16):
    k = 2.*np.pi/d * np.r_[:Nh+1]; # wave number: 0, 1, 2,.. Nh-1, Nh
    L = k**2 - k**4;
    E = np.exp(h * L);
    E2 = np.exp(h * L/ 2.);
    r = np.exp(1j*np.pi*(np.r_[1:M+1]-0.5)/M);
    LR = h*np.tile(L,(M,1)).T + np.tile(r,(Nh+1,1));
    Q = h*((np.exp(LR/2)-1)/LR).mean(1).real;
    f1 = h*((-4 - LR + np.exp(LR)*(4-3*LR+LR**2))/LR**3).mean(1).real;
    f2 = h*((2 + LR + np.exp(LR)*(-2+LR))/LR**3).mean(1).real;
    f3 = h*((-4 - 3*LR - LR**2 + np.exp(LR)*(4 - LR))/LR**3).mean(1).real;

    return k, E, E2, Q, f1, f2, f3;

def transJ(J):
    n, m = J.shape; n = n**0.5; #set_trace();
    Jp = np.empty([n, m*n]);
    for i in range(m):
        Jp[:, i*n:(i+1)*n] = J[:,i].reshape([n,n]);

    return Jp
<file_sep>/* time h5c++ test_CQCGL2dEIDc.cc -std=c++11 -lCQCGL2d -lmyfft -lmyH5 -ldenseRoutines -literMethod -lfftw3 -I $RESH/include/ -L $RESH/lib/ -I $XDAPPS/eigen/include/eigen3 -DEIGEN_FFTW_DEFAULT -O3  -o cgl2d.out && time ./cgl2d.out 
 */
#include <iostream>
#include <ctime>
#include "CQCGL2dEIDc.hpp"
#include "myH5.hpp"
#include "CQCGL2d.hpp"
#include "denseRoutines.hpp"

#define cee(x) cout << (x) << endl << endl;
#define N70

using namespace MyH5;
using namespace std;
using namespace Eigen;
using namespace denseRoutines;

int main(){

    std::vector<std::string> scheme = {"IFRK43", "IFRK54",
				       "Cox_Matthews", "Krogstad", "Hochbruck_Ostermann", 
				       "Luan_Ostermann", "SSPP43"};

#ifdef N15
    //====================================================================================================
    // test a single method to see whether there is a bug
    // Also, save the state for orbits 
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL2dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL2d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4);
    cgl.IntPrint = 1;
    
    MatrixXcd A0 = Gaussian2d(N, N, N/2, N/2, N/30, N/30, 2.5) 
	+ Gaussian2d(N, N, 2*N/5, 2*N/5, N/30, N/30, 0.2);
    ArrayXXcd a0 = cgl2.Config2Fourier(A0);
    double T = 20;

    cgl.setScheme("Cox_Matthews");	
    ArrayXXcd aa = cgl.intgC(a0, 0.002, T, 50, 0, "aa.h5");

    if(true){
	cgl.eidc.rtol = 1e-8;

	cgl.setScheme("Cox_Matthews");
	ArrayXXcd aaAdapt = cgl.intg(a0, T/(1<<10), T, 50, 0, "aaCox.h5");

	cgl.setScheme("SSPP43");
	aaAdapt = cgl.intg(a0, T/(1<<10), T, 50, 0, "aaSS.h5");
    }
    
#endif
#ifdef N30
    //====================================================================================================
    // fix the time step. try to look at the estimated local error of all shemes
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL2dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL2d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4);
    cgl.IntPrint = 10;

    MatrixXcd A0 = Gaussian2d(N, N, N/2, N/2, N/30, N/30, 2.5) 
	+ Gaussian2d(N, N, 2*N/5, 2*N/5, N/30, N/30, 0.2);
    ArrayXXcd a0 = cgl2.Config2Fourier(A0);
    double T = 20;

    int n0 = 14, n1 = 5;
    double h0 = T / (1<<n0);	// T / 2^13   
    double w[] = {0, -7.3981920609491505};
    MatrixXd ltes(1<<(n0 - n1), 2*scheme.size());

    for(int k = 0; k < 2; k++){
	cgl.changeOmega(w[k]);
	for(int i = 0; i < scheme.size(); i++) {
	    fprintf(stderr, "k = %d, scheme is %s \n", k, scheme[i].c_str());
	    cgl.setScheme(scheme[i]);	
	    ArrayXXcd aa = cgl.intgC(a0, h0, T, 1<<n1, 2, "aa.h5");
	    ltes.col(k*scheme.size() + i) = cgl.lte;
	}
    }
    savetxt("cqcgl2d_N30_lte.dat", ltes);
#endif
#ifdef N50
    //====================================================================================================
    // static frame integration
    // set the rtol = 1e-9 and output time steps
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL2dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL2d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4);
    cgl.IntPrint = 10;
    cgl.eidc.rtol = 1e-9;

    MatrixXcd A0 = Gaussian2d(N, N, N/2, N/2, N/30, N/30, 2.5) 
	+ Gaussian2d(N, N, 2*N/5, 2*N/5, N/30, N/30, 0.2);
    ArrayXXcd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double h0 = T / (1<<12);	// T / 2^12
    
    for(int i = 0; i < scheme.size(); i++) {
	fprintf(stderr, "scheme is %s \n", scheme[i].c_str());
	cgl.setScheme(scheme[i]);
	ArrayXXcd aa = cgl.intg(a0, h0, T, 1<<5, 2, "aa.h5");
	savetxt("cqcgl2d_N50_hs_"+to_string(i)+".dat", cgl.hs);
    }
    
#endif
#ifdef N60
    //====================================================================================================
    // Comoving frame integration
    // set the rtol = 1e-9 and output time steps
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL2dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL2d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4);
    cgl.IntPrint = 10;
    cgl.eidc.rtol = 1e-9;
    cgl.changeOmega(-7.3981920609491505);

    MatrixXcd A0 = Gaussian2d(N, N, N/2, N/2, N/30, N/30, 2.5) 
	+ Gaussian2d(N, N, 2*N/5, 2*N/5, N/30, N/30, 0.2);
    ArrayXXcd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double h0 = T / (1<<12);	// T / 2^12
    
    for(int i = 0; i < scheme.size(); i++) {
	fprintf(stderr, "scheme is %s \n", scheme[i].c_str());
	cgl.setScheme(scheme[i]);
	ArrayXXcd aa = cgl.intg(a0, h0, T, 1<<5, 2, "aa.h5");
	savetxt("cqcgl2d_N60_comoving_hs_"+to_string(i)+".dat", cgl.hs);
    }
#endif
#ifdef N70
    //====================================================================================================
    // static & comoving frame integration with time step adaption turned on.
    // choose different rtol to obtain
    //      rtol vs global relative error
    //      rtol vs integration steps, N(x) evaluation times
    //      
    const int N = 1024; 
    const double d = 50;
    double Bi = 0.8, Gi = -0.6;

    CQCGL2dEIDc cgl(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi);
    CQCGL2d cgl2(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 4);
    cgl.IntPrint = 10;

    MatrixXcd A0 = Gaussian2d(N, N, N/2, N/2, N/30, N/30, 2.5) 
	+ Gaussian2d(N, N, 2*N/5, 2*N/5, N/30, N/30, 0.2);
    ArrayXXcd a0 = cgl2.Config2Fourier(A0);
    double T = 20;
    double w[] = {0, -7.3981920609491505};

    int n = 8;
    time_t t; 
	
    for(int p = 0; p < 2; p++){
	cgl.changeOmega(w[p]);

	MatrixXd erros(n, 5*scheme.size()+1);
	for(int i = 0; i < scheme.size(); i++) {
	    cgl.setScheme(scheme[i]);	
	    for(int j = 0, k=1; j < n; j++, k*=5){
		fprintf(stderr, "w = %f, scheme is %s, j = %d \n\n", w[p], scheme[i].c_str(), j);
		double rtol = k*1e-11;
		cgl.eidc.rtol = rtol;
		if(i == 0) {
		    erros(j, 0) = rtol; 
		}
		ArrayXXcd xf = cgl.intg(a0, T/(1<<12), T, 1000000, 2, "aa.h5");
		erros.row(j).segment(5*i+1, 5) << 
		    cgl.eidc.NCalCoe, 
		    cgl.eidc.NCallF,
		    cgl.eidc.NReject,
		    cgl.eidc.TotalTime,
		    cgl.eidc.CoefficientTime;
	    }
	}
	savetxt("cqcgl2d_N70_stat" + to_string(p) + ".dat", erros);
    }
#endif    
    return 0;
}
<file_sep>/**
 * Note :
 *
 * 1) the "many" scheme assumes performing FFT in each column of input matrix. Eigen is
 * column-wise in memory layout, while FFTW is assuming row-wise memory layout, so
 * caution is exerted there.
 * 
 * 2)   
 */
#ifndef FFTW_WRAP_H
#define FFTW_WRAP_H

#include <fftw3.h>
#include <complex>
#include <Eigen/Dense>

namespace FFTW_wrap {
    
    using namespace std;
    using namespace Eigen;

    //////////////////////////////////////////////////////////////////////////////////////////
    //                                   1d  FFT                                            //
    //////////////////////////////////////////////////////////////////////////////////////////
    class fft {
    public:
	const int N, M;
	MatrixXcd time, freq;
	fftw_plan p, ip;
	
	fft(const int N, const int M, bool doInit = true) : N(N), M(M) {
	    if (doInit) init();
	}
	
	~fft(){
	    if(p) fftw_destroy_plan(p);
	    if(ip) fftw_destroy_plan(ip);
	}

	inline void init(){
	    assert (M > 0);

	    time.resize(N, M);
	    freq.resize(N, M);

	    if (1 == M){
		p = fftw_plan_dft_1d(N, (fftw_complex*)time.data(), (fftw_complex*)freq.data(),
				     FFTW_FORWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
		ip = fftw_plan_dft_1d(N, (fftw_complex*)freq.data(), (fftw_complex*)time.data(),
				      FFTW_BACKWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    }
	    else{
		int n[] = { N };
		p = fftw_plan_many_dft(1, n, M, (fftw_complex*)time.data(), 
				       n, 1, N, (fftw_complex*)freq.data(), n, 1, N,
				       FFTW_FORWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
		ip = fftw_plan_many_dft(1, n, M, (fftw_complex*)freq.data(),
					n, 1, N, (fftw_complex*)time.data(), n, 1, N,
					FFTW_BACKWARD, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    }
	}
	
	inline void fwd(){
	    fftw_execute(p);  
	}
	
	inline void inv(){
	    fftw_execute(ip);
	    time *= 1.0/N;
	}
	
    };

    //////////////////////////////////////////////////////////////////////////////////////////
    //                                   1d  real FFT                                       //
    //////////////////////////////////////////////////////////////////////////////////////////
    class rfft {
    public:
	const int N, M;
	MatrixXd time;
	MatrixXcd freq;
	fftw_plan p, ip;
	
	fft(const int N, const int M, bool doInit = true) : N(N), M(M) {
	    if (doInit) init();
	}
	
	~fft(){
	    if(p) fftw_destroy_plan(p);
	    if(ip) fftw_destroy_plan(ip);
	}

	inline void init(){
	    assert (M > 0);

	    time.resize(N, M);
	    freq.resize(N/2+1, M);

	    if (1 == M){
		p = fftw_plan_dft_r2c_1d(N, time.data(), (fftw_complex*)freq.data(), FFTW_MEASURE|FFTW_PRESERVE_INPUT);
		ip = fftw_plan_dft_c2r_1d(N, (fftw_complex*)freq.data(), time.data(), FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    }
	    else{
		int n[] = { N };
		p = fftw_plan_many_dft_r2c(1, n, M, time.data(), n, 1, N,
					   (fftw_complex*)freq.data(), n, 1, N/2+1,
					   FFTW_MEASURE|FFTW_PRESERVE_INPUT);
		ip = fftw_plan_many_dft_r2c(1, n, M, (fftw_complex*)freq.data(), n, 1, N/2+1,
					    time.data(), n, 1, N,
					    FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    }
	}
	
	inline void fwd(){
	    fftw_execute(p);  
	}
	
	inline void inv(){
	    fftw_execute(ip);
	    time *= 1.0/N;
	}
	
    }
	
}

#endif	/* FFTW_WRAP_H */
<file_sep>/** To compile this class, you need to have g++ >= 4.6, eigen >= 3.1
 * g++ -o libksintm1.so ksintM1.cc ksint.cc
 * -shared -fpic -lm -lfftw3 -std=c++0x
 * -march=core2 -O3 -msse2 -I/path/to/eigen3 -I../../include
 *  */

#ifndef KSINTM1_H
#define KSINTM1_H

#include "ksint.hpp"

class KSM1 : public KS {

public:
  
  /* member functions */
  std::pair<ArrayXXd, ArrayXd> 
  intg(const ArrayXd &a0, size_t nstp, size_t np);
  std::pair<ArrayXXd, ArrayXd> 
  intg2(const ArrayXd &a0, double T, size_t np);

  /* constructors */
  KSM1(int N = 32, double h = 0.25, double d = 22);
  explicit KSM1(const KSM1 &x);
  KSM1 & operator=(const KSM1 &x);

protected:

  virtual void NL(KSfft &f);
  // virtual void jNL(KSfft &f);
};

#endif	/* KSINTM1_H */
<file_sep>#ifndef KSSOLVEM1_H
#define KSSOLVEM1_H

#include "kssolve.hpp"
#include <vector>

class KsM1 : public Ks {

public:
  /** structure definition */
  typedef std::vector<double> dvec;
  typedef std::vector<dcomp> dcvec;

  /** @brief KS solver in the 1st mode slice without Jacobian.
   *
   *  If np != 1, the time sequence is not accurate.
   *  */
  void kssolve(double *a0, int nstp, int np, double *aa, double *tt);
  void kssolve(double *a0, int nstp, int np, int nqr, double *aa,
	       double *daa, double *tt);

  /** @brief velocity in the 1st mode slice
   * 
   * @param[in] a0 vector of size N-3
   * @return velocity vector of size N-3
   */
  dvec velo(dvec &a0);

  /** @brief integrate point a0 to poincare section defined by x0
   * 
   * with its velocity filed. a0 should be below the section which means the
   * direction of the poincare section is parallel to the velocity field.
   * 
   * @param[in] x0 template point of the Poincare section 
   *            U(x) = v0 * (x - x0)
   * @param[in] a0 state point that needed to be integrated onto
   *            Poincare section.
   * @return  N-1 vector with last two elements be the time and error
   */
  dvec ks2poinc(dvec &x0, dvec &a0);

  

  // constructors, destructor, copy assignment.
  KsM1(int N = 32, double d = 22, double h = 0.25);
  explicit KsM1(const KsM1 &x);
  KsM1 & operator=(const KsM1 &x);

  /* ------------------- ---------------------------------------- */

protected:
  /* function onestep() keeps unchanged. */
  void initKs(double *a0, dcomp *v, double *aa, FFT &rp, FFT &p) override;
  void initKs(double *a0, dcomp *v, double *aa, FFT *rp, FFT *p) override;
  void calNL(dcomp*u, dcomp *Nv, const FFT &p, const FFT &rp) override;
  void calNL(dcomp *u, dcomp *Nv, const FFT *p, const FFT *rp ) override;
  void initJ(dcomp *v) override;

  dvec cv2rv(const dcvec &a0);

  /* ------------------------------------------------------------ */

private:
  class Int2p{
    
  public:
    KsM1 &ks;
    dvec v0;

    Int2p(KsM1 &k): ks(k){}
    void operator() (const dvec &x, dvec &dxdt, const double /* t */);
  };
  
  Int2p int2p;

};

#endif	/* KSSOLVEM1_H */
<file_sep>from py_ks import pyKSETD, pyKS
from personalFunctions import *

case = 1

if case == 1:
    N = 64
    L = 22
    ksetd = pyKSETD(N, L)
    
    poType = 'rpo'
    poId = 1
    a0, T, nstp, r, s = KSreadPO('../../data/ks22h001t120x64.h5', poType, poId)

    ksetd.setRtol(1e-8)
    tt, aa = ksetd.etd(a0, T, 0.01, 1, 2, False)
    hs = ksetd.hs()[1:]
    duu = ksetd.duu()[1:]
    plot1dfig(duu, yscale='log')
    plot1dfig(hs)
    print ksetd.etdParam()
    
    KSplotColorMapOrbit(aa, [0, L, 0, T])
<file_sep>import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

aa = sio.loadmat('../mat/cqcglStateTestN.mat')
a1 = aa['uu128'];
a2 = aa['uu256'];
a3 = aa['uu512'];

h = 0.01;

fig = plt.figure(figsize=(8,4));
ax = fig.add_subplot(131)
ax2 = fig.add_subplot(132)
ax3 = fig.add_subplot(133)

########## fig 1 ##########
ax.set_xlabel('x')
ax.set_ylabel('t')
ax.imshow(abs(np.fft.ifft(a1, axis = 0)).T, cmap=plt.get_cmap('jet'),
          extent=(0,128,0, h*a1.shape[1]), aspect='auto', origin ='lower');
ax.grid('on')

########## fig 2 ##########
ax2.set_xlabel('x')
ax2.set_ylabel('t')
ax2.imshow(abs(np.fft.ifft(a2, axis = 0)).T, cmap=plt.get_cmap('jet'),
          extent=(0,256,0, h*a1.shape[1]), aspect='auto', origin ='lower');
ax2.grid('on')

########## fig 3 ##########
ax3.set_xlabel('x')
ax3.set_ylabel('t')
im = ax3.imshow(abs(np.fft.ifft(a3, axis = 0)).T, cmap=plt.get_cmap('jet'),
          extent=(0,512,0, h*a1.shape[1]), aspect='auto', origin ='lower');
ax3.grid('on')
dr3 = make_axes_locatable(ax3)
cax3 = dr3.append_axes('right', size = '10%', pad =0.05)
bar = plt.colorbar(im, cax=cax3, ticks=[0, 2.5])

##############################
fig.tight_layout(pad=0)
plt.show()
<file_sep>#ifndef CQCGL1DSUB_H
#define CQCGL1DSUB_H

#include <complex>
#include <utility>
#include <algorithm>
#include <vector>
#include <unsupported/Eigen/FFT>
#include "denseRoutines.hpp"
#include "EIDc.hpp"

//////////////////////////////////////////////////////////////////////
//                       class CQCGL1dSub                           //
//////////////////////////////////////////////////////////////////////
class CQCGL1dSub {
  
public:
    typedef std::complex<double> dcp;
    
    const int N;		/* dimension of FFT */
    const double d;		/* system domain size */
    
    const int Ne;		// effective number of modes
    const int Ndim;		// dimension of state space
    const int DimTan;		// the dimension of tangent space
    
    bool IsQintic = true;	//  False => cubic equation
    
    double Mu, Dr, Di, Br, Bi, Gr, Gi;
    double Omega = 0;		/* used for comoving frame */
    ArrayXd K, QK;

    ArrayXcd L;

    FFT<double> fft;

    VectorXd hs;	      /* time step sequnce */
    VectorXd lte;	      /* local relative error estimation */
    VectorXd Ts;	      /* time sequnence for adaptive method */
    int cellSize = 500;	/* size of cell when resize output container */

    struct NL {
	CQCGL1dSub *cgl;
	int N, Ne;
	dcp B, G;
	ArrayXXcd modes, field;	// Fourier modes and physical field
	
	NL();
	NL(CQCGL1dSub *cgl, int cols);
	~NL();
	void operator()(ArrayXXcd &x, ArrayXXcd &dxdt, double t);
    };
    
    NL nl, nl2;
    
    ArrayXXcd Yv[10], Nv[10], Yv2[10], Nv2[10];
    EIDc eidc, eidc2;
    
    ////////////////////////////////////////////////////////////
    //         constructor, destructor, copy assignment.      //
    ////////////////////////////////////////////////////////////

    // A_t = Mu A + (Dr + Di*i) A_{xx} + (Br + Bi*i) |A|^2 A + (Gr + Gi*i) |A|^4 A
    CQCGL1dSub(int N, double d,
	       double Mu, double Dr, double Di, double Br, double Bi, 
	       double Gr, double Gi, int dimTan);
    
    // A_t = -A + (1 + b*i) A_{xx} + (1 + c*i) |A|^2 A - (dr + di*i) |A|^4 A
    CQCGL1dSub(int N, double d, 
	       double b, double c, double dr, double di, 
	       int dimTan);
    
    // iA_z + D A_{tt} + |A|^2 A + \nu |A|^4 A = i \delta A + i \beta A_{tt} + i |A|^2 A + i \mu |A|^4 A
    CQCGL1dSub(int N, double d,
	       double delta, double beta, double D, double epsilon,
	       double mu, double nu, int dimTan);
    ~CQCGL1dSub();
    CQCGL1dSub & operator=(const CQCGL1dSub &x);

    ////////////////////////////////////////////////////////////
    //                    member functions.                   //
    ////////////////////////////////////////////////////////////

    //============================================================    
    void setScheme(std::string x);
    void changeOmega(double w);

    ArrayXXd 
    intgC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgjC(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd
    intgvC(const ArrayXd &a0, const ArrayXXd &v, const double h, const double tend);
    ArrayXXd
    intg(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    std::pair<ArrayXXd, ArrayXXd>
    intgj(const ArrayXd &a0, const double h, const double tend, const int skip_rate);
    ArrayXXd 
    intgv(const ArrayXXd &a0, const ArrayXXd &v, const double h, const double tend);
    
    ArrayXXd C2R(const ArrayXXcd &v);
    ArrayXXcd R2C(const ArrayXXd &v);
    
    //============================================================  

    ArrayXXcd Fourier2Config(const Ref<const ArrayXXd> &aa);
    ArrayXXd Config2Fourier(const Ref<const ArrayXXcd> &AA);
    ArrayXXd calPhase(const Ref<const ArrayXXcd> &AA);
    VectorXd calQ(const Ref<const ArrayXXd> &aa);
    VectorXd calMoment(const Ref<const ArrayXXd> &aa, const int p = 1);
    
    ArrayXd velocity(const ArrayXd &a0);
    ArrayXd velocityReq(const ArrayXd &a0, const double phi);
    MatrixXd stab(const ArrayXd &a0);
    MatrixXd stabReq(const ArrayXd &a0, double phi);
    VectorXcd eReq(const ArrayXd &a0, double wphi);
    MatrixXcd vReq(const ArrayXd &a0, double wphi);
    std::pair<VectorXcd, MatrixXcd>
    evReq(const ArrayXd &a0, double wphi);

    ArrayXXd phaseRotate(const Ref<const ArrayXXd> &aa, const double phi);
    ArrayXXd phaseTangent(const Ref<const ArrayXXd> &aa);
    MatrixXd phaseGenerator();
};



#endif  /* CQCGL1DSUB_H */
<file_sep>from py_CQCGL1dSub import *
from cglHelp import *
import time

case = 10

if case == 10:
    """
    Test the integration result by EID method
    """
    N, d = 1024 , 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi = 2, -2

    cgl = pyCQCGL1dSub(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    req, cp = CQCGLreq(cgl), CQCGLplot(cgl)

    a0, wth0, wphi0, err0 = req.read('../../data/cgl/reqBiGiEV.h5', req.toStr(Bi, Gi, 1))
    a0 = a0[:cgl.Ndim]
    aE = a0 + 0.01 * norm(a0) *  rand(cgl.Ndim)
    T = 200

    t = time.time()
    aa = cgl.intgC(aE, h, T, 50)
    print time.time() - t 
    cp.config(aa, [0, d, 0, T])

    t = time.time()
    aa2 = cgl.intg(aE, h, T, 50)
    print time.time() - t
    cp.config(aa2, [0, d, 0, T])

    # t = time.time()
    # aa3  = EI.intg(aE, h, T, 10)
    # print time.time() -t 
    # cp.config(aa3, [0, d, 0, T])

if case == 20:
    """
    same test as case = 10, but with rpo intial condition
    """
    N, d = 1024 , 50
    h = 2e-3
    sysFlag = 1

    Bi, Gi =  4.8, -4.5

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, -1)
    EI = pyCQCGL1dEIDc(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi)
    rpo, cp = CQCGLrpo(cgl), CQCGLplot(cgl)

    x, T, nstp, th, phi, err, e, v = rpo.read('../../data/cgl/rpoBiGiEV.h5',
                                              rpo.toStr(Bi, Gi, 1), flag=2)
    a0 = x[:cgl.Ndim]
    aE = a0 + 0.001 * norm(a0) * v[0].real

    t = time.time()
    aa = cgl.intgC(aE, T/nstp/2, 20*T, 10)
    print time.time() - t 
    cp.config(aa, [0, d, 0, 20*T])

    t = time.time()
    aa2 = EI.intgC(aE, T/nstp/2, 20*T, 10)
    print time.time() - t
    cp.config(aa2, [0, d, 0, 20*T])

if case == 30:
    """
    test the function of calculating stability matrix
    """
    N, d = 1024 , 50
    Bi, Gi = 0.8, -0.6
    index = 1

    cgl = pyCQCGL1d(N, d, -0.1, 0.125, 0.5, 1, Bi, -0.1, Gi, 0)
    req = CQCGLreq(cgl)

    a0, wth0, wphi0, err0, e0, v0 = req.read('../../data/cgl/reqBiGiEV.h5',
                                             req.toStr(Bi, Gi, index), flag=2)
    e, v = req.eigReq(a0, wth0, wphi0)
    print e[:10]
<file_sep>#ifndef CQCGL2DDISLIN_H
#define CQCGL2DDISLIN_H

#include "CQCGL2d.hpp"
#include "discpp.h"

class CQCGL2dDislin : public CQCGL2d {

public:
    
    //////////////////////////////////////////////////////////////////////
   
    
    //////////////////////////////////////////////////////////////////////
    CQCGL2dDislin(int N, int M, double dx, double dy,
		  double b, double c, double dr, double di,
		  int threadNum);
    CQCGL2dDislin(int N, double dx,
		  double b, double c, double dr, double di,
		  int threadNum);
    ~CQCGL2dDislin();
    CQCGL2dDislin & operator=(const CQCGL2dDislin &x);

    //////////////////////////////////////////////////////////////////////
    void 
    initPlot(Dislin &g, const double Lx, const double Ly, 
	     const double Lz);
    void 
    plot(Dislin &g, const double t, const double err);
    void
    endPlot(Dislin &g);

    void
    constAnim(const ArrayXXcd &a0, const double h, const int skip_rate);
    void
    adaptAnim(const ArrayXXcd &a0, const double h0, const int skip_rate);  
};

#endif  /* CQCGL2DDISLIN_H */


<file_sep>#include "myfft.hpp"
#include <iostream>
using namespace Eigen;
using namespace std;

namespace MyFFT {
    
    long NumOfInstance = 0;

    //////////////////////////////////////////////////////////////////////////////////////////
    //                                   1d  FFT                                            //
    //////////////////////////////////////////////////////////////////////////////////////////
    
    void FFT::init(const int N, const int M){
	this-> N = N;
	this-> M = M;

	if(M > 0){
	    // initialize fft/ifft plan
	    c1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	    c2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	    c3 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	    //build the maps.
	    new (&v1) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c1[0][0]), N, M );
	    new (&v2) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c2[0][0]), N, M );
	    new (&v3) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c3[0][0]), N, M );
		
	    if (1 == M){
		p = fftw_plan_dft_1d(N, c2, c3, FFTW_FORWARD, FFTW_MEASURE);
		rp = fftw_plan_dft_1d(N, c1, c2, FFTW_BACKWARD, FFTW_MEASURE);
	    } else{
		int n[] = { N };
		p = fftw_plan_many_dft(1, n, M, c2, n, 1, N,
				       c3, n, 1, N, FFTW_FORWARD, FFTW_MEASURE);
		rp = fftw_plan_many_dft(1, n, M, c1, n, 1, N,
					c2, n, 1, N, FFTW_BACKWARD, FFTW_MEASURE);
	    }

	    hasInit = true;
	    NumOfInstance++;
	}
    }
    
    FFT::FFT(const int N, const int M) : N(N), M(M), v1(NULL, 0, 0), v2(NULL, 0, 0), v3(NULL, 0, 0){
	init(N, M);
    }
    
    FFT::FFT() : v1(NULL, 0, 0), v2(NULL, 0, 0), v3(NULL, 0, 0){}

    FFT::~FFT(){
	if (hasInit && M > 0){
	    fftw_destroy_plan(p);
	    fftw_destroy_plan(rp);
	    fftw_free(c1);
	    fftw_free(c2);
	    fftw_free(c3);
	    /* releae the map */
	    new (&(v1)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
	    new (&(v2)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
	    new (&(v3)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
	}
	
	// only the last instance cleans up
	if(--NumOfInstance == 0){
#ifdef CLEAN
	    fftw_cleanup();
#endif	/* CLEAN */
	}
	
    }

    void FFT::fft() {
	fftw_execute(p);  
    }

    void FFT::ifft() {
	fftw_execute(rp);
	v2 /= N;
    }

    //////////////////////////////////////////////////////////////////////////////////////////
    //                                 1d RFFT                                              //
    //////////////////////////////////////////////////////////////////////////////////////////
    RFFT::RFFT(const int N, const int M, const int threadNum) : 
	N(N), M(M), threadNum(threadNum),
	vc1(NULL, 0, 0), vr2(NULL, 0, 0), vc3(NULL, 0, 0) 
    {
	if(++NumOfInstance == 1) {
#ifdef TFFT  // mutlithread fft.
	    if(!fftw_init_threads()){
		fprintf(stderr, "error create MultiFFT.\n");
		exit(1);
	    }
	    // fftw_plan_with_nthreads(omp_get_max_threads());
	    fftw_plan_with_nthreads(threadNum);    
#endif	/* TFFT */
	}
	    
	if(M > 0) {
	    r2 = (double*) fftw_malloc(sizeof(double) * N * M);
	    c1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (N/2+1) * M);
	    c3 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (N/2+1) * M);
	    
	    new (&vr2) Map<ArrayXXd>( &(r2[0]), N, M);
	    new (&vc1) Map<ArrayXXcd>( (dcp*)&(c1[0][0]), N/2+1, M );
	    new (&vc3) Map<ArrayXXcd>( (dcp*)&(c3[0][0]), N/2+1, M );
	    
	    if (1 == M){
		p = fftw_plan_dft_r2c_1d(N, r2, c3, FFTW_MEASURE);
		rp = fftw_plan_dft_c2r_1d(N, c1, r2, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    } else{
		int n[]={N};
		p = fftw_plan_many_dft_r2c(1, n, M, r2, n, 1, N, 
					   c3, n, 1, N/2+1, FFTW_MEASURE);
		rp = fftw_plan_many_dft_c2r(1, n, M, c1, n, 1, N/2+1,
					    r2, n, 1, N, FFTW_MEASURE|FFTW_PRESERVE_INPUT);
	    }
	}

    }

    RFFT::~RFFT(){
	
	if(M > 0){	    
	    /* free the memory */
	    fftw_destroy_plan(p);
	    fftw_destroy_plan(rp);
	    fftw_free(c1);
	    fftw_free(r2);
	    fftw_free(c3);
	    /* release the maps */
	    new (&(vc1)) Map<ArrayXXcd>(NULL, 0, 0);
	    new (&(vr2)) Map<ArrayXXd>(NULL, 0, 0);
	    new (&(vc3)) Map<ArrayXXcd>(NULL, 0, 0);	   
	}
	
	if(--NumOfInstance == 0 ){
#ifdef CLEAN
	    fftw_cleanup();
#endif	/* CLEAN */
#ifdef TFFT
	    fftw_cleanup_threads();
#endif	/* TFFT */
	}

    }
    
    void RFFT::fft() {
	fftw_execute(p);
    }

    void RFFT::ifft() { //cout << vc1 << endl << endl;
	fftw_execute(rp); // cout << vr2 << endl;
	vr2 /= N;
    }	


    //////////////////////////////////////////////////////////////////////////////////////////
    //                                 2d FFT                                               //
    //////////////////////////////////////////////////////////////////////////////////////////
    
    /* @brief 2dFFT for a [N x M] matrix. Note N rows M colums */
    
    FFT2d::FFT2d(const int N, const int M, const int threadNum):
	N(N), M(M), threadNum(threadNum),
	v1(NULL, 0, 0), v2(NULL, 0, 0), v3(NULL, 0, 0)
    {
	// only the first instance do some initialization
	if(++NumOfInstance == 1){
#ifdef TFFT  // mutlithread fft.
	    if(!fftw_init_threads()){
		fprintf(stderr, "error create MultiFFT.\n");
		exit(1);
	    }
	    // fftw_plan_with_nthreads(omp_get_max_threads());
	    fftw_plan_with_nthreads(threadNum);    
#endif	/* TFFT */
	}
	
	c1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	c2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	c3 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N * M);
	//build the maps.
	new (&v1) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c1[0][0]), N, M );
	new (&v2) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c2[0][0]), N, M );
	new (&v3) Eigen::Map<Eigen::ArrayXXcd>( (dcp*)&(c3[0][0]), N, M );
	

	/* note, FFTW use row-major format, so M, N exchanged */
	p = fftw_plan_dft_2d(M, N, c2, c3, FFTW_FORWARD, FFTW_MEASURE);
	rp = fftw_plan_dft_2d(M, N, c1, c2, FFTW_BACKWARD, FFTW_MEASURE);

    }
    
    FFT2d::~FFT2d(){
    
	fftw_destroy_plan(p);
	fftw_destroy_plan(rp);
	fftw_free(c1);
	fftw_free(c2);
	fftw_free(c3);
	/* releae the map */
	new (&(v1)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
	new (&(v2)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
	new (&(v3)) Eigen::Map<Eigen::ArrayXXcd>(NULL, 0, 0);
    
    
	// only the last instance cleans up
	if(--NumOfInstance == 0){
#ifdef CLEAN
	    fftw_cleanup();
#endif	/* CLEAN */
#ifdef TFFT
	    fftw_cleanup_threads();
#endif	/* TFFT */
	}
	
    }

    void FFT2d::fft() {
	fftw_execute(p);  
    }

    void FFT2d::ifft() {
	fftw_execute(rp);
	v2 /= (N*M);
    }
}
<file_sep>/* h5c++ test_KSEIDr.cc -std=c++11 -lksint -lmyfft -lmyH5 -ldenseRoutines -literMethod -lfftw3 -I $RESH/include/ -L $RESH/lib/ -I $XDAPPS/eigen/include/eigen3 -DEIGEN_FFTW_DEFAULT -O3 && ./a.out 
 */
#include <iostream>
#include <ctime>
#include "KSEIDr.hpp"
#include "myH5.hpp"
#include "ksint.hpp"
#include "denseRoutines.hpp"

#define cee(x) cout << (x) << endl << endl;
#define N50

using namespace MyH5;
using namespace std;
using namespace Eigen;
using namespace denseRoutines;

int main(){

    std::vector<std::string> scheme = {"Cox_Matthews", 
				       "Krogstad",
				       "Hochbruck_Ostermann", 
				       "Luan_Ostermann", 
				       "IFRK43",
				       "IFRK54", 
				       "SSPP43"};
    std::string file = "/usr/local/home/xiong/00git/research/data/ks22h001t120x64.h5";
    std::string poType = "ppo";

    MatrixXd a0;
    double T, r, s;
    int nstp;
    std::tie(a0, T, nstp, r, s) = KSreadRPO(file, poType, 1);

#ifdef N3
    //====================================================================================================
    // save the state of 2T of ppo1 by one scheme to check whether the orbit is closed or not
    KSEIDr ks(64, 22);
    ks.setScheme(scheme[6]);
    ArrayXXd aa = ks.intgC(a0, T/nstp, 2*T, 1);
    
    savetxt("aa.dat", aa.topRows(3));


#endif
#ifdef N5
    //====================================================================================================
    // test the implemenation of Cox-Matthews is consistent with previous implementation by
    // verifying the accuarycy of ppo1
    KSEIDr ks(64, 22);
    ArrayXXd aa = ks.intgC(a0, T/nstp, T, 1);
    KS ks2(64, 22);
    VectorXd a1 = ks2.Reflection(aa.rightCols(1));
    ArrayXXd aa2 = ks2.intg(a0, T/nstp, nstp, 1);
    VectorXd a2 = ks2.Reflection(aa2.rightCols(1));
    double err1 = (a1-a0).norm();
    double err2 = (a2-a0).norm();
    cout << err1 << '\t' << err2 << endl;

    // Result:
    // 4.05043e-14	3.92468e-14

#endif
#ifdef N10
    //====================================================================================================
    // test whether the implementations are correct by using ppo1.
    // Criteria : after one period and reflection, the orbit should be closed
    KSEIDr ks(64, 22);
    KS ks2(64, 22);
    ArrayXXd aa;
    for(int i = 0; i < scheme.size(); i++) {
	ks.setScheme(scheme[i]);
	aa = ks.intgC(a0, T/nstp, T, 1);
	VectorXd a1 = ks2.Reflection(aa.rightCols(1));
	cout << (a1 - a0).norm() << endl;
    }
    // Output:
    // 4.08788e-14
    // 2.10358e-13
    // 3.26765e-13
    // 3.67868e-13
    // 7.0766e-11
    // 3.80098e-13
    // 3.1632e-11


#endif
#ifdef N20
    //====================================================================================================
    // test the order of different schemes by varying time step
    // By constant stepping, the estimated LTEs are saved
    KSEIDr ks(64, 22);
    for(int k = 1; k < 1000; k*=10){
	MatrixXd lte(nstp/k, scheme.size());
	for(int i = 0; i < scheme.size(); i++) {
	    ks.setScheme(scheme[i]);
	    ArrayXXd aa = ks.intgC(a0, T/nstp*k,  T, 1);
	    lte.col(i) = ks.lte;
	}
	savetxt("KS_N20_lte" + to_string(k) + ".dat", lte);
    }

#endif
#ifdef N30
    //====================================================================================================
    // Test the accuracy of constant stepping shemes.
    // Choose Luan-Ostermann method with a small time step as the base, then integrate the
    // system for one period of ppo1.
    KSEIDr ks(64, 22);
    ks.setScheme("Luan_Ostermann");

    double h0 = T/131072;	// 2^17
    ArrayXd x0 = ks.intgC(a0, h0, T, 10000).rightCols(1);

    int n = 10;

    MatrixXd erros(n, scheme.size()+1);
    for(int i = 0; i < scheme.size(); i++) {
	ks.setScheme(scheme[i]);	
	for(int j = 0, k=8; j < n; j++, k*=2){
	    double h = k*h0;
	    if(i == 0) erros(j, 0) = h;
	    ArrayXXd aa = ks.intgC(a0, h, T, 1);
	    double err = (aa.rightCols(1) - x0).abs().maxCoeff() / x0.abs().maxCoeff();
	    erros(j, i+1) = err; 
	    cout << err << ' ';
	}
	cout << endl;
    }
    savetxt("KS_N30_err.dat", erros);

#endif
#ifdef N40
    //====================================================================================================
    // time adaptive stepping
    // test the implemenation of Cox-Matthews is consistent with previous implementation by
    // verifying the accuarycy of ppo1
    KSEIDr ks(64, 22);
    ArrayXXd aa = ks.intg(a0, T/nstp, T, 1);
    KS ks2(64, 22);
    VectorXd a1 = ks2.Reflection(aa.rightCols(1));
    ArrayXXd aa2 = ks2.intg(a0, T/nstp, nstp, 1);
    VectorXd a2 = ks2.Reflection(aa2.rightCols(1));
    double err1 = (a1-a0).norm();
    double err2 = (a2-a0).norm();
    cout << err1 << '\t' << err2 << endl;
    cout << aa.cols() << '\t' << ks.lte.maxCoeff() << '\t' << ks.hs.maxCoeff() << endl;
    cout << ks.eidr.NCalCoe << ' ' << ks.eidr.NReject << ' ' << ks.eidr.NCallF << ' ' << ks.eidr.NSteps << endl;

    // Output:
    // 1.19741e-08	3.92468e-14
    // 699	6.53879e-09	0.0152952
    // 8 2 3505 699

#endif
#ifdef N50
    //====================================================================================================
    // same as N40, but test all shemes
    KSEIDr ks(64, 22);
    KS ks2(64, 22);
    for(int i = 0; i < scheme.size(); i++) {
	ks.setScheme(scheme[i]);
	ArrayXXd aa = ks.intg(a0, T/nstp, T, 1);
	VectorXd a1 = ks2.Reflection(aa.rightCols(1));
	cout << (a1-a0).norm() << ' ' << ks.lte.maxCoeff() << ' ' << ks.hs.maxCoeff() << ' ';
	cout << ks.eidr.NCalCoe << ' ' << ks.eidr.NReject << ' ' << ks.eidr.NCallF << ' ' << ks.eidr.NSteps << endl;
    }
    
    // Output:
    // 
    // 1.19741e-08 6.53879e-09 0.0152952 8 2 3505 699
    // 1.45044e-08 6.51859e-09 0.0251392 9 2 2600 518
    // 7.36104e-09 6.53008e-09 0.0251002 10 2 2600 518
    // 2.12496e-09 2.44513e-09 0.082695 8 0 1215 135
    // 2.50557e-08 6.54958e-09 0.00559735 8 2 11695 2337
    // 1.90432e-08 5.89591e-09 0.0132776 8 1 6202 885
    // 1.94839e-10 6.55866e-09 0.00202678 7 2 154752 6446
    


#endif
    
    return 0;
}
<file_sep>from personalFunctions import *
from py_ks import *

case = 50

N, L = 64, 22
eqFile =  '../../data/ks22Reqx64.h5'
poFile = '../../data/ks22h001t120x64EV.h5'

if case == 10:
    """
    plot the configuration profile of eq and req
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    for i in range(1, 4):
        a, err = ksp.readEq(eqFile, i)
        ksp.oneConfig(a, axisLabelSize=25, tickSize=18)
    for i in range(1, 3):
        a, w, err = ksp.readReq(eqFile, i)
        ksp.oneConfig(a, axisLabelSize=25, tickSize=18)
    
if case == 20:
    """
    plot the 2 req with time and the symmetry reduced figues 
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    h = 2e-3
    T = 100
    for i in range(1, 3):
        a, w, err = ksp.readReq(eqFile, i)
        aa = ks.intg(a, h, np.int(T/h), 5)
        raa, ths = ks.redSO2(aa, 1, False)
        ksp.config(aa, [0, L, 0, T], axisLabelSize=25, tickSize=16)
        ksp.config(raa, [0, L, 0, T], axisLabelSize=25, tickSize=16)
    

if case == 30:
    """
    Plot rpo and ppo configuration in the full state space and 
    in the reduced space. Also plot without labels.
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    Ts = 100
    for poType in ['ppo', 'rpo']:
        for i in range(1, 4):
            a0, T, nstp, r, s = ksp.readPO(poFile, poType, i)
            h = T / nstp
            aa = ks.intg(a0, h, np.int(Ts/h), 5)
            raa, ths = ks.redSO2(aa, 1, False)
            name = 'ks' + poType + str(i) + 'T100'
            ksp.config(aa, [0, L, 0, Ts], axisLabelSize=25, tickSize=16, save=True, name=name)
            ksp.config(raa, [0, L, 0, Ts], axisLabelSize=25, tickSize=16,save=True, name=name+'Red')
            ksp.config(aa, [0, L, 0, Ts], axisLabelSize=25, tickSize=16, save=True, name=name+'NoLabel', 
                       labs=[None, None])
            ksp.config(raa, [0, L, 0, Ts], axisLabelSize=25, tickSize=16,save=True, name=name+'NoLabel'+'Red',
                       labs=[None, None])

if case == 50:
    """
    plot rpo / ppo in the full state space
    for a few pieces 
    """
    ks = pyKS(N, L)
    ksp = KSplot(ks)
    Ts = 100

    fig, ax = pl3d(size=[8, 6], labs=[r'$b_1$', r'$b_2$', r'$c_2$'])
    fig2, ax2 = pl3d(size=[8, 6], labs=[r'$b_1$', r'$b_2$', r'$c_2$'])

    poType = 'rpo'
    poIds = [5, 22]
    cs = ['b', 'r']
    for i in range(len(poIds)):
        poId = poIds[i]
        a0, T, nstp, r, s = ksp.readPO(poFile, poType, poId)
        h = T / nstp
        aa = ks.intg(a0, h, np.int(T/h), 5)
        raa, ths = ks.redSO2(aa, 1, False)
        name = 'ks' + poType + str(i) + 'T100'
        
        for j in range(10):
            aa2 = ks.Rotation(aa, -s*j / L*2*np.pi)
            ax.plot(aa2[:, 0], aa2[:, 2], aa2[:, 3], c=cs[i])
        ax2.plot(raa[:, 0], raa[:, 2], raa[:, 3], c=cs[i])
        
    plt.locator_params(nbins=4)
    
    ax3d(fig, ax)
    ax3d(fig2, ax2)
