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