1 /* 2 This file is part of GNU APL, a free implementation of the 3 ISO/IEC Standard 13751, "Programming Language APL, Extended" 4 5 Copyright (C) 2008-2015 Dr. Jürgen Sauermann 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef __COMPLEXCELL_HH_DEFINED__ 22 #define __COMPLEXCELL_HH_DEFINED__ 23 24 #include "NumericCell.hh" 25 #include "IntCell.hh" 26 27 //----------------------------------------------------------------------------- 28 /** 29 A cell containing a single APL complex value. This class essentially 30 overloads certain functions in class Cell with complex number specific 31 implementations. 32 */ 33 /// A celkl containing one complex numbver 34 class ComplexCell : public NumericCell 35 { 36 public: 37 /// Construct an complex number cell from a complex number 38 ComplexCell(APL_Complex c); 39 40 /// overloaded Cell::init_other init_other(void * other,Value & cell_owner,const char * loc) const41 virtual void init_other(void * other, Value & cell_owner, const char * loc) 42 const { new (other) ComplexCell(value.cval[0], value.cval[1]); } 43 44 /// Construct an complex number cell from real part \b r and imag part \b i. 45 ComplexCell(APL_Float r, APL_Float i); 46 47 /// overloaded Cell::is_complex_cell(). is_complex_cell() const48 virtual bool is_complex_cell() const { return true; } 49 50 /// Overloaded Cell::is_finite(). is_finite() const51 virtual bool is_finite() const 52 { return isfinite(value.cval[0]) && isfinite(value.cval[1]); } 53 54 /// overloaded Cell::greater(). 55 virtual bool greater(const Cell & other) const; 56 57 /// overloaded Cell::equal(). 58 virtual bool equal(const Cell & other, double qct) const; 59 60 /// overloaded Cell::compare() 61 virtual Comp_result compare(const Cell & other) const; 62 63 /// overloaded from the corresponding Cell:: function (see class Cell). 64 virtual ErrorCode bif_ceiling(Cell * Z) const; 65 66 /// overloaded from the corresponding Cell:: function (see class Cell). 67 virtual ErrorCode bif_conjugate(Cell * Z) const; 68 69 /// overloaded from the corresponding Cell:: function (see class Cell). 70 virtual ErrorCode bif_direction(Cell * Z) const; 71 72 /// overloaded from the corresponding Cell:: function (see class Cell). 73 virtual ErrorCode bif_exponential(Cell * Z) const; 74 75 /// overloaded from the corresponding Cell:: function (see class Cell). 76 virtual ErrorCode bif_factorial(Cell * Z) const; 77 78 /// overloaded from the corresponding Cell:: function (see class Cell). 79 virtual ErrorCode bif_floor(Cell * Z) const; 80 81 /// overloaded from the corresponding Cell:: function (see class Cell). 82 virtual ErrorCode bif_magnitude(Cell * Z) const; 83 84 /// overloaded from the corresponding Cell:: function (see class Cell). 85 virtual ErrorCode bif_nat_log(Cell * Z) const; 86 87 /// overloaded from the corresponding Cell:: function (see class Cell). 88 virtual ErrorCode bif_negative(Cell * Z) const; 89 90 /// overloaded from the corresponding Cell:: function (see class Cell). 91 virtual ErrorCode bif_pi_times(Cell * Z) const; 92 93 /// overloaded from the corresponding Cell:: function (see class Cell). 94 virtual ErrorCode bif_pi_times_inverse(Cell * Z) const; 95 96 /// overloaded from the corresponding Cell:: function (see class Cell). 97 virtual ErrorCode bif_reciprocal(Cell * Z) const; 98 99 /// overloaded from the corresponding Cell:: function (see class Cell). 100 virtual ErrorCode bif_roll(Cell * Z) const; 101 102 /// overloaded from the corresponding Cell:: function (see class Cell). 103 virtual ErrorCode bif_add(Cell * Z, const Cell * A) const; 104 105 /// overloaded from the corresponding Cell:: function (see class Cell). 106 virtual ErrorCode bif_subtract(Cell * Z, const Cell * A) const; 107 108 /// overloaded from the corresponding Cell:: function (see class Cell). 109 virtual ErrorCode bif_divide(Cell * Z, const Cell * A) const; 110 111 /// overloaded from the corresponding Cell:: function (see class Cell). 112 virtual ErrorCode bif_equal(Cell * Z, const Cell * A) const; 113 114 /// overloaded from the corresponding Cell:: function (see class Cell). 115 virtual ErrorCode bif_logarithm(Cell * Z, const Cell * A) const; 116 117 /// overloaded from the corresponding Cell:: function (see class Cell). 118 virtual ErrorCode bif_multiply(Cell * Z, const Cell * A) const; 119 120 /// overloaded from the corresponding Cell:: function (see class Cell). 121 virtual ErrorCode bif_power(Cell * Z, const Cell * A) const; 122 123 /// Overloaded from the corresponding Cell:: function (see class Cell). 124 virtual ErrorCode bif_maximum(Cell * Z, const Cell * A) const; 125 126 /// Overloaded from the corresponding Cell:: function (see class Cell). 127 virtual ErrorCode bif_minimum(Cell * Z, const Cell * A) const; 128 129 /// overloaded from the corresponding Cell:: function (see class Cell). 130 virtual ErrorCode bif_residue(Cell * Z, const Cell * A) const; 131 132 /// overloaded from the corresponding Cell:: function (see class Cell). 133 virtual ErrorCode bif_circle_fun(Cell * Z, const Cell * A) const; 134 135 /// overloaded from the corresponding Cell:: function (see class Cell). 136 virtual ErrorCode bif_circle_fun_inverse(Cell * Z, const Cell * A) const; 137 138 /// the Quad_CR representation of this cell. 139 virtual PrintBuffer character_representation(const PrintContext &pctx) const; 140 141 /// return true iff this cell needs scaling (exponential format) in pctx. 142 virtual bool need_scaling(const PrintContext &pctx) const; 143 144 /// overloaded Cell::bif_add_inverse() 145 virtual ErrorCode bif_add_inverse(Cell * Z, const Cell * A) const; 146 147 /// overloaded Cell::bif_multiply_inverse() 148 virtual ErrorCode bif_multiply_inverse(Cell * Z, const Cell * A) const; 149 150 /// the square of the magnitude of aJb (= a² + b²) mag2() const151 APL_Float mag2() const 152 { return value.cval[0] * value.cval[0] + value.cval[1] * value.cval[1]; } 153 154 /// the square of the magnitude (a² + b² for aJb) mag2(APL_Complex A)155 static APL_Float mag2(APL_Complex A) 156 { return A.real() * A.real() + A.imag() * A.imag(); } 157 158 /// initialize Z to real r zv(Cell * Z,APL_Float r)159 static ErrorCode zv(Cell * Z, APL_Float r) 160 { new (Z) ComplexCell(r, 0.0); return E_NO_ERROR; } 161 162 /// initialize Z to complex r + ij zv(Cell * Z,APL_Float r,APL_Float j)163 static ErrorCode zv(Cell * Z, APL_Float r, APL_Float j) 164 { new (Z) ComplexCell(r, j); return E_NO_ERROR; } 165 166 /// initialize Z to APL_Complex v zv(Cell * Z,APL_Complex v)167 static ErrorCode zv(Cell * Z, APL_Complex v) 168 { new (Z) ComplexCell(v.real(), v.imag()); return E_NO_ERROR; } 169 170 /// the lanczos approximation for gamma(x + iy) 171 static APL_Complex gamma(APL_Float x, const APL_Float & y); 172 173 /// compute circle function \b fun 174 static ErrorCode do_bif_circle_fun(Cell * Z, int fun, APL_Complex b); 175 176 protected: 177 /// return the complex value of \b this cell cval() const178 APL_Complex cval() const 179 { return APL_Complex(value.cval[0], value.cval[1]); } 180 181 /// 1.0 ONE()182 static APL_Complex ONE() { return APL_Complex(1, 0); } 183 184 /// i PLUS_i()185 static APL_Complex PLUS_i() { return APL_Complex(0, 1); } 186 187 /// -i MINUS_i()188 static APL_Complex MINUS_i() { return APL_Complex(0, -1); } 189 190 /// overloaded Cell::get_cell_type(). get_cell_type() const191 virtual CellType get_cell_type() const 192 { return CT_COMPLEX; } 193 194 /// overloaded Cell::get_real_value(). 195 virtual APL_Float get_real_value() const; 196 197 /// overloaded Cell::get_imag_value(). 198 virtual APL_Float get_imag_value() const; 199 200 /// overloaded Cell::get_complex_value() get_complex_value() const201 virtual APL_Complex get_complex_value() const { return cval(); } 202 203 /// overloaded Cell::get_near_bool() 204 virtual bool get_near_bool() const; 205 206 /// overloaded Cell::get_near_int() 207 virtual APL_Integer get_near_int() const; 208 209 /// overloaded Cell::get_checked_near_int() get_checked_near_int() const210 virtual APL_Integer get_checked_near_int() const 211 { 212 if (value.cval[0] < 0.0) return APL_Integer(value.cval[0] - 0.3); 213 else return APL_Integer(value.cval[0] + 0.3); 214 } 215 216 /// overloaded Cell::is_near_int() 217 virtual bool is_near_int() const; 218 219 /// overloaded Cell::is_near_int64_t() 220 virtual bool is_near_int64_t() const; 221 222 /// overloaded Cell::bif_near_int64_t() 223 virtual ErrorCode bif_near_int64_t(Cell * Z) const; 224 225 /// overloaded Cell::bif_within_quad_CT() 226 virtual ErrorCode bif_within_quad_CT(Cell * Z) const; 227 228 /// overloaded Cell::is_near_zero() 229 virtual bool is_near_zero() const; 230 231 /// overloaded Cell::is_near_one() 232 virtual bool is_near_one() const; 233 234 /// overloaded Cell::is_near_real() 235 virtual bool is_near_real() const; 236 237 /// overloaded Cell::get_classname() get_classname() const238 virtual const char * get_classname() const { return "ComplexCell"; } 239 240 /// overloaded Cell::CDR_size() CDR_size() const241 virtual int CDR_size() const { return 16; } 242 243 /// overloaded Cell::to_type() to_type()244 virtual void to_type() 245 { new(this) IntCell(0); } 246 }; 247 //============================================================================= 248 249 #endif // __COMPLEXCELL_HH_DEFINED__ 250