26#if defined (HAVE_CONFIG_H)
47 error (
"gcd: all values must be integers");
54 double tt = fmod (aa, bb);
67divide (
const std::complex<FP>& a,
const std::complex<FP>& b,
68 std::complex<FP>& q, std::complex<FP>& r)
73 q = std::complex<FP> (
qr, qi);
79static std::complex<FP>
80simple_gcd (
const std::complex<FP>& a,
const std::complex<FP>& b)
86 error (
"gcd: all complex parts must be integers");
88 std::complex<FP> aa = a;
89 std::complex<FP> bb = b;
96 std::complex<FP> qq, rr;
109 T aa = a.
abs ().value ();
110 T bb = b.
abs ().value ();
126 error (
"gcd: all values must be integers");
128 double aa = fabs (a);
129 double bb = fabs (b);
131 double xx, lx, yy, ly;
138 double tt = fmod (aa, bb);
143 double tx = lx - qq*xx;
147 double ty = ly - qq*yy;
152 x = (a >= 0 ? lx : -lx);
153 y = (b >= 0 ? ly : -ly);
158template <
typename FP>
159static std::complex<FP>
161 std::complex<FP>&
x, std::complex<FP>& y)
167 error (
"gcd: all complex parts must be integers");
169 std::complex<FP> aa = a;
170 std::complex<FP> bb = b;
171 bool swapped =
false;
178 std::complex<FP> xx, lx, yy, ly;
184 std::complex<FP> qq, rr;
189 std::complex<FP> tx = lx - qq*xx;
193 std::complex<FP> ty = ly - qq*yy;
212 T aa = a.
abs ().value ();
213 T bb = b.
abs ().value ();
240template <
typename NDA>
244 typedef typename NDA::element_type T;
250 T aa = octave_value_extract<T> (a);
251 T bb = octave_value_extract<T> (b);
256 NDA aa = octave_value_extract<NDA> (a);
257 NDA bb = octave_value_extract<NDA> (b);
258 retval = binmap<T> (aa, bb,
simple_gcd,
"gcd");
276 retval = do_simple_gcd<SparseMatrix> (a, b);
282 retval = do_simple_gcd<NDArray> (a, b);
285#define MAKE_INT_BRANCH(X) \
287 retval = do_simple_gcd<X ## NDArray> (a, b); \
299#undef MAKE_INT_BRANCH
302 retval = do_simple_gcd<ComplexNDArray> (a, b);
306 retval = do_simple_gcd<FloatComplexNDArray> (a, b);
310 error (
"gcd: invalid class combination for gcd: %s and %s\n",
320template <
typename NDA>
325 typedef typename NDA::element_type T;
331 T aa = octave_value_extract<T> (a);
332 T bb = octave_value_extract<T> (b);
340 NDA aa = octave_value_extract<NDA> (a);
341 NDA bb = octave_value_extract<NDA> (b);
344 if (aa.numel () == 1)
346 else if (bb.numel () != 1 && bb.dims () != dv)
349 NDA gg (dv), xx (dv), yy (dv);
351 const T *aptr = aa.data ();
352 const T *bptr = bb.data ();
354 bool inca = aa.numel () != 1;
355 bool incb = bb.numel () != 1;
357 T *gptr = gg.fortran_vec ();
358 T *xptr = xx.fortran_vec ();
359 T *yptr = yy.fortran_vec ();
366 *gptr++ =
extended_gcd (*aptr, *bptr, *xptr++, *yptr++);
394 retval = do_extended_gcd<NDArray> (a, b,
x, y);
397#define MAKE_INT_BRANCH(X) \
399 retval = do_extended_gcd<X ## NDArray> (a, b, x, y); \
411#undef MAKE_INT_BRANCH
414 retval = do_extended_gcd<ComplexNDArray> (a, b,
x, y);
418 retval = do_extended_gcd<FloatComplexNDArray> (a, b,
x, y);
422 error (
"gcd: invalid class combination for gcd: %s and %s\n",
430 x =
x.sparse_matrix_value ();
437 x =
x.float_array_value ();
444DEFUN (gcd, args, nargout,
482 int nargin = args.length ();
491 retval.
resize (nargin + 1);
495 for (
int j = 2; j < nargin; j++)
499 for (
int i = 0; i < j; i++)
507 for (
int j = 2; j < nargin; j++)
Vector representing the dimensions (size) of an Array.
octave_int< T > abs() const
octave_int< T > signum() const
void resize(octave_idx_type n, const octave_value &rfv=octave_value())
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
bool issparse(void) const
builtin_type_t builtin_type(void) const
bool is_scalar_type(void) const
std::string class_name(void) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
dim_vector dims(void) const
ColumnVector real(const ComplexColumnVector &a)
ColumnVector imag(const ComplexColumnVector &a)
OCTINTERP_API void print_usage(void)
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
static octave_value do_extended_gcd(const octave_value &a, const octave_value &b, octave_value &x, octave_value &y)
static void divide(const std::complex< FP > &a, const std::complex< FP > &b, std::complex< FP > &q, std::complex< FP > &r)
static octave_value do_simple_gcd(const octave_value &a, const octave_value &b)
static double extended_gcd(double a, double b, double &x, double &y)
#define MAKE_INT_BRANCH(X)
static OCTAVE_NAMESPACE_BEGIN double simple_gcd(double a, double b)
F77_RET_T const F77_DBLE * x
std::complex< T > floor(const std::complex< T > &x)
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
builtin_type_t btyp_mixed_numeric(builtin_type_t x, builtin_type_t y)
Determine the resulting type for a possible mixed-type operation.