⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 complex.cc

📁 使用量子轨道方法计算量子主方程的C++库
💻 CC
字号:
// Complex.cc/* Copyright (C) 1988 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*/// Modified and adapted to QSD software by rschack#include "Complex.h"#include <stdlib.h>static const char rcsid[] = "$Id: Complex.cc,v 3.1 1996/11/19 10:05:08 rschack Exp $";void Complex::error(const char* msg) const{  cerr << "Fatal Complex arithmetic error. " << msg << endl;  exit(1);} double hypotenuse(double a, double b)//// Returns sqrt(a*a+b*b).// See Numerical Recipes in C, 2nd edition, p.177, Eq.(5.4.4) and p.949.{  double x = fabs(a);  double y = fabs(b);  if( x == 0.0 )    return y;  else if( y == 0.0 )    return x;  else if( x > y ) {    double tmp = y/x;    return x * sqrt( 1.0 + tmp*tmp );  }  else {    double tmp = x/y;    return y * sqrt( 1.0 + tmp*tmp );  }}    Complex& Complex::timesI() {  double tmp = im;  im = re;  re = -tmp;  return *this;}Complex& Complex::timesMinusI() {  double tmp = im;  im = -re;  re = tmp;  return *this;}/* from romine@xagsun.epm.ornl.gov */Complex /* const */ operator / (const Complex& x, const Complex& y){  double den = fabs(y.real()) + fabs(y.imag());  if (den == 0.0) x.error ("Attempted division by zero.");  double xrden = x.real() / den;  double xiden = x.imag() / den;  double yrden = y.real() / den;  double yiden = y.imag() / den;  double nrm   = yrden * yrden + yiden * yiden;  return Complex((xrden * yrden + xiden * yiden) / nrm,                 (xiden * yrden - xrden * yiden) / nrm);}Complex& Complex::operator /= (const Complex& y){  double den = fabs(y.real()) + fabs(y.imag());  if (den == 0.0) error ("Attempted division by zero.");  double xrden = re / den;  double xiden = im / den;  double yrden = y.real() / den;  double yiden = y.imag() / den;  double nrm   = yrden * yrden + yiden * yiden;  re = (xrden * yrden + xiden * yiden) / nrm;  im = (xiden * yrden - xrden * yiden) / nrm;  return *this;}Complex /* const */ operator / (double x, const Complex& y){  double den = norm(y);  if (den == 0.0) y.error ("Attempted division by zero.");  return Complex((x * y.real()) / den, -(x * y.imag()) / den);}Complex /* const */ operator / (const Complex& x, double y){  if (y == 0.0) x.error ("Attempted division by zero.");  return Complex(x.real() / y, x.imag() / y);}Complex& Complex::operator /= (double y){  if (y == 0.0) error ("Attempted division by zero.");  re /= y;  im /= y;  return *this;}Complex /* const */ exp(const Complex& x){  double r = exp(x.real());  return Complex(r * cos(x.imag()),                  r * sin(x.imag()));}Complex /* const */ cosh(const Complex& x){  return Complex(cos(x.imag()) * cosh(x.real()),                  sin(x.imag()) * sinh(x.real()));}Complex /* const */ sinh(const Complex& x){  return Complex(cos(x.imag()) * sinh(x.real()),                  sin(x.imag()) * cosh(x.real()));}Complex /* const */ cos(const Complex& x){  return Complex(cos(x.real()) * cosh(x.imag()),                  -sin(x.real()) * sinh(x.imag()));}Complex /* const */ sin(const Complex& x){  return Complex(sin(x.real()) * cosh(x.imag()),                  cos(x.real()) * sinh(x.imag()));}Complex /* const */ log(const Complex& x){  double h = hypotenuse(x.real(), x.imag());  if (h <= 0.0) x.error("attempted log of zero magnitude number.");  return Complex(log(h), atan2(x.imag(), x.real()));}// Corrections based on reports from: thc@cs.brown.edu & saito@sdr.slb.comComplex /* const */ pow(const Complex& x, const Complex& p){  double h = hypotenuse(x.real(), x.imag());  if (h <= 0.0) x.error("attempted power of zero magnitude number.");  double a = atan2(x.imag(), x.real());  double lr = pow(h, p.real());  double li = p.real() * a;  if (p.imag() != 0.0)  {    lr /= exp(p.imag() * a);    li += p.imag() * log(h);  }  return Complex(lr * cos(li), lr * sin(li));}Complex /* const */ pow(const Complex& x, double p){  double h = hypotenuse(x.real(), x.imag());  if (h <= 0.0) x.error("attempted power of zero magnitude number.");  double lr = pow(h, p);  double a = atan2(x.imag(), x.real());  double li = p * a;  return Complex(lr * cos(li), lr * sin(li));}Complex /* const */ sqrt(const Complex& x){  if (x.real() == 0.0 && x.imag() == 0.0)    return Complex(0.0, 0.0);  else  {    double s = sqrt((fabs(x.real()) + hypotenuse(x.real(), x.imag())) * 0.5);    double d = (x.imag() / s) * 0.5;    if (x.real() > 0.0)      return Complex(s, d);    else if (x.imag() >= 0.0)      return Complex(d, s);    else      return Complex(-d, -s);  }}Complex /* const */ pow(const Complex& x, int p){  if (p == 0)    return Complex(1.0, 0.0);  else if (x == 0.0)    return Complex(0.0, 0.0);  else  {    Complex res(1.0, 0.0);    Complex b = x;    if (p < 0)    {      p = -p;      b = 1.0 / b;    }    for(;;)    {      if (p & 1)        res *= b;      if ((p >>= 1) == 0)        return res;      else        b *= b;    }  }}ostream& operator << (ostream& s, const Complex& x){  return s << "(" << x.real() << ", " << x.imag() << ")" ;}istream& operator >> (istream& s, Complex& x){#ifdef _OLD_STREAMS  if (!s.good())  {    return s;  }#else  if (!s.ipfx(0))  {    s.clear(ios::failbit|s.rdstate()); // Redundant if using GNU iostreams.    return s;  }#endif  double r, i;  char ch;  s >> ws;  s.get(ch);  if (ch == '(')  {    s >> r;    s >> ws;    s.get(ch);    if (ch == ',')    {      s >> i;      s >> ws;      s .get(ch);    }    else      i = 0;    if (ch != ')')      s.clear(ios::failbit);  }  else  {    s.putback(ch);    s >> r;    i = 0;  }  x = Complex(r, i);  return s;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -