/* This file is part of GNU APL, a free implementation of the ISO/IEC Standard 13751, "Programming Language APL, Extended" Copyright (C) 2008-2015 Dr. Jürgen Sauermann This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __COMPLEXCELL_HH_DEFINED__ #define __COMPLEXCELL_HH_DEFINED__ #include "NumericCell.hh" #include "IntCell.hh" //----------------------------------------------------------------------------- /** A cell containing a single APL complex value. This class essentially overloads certain functions in class Cell with complex number specific implementations. */ /// A celkl containing one complex numbver class ComplexCell : public NumericCell { public: /// Construct an complex number cell from a complex number ComplexCell(APL_Complex c); /// overloaded Cell::init_other virtual void init_other(void * other, Value & cell_owner, const char * loc) const { new (other) ComplexCell(value.cval[0], value.cval[1]); } /// Construct an complex number cell from real part \b r and imag part \b i. ComplexCell(APL_Float r, APL_Float i); /// overloaded Cell::is_complex_cell(). virtual bool is_complex_cell() const { return true; } /// Overloaded Cell::is_finite(). virtual bool is_finite() const { return isfinite(value.cval[0]) && isfinite(value.cval[1]); } /// overloaded Cell::greater(). virtual bool greater(const Cell & other) const; /// overloaded Cell::equal(). virtual bool equal(const Cell & other, double qct) const; /// overloaded Cell::compare() virtual Comp_result compare(const Cell & other) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_ceiling(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_conjugate(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_direction(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_exponential(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_factorial(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_floor(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_magnitude(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_nat_log(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_negative(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_pi_times(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_pi_times_inverse(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_reciprocal(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_roll(Cell * Z) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_add(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_subtract(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_divide(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_equal(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_logarithm(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_multiply(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_power(Cell * Z, const Cell * A) const; /// Overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_maximum(Cell * Z, const Cell * A) const; /// Overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_minimum(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_residue(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_circle_fun(Cell * Z, const Cell * A) const; /// overloaded from the corresponding Cell:: function (see class Cell). virtual ErrorCode bif_circle_fun_inverse(Cell * Z, const Cell * A) const; /// the Quad_CR representation of this cell. virtual PrintBuffer character_representation(const PrintContext &pctx) const; /// return true iff this cell needs scaling (exponential format) in pctx. virtual bool need_scaling(const PrintContext &pctx) const; /// overloaded Cell::bif_add_inverse() virtual ErrorCode bif_add_inverse(Cell * Z, const Cell * A) const; /// overloaded Cell::bif_multiply_inverse() virtual ErrorCode bif_multiply_inverse(Cell * Z, const Cell * A) const; /// the square of the magnitude of aJb (= a² + b²) APL_Float mag2() const { return value.cval[0] * value.cval[0] + value.cval[1] * value.cval[1]; } /// the square of the magnitude (a² + b² for aJb) static APL_Float mag2(APL_Complex A) { return A.real() * A.real() + A.imag() * A.imag(); } /// initialize Z to real r static ErrorCode zv(Cell * Z, APL_Float r) { new (Z) ComplexCell(r, 0.0); return E_NO_ERROR; } /// initialize Z to complex r + ij static ErrorCode zv(Cell * Z, APL_Float r, APL_Float j) { new (Z) ComplexCell(r, j); return E_NO_ERROR; } /// initialize Z to APL_Complex v static ErrorCode zv(Cell * Z, APL_Complex v) { new (Z) ComplexCell(v.real(), v.imag()); return E_NO_ERROR; } /// the lanczos approximation for gamma(x + iy) static APL_Complex gamma(APL_Float x, const APL_Float & y); /// compute circle function \b fun static ErrorCode do_bif_circle_fun(Cell * Z, int fun, APL_Complex b); protected: /// return the complex value of \b this cell APL_Complex cval() const { return APL_Complex(value.cval[0], value.cval[1]); } /// 1.0 static APL_Complex ONE() { return APL_Complex(1, 0); } /// i static APL_Complex PLUS_i() { return APL_Complex(0, 1); } /// -i static APL_Complex MINUS_i() { return APL_Complex(0, -1); } /// overloaded Cell::get_cell_type(). virtual CellType get_cell_type() const { return CT_COMPLEX; } /// overloaded Cell::get_real_value(). virtual APL_Float get_real_value() const; /// overloaded Cell::get_imag_value(). virtual APL_Float get_imag_value() const; /// overloaded Cell::get_complex_value() virtual APL_Complex get_complex_value() const { return cval(); } /// overloaded Cell::get_near_bool() virtual bool get_near_bool() const; /// overloaded Cell::get_near_int() virtual APL_Integer get_near_int() const; /// overloaded Cell::get_checked_near_int() virtual APL_Integer get_checked_near_int() const { if (value.cval[0] < 0.0) return APL_Integer(value.cval[0] - 0.3); else return APL_Integer(value.cval[0] + 0.3); } /// overloaded Cell::is_near_int() virtual bool is_near_int() const; /// overloaded Cell::is_near_int64_t() virtual bool is_near_int64_t() const; /// overloaded Cell::bif_near_int64_t() virtual ErrorCode bif_near_int64_t(Cell * Z) const; /// overloaded Cell::bif_within_quad_CT() virtual ErrorCode bif_within_quad_CT(Cell * Z) const; /// overloaded Cell::is_near_zero() virtual bool is_near_zero() const; /// overloaded Cell::is_near_one() virtual bool is_near_one() const; /// overloaded Cell::is_near_real() virtual bool is_near_real() const; /// overloaded Cell::get_classname() virtual const char * get_classname() const { return "ComplexCell"; } /// overloaded Cell::CDR_size() virtual int CDR_size() const { return 16; } /// overloaded Cell::to_type() virtual void to_type() { new(this) IntCell(0); } }; //============================================================================= #endif // __COMPLEXCELL_HH_DEFINED__