26 #if defined (HAVE_CONFIG_H)
47 error (
"gcd: all values must be integers");
54 double tt = fmod (aa, bb);
62 template <
typename FP>
64 divide (
const std::complex<FP>& a,
const std::complex<FP>& b,
65 std::complex<FP>& q, std::complex<FP>&
r)
70 q = std::complex<FP> (
qr, qi);
75 template <
typename FP>
76 static std::complex<FP>
77 simple_gcd (
const std::complex<FP>& a,
const std::complex<FP>& b)
83 error (
"gcd: all complex parts must be integers");
85 std::complex<FP> aa = a;
86 std::complex<FP> bb = b;
93 std::complex<FP> qq, rr;
102 template <
typename T>
106 T aa = a.
abs ().value ();
107 T bb = b.
abs ().value ();
123 error (
"gcd: all values must be integers");
125 double aa = fabs (a);
126 double bb = fabs (b);
128 double xx, lx, yy, ly;
135 double tt = fmod (aa, bb);
140 double tx = lx - qq*xx;
144 double ty = ly - qq*yy;
149 x = (a >= 0 ? lx : -lx);
150 y = (b >= 0 ? ly : -ly);
155 template <
typename FP>
156 static std::complex<FP>
158 std::complex<FP>&
x, std::complex<FP>& y)
164 error (
"gcd: all complex parts must be integers");
166 std::complex<FP> aa = a;
167 std::complex<FP> bb = b;
168 bool swapped =
false;
175 std::complex<FP> xx, lx, yy, ly;
181 std::complex<FP> qq, rr;
186 std::complex<FP> tx = lx - qq*xx;
190 std::complex<FP> ty = ly - qq*yy;
204 template <
typename T>
209 T aa = a.
abs ().value ();
210 T bb = b.
abs ().value ();
237 template <
typename NDA>
241 typedef typename NDA::element_type T;
247 T aa = octave_value_extract<T> (a);
248 T bb = octave_value_extract<T> (b);
253 NDA aa = octave_value_extract<NDA> (a);
254 NDA bb = octave_value_extract<NDA> (b);
255 retval = binmap<T> (aa, bb,
simple_gcd,
"gcd");
273 retval = do_simple_gcd<SparseMatrix> (a, b);
279 retval = do_simple_gcd<NDArray> (a, b);
282 #define MAKE_INT_BRANCH(X) \
284 retval = do_simple_gcd<X ## NDArray> (a, b); \
296 #undef MAKE_INT_BRANCH
299 retval = do_simple_gcd<ComplexNDArray> (a, b);
303 retval = do_simple_gcd<FloatComplexNDArray> (a, b);
307 error (
"gcd: invalid class combination for gcd: %s and %s\n",
317 template <
typename NDA>
322 typedef typename NDA::element_type T;
328 T aa = octave_value_extract<T> (a);
329 T bb = octave_value_extract<T> (b);
337 NDA aa = octave_value_extract<NDA> (a);
338 NDA bb = octave_value_extract<NDA> (b);
341 if (aa.numel () == 1)
343 else if (bb.numel () != 1 && bb.dims () != dv)
346 NDA gg (dv), xx (dv), yy (dv);
348 const T *aptr = aa.data ();
349 const T *bptr = bb.data ();
351 bool inca = aa.numel () != 1;
352 bool incb = bb.numel () != 1;
354 T *gptr = gg.fortran_vec ();
355 T *xptr = xx.fortran_vec ();
356 T *yptr = yy.fortran_vec ();
363 *gptr++ =
extended_gcd (*aptr, *bptr, *xptr++, *yptr++);
391 retval = do_extended_gcd<NDArray> (a, b,
x, y);
394 #define MAKE_INT_BRANCH(X) \
396 retval = do_extended_gcd<X ## NDArray> (a, b, x, y); \
408 #undef MAKE_INT_BRANCH
411 retval = do_extended_gcd<ComplexNDArray> (a, b,
x, y);
415 retval = do_extended_gcd<FloatComplexNDArray> (a, b,
x, y);
419 error (
"gcd: invalid class combination for gcd: %s and %s\n",
427 x =
x.sparse_matrix_value ();
434 x =
x.float_array_value ();
441 DEFUN (gcd, args, nargout,
479 int nargin = args.length ();
488 retval.
resize (nargin + 1);
492 for (
int j = 2; j < nargin; j++)
496 for (
int i = 0; i < j; i++)
504 for (
int j = 2; j < nargin; j++)
Vector representing the dimensions (size) of an Array.
octave_int< T > signum() const
octave_int< T > abs() 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)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
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)
void err_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
std::complex< T > floor(const std::complex< T > &x)
F77_RET_T const F77_DBLE * x
builtin_type_t btyp_mixed_numeric(builtin_type_t x, builtin_type_t y)
Determine the resulting type for a possible mixed-type operation.