mirror of
https://github.com/opnsense/src.git
synced 2026-02-16 00:58:21 -05:00
issues in these areas:
.h's installed
.hP's installed
-lcurses interaction
files needed in ~/legal for copyleft reasons.
256 lines
6 KiB
C++
256 lines
6 KiB
C++
/*
|
|
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 free
|
|
software; you can redistribute it and/or modify it under the terms of
|
|
the GNU Library General Public License as published by the Free
|
|
Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version. This library is distributed in the hope
|
|
that it will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the GNU Library General Public License for more details.
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifdef __GNUG__
|
|
#pragma implementation
|
|
#endif
|
|
#include <Complex.h>
|
|
#include <std.h>
|
|
#include <builtin.h>
|
|
|
|
// error handling
|
|
|
|
void default_Complex_error_handler(const char* msg)
|
|
{
|
|
cerr << "Fatal Complex arithmetic error. " << msg << "\n";
|
|
exit(1);
|
|
}
|
|
|
|
one_arg_error_handler_t Complex_error_handler = default_Complex_error_handler;
|
|
|
|
one_arg_error_handler_t set_Complex_error_handler(one_arg_error_handler_t f)
|
|
{
|
|
one_arg_error_handler_t old = Complex_error_handler;
|
|
Complex_error_handler = f;
|
|
return old;
|
|
}
|
|
|
|
void Complex::error(const char* msg) const
|
|
{
|
|
(*Complex_error_handler)(msg);
|
|
}
|
|
|
|
/* 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 = hypot(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.com
|
|
Complex /* const */ pow(const Complex& x, const Complex& p)
|
|
{
|
|
double h = hypot(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 = hypot(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()) + hypot(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;
|
|
}
|
|
|