GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
__pchip_deriv__.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2002-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include "lo-slatec-proto.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "errwarn.h"
35 #include "ovl.h"
36 #include "utils.h"
37 #include "f77-fcn.h"
38 
40 
41 // Wrapper for SLATEC/PCHIP function DPCHIM to calculate the derivates
42 // for piecewise polynomials.
43 
44 DEFUN (__pchip_deriv__, args, ,
45  doc: /* -*- texinfo -*-
46 @deftypefn {} {@var{d} =} __pchip_deriv__ (@var{x}, @var{y}, @var{dim})
47 Undocumented internal function.
48 @end deftypefn */)
49 {
50  octave_value retval;
51  int nargin = args.length ();
52 
53  bool rows = (nargin == 3 && args(2).uint_value () == 2);
54 
55  if (nargin >= 2)
56  {
57  if (args(0).is_single_type () || args(1).is_single_type ())
58  {
59  FloatColumnVector xvec (args(0).float_vector_value ());
60  F77_INT nx = to_f77_int (xvec.numel ());
61  if (nx < 2)
62  error ("__pchip_deriv__: X must be at least of length 2");
63 
64  if (args(1).iscomplex ())
65  {
66  FloatComplexMatrix ymat (args(1).float_complex_matrix_value ());
67 
68  octave_idx_type nyr = ymat.rows ();
69  octave_idx_type nyc = ymat.columns ();
70 
71  if (nx != (rows ? nyc : nyr))
72  error ("__pchip_deriv__: X and Y dimension mismatch");
73 
74  FloatComplexMatrix dmat (nyr, nyc);
75 
76  F77_INT ierr;
77  const F77_INT incfd = (rows ? to_f77_int (2*nyr) : 2);
78  volatile const octave_idx_type inc = (rows ? 2 : 2*nyr);
79  volatile octave_idx_type k = 0;
80 
81  for (volatile octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
82  {
83  F77_XFCN (pchim, PCHIM, (nx, xvec.data (),
84  reinterpret_cast<float const *> (ymat.data ()) + k * inc,
85  reinterpret_cast<float *> (dmat.fortran_vec ()) + k * inc,
86  incfd, ierr));
87 
88  if (ierr < 0)
89  error ("__pchip_deriv__: PCHIM failed for real part with ierr = %"
90  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
91 
92  F77_XFCN (pchim, PCHIM, (nx, xvec.data (),
93  reinterpret_cast<float const *> (ymat.data ()) + 1 + k * inc,
94  reinterpret_cast<float *> (dmat.fortran_vec ()) + 1 + k * inc,
95  incfd, ierr));
96 
97  if (ierr < 0)
98  error ("__pchip_deriv__: PCHIM failed for imaginary part with ierr = %"
99  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
100 
101  k++;
102  }
103 
104  retval = dmat;
105  }
106  else
107  {
108  FloatMatrix ymat (args(1).float_matrix_value ());
109 
110  octave_idx_type nyr = ymat.rows ();
111  octave_idx_type nyc = ymat.columns ();
112 
113  if (nx != (rows ? nyc : nyr))
114  error ("__pchip_deriv__: X and Y dimension mismatch");
115 
116  FloatMatrix dmat (nyr, nyc);
117 
118  F77_INT ierr;
119  const F77_INT incfd = (rows ? to_f77_int (nyr) : 1);
120  volatile const octave_idx_type inc = (rows ? 1 : nyr);
121  volatile octave_idx_type k = 0;
122 
123  for (volatile octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
124  {
125  F77_XFCN (pchim, PCHIM, (nx, xvec.data (),
126  ymat.data () + k * inc,
127  dmat.fortran_vec () + k * inc,
128  incfd, ierr));
129 
130  k++;
131 
132  if (ierr < 0)
133  error ("__pchip_deriv__: PCHIM failed with ierr = %"
134  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
135  }
136 
137  retval = dmat;
138  }
139  }
140  else
141  {
142  ColumnVector xvec (args(0).vector_value ());
143  F77_INT nx = to_f77_int (xvec.numel ());
144  if (nx < 2)
145  error ("__pchip_deriv__: X must be at least of length 2");
146 
147  if (args(1).iscomplex ())
148  {
149  ComplexMatrix ymat (args(1).complex_matrix_value ());
150 
151  octave_idx_type nyr = ymat.rows ();
152  octave_idx_type nyc = ymat.columns ();
153 
154  if (nx != (rows ? nyc : nyr))
155  error ("__pchip_deriv__: X and Y dimension mismatch");
156 
157  ComplexMatrix dmat (nyr, nyc);
158 
159  F77_INT ierr;
160  const F77_INT incfd = (rows ? to_f77_int (2*nyr) : 2);
161  volatile const octave_idx_type inc = (rows ? 2 : 2*nyr);
162  volatile octave_idx_type k = 0;
163 
164  for (volatile octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
165  {
166  F77_XFCN (dpchim, DPCHIM, (nx, xvec.data (),
167  reinterpret_cast<double const *> (ymat.data ()) + k * inc,
168  reinterpret_cast<double *> (dmat.fortran_vec ()) + k * inc,
169  incfd, ierr));
170 
171  if (ierr < 0)
172  error ("__pchip_deriv__: DPCHIM failed for real part with ierr = %"
173  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
174 
175  F77_XFCN (dpchim, DPCHIM, (nx, xvec.data (),
176  reinterpret_cast<double const *> (ymat.data ()) + 1 + k * inc,
177  reinterpret_cast<double *> (dmat.fortran_vec ()) + 1 + k * inc,
178  incfd, ierr));
179 
180  if (ierr < 0)
181  error ("__pchip_deriv__: DPCHIM failed for imaginary part with ierr = %"
182  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
183 
184  k++;
185  }
186 
187  retval = dmat;
188  }
189  else
190  {
191  Matrix ymat (args(1).matrix_value ());
192 
193  octave_idx_type nyr = ymat.rows ();
194  octave_idx_type nyc = ymat.columns ();
195 
196  if (nx != (rows ? nyc : nyr))
197  error ("__pchip_deriv__: X and Y dimension mismatch");
198 
199  Matrix dmat (nyr, nyc);
200 
201  F77_INT ierr;
202  const F77_INT incfd = (rows ? to_f77_int (nyr) : 1);
203  volatile const octave_idx_type inc = (rows ? 1 : nyr);
204  volatile octave_idx_type k = 0;
205 
206  for (volatile octave_idx_type i = (rows ? nyr : nyc); i > 0; i--)
207  {
208  F77_XFCN (dpchim, DPCHIM, (nx, xvec.data (),
209  ymat.data () + k * inc,
210  dmat.fortran_vec () + k * inc,
211  incfd, ierr));
212  k++;
213 
214  if (ierr < 0)
215  error ("__pchip_deriv__: DPCHIM failed with ierr = %"
216  OCTAVE_F77_INT_TYPE_FORMAT, ierr);
217  }
218 
219  retval = dmat;
220  }
221  }
222  }
223 
224  return retval;
225 }
226 
227 /*
228 %!shared x, y
229 %! x = 0:3;
230 %! y = x.^2 + 1i * x.^3;
231 
232 %!test
233 %! d_complex = __pchip_deriv__ (x, y, 2);
234 %! d_real = __pchip_deriv__ (x, real (y), 2);
235 %! d_imag = __pchip_deriv__ (x, imag (y), 2);
236 %! assert (real (d_complex), d_real);
237 %! assert (imag (d_complex), d_imag);
238 
239 %!test
240 %! d_complex = __pchip_deriv__ (x.', y.');
241 %! d_real = __pchip_deriv__ (x.', real (y.'));
242 %! d_imag = __pchip_deriv__ (x.', imag (y.'));
243 %! assert (real (d_complex), d_real);
244 %! assert (imag (d_complex), d_imag);
245 
246 %!test
247 %! d_complex = __pchip_deriv__ (single (x), single (y), 2);
248 %! d_real = __pchip_deriv__ (single (x), real (single (y)), 2);
249 %! d_imag = __pchip_deriv__ (single (x), imag (single (y)), 2);
250 %! assert (real (d_complex), d_real);
251 %! assert (imag (d_complex), d_imag);
252 
253 %!test
254 %! d_complex = __pchip_deriv__ (single (x'), single (y'));
255 %! d_real = __pchip_deriv__ (single (x'), real (single (y')));
256 %! d_imag = __pchip_deriv__ (single (x'), imag (single (y')));
257 %! assert (real (d_complex), d_real);
258 %! assert (imag (d_complex), d_imag);
259 */
260 
261 OCTAVE_END_NAMESPACE(octave)
T * fortran_vec()
Size of the specified dimension.
Definition: Array-base.cc:1764
octave_idx_type rows() const
Definition: Array.h:459
const T * data() const
Size of the specified dimension.
Definition: Array.h:663
octave_idx_type columns() const
Definition: Array.h:471
octave_idx_type numel() const
Number of elements in the array.
Definition: Array.h:414
Definition: dMatrix.h:42
octave_idx_type length() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
subroutine dpchim(N, X, F, D, INCFD, IERR)
Definition: dpchim.f:3
void() error(const char *fmt,...)
Definition: error.cc:988
#define F77_XFCN(f, F, args)
Definition: f77-fcn.h:45
octave_f77_int_type F77_INT
Definition: f77-fcn.h:306
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE const F77_INT F77_INT & ierr
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE const F77_INT & incfd
subroutine pchim(N, X, F, D, INCFD, IERR)
Definition: pchim.f:3