Module: Numo::GSL::Poly
- Defined in:
- ext/numo/gsl/poly/gsl_poly.c
Defined Under Namespace
Classes: ComplexWorkspace
Class Method Summary collapse
-
.complex_solve(a) ⇒ Numo::DComplex
This function computes the roots of the general polynomial $P(x) = a_0 + a_1 x + a_2 x^2 + …
-
.complex_solve_cubic(a, b, c) ⇒ [Numo::DComplex, Numo::DComplex, Numo::DComplex, Numo::Int]
This function finds the complex roots of the cubic equation,.
-
.complex_solve_quadratic(a, b, c) ⇒ [Numo::DComplex, Numo::DComplex, Numo::Int]
This function finds the complex roots of the quadratic equation,.
-
.eval(c, x) ⇒ Numo::DFloat or DComplex
This function calls gsl_poly_eval or gsl_poly_complex_eval or gsl_complex_poly_complex_eval according to whether argument is complex or not.
-
.eval_derivs(c, x, lenres) ⇒ Numo::DFloat
This function evaluates a polynomial and its derivatives storing the results in the array res of size lenres.
-
.solve_cubic(a, b, c) ⇒ [Numo::DFloat, Numo::DFloat, Numo::DFloat, Numo::Int]
This function finds the real roots of the cubic equation,.
-
.solve_quadratic(a, b, c) ⇒ [Numo::DFloat, Numo::DFloat, Numo::Int]
This function finds the real roots of the quadratic equation,.
Class Method Details
.complex_solve(a) ⇒ Numo::DComplex
This function computes the roots of the general polynomial $P(x) = a_0 + a_1 x + a_2 x^2 + … + a_n-1 x^n-1$ P(x) = a_0 + a_1 x + a_2 x^2 + … + a_[n-1] x^[n-1] using balanced-QR reduction of the companion matrix. The parameter n specifies the length of the coefficient array. The coefficient of the highest order term must be non-zero. The function requires a workspace w of the appropriate size. The n-1 roots are returned in the packed complex array z of length 2(n-1), alternating real and imaginary parts.
The function returns GSL_SUCCESS if all the roots are found. If the QR reduction does not converge, the error handler is invoked with an error code of GSL_EFAILED. Note that due to finite precision, roots of higher multiplicity are returned as a cluster of simple roots with reduced accuracy. The solution of polynomials with higher-order roots requires specialized algorithms that take the multiplicity structure into account (see e.g. Z. Zeng, Algorithm 835, ACM Transactions on Mathematical Software, Volume 30, Issue 2 (2004), pp 218–236).
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 564
static VALUE
poly_s_complex_solve(VALUE mod, VALUE v1)
{
size_t shape[0];
ndfunc_arg_in_t ain[1] = {{cDF,1}};
ndfunc_arg_out_t aout[1] = {{cDC,1,shape}};
ndfunc_t ndf = {iter_poly_s_complex_solve, NO_LOOP, 1,1, ain,aout};
gsl_poly_complex_workspace *w;
void *opts[1];
VALUE vz, vws;
size_t n;
narray_t *na;
v1 = rb_funcall(cDF, rb_intern("cast"), 1, v1);
GetNArray(v1,na);
if (na->ndim == 0) {
rb_raise(nary_eDimensionError,"ndim(=%d) should >= %d", na->ndim, 0);
}
if (na->shape[na->ndim-1] < 2) {
rb_raise(nary_eShapeError, "last axis size must be >= 2");
}
n = na->shape[na->ndim-1];
shape[0] = n-1;
vws = poly_complex_workspace_s_new(cComplexWorkspace, SIZET2NUM(n));
TypedData_Get_Struct(vws, gsl_poly_complex_workspace, &poly_complex_workspace_data_type, w);
opts[0] = w;
vz = na_ndloop3(&ndf, opts, 1, v1);
RB_GC_GUARD(vws);
RB_GC_GUARD(v1);
return vz;
}
|
.complex_solve_cubic(a, b, c) ⇒ [Numo::DComplex, Numo::DComplex, Numo::DComplex, Numo::Int]
This function finds the complex roots of the cubic equation,
z^3 + a z^2 + b z + c = 0
The number of complex roots is returned (always three) and the locations of the roots are stored in z0, z1 and z2. The roots are returned in ascending order, sorted first by their real components and then by their imaginary components.
503 504 505 506 507 508 509 510 511 512 513 514 515 516 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 503
static VALUE
poly_s_complex_solve_cubic(VALUE mod,VALUE v0,VALUE v1,VALUE v2)
{
ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
ndfunc_arg_out_t aout[4] = {{cDC,0},{cDC,0},{cDC,0},{cI,0}};
ndfunc_t ndf = {iter_poly_s_complex_solve_cubic,NO_LOOP|NDF_INPLACE|NDF_EXTRACT,
3,4,ain,aout};
return na_ndloop(&ndf,3,v0,v1,v2);
}
|
.complex_solve_quadratic(a, b, c) ⇒ [Numo::DComplex, Numo::DComplex, Numo::Int]
This function finds the complex roots of the quadratic equation,
a z^2 + b z + c = 0
The number of complex roots is returned (either one or two) and the locations of the roots are stored in z0 and z1. The roots are returned in ascending order, sorted first by their real components and then by their imaginary components. If only one real root is found (i.e. if a=0) then it is stored in z0.
366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 366
static VALUE
poly_s_complex_solve_quadratic(VALUE mod,VALUE v0,VALUE v1,VALUE v2)
{
ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
ndfunc_arg_out_t aout[3] = {{cDC,0},{cDC,0},{cI,0}};
ndfunc_t ndf = {iter_poly_s_complex_solve_quadratic,NO_LOOP|NDF_INPLACE|NDF_EXTRACT,
3,3,ain,aout};
return na_ndloop(&ndf,3,v0,v1,v2);
}
|
.eval(c, x) ⇒ Numo::DFloat or DComplex
This function calls gsl_poly_eval or gsl_poly_complex_eval or gsl_complex_poly_complex_eval according to whether argument is complex or not.
This function evaluates a polynomial with real coefficients for the real variable x.
185 186 187 188 189 190 191 192 193 194 195 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 185
static VALUE
poly_s_eval(VALUE mod, VALUE v0, VALUE v1)
{
if (is_complex_nary(v0)) {
return poly_eval_cc(v0,v1);
} else if (is_complex_nary(v1)) {
return poly_eval_fc(v0,v1);
} else {
return poly_eval_ff(v0,v1);
}
}
|
.eval_derivs(c, x, lenres) ⇒ Numo::DFloat
This function evaluates a polynomial and its derivatives storing the results in the array res of size lenres. The output array contains the values of d^k P/d x^k for the specified value of x starting with k = 0.
231 232 233 234 235 236 237 238 239 240 241 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 231
static VALUE
poly_s_eval_derivs(VALUE mod, VALUE v0, VALUE v1, VALUE v2)
{
size_t shape[1];
ndfunc_arg_in_t ain[2] = {{cDF,1},{cDF,0}};
ndfunc_arg_out_t aout[1] = {{cDF,1,shape}};
ndfunc_t ndf = {iter_poly_s_eval_derivs,NO_LOOP|NDF_INPLACE|NDF_EXTRACT,2,1,ain,aout};
shape[0] = NUM2SIZET(v2);
return na_ndloop(&ndf,2,v0,v1);
}
|
.solve_cubic(a, b, c) ⇒ [Numo::DFloat, Numo::DFloat, Numo::DFloat, Numo::Int]
This function finds the real roots of the cubic equation,
x^3 + a x^2 + b x + c = 0
with a leading coefficient of unity. The number of real roots (either one or three) is returned, and their locations are stored in x0, x1 and x2. If one real root is found then only x0 is modified. When three real roots are found they are stored in x0, x1 and x2 in ascending order. The case of coincident roots is not considered special. For example, the equation (x-1)^3=0 will have three roots with exactly equal values. As in the quadratic case, finite precision may cause equal or closely-spaced real roots to move off the real axis into the complex plane, leading to a discrete change in the number of real roots.
437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 437
static VALUE
poly_s_solve_cubic(VALUE mod,VALUE v0,VALUE v1,VALUE v2)
{
ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
ndfunc_arg_out_t aout[4] = {{cDF,0},{cDF,0},{cDF,0},{cI,0}};
ndfunc_t ndf = {iter_poly_s_solve_cubic,NO_LOOP|NDF_INPLACE|NDF_EXTRACT,
3,4,ain,aout};
return na_ndloop(&ndf,3,v0,v1,v2);
}
|
.solve_quadratic(a, b, c) ⇒ [Numo::DFloat, Numo::DFloat, Numo::Int]
This function finds the real roots of the quadratic equation,
a x^2 + b x + c = 0
The number of real roots (either zero, one or two) is returned, and their locations are stored in x0 and x1. If no real roots are found then x0 and x1 are not modified. If one real root is found (i.e. if a=0) then it is stored in x0. When two real roots are found they are stored in x0 and x1 in ascending order. The case of coincident roots is not considered special. For example (x-1)^2=0 will have two roots, which happen to have exactly equal values.
The number of roots found depends on the sign of the discriminant b^2 - 4 a c. This will be subject to rounding and cancellation errors when computed in double precision, and will also be subject to errors if the coefficients of the polynomial are inexact. These errors may cause a discrete change in the number of roots. However, for polynomials with small integer coefficients the discriminant can always be computed exactly.
302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'ext/numo/gsl/poly/gsl_poly.c', line 302
static VALUE
poly_s_solve_quadratic(VALUE mod,VALUE v0,VALUE v1,VALUE v2)
{
ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
ndfunc_arg_out_t aout[3] = {{cDF,0},{cDF,0},{cI,0}};
ndfunc_t ndf = {iter_poly_s_solve_quadratic,NO_LOOP|NDF_INPLACE|NDF_EXTRACT,
3,3,ain,aout};
return na_ndloop(&ndf,3,v0,v1,v2);
}
|