ccgsl 2.7.2
C++wrappersforGnuScientificLibrary
poly.hpp
Go to the documentation of this file.
1/*
2 * $Id: poly.hpp 309 2013-11-17 16:26:16Z jdl3 $
3 * Copyright (C) 2012 John D Lamb
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef CCGSL_POLY_HPP
21#define CCGSL_POLY_HPP
22
23#include<stdexcept>
24#include<gsl/gsl_poly.h>
25#include<gsl/gsl_errno.h>
26#include"complex.hpp"
27
28namespace gsl {
39 namespace poly {
44 public:
49 ccgsl_pointer = 0;
50 count = 0; // initially nullptr will do
51 }
52 // Refines random access container
53 // Refines assignable
59 explicit complex_workspace( size_t const n ){
60 ccgsl_pointer = gsl_poly_complex_workspace_alloc( n );
61 // just plausibly we could allocate complex_workspace but not count
62 try { count = new size_t; } catch( std::bad_alloc& e ){
63 // try to tidy up before rethrowing
64 gsl_poly_complex_workspace_free( ccgsl_pointer );
65 throw e;
66 }
67 *count = 1; // initially there is just one reference to ccgsl_pointer
68 }
75 explicit complex_workspace( gsl_poly_complex_workspace* v ){
76 ccgsl_pointer = v;
77 // just plausibly we could fail to allocate count: no further action needed.
78 count = new size_t;
79 *count = 1; // initially there is just one reference to ccgsl_pointer
80 }
81 // copy constructor
87 count = v.count; if( count != 0 ) ++*count; }
88 // assignment operator
94 // first, possibly delete anything pointed to by this
95 if( count == 0 or --*count == 0 ){
96 if( ccgsl_pointer != 0 ) gsl_poly_complex_workspace_free( ccgsl_pointer );
97 delete count;
98 } // Then copy
99 ccgsl_pointer = v.ccgsl_pointer; count = v.count; if( count != 0 ) ++*count; return *this;
100 }
101 // destructor
106 if( count == 0 or --*count == 0 ){
107 // could have allocated null pointer
108 if( ccgsl_pointer != 0 ) gsl_poly_complex_workspace_free( ccgsl_pointer );
109 delete count;
110 }
111 }
112#ifdef __GXX_EXPERIMENTAL_CXX0X__
118 std::swap( count, v.count );
119 v.ccgsl_pointer = nullptr;
120 }
127 complex_workspace( std::move( v ) ).swap( *this );
128 return *this;
129 }
130#endif
131 // Refines equality comparable
132 // == operator
139 bool operator==( complex_workspace const& v ) const { return ccgsl_pointer == v.ccgsl_pointer; }
140 // != operator
147 bool operator!=( complex_workspace const& v ) const { return not operator==( v ); }
148 // Refines forward container
149 // Refines less than comparable
150 // operator<
159 bool operator<( complex_workspace const& v ) const { return ccgsl_pointer < v.ccgsl_pointer; }
160 // operator>
169 bool operator>( complex_workspace const& v ) const { return ccgsl_pointer > v.ccgsl_pointer; }
170 // operator<=
179 bool operator<=( complex_workspace const& v ) const { return ccgsl_pointer <= v.ccgsl_pointer; }
180 // operator>=
189 bool operator>=( complex_workspace const& v ) const { return ccgsl_pointer >= v.ccgsl_pointer; }
194 bool empty() const { return ccgsl_pointer == 0; }
195 // swap() --- should work even if sizes don't match
202 std::swap( ccgsl_pointer, v.ccgsl_pointer );
203 std::swap( count, v.count );
204 }
205 private:
209 gsl_poly_complex_workspace* ccgsl_pointer;
213 size_t* count;
214 public:
215 // shared reference functions
220 gsl_poly_complex_workspace* get() const { return ccgsl_pointer; }
226 bool unique() const { return count != 0 and *count == 1; }
231 size_t use_count() const { return count == 0 ? 0 : *count; }
237#ifdef __GXX_EXPERIMENTAL_CXX0X__
238 explicit
239#endif
240 operator bool() const { return ccgsl_pointer != 0; }
241 };
242
243#ifndef DOXYGEN_SKIP
251 inline double eval( double const c[], int const len, double const x ){
252 return gsl_poly_eval( c, len, x ); }
253#endif // DOXYGEN_SKIP
254
262 template<typename T>
263 inline double eval( T const& c, double const x ){
264 return gsl_poly_eval( c.data(), c.size(), x ); }
265
266#ifndef DOXYGEN_SKIP
274 inline complex complex_eval( double const c[], int const len, gsl::complex const z ){
275 return gsl_poly_complex_eval( c, len, z.get() ); }
276#endif // DOXYGEN_SKIP
277
285 template<typename T>
286 inline complex complex_eval( T const& c, gsl::complex const z ){
287 return gsl_poly_complex_eval( c.data(), c.size() , z.get() ); }
288
289#ifndef DOXYGEN_SKIP
301 inline int eval_derivs( double const c[], size_t const lenc, double const x,
302 double res[], size_t const lenres ){
303 return gsl_poly_eval_derivs( c, lenc, x, res, lenres ); }
304#endif // DOXYGEN_SKIP
305
316 template<typename T, typename U>
317 inline int eval_derivs( T const& c, double const x, U& res ){
318 return gsl_poly_eval_derivs( c.data(), c.size(), x, res.data(), res.size() ); }
319
320#ifndef DOXYGEN_SKIP
329 inline int dd_init( double dd[], double const x[], double const y[], size_t size ){
330 return gsl_poly_dd_init( dd, x, y, size ); }
331#endif // DOXYGEN_SKIP
332
341 template<typename T, typename U, typename V>
342 inline int dd_init( T& dd, U const& x, V const& y ){
343 size_t const size = dd.size() < x.size() ?
344 ( dd.size() < y.size() ? dd.size() : y.size() ) : x.size();
345 return gsl_poly_dd_init( dd.data(), x.data(), y.data(), size ); }
346
347#ifndef DOXYGEN_SKIP
367 inline int
368 dd_hermite_init( double dd[], double z[], double const xa[], double const ya[],
369 double const dya[], size_t const size ){
370 return gsl_poly_dd_hermite_init( dd, z, xa, ya, dya, size ); }
371#endif // DOXYGEN_SKIP
372
391 template<typename DD, typename Z, typename XA, typename YA, typename DYA>
392 inline int
393 dd_hermite_init( DD& dd, Z& z, XA const& xa, YA const& ya,
394 DYA const& dya){
395 size_t const size {xa.size()};
396 if(z.size() != 2*size)
397 throw std::length_error("gsl::poly::dd_hermite_init(): "
398 "z must have twice the length of xa.");
399 if(dd.size() != size)
400 throw std::length_error("gsl::poly::dd_hermite_init(): xa and dd must have same length.");
401 if(ya.size() != size)
402 throw std::length_error("gsl::poly::dd_hermite_init(): xa and ya must have same length.");
403 if(dya.size() != size)
404 throw std::length_error("gsl::poly::dd_hermite_init(): "
405 "xa and dya must have same length.");
406 return gsl_poly_dd_hermite_init( dd.data(), z.data(), xa.data(), ya.data(), dya.data(),
407 size );
408 }
409
410
411#ifndef DOXYGEN_SKIP
421 inline double dd_eval( double const dd[], double const xa[], size_t const size,
422 double const x ){
423 return gsl_poly_dd_eval( dd, xa, size, x ); }
424#endif // DOXYGEN_SKIP
425
435 template<typename T, typename U>
436 inline double dd_eval( T const& dd, U const& xa, double const x ){
437 size_t const size = dd.size() < xa.size() ? dd.size() : xa.size();
438 return gsl_poly_dd_eval( dd.data(), xa.data(), size, x ); }
439
440#ifndef DOXYGEN_SKIP
451 inline int dd_taylor( double c[], double xp, double const dd[], double const x[],
452 size_t size, double w[] ){
453 return gsl_poly_dd_taylor( c, xp, dd, x, size, w ); }
454#endif // DOXYGEN_SKIP
455
466 template<typename C, typename DD, typename X, typename W>
467 inline int dd_taylor( C& c, double xp, DD const& dd, X const& x, W& w ){
468 size_t const size = c.size() < dd.size() ?
469 ( c.size() < x.size() ? c.size() : x.size() ) : dd.size();
470 if( w.size() < size )
471 gsl_error( "workspace too small", __FILE__, __LINE__, GSL_EBADLEN );
472 return gsl_poly_dd_taylor( c.data(), xp, dd.data(), x.data(), size, w.data() ); }
473
474#ifndef DOXYGEN_SKIP
484 inline int solve_quadratic( double a, double b, double c, double* x0, double* x1 ){
485 return gsl_poly_solve_quadratic( a, b, c, x0, x1 ); }
486#endif // DOXYGEN_SKIP
496 inline int solve_quadratic( double a, double b, double c, double& x0, double& x1 ){
497 return gsl_poly_solve_quadratic( a, b, c, &x0, &x1 ); }
498
508 inline int complex_solve_quadratic( double a, double b, double c,
509 complex& z0, complex& z1 ){
510 return gsl_poly_complex_solve_quadratic( a, b, c, &z0.get(), &z1.get() ); }
511
512
513#ifndef DOXYGEN_SKIP
524 inline int solve_cubic( double a, double b, double c, double* x0,
525 double* x1, double* x2 ){
526 return gsl_poly_solve_cubic( a, b, c, x0, x1, x2 ); }
527#endif // DOXYGEN_SKIP
538 inline int solve_cubic( double a, double b, double c, double& x0,
539 double& x1, double& x2 ){
540 return gsl_poly_solve_cubic( a, b, c, &x0, &x1, &x2 ); }
541
552 inline int complex_solve_cubic( double a, double b, double c, complex& z0,
553 complex& z1, complex& z2 ){
554 return gsl_poly_complex_solve_cubic( a, b, c, &z0.get(), &z1.get(), &z2.get() ); }
555
556#ifndef DOXYGEN_SKIP
565 inline int complex_solve( double const* a, size_t n, complex_workspace& w,
567 return gsl_poly_complex_solve( a, n, w.get(), z ); }
568#endif // DOXYGEN_SKIP
569
580 template<typename A, typename Z>
581 inline int complex_solve( A const& a, complex_workspace& w, Z& z ){
582 size_t const n = a.size();
583 size_t const n_2 = z.size();
584 if( 2 * n != n_2 + 2 )
585 gsl_error( "mismatch in sizes of coefficients and roots",
586 __FILE__, __LINE__, GSL_EBADLEN );
587 return gsl_poly_complex_solve( a.data(), n, w.get(), z.data() ); }
588 }
592#ifdef DOXYGEN_SKIP
593 namespace poly::complex_poly {
594#else
595 namespace complex_poly {
596#endif
604 inline complex complex_eval( gsl_complex c[], size_t const len, gsl::complex const z ){
605 return gsl_complex_poly_complex_eval( c, len, z.get() ); }
606 }
607}
608#endif
This class handles complex numbers.
Definition: complex.hpp:42
gsl_complex & get()
Get the base class object.
Definition: complex.hpp:106
Workspace for solving polynomials.
Definition: poly.hpp:43
~complex_workspace()
The destructor only deletes the pointers if count reaches zero.
Definition: poly.hpp:105
bool operator>=(complex_workspace const &v) const
A container needs to define an ordering for sorting.
Definition: poly.hpp:189
bool operator!=(complex_workspace const &v) const
Two complex_workspace are different equal if their elements are not identical.
Definition: poly.hpp:147
complex_workspace()
The default constructor is only really useful for assigning to.
Definition: poly.hpp:48
complex_workspace & operator=(complex_workspace &&v)
Move operator.
Definition: poly.hpp:126
size_t * count
The shared reference count.
Definition: poly.hpp:213
gsl_poly_complex_workspace * get() const
Get the gsl_poly_complex_workspace.
Definition: poly.hpp:220
bool operator==(complex_workspace const &v) const
Two complex_workspace are identically equal if their elements are identical.
Definition: poly.hpp:139
complex_workspace(complex_workspace &&v)
Move constructor.
Definition: poly.hpp:117
bool operator<=(complex_workspace const &v) const
A container needs to define an ordering for sorting.
Definition: poly.hpp:179
bool operator<(complex_workspace const &v) const
A container needs to define an ordering for sorting.
Definition: poly.hpp:159
bool unique() const
Find if this is the only object sharing the gsl_poly_complex_workspace.
Definition: poly.hpp:226
size_t use_count() const
Find how many gen_workspace objects share this pointer.
Definition: poly.hpp:231
bool empty() const
Find if the complex_workspace is empty.
Definition: poly.hpp:194
complex_workspace(size_t const n)
The default constructor creates a new complex_workspace with n elements.
Definition: poly.hpp:59
gsl_poly_complex_workspace * ccgsl_pointer
The shared pointer.
Definition: poly.hpp:209
complex_workspace & operator=(complex_workspace const &v)
The assignment operator.
Definition: poly.hpp:93
complex_workspace(complex_workspace const &v)
The copy constructor.
Definition: poly.hpp:86
bool operator>(complex_workspace const &v) const
A container needs to define an ordering for sorting.
Definition: poly.hpp:169
complex_workspace(gsl_poly_complex_workspace *v)
Could construct from a gsl_poly_complex_workspace.
Definition: poly.hpp:75
void swap(complex_workspace &v)
Swap two complex_workspace.
Definition: poly.hpp:201
size_t size(series const &cs)
C++ version of gsl_cheb_size().
Definition: chebyshev.hpp:287
complex complex_eval(gsl_complex c[], size_t const len, gsl::complex const z)
C++ version of gsl_complex_poly_complex_eval().
Definition: poly.hpp:604
int complex_solve_quadratic(double a, double b, double c, complex &z0, complex &z1)
C++ version of gsl_poly_complex_solve_quadratic().
Definition: poly.hpp:508
int dd_init(T &dd, U const &x, V const &y)
C++ version of gsl_poly_dd_init().
Definition: poly.hpp:342
int dd_hermite_init(DD &dd, Z &z, XA const &xa, YA const &ya, DYA const &dya)
This function computes a divided-difference representation of the interpolating Hermite polynomial fo...
Definition: poly.hpp:393
int dd_taylor(C &c, double xp, DD const &dd, X const &x, W &w)
C++ version of gsl_poly_dd_taylor().
Definition: poly.hpp:467
int complex_solve_cubic(double a, double b, double c, complex &z0, complex &z1, complex &z2)
C++ version of gsl_poly_complex_solve_cubic().
Definition: poly.hpp:552
double eval(T const &c, double const x)
C++ version of gsl_poly_eval().
Definition: poly.hpp:263
double dd_eval(T const &dd, U const &xa, double const x)
C++ version of gsl_poly_dd_eval().
Definition: poly.hpp:436
int complex_solve(A const &a, complex_workspace &w, Z &z)
C++ version of gsl_poly_complex_solve().
Definition: poly.hpp:581
int solve_cubic(double a, double b, double c, double &x0, double &x1, double &x2)
C++ version of gsl_poly_solve_cubic().
Definition: poly.hpp:538
int eval_derivs(T const &c, double const x, U &res)
C++ version of gsl_poly_eval_derivs().
Definition: poly.hpp:317
int solve_quadratic(double a, double b, double c, double &x0, double &x1)
C++ version of gsl_poly_solve_quadratic().
Definition: poly.hpp:496
complex complex_eval(T const &c, gsl::complex const z)
C++ version of gsl_poly_complex_eval().
Definition: poly.hpp:286
size_t n(workspace const &w)
C++ version of gsl_rstat_n().
Definition: rstat.hpp:299
double b(int order, double qq)
C++ version of gsl_sf_mathieu_b().
Definition: sf_mathieu.hpp:298
double a(int order, double qq)
C++ version of gsl_sf_mathieu_a().
Definition: sf_mathieu.hpp:272
The gsl package creates an interface to the GNU Scientific Library for C++.
Definition: blas.hpp:34
gsl_complex_packed_ptr complex_packed_ptr
Typedef.
Definition: complex.hpp:1210