C++ 头文件中的名称空间有问题;未定义的引用;错误?

C++ 头文件中的名称空间有问题;未定义的引用;错误?,c++,namespaces,undefined-reference,C++,Namespaces,Undefined Reference,由于命名空间cpl,我收到以下错误? 我在下面包括了Wavepacket.cpp和Vector.hpp obj\Debug\wavepacket.o||In function `Z10initializev':| wavepacket.cpp|79|undefined reference to `cpl::Vector::Vector(int)'| wavepacket.cpp|79|undefined reference to `cpl::Vector::operator=(cpl::Vect

由于命名空间
cpl
,我收到以下错误? 我在下面包括了Wavepacket.cpp和Vector.hpp

obj\Debug\wavepacket.o||In function `Z10initializev':|
wavepacket.cpp|79|undefined reference to `cpl::Vector::Vector(int)'|
wavepacket.cpp|79|undefined reference to `cpl::Vector::operator=(cpl::Vector const&)'|
wavepacket.cpp|80|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|80|undefined reference to `cpl::ComplexVector::operator=(cpl::ComplexVector const&)'|
wavepacket.cpp|81|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|81|undefined reference to `cpl::ComplexVector::operator=(cpl::ComplexVector const&)'|
wavepacket.cpp|101|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|101|undefined reference to `cpl::ComplexVector::operator=(cpl::ComplexVector const&)'|
wavepacket.cpp|102|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|102|undefined reference to `cpl::ComplexVector::operator=(cpl::ComplexVector const&)'|
wavepacket.cpp|103|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|103|undefined reference to `cpl::ComplexVector::operator=(cpl::ComplexVector const&)'|
obj\Debug\wavepacket.o||In function `Z8timeStepv':|
wavepacket.cpp|124|undefined reference to `cpl::solveTridiagonalCyclic(cpl::ComplexVector&, cpl::ComplexVector&, cpl::ComplexVector&, std::complex<double>, std::complex<double>, cpl::ComplexVector&, cpl::ComplexVector&)'|
wavepacket.cpp|126|undefined reference to `cpl::solveTridiagonal(cpl::ComplexVector&, cpl::ComplexVector&, cpl::ComplexVector&, cpl::ComplexVector&, cpl::ComplexVector&)'|
obj\Debug\wavepacket.o||In function `_static_initialization_and_destruction_0':|
wavepacket.cpp|22|undefined reference to `cpl::Vector::Vector(int)'|
wavepacket.cpp|71|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|71|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|72|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|72|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
wavepacket.cpp|72|undefined reference to `cpl::ComplexVector::ComplexVector(int)'|
||=== Build finished: 20 errors, 0 warnings ===|
函数“Z10initializev”中的obj\Debug\wavepacket.o | || wavepacket.cpp | 79 |对“cpl::Vector::Vector(int)”的未定义引用| wavepacket.cpp | 79 |对'cpl::Vector::operator=(cpl::Vector const&')的未定义引用| wavepacket.cpp | 80 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 80 |对'cpl::ComplexVector::operator=(cpl::ComplexVector const&')的未定义引用| wavepacket.cpp | 81 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 81 |对'cpl::ComplexVector::operator=(cpl::ComplexVector const&')的未定义引用| wavepacket.cpp | 101 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 101 |对'cpl::ComplexVector::operator=(cpl::ComplexVector const&')的未定义引用| wavepacket.cpp | 102 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 102 |对'cpl::ComplexVector::operator=(cpl::ComplexVector const&')的未定义引用| wavepacket.cpp | 103 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 103 |对'cpl::ComplexVector::operator=(cpl::ComplexVector const&')的未定义引用| obj\Debug\wavepacket.o | |在函数“Z8timeStepv”中:| wavepacket.cpp | 124 |未定义对`cpl::solveTridiagonalCyclic(cpl::ComplexVector&,cpl::ComplexVector&,cpl::ComplexVector&,std::complex,std::complex,cpl::ComplexVector&),cpl::ComplexVector&)的引用| wavepacket.cpp | 126 |未定义对`cpl::solveTridiagonal(cpl::ComplexVector&,cpl::ComplexVector&,cpl::ComplexVector&,cpl::ComplexVector&,cpl::ComplexVector&),的引用| obj\Debug\wavepacket.o |在函数`_static_initialization_和_destruction_0'中:| wavepacket.cpp | 22 |对'cpl::Vector::Vector(int)'的未定义引用| wavepacket.cpp | 71 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 71 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 72 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 72 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| wavepacket.cpp | 72 |对'cpl::ComplexVector::ComplexVector(int)'的未定义引用| ||==生成完成:20个错误,0个警告===| Wavepacket.cpp

#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <string>
#include <sstream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include "Vector.hpp"

const double pi = 4*std::atan(1.0);
double h_bar = 1;               // natural units
double mass = 1;                // natural units

// The spatial grid
int N = 200;                    // number of interior grid points
double L = 100;                 // system extends from x=0 to x=L
double h = L / (N + 1);         // grid size
double tau = 1;                 // time step
cpl::Vector x;                  // coordinates of grid points
bool periodic = true;           // false = oo potential, true = periodic

// The potential V(x)
double V0 = 1.0;                // height of potential well
double Vwidth = 10;             // width of potential well
double Vcenter = 0.75 * L;      // center of potential well
bool gaussian;                  // false = step potential

double V(double x) {
    double halfWidth = std::abs(0.5 * Vwidth);
    if (gaussian) {
        double dx = (x - Vcenter) / halfWidth;
        return V0 * std::exp( - dx * dx / 2);
    } else {
        if (std::abs(x - Vcenter) <= halfWidth)
            return V0;
        else
            return 0;
    }
}

// Inital wave packet
double x0 = L / 4;              // location of center
double E = 1;                   // average energy
double sigma0 = L / 10;         // width of wave packet
double Norm_psi;                // norm of psi
double k0;                      // average wavenumber
double velocity;                // average velocity

void getInput() {
    std::cout << "Time-dependent Schroedinger Equation\n";
    std::cout << "Enter size of x region L = ";
    std::cin >> L;
    std::cout << "Enter number of grid points N = ";
    std::cin >> N;
    std::cout << "Enter integration time step tau = ";
    std::cin >> tau;
    std::cout << "Enter width of potential = ";
    std::cin >> Vwidth;
    std::cout << "Enter height of potential V0 = ";
    std::cin >> V0;
    std::cout << "Enter width of packet sigma = ";
    std::cin >> sigma0;
    std::cout << "Enter energy of packet E = ";
    std::cin >> E;
}

double t;                           // time
cpl::ComplexVector psi, chi;        // complex wavefunction
cpl::ComplexVector a, b, c;         // to represent tridiagonal Q matrix
std::complex<double> alpha, beta;   // corner elements of Q

void initialize () {
    t = 0;

    // reset vectors
    x = cpl::Vector(N);
    psi = cpl::ComplexVector(N);
    chi = cpl::ComplexVector(N);

    // reset the lattice
    h = L / (N + 1);
    for (int j = 0; j < N; j++)
        x[j] = (j + 1) * h;

    // inititalize the packet
    k0 = std::sqrt(2*mass*E - h_bar*h_bar/2/sigma0/sigma0) / h_bar;
    velocity = k0 / mass;
    Norm_psi = 1 / std::sqrt(sigma0 * std::sqrt(pi));
    for (int j = 0; j < N; j++) {
        double expFactor = std::exp(-(x[j] - x0) * (x[j] - x0)
                                / (2 * sigma0 * sigma0));
        psi[j] = std::complex<double>(
                     Norm_psi * std::cos(k0 * x[j]) * expFactor,
                     Norm_psi * std::sin(k0 * x[j]) * expFactor);
    }

    // elements of tridiagonal matrix Q = (1/2)(1 + i tau H / (2 hbar))
    a = cpl::ComplexVector(N);
    b = cpl::ComplexVector(N);
    c = cpl::ComplexVector(N);
    for (int j = 0; j < N; j++) {
        const std::complex<double> i(0.0, 1.0);
        b[j] = 0.5 + i * tau / (4 * h_bar) *
            (V(x[j]) + h_bar * h_bar / (mass * h * h));
        a[j] = c[j] = - i * tau * h_bar / (8 * mass * h * h);
    }
    alpha = c[N-1];
    beta = a[0];
}

double T = 5;                   // time to travel length L
double framesPerSec = 50;       // animation rate for screen redraws

void timeStep() {
    static std::clock_t clockStart;
    static bool done;
    if (!done) {
        double t0 = t;
        do {
            if (periodic)
                solveTridiagonalCyclic(a, b, c, alpha, beta, psi, chi);
            else
                solveTridiagonal(a, b, c, psi, chi);
            for (int j = 0; j < N; j++)
                psi[j] = chi[j] - psi[j];
            t += tau;
        } while (std::abs(velocity * (t - t0)) < L / T / framesPerSec);
        done = true;
    }
    std::clock_t clockNow = std::clock();
    double seconds = (clockNow - clockStart) / double(CLOCKS_PER_SEC);
    if ( seconds < 1 / framesPerSec ) {
        return;
    } else {
        clockStart = clockNow;
        done = false;
    }    
    glutPostRedisplay();
    glFlush();
}

void drawText(const std::string& str, double x, double y) {
    glRasterPos2d(x, y);
    int len = str.find('\0');
    for (int i = 0; i < len; i++)
       glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, str[i]); 
}

bool showRealImaginary;       // false = probability only

void display() {
    glClear(GL_COLOR_BUFFER_BIT);

    if (showRealImaginary) {
        glColor3f(0, 0, 1);   // real part of psi blue
        glBegin(GL_LINES);
            for (int j = 1; j < N; j++) {
                glVertex2d(x[j-1], psi[j-1].real());
                glVertex2d(x[j], psi[j].real());
            }
        glEnd();
        glColor3f(0, 1, 0);   // imaginary part of psi green
        glBegin(GL_LINES);
            for (int j = 1; j < N; j++) {
                glVertex2d(x[j-1], psi[j-1].imag());
                glVertex2d(x[j], psi[j].imag());
            }
        glEnd();
    }

    glColor3f(1, 0, 0);       // probability red
    double pOld = psi[0].real() * psi[0].real() +
        psi[0].imag() * psi[0].imag();
    glBegin(GL_LINES);
        for (int j = 1; j < N; j++) {
            double p = psi[j].real() * psi[j].real() +
                psi[j].imag() * psi[j].imag();
            glVertex2d(x[j-1], 4 * pOld);
            glVertex2d(x[j], 4 * p);
            pOld = p;
        }
    glEnd();

    glColor3ub(255, 165, 0);   // potential orange
    double Vold = V(x[1]);
    glBegin(GL_LINES);
        for (int j = 1; j < N; j++) {
            double Vnew = V(x[j]);
            glVertex2d(x[j-1], 0.2 * Vold);
            glVertex2d(x[j], 0.2 * Vnew);
            Vold = Vnew;
        }
    glEnd();

    glColor3f(0, 0, 0);        // text black
    std::ostringstream os;
    os << (periodic  ? "Periodic " : "Infinite Wall ") 
       << "Boundary Conditions" << std::ends;
    drawText(os.str(), 0.02 * L, 0.28);
    os.seekp(0);               // beginning of string stream
    os << "0" << std::ends;
    drawText(os.str(), 0, -0.02);
    drawText("0", 0, -0.02);
    os.seekp(0);
    os << "x = " << L << std::ends;
    drawText(os.str(), (1 - 0.1) * L, -0.02);
    os.seekp(0);
    os << "t = " << t << std::ends;
    drawText(os.str(), 0.02 * L, -0.29);
    glutSwapBuffers();    
}

void reshape(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, L, -0.3, 0.3);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

bool running;                  // to control animation

void mouse(int button, int state, int x, int y) {
    switch (button) {
    case GLUT_LEFT_BUTTON:
        if (state == GLUT_DOWN) {
            if (running) {
                glutIdleFunc(NULL);
                running = false;
            } else {
                glutIdleFunc(timeStep);
                running = true;
            }
        }
        break;
    default:
        break;
    }
}

void menu(int menuItem) {
    switch (menuItem) {
    case 1:
        gaussian = !gaussian;
        break;
    case 2:
        periodic = !periodic;
        break;
    case 3:
        showRealImaginary = !showRealImaginary;
        break;
    case 4:
        if (running) { 
            glutIdleFunc(NULL); 
            running = false; 
        }
        initialize();
        glutPostRedisplay();
        break;
    default:
        break;
    }
}

int main(int argc, char *argv[]) {
    getInput();
    initialize();
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(600, 400);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Schroedinger Wave Packet Motion");
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glShadeModel(GL_FLAT);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMouseFunc(mouse);
    glutCreateMenu(menu);
    glutAddMenuEntry("Potential: Square/Gaussian", 1);
    glutAddMenuEntry("Boundaries: Dirichlet/Periodic", 2);
    glutAddMenuEntry("Real & Imag: Show/Hide", 3);
    glutAddMenuEntry("Reset", 4);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    glutMainLoop();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“Vector.hpp”
常数双pi=4*std::atan(1.0);
双h_杆=1;//自然单位
双质量=1;//自然单位
//空间网格
int N=200;//内部栅格点的数量
双L=100;//系统从x=0扩展到x=L
双h=L/(N+1);//网格大小
双τ=1;//时间步长
cpl::向量x;//网格点坐标
bool periodic=true;//false=oo电位,true=周期性
//电势V(x)
双V0=1.0;//势阱高度
双Vwidth=10;//势阱宽度
双Vcenter=0.75*L;//势阱中心
布尔高斯;//假=阶跃电位
双V(双x){
双半宽=std::abs(0.5*Vwidth);
中频(高斯){
双dx=(x-Vcenter)/半宽;
返回V0*std::exp(-dx*dx/2);
}否则{
if(std::abs(x-Vcenter)N;
std::cout>tau;
标准:cout>Vwidth;
标准:cout>V0;
std::cout>sigma0;
std::cout>E;
}
双t;//时间
复数向量psi,chi;//复数波函数
复数向量a,b,c;//表示三对角Q矩阵
std::复数alpha,beta;//Q的角元素
无效初始化(){
t=0;
//重置向量
x=cpl::向量(N);
psi=cpl::ComplexVector(N);
chi=cpl::ComplexVector(N);
//重置晶格
h=L/(N+1);
对于(int j=0;j#ifndef CPL_VECTOR_HPP
#define CPL_VECTOR_HPP

#include <complex>
#include <iostream>

namespace cpl {

class Vector {
  public:

    Vector(int dim = 1);

    Vector(const Vector& dv);

    ~Vector() { delete [] v; }

    int dimension() const { return dim; }

    void resize(const int);

    const double operator[](const int i) const { return v[i]; }

    double& operator[](const int i) { return v[i]; }

    Vector& operator = (const Vector& dv);

    Vector& operator += (const Vector& dv);

    Vector& operator -= (const Vector& dv);

    Vector& operator *= (double d);

    Vector& operator /= (double d);

    double abs();

    double norm();

    double dot(const Vector& dv);

    friend std::ostream& operator<<(std::ostream& os, const Vector& dv);

  private:
    int dim;
    double *v;
};

inline Vector operator + (const Vector& dv) {
    return dv;
}

extern Vector operator - (const Vector& dv);

extern Vector operator * (const Vector& dv, double d);

extern Vector operator * (double d, const Vector& dv);

extern Vector operator / (const Vector& dv, double d);

extern Vector operator + (const Vector& v1, const Vector& v2);

extern Vector operator - (const Vector& v1, const Vector& v2);

class ComplexVector {
  public:
    ComplexVector(int dim = 1);
    ComplexVector(const ComplexVector& cv);
    ~ComplexVector() { delete [] v; }

    int dimension() const { return dim; }
    const std::complex<double> operator[](const int i) const { return v[i]; }
    std::complex<double>& operator[](const int i) { return v[i]; }
    ComplexVector& operator = (const ComplexVector& cv);

  private:
    int dim;
    std::complex<double> *v;
};

class FFT {
  public:
    FFT() { N = 0; f = 0; inverse = false; }
    void transform(ComplexVector& data);
    void inverseTransform(ComplexVector& data);
    Vector power(ComplexVector& data);

  private:
    int N;
    ComplexVector *f;
    bool inverse;

    void bitReverse();
    void DanielsonLanczos(int n);
};

extern void solveTridiagonal(
        ComplexVector& a, ComplexVector& b, ComplexVector& c, 
        ComplexVector& r, ComplexVector& u);

extern void solveTridiagonalCyclic(
        ComplexVector& a, ComplexVector& b, ComplexVector& c, 
        std::complex<double> alpha, std::complex<double> beta,
        ComplexVector& r, ComplexVector& x);

}  /* end namespace cpl */

#endif  /* CPL_VECTOR_HPP */
#include "Vector.hpp"

namespace cpl {

Vector::Vector(int dim) {
    v = new double [this->dim = dim];
    for (int i = 0; i < dim; i++) v[i] = 0;
}

Vector::Vector(const Vector& dv) {
    v = new double [dim = dv.dim];
    for (int i = 0; i < dim; i++) v[i] = dv.v[i];
}

void Vector::resize(const int dimension) {
    delete [] v;
    v = new double [dim = dimension];
    for (int i = 0; i < dim; i++) v[i] = 0;
}

Vector& Vector::operator = (const Vector& dv) {
    if (this != &dv) {
        if (dim != dv.dim) {
            delete [] v;
            v = new double [dim = dv.dim];
        }
        for (int i = 0; i < dim; i++) v[i] = dv[i];
    }
    return *this;
}

Vector& Vector::operator += (const Vector& dv) {
    for (int i = 0; i < dim; i++) v[i] += dv[i];
    return *this;
}

Vector& Vector::operator -= (const Vector& dv) {
    for (int i = 0; i < dim; i++) v[i] -= dv[i];
    return *this;
}

Vector& Vector::operator *= (double d) {
    for (int i = 0; i < dim; i++) v[i] *= d;
    return *this;
}

Vector& Vector::operator /= (double d) {
    for (int i = 0; i < dim; i++) v[i] /= d;
    return *this;
}

Vector operator - (const Vector& dv) {
    int dim = dv.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = -dv[i];
    return temp;   
}

Vector operator * (const Vector& dv, double d) {
    int dim = dv.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = dv[i] * d;
    return temp;    
}

Vector operator * (double d, const Vector& dv) {
    int dim = dv.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = dv[i] * d;
    return temp;    
}

Vector operator / (const Vector& dv, double d) {
    int dim = dv.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = dv[i] / d;
    return temp;    
}

Vector operator + (const Vector& v1, const Vector& v2) {
    int dim = v1.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = v1[i] + v2[i];
    return temp;    
}

Vector operator - (const Vector& v1, const Vector& v2) {
    int dim = v1.dimension();
    Vector temp(dim);
    for (int i = 0; i < dim; i++) temp[i] = v1[i] - v2[i];
    return temp;    
}

double Vector::abs() {
    return std::sqrt(norm());
}

double Vector::norm() {
    double sum = 0;
    for (int i = 0; i < dim; i++) sum += v[i] * v[i];
    return sum;
}

double Vector::dot(const Vector& dv) {
    double sum = 0;
    for (int i = 0; i < dim; i++) sum += v[i] * dv[i];
    return sum;
}

std::ostream& operator<<(std::ostream& os, const Vector& dv) {
    for (int i = 0; i < dv.dim; i++) {
        os << dv.v[i];
        if (i < dv.dim-1)
            os << '\t';
        else
            os << '\n';
    }
    return os;
}

// ComplexVector implementation

ComplexVector::ComplexVector(int dim) {
    v = new std::complex<double> [this->dim = dim];
    for (int i = 0; i < dim; i++) v[i] = 0.0;
}

ComplexVector::ComplexVector(const ComplexVector& cv) {
    v = new std::complex<double> [dim = cv.dim];
    for (int i = 0; i < dim; i++) v[i] = cv.v[i];
}

ComplexVector& ComplexVector::operator = (const ComplexVector& cv) {
    if (this != &cv) {
        if (dim != cv.dim) {
            delete [] v;
            v = new std::complex<double> [dim = cv.dim];
        }
        for (int i = 0; i < dim; i++) v[i] = cv[i];
    }
    return *this;
}

// FFT implementation

void FFT::transform(ComplexVector& data) {
    N = data.dimension();
    f = &data;
    bitReverse();
    for (int n = 1; n < N; n *= 2)
        DanielsonLanczos(n);
    for (int i = 0; i < N; ++i)
        (*f)[i] /= std::sqrt(double(N));
}

void FFT::inverseTransform(ComplexVector& data) {
    inverse = true;
    transform(data);
    inverse = false;
}

void FFT::bitReverse() {
    int j = 1;
    for (int i = 1; i < N; ++i) {
        if (i < j) {
            std::complex<double> temp = (*f)[i-1];
            (*f)[i-1] = (*f)[j-1];
            (*f)[j-1] = temp;
        }
        int k = N / 2;
        while ( k < j ) {
            j -= k;
            k /= 2;
        }
        j += k;
    }
}

void FFT::DanielsonLanczos(int n) {
    const double pi = 4 * atan(1.0);
    std::complex<double> W(0, pi / n);
    W = inverse ? std::exp(-W) : std::exp(W);
    std::complex<double> W_j(1, 0);
    for (int j = 0; j < n; ++j) {
        for (int i = j; i < N; i += 2 * n) {
            std::complex<double> temp = W_j * (*f)[n+i];
            (*f)[n+i] = (*f)[i] - temp;
            (*f)[i] += temp;
        }
        W_j *= W;
    }
}

Vector FFT::power(ComplexVector& data) {
    Vector P(1 + N / 2);
    P[0] = std::norm(data[0]) / double(N);
    for (int i = 1; i < N / 2; i++)
        P[i] = (std::norm(data[i]) + std::norm(data[N-i])) / double(N);
    P[N/2] = std::norm(data[N/2]) / double(N);
    return P;
}

// Solving tridiagonal complex matrices

void solveTridiagonal(
        ComplexVector& a, ComplexVector& b, ComplexVector& c, 
        ComplexVector& r, ComplexVector& u) 
{
    int n = a.dimension();
    ComplexVector gamma(n);
    std::complex<double> beta = b[0];
    u[0] = r[0] / beta;
    for (int j = 1; j < n; j++) {
        gamma[j] = c[j-1] / beta;
        beta = b[j] - a[j] * gamma[j];
        u[j] = (r[j] - a[j] * u[j-1]) / beta;
    }
    for (int j = n - 2; j >= 0; j--)
        u[j] -= gamma[j+1] * u[j+1];
}

void solveTridiagonalCyclic(
        ComplexVector& a, ComplexVector& b, ComplexVector& c, 
        std::complex<double> alpha, std::complex<double> beta,
        ComplexVector& r, ComplexVector& x)
{
    int n = a.dimension();
    ComplexVector bb(n), u(n), z(n);
    std::complex<double> gamma = -b[0];
    bb[0] = b[0] - gamma;
    bb[n-1] = b[n-1] - alpha * beta / gamma;
    for (int i = 1; i < n-1; i++)
        bb[i] = b[i];
    solveTridiagonal(a, bb, c, r, x);
    u[0] = gamma;
    u[n-1] = alpha;
    for (int i = 1; i < n-1; i++)
        u[i] = 0.0;
    solveTridiagonal(a, bb, c, u, z);
    std::complex<double> fact = x[0] + beta * x[n-1] / gamma;
    fact /= 1.0 + z[0] + beta * z[n-1] / gamma;
    for (int i = 0; i < n; i++)
        x[i] -= fact * z[i];
}

}  /* end namespace cpl */
g++ -c Vector.cpp -o Vector.o
g++ -c Wavepacket.cpp -o Wavepacket.o
g++ Vector.o Wavepacket.o -lGL -lGLU -lglut -o app