26 #if defined (HAVE_CONFIG_H)
45 error (
"gcd: all values must be integers");
52 double tt = fmod (aa, bb);
63 template <
typename FP>
65 divide (
const std::complex<FP>& a,
const std::complex<FP>& b,
66 std::complex<FP>& q, std::complex<FP>&
r)
71 q = std::complex<FP> (
qr, qi);
76 template <
typename FP>
77 static std::complex<FP>
78 simple_gcd (
const std::complex<FP>& a,
const std::complex<FP>& b)
84 error (
"gcd: all complex parts must be integers");
86 std::complex<FP> aa = a;
87 std::complex<FP> bb = b;
94 std::complex<FP> qq, rr;
103 template <
typename T>
107 T aa = a.
abs ().value ();
108 T bb = b.
abs ().value ();
124 error (
"gcd: all values must be integers");
126 double aa = fabs (a);
127 double bb = fabs (b);
129 double xx, lx, yy, ly;
136 double tt = fmod (aa, bb);
141 double tx = lx - qq*xx;
145 double ty = ly - qq*yy;
150 x = (a >= 0 ? lx : -lx);
151 y = (b >= 0 ? ly : -ly);
156 template <
typename FP>
157 static std::complex<FP>
159 std::complex<FP>&
x, std::complex<FP>& y)
165 error (
"gcd: all complex parts must be integers");
167 std::complex<FP> aa = a;
168 std::complex<FP> bb = b;
169 bool swapped =
false;
176 std::complex<FP> xx, lx, yy, ly;
182 std::complex<FP> qq, rr;
187 std::complex<FP> tx = lx - qq*xx;
191 std::complex<FP> ty = ly - qq*yy;
205 template <
typename T>
210 T aa = a.
abs ().value ();
211 T bb = b.
abs ().value ();
238 template <
typename NDA>
242 typedef typename NDA::element_type T;
248 T aa = octave_value_extract<T> (a);
249 T bb = octave_value_extract<T> (b);
254 NDA aa = octave_value_extract<NDA> (a);
255 NDA bb = octave_value_extract<NDA> (b);
274 retval = do_simple_gcd<SparseMatrix> (a, b);
280 retval = do_simple_gcd<NDArray> (a, b);
283 #define MAKE_INT_BRANCH(X) \
285 retval = do_simple_gcd<X ## NDArray> (a, b); \
297 #undef MAKE_INT_BRANCH
300 retval = do_simple_gcd<ComplexNDArray> (a, b);
304 retval = do_simple_gcd<FloatComplexNDArray> (a, b);
308 error (
"gcd: invalid class combination for gcd: %s and %s\n",
318 template <
typename NDA>
323 typedef typename NDA::element_type T;
329 T aa = octave_value_extract<T> (a);
330 T bb = octave_value_extract<T> (b);
338 NDA aa = octave_value_extract<NDA> (a);
339 NDA bb = octave_value_extract<NDA> (b);
342 if (aa.numel () == 1)
344 else if (bb.numel () != 1 && bb.dims () != dv)
347 NDA gg (dv), xx (dv), yy (dv);
349 const T *aptr = aa.fortran_vec ();
350 const T *bptr = bb.fortran_vec ();
352 bool inca = aa.numel () != 1;
353 bool incb = bb.numel () != 1;
355 T *gptr = gg.fortran_vec ();
356 T *xptr = xx.fortran_vec ();
357 T *yptr = yy.fortran_vec ();
364 *gptr++ =
extended_gcd (*aptr, *bptr, *xptr++, *yptr++);
392 retval = do_extended_gcd<NDArray> (a, b,
x, y);
395 #define MAKE_INT_BRANCH(X) \
397 retval = do_extended_gcd<X ## NDArray> (a, b, x, y); \
409 #undef MAKE_INT_BRANCH
412 retval = do_extended_gcd<ComplexNDArray> (a, b,
x, y);
416 retval = do_extended_gcd<FloatComplexNDArray> (a, b,
x, y);
420 error (
"gcd: invalid class combination for gcd: %s and %s\n",
428 x =
x.sparse_matrix_value ();
435 x =
x.float_array_value ();
442 DEFUN (gcd, args, nargout,
480 int nargin = args.length ();
493 for (
int j = 2; j < nargin; j++)
497 for (
int i = 0; i < j; i++)
505 for (
int j = 2; j < nargin; j++)
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
void assign(const idx_vector &i, const Array< T > &rhs, const T &rfv)
Indexed assignment (always with resize & fill).
Vector representing the dimensions (size) of an Array.
octave_int< T > signum() const
octave_int< T > abs() const
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 double simple_gcd(double a, double b)
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)
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.
octave_value::octave_value(const Array< char > &chm, char type) return retval