Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package octave-forge-nurbs for 
openSUSE:Factory checked in at 2025-08-27 21:35:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/octave-forge-nurbs (Old)
 and      /work/SRC/openSUSE:Factory/.octave-forge-nurbs.new.30751 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "octave-forge-nurbs"

Wed Aug 27 21:35:07 2025 rev:6 rq:1301568 version:1.4.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/octave-forge-nurbs/octave-forge-nurbs.changes    
2024-02-26 19:48:05.527768009 +0100
+++ 
/work/SRC/openSUSE:Factory/.octave-forge-nurbs.new.30751/octave-forge-nurbs.changes
 2025-08-27 21:36:09.746397790 +0200
@@ -1,0 +2,6 @@
+Tue Aug 26 18:11:15 UTC 2025 - Stefan BrĂ¼ns <stefan.bru...@rwth-aachen.de>
+
+- Update to version 1.4.4:
+  * Update to work with upcoming Octave 10 release
+
+-------------------------------------------------------------------

Old:
----
  nurbs-1.4.3.tar.gz

New:
----
  nurbs-1.4.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ octave-forge-nurbs.spec ++++++
--- /var/tmp/diff_new_pack.H9wBZF/_old  2025-08-27 21:36:10.414425679 +0200
+++ /var/tmp/diff_new_pack.H9wBZF/_new  2025-08-27 21:36:10.418425847 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package octave-forge-nurbs
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,12 +18,12 @@
 
 %define octpkg  nurbs
 Name:           octave-forge-%{octpkg}
-Version:        1.4.3
+Version:        1.4.4
 Release:        0
 Summary:        Routines for Non-Uniform Rational B-Splines for Octave
 License:        GPL-3.0-or-later
 Group:          Productivity/Scientific/Math
-URL:            https://octave.sourceforge.io/%{octpkg}/
+URL:            https://gnu-octave.github.io/packages/nurbs/
 Source0:        
https://downloads.sourceforge.net/octave/%{octpkg}-%{version}.tar.gz
 # PATCH-FIX-UPSTREAM nurbs-openmp.patch -- Fix build with openmp
 Patch1:         nurbs-openmp.patch

++++++ nurbs-1.4.3.tar.gz -> nurbs-1.4.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/DESCRIPTION new/nurbs-1.4.4/DESCRIPTION
--- old/nurbs-1.4.3/DESCRIPTION 2021-03-29 12:11:45.775919014 +0200
+++ new/nurbs-1.4.4/DESCRIPTION 2025-02-10 14:35:08.000000000 +0100
@@ -1,6 +1,6 @@
 Name: nurbs
-Version: 1.4.3
-Date: 2021-03-29
+Version: 1.4.4
+Date: 2025-02-10
 Author: Mark Spink, Daniel Claxton, Carlo de Falco, Rafael Vazquez
 Maintainer: Carlo de Falco and Rafael Vazquez
 Title: Nurbs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/NEWS new/nurbs-1.4.4/NEWS
--- old/nurbs-1.4.3/NEWS        2021-03-29 12:11:45.779919075 +0200
+++ new/nurbs-1.4.4/NEWS        2025-02-10 14:35:08.000000000 +0100
@@ -1,3 +1,10 @@
+Summary of important user-visible changes for next release of nurbs:
+-------------------------------------------------------------------
+
+Summary of important user-visible changes for nurbs 1.4.4:
+-------------------------------------------------------------------
+Update to work with upcoming Octave 10 release
+
 Summary of important user-visible changes for nurbs 1.4.3:
 -------------------------------------------------------------------
 * inst/nrbctrlplot: allow the number of points for the plot as input
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/basisfun.m 
new/nurbs-1.4.4/inst/basisfun.m
--- old/nurbs-1.4.3/inst/basisfun.m     2021-03-29 12:11:45.779919075 +0200
+++ new/nurbs-1.4.4/inst/basisfun.m     2025-02-10 14:35:08.000000000 +0100
@@ -1,91 +1,81 @@
-function B = basisfun (iv, uv, p, U)
-
-% BASISFUN:  Basis function for B-Spline
-%
-% Calling Sequence:
-% 
-%   N = basisfun(iv,uv,p,U)
-%   
-%    INPUT:
-%   
-%      iv - knot span  ( from FindSpan() )
-%      uv - parametric points
-%      p  - spline degree
-%      U  - knot sequence
-%   
-%    OUTPUT:
-%   
-%      N - Basis functions vector(numel(uv)*(p+1))
-%   
-%    Adapted from Algorithm A2.2 from 'The NURBS BOOK' pg70.
-%
-% See also: 
-%
-%    numbasisfun, basisfunder, findspan
-%
-% Copyright (C) 2000 Mark Spink
-% Copyright (C) 2007 Daniel Claxton
-% Copyright (C) 2009 Carlo de Falco
-%
-%    This program is free software: you can redistribute it and/or modify
-%    it under the terms of the GNU General Public License as published by
-%    the Free Software Foundation, either version 3 of the License, or
-%    (at your option) any later version.
-
-%    This program is distributed in the hope that it will be useful,
-%    but WITHOUT ANY WARRANTY; without even the implied warranty of
-%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-%    GNU General Public License for more details.
-%
-%    You should have received a copy of the GNU General Public License
-%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-B = zeros(numel(uv), p+1);
-                                               
-for jj = 1:numel(uv) 
-
-  i = iv(jj) + 1; %% findspan uses 0-based numbering
-  u = uv(jj);
-
-  left = zeros(p+1,1);
-  right = zeros(p+1,1);
-
-  N(1) = 1;
-  for j=1:p
-    left(j+1) = u - U(i+1-j);
-    right(j+1) = U(i+j) - u;
-    saved = 0;
-
-    for r=0:j-1
-      temp = N(r+1)/(right(r+2) + left(j-r+1));
-      N(r+1) = saved + right(r+2)*temp;
-      saved = left(j-r+1)*temp;
-    end
-    
-    N(j+1) = saved;
-  end
-
-  B (jj, :) = N;
-
-end
-
-end
-
-%!test
-%!  n = 3; 
-%!  U = [0 0 0 1/2 1 1 1]; 
-%!  p = 2; 
-%!  u = linspace (0, 1, 10);  
-%!  s = findspan (n, p, u, U);  
-%!  Bref = [1.00000   0.00000   0.00000
-%!          0.60494   0.37037   0.02469
-%!          0.30864   0.59259   0.09877
-%!          0.11111   0.66667   0.22222
-%!          0.01235   0.59259   0.39506
-%!          0.39506   0.59259   0.01235
-%!          0.22222   0.66667   0.11111
-%!          0.09877   0.59259   0.30864
-%!          0.02469   0.37037   0.60494
-%!          0.00000   0.00000   1.00000];
-%!  B = basisfun (s, u, p, U);
-%!  assert (B, Bref, 1e-5);
+function B = basisfun (mu, x, p, knots)
+
+% BASISFUN:  Basis function for B-Spline
+%
+% Calling Sequence:
+% 
+%   N = basisfun(mu,x,p,knots)
+%   
+%    INPUT:
+%   
+%      mu    - knot span  ( from FindSpan() )
+%      x     - parametric points
+%      p     - spline degree
+%      knots - knot sequence
+%   
+%    OUTPUT:
+%   
+%      N - Basis functions vector(numel(uv)*(p+1))
+%   
+%    Adapted from Algorithm A2.2 from 'The NURBS BOOK' pg70.
+%
+% See also: 
+%
+%    numbasisfun, basisfunder, findspan
+%
+% Copyright (C) 2000 Mark Spink
+% Copyright (C) 2007 Daniel Claxton
+% Copyright (C) 2009 Carlo de Falco
+% Copyright (C) 2022 Yannis Voet
+%
+%    This program is free software: you can redistribute it and/or modify
+%    it under the terms of the GNU General Public License as published by
+%    the Free Software Foundation, either version 3 of the License, or
+%    (at your option) any later version.
+
+%    This program is distributed in the hope that it will be useful,
+%    but WITHOUT ANY WARRANTY; without even the implied warranty of
+%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%    GNU General Public License for more details.
+%
+%    You should have received a copy of the GNU General Public License
+%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+mu = mu + 1;
+% Making sure x and mu are both column vectors
+x = x(:);
+mu = mu(:);
+
+Np = length(x);
+B = ones(Np,1);
+
+for k = 1:p
+  i1 = mu + ((1-k):0);
+  i2 = mu + (1:k);
+  t1 = reshape(knots(i1(:)), Np, k);
+  t2 = reshape(knots(i2(:)), Np, k);
+  omega = (x-t1)./(t2-t1);
+  omega(t2-t1<1e-15) = 0; % "Anything divided by zero is zero" convention
+  B = [(1-omega).*B zeros(Np,1)] + [zeros(Np,1) omega.*B];
+end
+
+end
+
+%!test
+%!  n = 3;
+%!  U = [0 0 0 1/2 1 1 1];
+%!  p = 2; 
+%!  u = linspace (0, 1, 10);
+%!  s = findspan (n, p, u, U);
+%!  Bref = [1.00000   0.00000   0.00000
+%!          0.60494   0.37037   0.02469
+%!          0.30864   0.59259   0.09877
+%!          0.11111   0.66667   0.22222
+%!          0.01235   0.59259   0.39506
+%!          0.39506   0.59259   0.01235
+%!          0.22222   0.66667   0.11111
+%!          0.09877   0.59259   0.30864
+%!          0.02469   0.37037   0.60494
+%!          0.00000   0.00000   1.00000];
+%!  B = basisfun (s, u, p, U);
+%!  assert (B, Bref, 1e-5);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/basisfunder.m 
new/nurbs-1.4.4/inst/basisfunder.m
--- old/nurbs-1.4.3/inst/basisfunder.m  2021-03-29 12:11:45.779919075 +0200
+++ new/nurbs-1.4.4/inst/basisfunder.m  2025-02-10 14:35:08.000000000 +0100
@@ -1,155 +1,119 @@
-function dersv = basisfunder (ii, pl, uu, u_knotl, nders)
-
-% BASISFUNDER:  B-Spline Basis function derivatives.
-%
-% Calling Sequence:
-% 
-%   ders = basisfunder (ii, pl, uu, k, nd)
-%
-%    INPUT:
-%   
-%      ii  - knot span index (see findspan)
-%      pl  - degree of curve
-%      uu  - parametric points
-%      k   - knot vector
-%      nd  - number of derivatives to compute
-%
-%    OUTPUT:
-%   
-%      ders - ders(n, i, :) (i-1)-th derivative at n-th point
-%   
-%    Adapted from Algorithm A2.3 from 'The NURBS BOOK' pg72.
-%
-% See also: 
-%
-%    numbasisfun, basisfun, findspan
-%
-%    Copyright (C) 2009,2011 Rafael Vazquez
-%
-%    This program is free software: you can redistribute it and/or modify
-%    it under the terms of the GNU General Public License as published by
-%    the Free Software Foundation, either version 3 of the License, or
-%    (at your option) any later version.
-
-%    This program is distributed in the hope that it will be useful,
-%    but WITHOUT ANY WARRANTY; without even the implied warranty of
-%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-%    GNU General Public License for more details.
-%
-%    You should have received a copy of the GNU General Public License
-%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-  dersv = zeros(numel(uu), nders+1, pl+1);
-
-  for jj = 1:numel(uu)
-
-    i = ii(jj)+1; %% convert to base-1 numbering of knot spans
-    u = uu(jj);
-
-    ders = zeros(nders+1,pl+1);
-    ndu = zeros(pl+1,pl+1);
-    left = zeros(pl+1);
-    right = zeros(pl+1);
-    a = zeros(2,pl+1);
-    ndu(1,1) = 1;
-    for j = 1:pl
-      left(j+1) = u - u_knotl(i+1-j);
-      right(j+1) = u_knotl(i+j) - u;
-      saved = 0;
-      for r = 0:j-1
-        ndu(j+1,r+1) = right(r+2) + left(j-r+1);
-        temp = ndu(r+1,j)/ndu(j+1,r+1);
-        ndu(r+1,j+1) = saved + right(r+2)*temp;
-        saved = left(j-r+1)*temp;
-      end
-      ndu(j+1,j+1) = saved;
-    end   
-    for j = 0:pl
-      ders(1,j+1) = ndu(j+1,pl+1);
-    end
-    for r = 0:pl
-      s1 = 0;
-      s2 = 1;
-      a(1,1) = 1;
-      for k = 1:nders %compute kth derivative
-        d = 0;
-        rk = r-k;
-        pk = pl-k;
-        if (r >= k)
-          a(s2+1,1) = a(s1+1,1)/ndu(pk+2,rk+1);
-          d = a(s2+1,1)*ndu(rk+1,pk+1);
-        end
-        if (rk >= -1)
-          j1 = 1;
-        else 
-          j1 = -rk;
-        end
-        if ((r-1) <= pk)
-          j2 = k-1;
-        else 
-          j2 = pl-r;
-        end
-        for j = j1:j2
-          a(s2+1,j+1) = (a(s1+1,j+1) - a(s1+1,j))/ndu(pk+2,rk+j+1);
-          d = d + a(s2+1,j+1)*ndu(rk+j+1,pk+1);
-        end
-        if (r <= pk)
-          a(s2+1,k+1) = -a(s1+1,k)/ndu(pk+2,r+1);
-          d = d + a(s2+1,k+1)*ndu(r+1,pk+1);
-        end
-        ders(k+1,r+1) = d;
-        j = s1;
-        s1 = s2;
-        s2 = j;
-      end
-    end
-    r = pl;
-    for k = 1:nders
-      for j = 0:pl
-        ders(k+1,j+1) = ders(k+1,j+1)*r;
-      end
-      r = r*(pl-k);
-    end
-
-    dersv(jj, :, :) = ders;
-    
-  end
-
-end
-
-%!test
-%! k    = [0 0 0 0 1 1 1 1];
-%! p    = 3;
-%! u    = rand (1);
-%! i    = findspan (numel(k)-p-2, p, u, k);
-%! ders = basisfunder (i, p, u, k, 1);
-%! sumders = sum (squeeze(ders), 2);
-%! assert (sumders(1), 1, 1e-15);
-%! assert (sumders(2:end), 0, 1e-15);
-
-%!test
-%! k    = [0 0 0 0 1/3 2/3 1 1 1 1];
-%! p    = 3;
-%! u    = rand (1);
-%! i    = findspan (numel(k)-p-2, p, u, k);
-%! ders = basisfunder (i, p, u, k, 7); 
-%! sumders = sum (squeeze(ders), 2);
-%! assert (sumders(1), 1, 1e-15);
-%! assert (sumders(2:end), zeros(rows(squeeze(ders))-1, 1), 1e-13);
-
-%!test
-%! k    = [0 0 0 0 1/3 2/3 1 1 1 1];
-%! p    = 3;
-%! u    = rand (100, 1);
-%! i    = findspan (numel(k)-p-2, p, u, k);
-%! ders = basisfunder (i, p, u, k, 7);
-%! for ii=1:10
-%!   sumders = sum (squeeze(ders(ii,:,:)), 2);
-%!   assert (sumders(1), 1, 1e-15);
-%!   assert (sumders(2:end), zeros(rows(squeeze(ders(ii,:,:)))-1, 1), 1e-13);
-%! end
-%! assert (ders(:, (p+2):end, :), zeros(numel(u), 8-p-1, p+1), 1e-13)
-%! assert (all(all(ders(:, 1, :) <= 1)), true)
-
-
-
+function dersv = basisfunder (mu, p, x, knots, nders)
+
+% BASISFUNDER:  B-Spline Basis function derivatives.
+%
+% Calling Sequence:
+% 
+%   ders = basisfunder (mu, p, x, knots, nders)
+%
+%    INPUT:
+%   
+%      mu    - knot span index (see findspan)
+%      p     - degree of curve
+%      x     - parametric points
+%      knots - knot vector
+%      nders - number of derivatives to compute
+%
+%    OUTPUT:
+%   
+%      ders - ders(n, i, :) (i-1)-th derivative at n-th point
+%   
+%    Adapted from Algorithm A2.3 from 'The NURBS BOOK' pg72.
+%
+% See also: 
+%
+%    numbasisfun, basisfun, findspan
+%
+%    Copyright (C) 2009,2011 Rafael Vazquez
+%    Copyright (C) 2022 Yannis Voet, Rafael Vazquez
+%
+%    This program is free software: you can redistribute it and/or modify
+%    it under the terms of the GNU General Public License as published by
+%    the Free Software Foundation, either version 3 of the License, or
+%    (at your option) any later version.
+
+%    This program is distributed in the hope that it will be useful,
+%    but WITHOUT ANY WARRANTY; without even the implied warranty of
+%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%    GNU General Public License for more details.
+%
+%    You should have received a copy of the GNU General Public License
+%    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+x = x(:);
+mu = mu(:);
+
+r = min([nders p]);
+mu = mu+1;
+N = length(x);
+D = cell(1, r+1);
+B = basisfun(mu-1, x, p-r, knots);
+D{r+1} = B;
+
+for k = p-r+1:p
+
+  i1 = mu + ((1-k):0);
+  i2 = mu + (1:k);
+  t1 = reshape(knots(i1(:)), N, k);
+  t2 = reshape(knots(i2(:)), N, k);
+
+  omega = (x-t1)./(t2-t1);
+  omega(t2-t1<1e-15) = 0; % "Anything divided by zero is zero" convention
+  B = [(1-omega).*B zeros(N,1)]+[zeros(N,1) omega.*B];
+
+  % Save for the next iteration
+  D{p-k+1} = B;
+
+  % Compute the derivative
+  omega = 1./(t2-t1);
+  omega(t2-t1<1e-15) = 0; % "Anything divided by zero is zero" convention
+  for j = 1:k-p+r
+    D{end-j+1} = [-omega.*D{end-j+1} zeros(N,1)]+[zeros(N,1) 
omega.*D{end-j+1}];
+  end
+end
+
+for k = 1:nders-p
+  D{r+1+k} = zeros(N, p+1);
+end
+
+D = reshape(cell2mat(D), N, p+1, nders+1);
+v = 0:nders;
+v(v>r) = r;
+f = reshape(factorial(p)./factorial(p-v), 1, 1, nders+1);
+dersv = f.*D;
+dersv = permute(dersv, [1 3 2]);
+
+
+%!test
+%! k    = [0 0 0 0 1 1 1 1];
+%! p    = 3;
+%! u    = rand (1);
+%! i    = findspan (numel(k)-p-2, p, u, k);
+%! ders = basisfunder (i, p, u, k, 1);
+%! sumders = sum (squeeze(ders), 2);
+%! assert (sumders(1), 1, 1e-15);
+%! assert (sumders(2:end), 0, 1e-15);
+
+%!test
+%! k    = [0 0 0 0 1/3 2/3 1 1 1 1];
+%! p    = 3;
+%! u    = rand (1);
+%! i    = findspan (numel(k)-p-2, p, u, k);
+%! ders = basisfunder (i, p, u, k, 7); 
+%! sumders = sum (squeeze(ders), 2);
+%! assert (sumders(1), 1, 1e-15);
+%! assert (sumders(2:end), zeros(rows(squeeze(ders))-1, 1), 1e-13);
+
+%!test
+%! k    = [0 0 0 0 1/3 2/3 1 1 1 1];
+%! p    = 3;
+%! u    = rand (100, 1);
+%! i    = findspan (numel(k)-p-2, p, u, k);
+%! ders = basisfunder (i, p, u, k, 7);
+%! for ii=1:10
+%!   sumders = sum (squeeze(ders(ii,:,:)), 2);
+%!   assert (sumders(1), 1, 1e-15);
+%!   assert (sumders(2:end), zeros(rows(squeeze(ders(ii,:,:)))-1, 1), 1e-13);
+%! end
+%! assert (ders(:, (p+2):end, :), zeros(numel(u), 8-p-1, p+1), 1e-13)
+%! assert (all(all(ders(:, 1, :) <= 1)), true)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/findspan.m 
new/nurbs-1.4.4/inst/findspan.m
--- old/nurbs-1.4.3/inst/findspan.m     2021-03-29 12:11:45.783919136 +0200
+++ new/nurbs-1.4.4/inst/findspan.m     2025-02-10 14:35:08.000000000 +0100
@@ -18,7 +18,7 @@
 %
 %  Modification of Algorithm A2.1 from 'The NURBS BOOK' pg68
 %
-%    Copyright (C) 2010 Rafael Vazquez
+%    Copyright (C) 2010, 2021 Rafael Vazquez
 %
 %    This program is free software: you can redistribute it and/or modify
 %    it under the terms of the GNU General Public License as published by
@@ -33,6 +33,11 @@
 %    You should have received a copy of the GNU General Public License
 %    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
                                           
 
+if (isempty (u))
+  s = zeros (size(u));
+  return
+end
+
 if (max(u(:))>U(end) || min(u(:))<U(1))
   error('Some value is outside the knot span')
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/nrbderiv.m 
new/nurbs-1.4.4/inst/nrbderiv.m
--- old/nurbs-1.4.3/inst/nrbderiv.m     2021-03-29 12:11:45.791919259 +0200
+++ new/nurbs-1.4.4/inst/nrbderiv.m     2025-02-10 14:35:08.000000000 +0100
@@ -429,8 +429,8 @@
 %! D2F(2,:) = -16*(12*x.^2-12*x+5)./w.^3;
 %! D2F(3,:) = -8*(16*x.^3+60*x.^2-48*x+21)./w.^3 .* (x<0.5) 
-8*(16*x.^3-36*x.^2+48*x-19)./w.^3 .* (x>0.5);
 %! assert (F, pnt, 1e3*eps)
-%! assert (DF, jac, 1e3*eps)
-%! assert (D2F, hess, 1e3*eps)
+%! assert (DF, jac{1}, 1e3*eps)
+%! assert (D2F, hess{1}, 1e3*eps)
 
 %!test
 %! knots = {[0 0 0 1 1 1], [0 0 0 0.5 1 1 1]};
@@ -668,8 +668,8 @@
 %! D2F(2,:) = -16*(12*x.^2-12*x+5)./w.^3;
 %! D2F(3,:) = -8*(16*x.^3+60*x.^2-48*x+21)./w.^3 .* (x<0.5) 
-8*(16*x.^3-36*x.^2+48*x-19)./w.^3 .* (x>0.5);
 %! assert (F, pnt, 1e3*eps)
-%! assert (DF, jac, 1e3*eps)
-%! assert (D2F, hess, 1e3*eps)
+%! assert (DF, jac{1}, 1e3*eps)
+%! assert (D2F, hess{1}, 1e3*eps)
 
 %!test
 %! knots = {[0 0 0 1 1 1], [0 0 0 0.5 1 1 1]};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/nrbdeval.m 
new/nurbs-1.4.4/inst/nrbdeval.m
--- old/nurbs-1.4.3/inst/nrbdeval.m     2021-03-29 12:11:45.791919259 +0200
+++ new/nurbs-1.4.4/inst/nrbdeval.m     2025-02-10 14:35:08.000000000 +0100
@@ -41,6 +41,7 @@
 % Copyright (C) 2010 Carlo de Falco
 % Copyright (C) 2010, 2011 Rafael Vazquez
 % Copyright (C) 2018 Luca Coradello
+% Copyright (C) 2023 Pablo Antolin
 %
 %    This program is free software: you can redistribute it and/or modify
 %    it under the terms of the GNU General Public License as published by
@@ -57,12 +58,18 @@
 
 if (nargin == 3)
   tt = varargin{1};
+  dnurbs2 = [];
+  dnurbs3 = [];
+  dnurbs4 = [];
 elseif (nargin == 4)
   dnurbs2 = varargin{1};
+  dnurbs3 = [];
+  dnurbs4 = [];
   tt = varargin{2};
 elseif (nargin == 5)
   dnurbs2 = varargin{1};
   dnurbs3 = varargin{2};       
+  dnurbs4 = [];
   tt = varargin{3}; 
 elseif (nargin == 6)
   dnurbs2 = varargin{1};
@@ -81,244 +88,564 @@
   error('Not a recognised NURBS representation');
 end
 
-[cp,cw] = nrbeval(nurbs, tt);
+max_der = 1;
 
-if (iscell(nurbs.knots))
-  if (size(nurbs.knots,2) == 3)
-  % NURBS structure represents a volume
-    temp = cw(ones(3,1),:,:,:);
-    pnt = cp./temp;
-  
-    [cup,cuw] = nrbeval (dnurbs{1}, tt);
-    tempu = cuw(ones(3,1),:,:,:);
-    jac{1} = (cup-tempu.*pnt)./temp;
-  
-    [cvp,cvw] = nrbeval (dnurbs{2}, tt);
-    tempv = cvw(ones(3,1),:,:,:);
-    jac{2} = (cvp-tempv.*pnt)./temp;
-
-    [cwp,cww] = nrbeval (dnurbs{3}, tt);
-    tempw = cww(ones(3,1),:,:,:);
-    jac{3} = (cwp-tempw.*pnt)./temp;
-
-% second derivatives
-    if (nargout >= 3)
-      if (exist ('dnurbs2'))
-        [cuup, cuuw] = nrbeval (dnurbs2{1,1}, tt);
-        tempuu = cuuw(ones(3,1),:,:,:);
-        hess{1,1} = (cuup - (2*cup.*tempu + cp.*tempuu)./temp + 
2*cp.*tempu.^2./temp.^2)./temp;
-        clear cuup cuuw tempuu
-
-        [cvvp, cvvw] = nrbeval (dnurbs2{2,2}, tt);
-        tempvv = cvvw(ones(3,1),:,:,:);
-        hess{2,2} = (cvvp - (2*cvp.*tempv + cp.*tempvv)./temp + 
2*cp.*tempv.^2./temp.^2)./temp;
-        clear cvvp cvvw tempvv
-
-        [cwwp, cwww] = nrbeval (dnurbs2{3,3}, tt);
-        tempww = cwww(ones(3,1),:,:,:);
-        hess{3,3} = (cwwp - (2*cwp.*tempw + cp.*tempww)./temp + 
2*cp.*tempw.^2./temp.^2)./temp;
-        clear cwwp cwww tempww
-
-        [cuvp, cuvw] = nrbeval (dnurbs2{1,2}, tt);
-        tempuv = cuvw(ones(3,1),:,:,:);
-        hess{1,2} = (cuvp - (cup.*tempv + cvp.*tempu + cp.*tempuv)./temp + 
2*cp.*tempu.*tempv./temp.^2)./temp;
-        hess{2,1} = hess{1,2};
-        clear cuvp cuvw tempuv
-
-        [cuwp, cuww] = nrbeval (dnurbs2{1,3}, tt);
-        tempuw = cuww(ones(3,1),:,:,:);
-        hess{1,3} = (cuwp - (cup.*tempw + cwp.*tempu + cp.*tempuw)./temp + 
2*cp.*tempu.*tempw./temp.^2)./temp;
-        hess{3,1} = hess{1,3};
-        clear cuwp cuww tempuw
-
-        [cvwp, cvww] = nrbeval (dnurbs2{2,3}, tt);
-        tempvw = cvww(ones(3,1),:,:,:);
-        hess{2,3} = (cvwp - (cvp.*tempw + cwp.*tempv + cp.*tempvw)./temp + 
2*cp.*tempv.*tempw./temp.^2)./temp;
-        hess{3,2} = hess{2,3};
-        clear cvwp cvww tempvw
-      else
-        warning ('nrbdeval: dnurbs2 missing. The second derivative is not 
computed');
-        hess = [];
-      end
-      if (nargout > 3)
-        warning ('nrbdeval: 3rd and 4th order derivatives not implemented for 
volumes');
-        third_der = [];
-        fourth_der = [];
-      end
-    end
+if (nargout >= 3)
+  if (isempty (dnurbs2))
+    warning ('nrbdeval: dnurbs4 missing. The second derivative is not 
computed');
+  else
+    max_der = 2;
+  end
+end
+
+if (nargout >= 4)
+  if (isempty (dnurbs3))
+    warning ('nrbdeval: dnurbs4 missing. The third derivative is not 
computed');
+  else
+    max_der = 3;
+  end
+end
+
+if (nargout >= 5)
+  if (isempty  (dnurbs4))
+    warning ('nrbdeval: dnurbs4 missing. The fourth derivative is not 
computed');
+  else
+    max_der = 4;
+  end
+end
+
+
+% The evaluation of the NURBS can be computed as
+% X = P / W, where P and W are the cp and cw just above, respectively.
+% Thus, its four first derivatives are computed as:
+%
+% Xi    = (Pi - X * Wi) / W
+%
+% Xij   = (Pij - Xi * Wj - Xj * Wi - X * Wij) / W
+%
+% Xijk  = (Pijk - Xij * Wk   - Xik * Wj -  Xjk * Wi
+%               - Xi  * Wjk  - Xj  * Wik - Xk  * Wij
+%               - X   * Wijk) / W
+%
+% Xijkl = (Pijkl - Xijk * Wl   - Xijl * Wk -   Xikl * Wj   - Xjkl * Wi
+%                - Xij  * Wkl  - Xik  * Wjl -  Xil  * Wjk  - Xjk  * Wil - Xjl 
* Wik - Xkl * Wij
+%                - Xi   * Wjkl - Xj   * Wikl - Xk   * Wijl - Xl   * Wijk
+%                - X    * Wijkl) / W
+%
+% where the subindices i,j,k,l mean partial derivatives respect to the i 
(j,k,l) coordinates, respectively.
+
+if (is_rational(nurbs))
+
+  if (iscell(nurbs.knots))
+    ndim = size(nurbs.knots,2);
+  else
+    ndim = 1;
+  end
+
+  if (ndim == 1)
+    [X, dX, d2X, d3X, d4X] = nrbdeval_crv_rational (nurbs, dnurbs, dnurbs2, 
dnurbs3, dnurbs4, tt, max_der);
+  elseif (ndim == 2)
+    [X, dX, d2X, d3X, d4X] = nrbdeval_srf_rational (nurbs, dnurbs, dnurbs2, 
dnurbs3, dnurbs4, tt, max_der);
+  else % if (ndim == 3)
+    [X, dX, d2X, d3X, d4X] = nrbdeval_vol_rational (nurbs, dnurbs, dnurbs2, 
dnurbs3, dnurbs4, tt, max_der);
+  end
+else
+  [X, dX, d2X, d3X, d4X] = nrbdeval_non_rational (nurbs, dnurbs, dnurbs2, 
dnurbs3, dnurbs4, tt, max_der);
+end
+
+varargout{1} = X;
+varargout{2} = dX;
+if (max_der >= 2)
+  varargout{3} = d2X;
+end
+if (max_der >= 3)
+  varargout{4} = d3X;
+end
+if (max_der == 4)
+  varargout{5} = d4X;
+end
 
-  elseif (size(nurbs.knots,2) == 2)
-  % NURBS structure represents a surface
-    temp = cw(ones(3,1),:,:);
-    pnt = cp./temp;
-  
-    [cup,cuw] = nrbeval (dnurbs{1}, tt);
-    tempu = cuw(ones(3,1),:,:);
-    jac{1} = (cup-tempu.*pnt)./temp;
-  
-    [cvp,cvw] = nrbeval (dnurbs{2}, tt);
-    tempv = cvw(ones(3,1),:,:);
-    jac{2} = (cvp-tempv.*pnt)./temp;
-
-% second derivatives
-    if (nargout >= 3) 
-      if (exist ('dnurbs2'))
-        [cuup, cuuw] = nrbeval (dnurbs2{1,1}, tt);
-        tempuu = cuuw(ones(3,1),:,:);
-        hess{1,1} = (cuup - (2*cup.*tempu + cp.*tempuu)./temp + 
2*cp.*tempu.^2./temp.^2)./temp;
-
-        [cvvp, cvvw] = nrbeval (dnurbs2{2,2}, tt);
-        tempvv = cvvw(ones(3,1),:,:);
-        hess{2,2} = (cvvp - (2*cvp.*tempv + cp.*tempvv)./temp + 
2*cp.*tempv.^2./temp.^2)./temp;
-
-        [cuvp, cuvw] = nrbeval (dnurbs2{1,2}, tt);
-        tempuv = cuvw(ones(3,1),:,:);
-        hess{1,2} = (cuvp - (cup.*tempv + cvp.*tempu + cp.*tempuv)./temp + 
2*cp.*tempu.*tempv./temp.^2)./temp;
-        hess{2,1} = hess{1,2};
-      else
-        warning ('nrbdeval: dnurbs2 missing. The second derivative is not 
computed');
-        hess = [];
-      end
-    end
-    if (nargout >= 4) 
-      if (exist ('dnurbs3'))
-        [cuuup, cuuuw] = nrbeval (dnurbs3{1,1,1}, tt);
-        tempuuu = cuuuw(ones(3,1),:,:);
-        third_der{1,1,1} = (cuuup - 3*jac{1}.*tempuu - cp.*tempuuu - 
3*hess{1,1}.*tempu)./temp;
-
-        [cvvvp, cvvvw] = nrbeval (dnurbs3{2,2,2}, tt);
-        tempvvv = cvvvw(ones(3,1),:,:);
-        third_der{2,2,2} = (cvvvp - 3*jac{2}.*tempvv - cp.*tempvvv - 
3*hess{2,2}.*tempv)./temp;
-        
-        [cuuvp, cuuvw] = nrbeval (dnurbs3{1,1,2}, tt);
-        tempuuv = cuuvw(ones(3,1),:,:);
-        third_der{1,1,2} = (cuuvp - 2*jac{1}.*tempuv - jac{2}.*tempuu - 
cp.*tempuuv - 2*hess{1,2}.*tempu - hess{1,1}.*tempv)./temp;
-        third_der{1,2,1} = third_der{1,1,2};
-        third_der{2,1,1} = third_der{1,1,2};
-  
-        [cuvvp, cuvvw] = nrbeval (dnurbs3{1,2,2}, tt);
-        tempuvv = cuvvw(ones(3,1),:,:);
-        third_der{1,2,2} = (cuvvp - 2*jac{2}.*tempuv - jac{1}.*tempvv - 
cp.*tempuvv - 2*hess{1,2}.*tempv - hess{2,2}.*tempu)./temp;
-        third_der{2,2,1} = third_der{1,2,2};
-        third_der{2,1,2} = third_der{1,2,2};
-        
-      else
-        warning ('nrbdeval: dnurbs3 missing. The third derivative is not 
computed');
-        third_der = [];
-      end
-    end
 
-    if (nargout == 5) 
-      if (exist ('dnurbs4'))
-        [cuuuup, cuuuuw] = nrbeval (dnurbs4{1,1,1,1}, tt);
-        tempuuuu = cuuuuw(ones(3,1),:,:);
-        fourth_der{1,1,1,1} = (cuuuup - cp.*tempuuuu - 4*jac{1}.*tempuuu 
-6*hess{1,1}.*tempuu - 4*third_der{1,1,1}.*tempu)./temp;
-
-        [cvvvvp, cvvvvw] = nrbeval (dnurbs4{2,2,2,2}, tt);
-        tempvvvv = cvvvvw(ones(3,1),:,:);
-        fourth_der{2,2,2,2} = (cvvvvp - cp.*tempvvvv - 4*jac{2}.*tempvvv 
-6*hess{2,2}.*tempvv - 4*third_der{2,2,2}.*tempv)./temp;
-
-        [cuuuvp, cuuuvw] = nrbeval (dnurbs4{1,1,1,2}, tt);
-        tempuuuv = cuuuvw(ones(3,1),:,:);
-        fourth_der{1,1,1,2} = (cuuuvp - cp.*tempuuuv - 3*jac{1}.*tempuuv - 
jac{2}.*tempuuu -3*hess{1,2}.*tempuu -3*hess{1,1}.*tempuv ...
-                                - third_der{1,1,1}.*tempv - 
3*third_der{1,1,2}.*tempu)./temp;
-                            
-        fourth_der{1,1,2,1} = fourth_der{1,1,1,2};
-        fourth_der{1,2,1,1} = fourth_der{1,1,1,2};
-        fourth_der{2,1,1,1} = fourth_der{1,1,1,2};
-
-        [cuvvvp, cuvvvw] = nrbeval (dnurbs4{1,2,2,2}, tt);
-        tempuvvv = cuvvvw(ones(3,1),:,:);
-        fourth_der{1,2,2,2} = (cuvvvp - cp.*tempuvvv - 3*jac{2}.*tempuvv - 
jac{1}.*tempvvv -3*hess{1,2}.*tempvv -3*hess{2,2}.*tempuv ...
-                                - third_der{2,2,2}.*tempu - 
3*third_der{1,2,2}.*tempv)./temp;
-                            
-        fourth_der{2,2,1,2} = fourth_der{1,2,2,2};
-        fourth_der{2,1,2,2} = fourth_der{1,2,2,2};
-        fourth_der{2,2,2,1} = fourth_der{1,2,2,2};
-
-        [cuuvvp, cuuvvw] = nrbeval (dnurbs4{1,1,2,2}, tt);
-        tempuuvv = cuuvvw(ones(3,1),:,:);
-        fourth_der{1,1,2,2} = (cuuvvp - cp.*tempuuvv - 2*jac{1}.*tempuvv - 
2*jac{2}.*tempuuv -hess{1,1}.*tempvv -hess{2,2}.*tempuu ...
-                                -4*hess{1,2}.*tempuv - 
2*third_der{1,1,2}.*tempv - 2*third_der{1,2,2}.*tempu)./temp;
-                            
-        fourth_der{1,2,2,1} = fourth_der{1,1,2,2};
-        fourth_der{2,2,1,1} = fourth_der{1,1,2,2};
-        fourth_der{1,2,1,2} = fourth_der{1,1,2,2};
-        fourth_der{2,1,2,1} = fourth_der{1,1,2,2};
-        fourth_der{2,1,1,2} = fourth_der{1,1,2,2};
-        
-        clear cuup cuuw tempuu cvvp cvvw tempvv cuvp cuvw tempuv
-        clear cuuup cuuuw tempuuu cvvvp cvvvw tempvvv cuuvp cuuvw tempuuv 
cuvvp cuvvw tempuvv
-        clear cuuuup cuuuuw tempuuuu cvvvvp cvvvvw tempvvvv cuuuvp cuuuvw 
tempuuuv cuuvvp cuuvvw tempuuvv cvvvup cvvvuw tempvvvu
-        
-      else
-        warning ('nrbdeval: dnurbs4 missing. The fourth derivative is not 
computed');
-        fourth_der = [];
+end
+
+function [X, dX, d2X, d3X, d4X] = nrbdeval_non_rational (nurbs, dnurbs, 
dnurbs2, dnurbs3, dnurbs4, tt, max_der)
+
+  if (iscell(nurbs.knots))
+    ndim = size(nurbs.knots,2);
+  else
+    ndim = 1;
+  end
+
+  [X, ~] = nrbeval(nurbs, tt);
+
+  if (~iscell(dnurbs))
+    dnurbs = {dnurbs};
+  end
+
+  for i = 1 : ndim
+    [dX{i}, ~] = nrbeval(dnurbs{i}, tt);
+  end
+
+  d2X = []; d3X = []; d4X = [];
+
+  if (max_der < 2)
+      return;
+  end
+
+  if (~iscell(dnurbs2))
+    dnurbs2 = {dnurbs2};
+  end
+
+  for i = 1 : ndim
+    for j = 1 : ndim
+      [d2X{i,j}, ~] = nrbeval(dnurbs2{i,j}, tt);
+   end
+  end
+
+  if (max_der < 3)
+      return;
+  end
+
+  if (~iscell(dnurbs3))
+    dnurbs3 = {dnurbs3};
+  end
+
+  for i = 1 : ndim
+    for j = 1 : ndim
+      for k = 1 : ndim
+        [d3X{i,j,k}, ~] = nrbeval(dnurbs3{i,j,k}, tt);
       end
     end
+  end
 
-    
+  if (max_der < 4)
+      return;
   end
-else
 
-  % NURBS is a curve
-  temp = cw(ones(3,1),:);
-  pnt = cp./temp;
-  
-  % first derivative
-  [cup,cuw] = nrbeval (dnurbs,tt);
-  temp1 = cuw(ones(3,1),:);
-  jac = (cup-temp1.*pnt)./temp;
-
-  % second derivative
-  if (nargout >= 3 && exist ('dnurbs2'))
-    [cuup,cuuw] = nrbeval (dnurbs2, tt);
-    temp2 = cuuw(ones(3,1),:);
-    hess = (cuup - (2*cup.*temp1 + cp.*temp2)./temp + 
2*cp.*temp1.^2./temp.^2)./temp; 
-    if (nargout >= 4 && exist ('dnurbs3')) 
-    
-      [cuuup, cuuuw] = nrbeval (dnurbs3, tt);
-      temp3 = cuuuw(ones(3,1),:);
-      third_der = (cuuup - 3*jac.*temp2 - cp.*temp3 - 3*hess.*temp1)./temp;
-      if (nargout >= 5 && exist ('dnurbs4')) 
-    
-        [cuuuup, cuuuuw] = nrbeval (dnurbs4, tt);
-        temp4 = cuuuuw(ones(3,1),:);
-        fourth_der = (cuuuup - cp.*temp4 - 4*jac.*temp3 -6*hess.*temp2 - 
4*third_der.*temp1)./temp;
-        if (iscell (tt))
-          fourth_der = {fourth_der};
-        end
+  if (~iscell(dnurbs4))
+    dnurbs4 = {dnurbs4};
+  end
 
+  for i = 1 : ndim
+    for j = 1 : ndim
+      for k = 1 : ndim
+        for l = 1 : ndim
+          [d4X{i,j,k,l}, ~] = nrbeval(dnurbs4{i,j,k,l}, tt);
+        end
       end
-      
-      if (iscell (tt))
-        third_der = {third_der};
-      end      
     end
-    
-    if (iscell (tt))
-      hess = {hess};
-    end    
-  end 
-  
-  if (iscell (tt))
-    jac = {jac};
   end
-  
 end
 
-varargout{1} = pnt;
-varargout{2} = jac;
-if (nargout >= 3)
-  varargout{3} = hess;
+
+
+function [X, dX, d2X, d3X, d4X] = nrbdeval_crv_rational (nurbs, dnurbs, 
dnurbs2, dnurbs3, dnurbs4, tt, max_der)
+
+[P, W] = nrbeval(nurbs, tt);
+W = W(ones(3,1), :, :, :);
+one_div_W = 1.0 ./ W;
+
+X = one_div_W .* P;
+
+clear P;
+
+
+[dP, dW] = nrbeval(dnurbs, tt);
+dW = dW(ones(3,1), :, :, :);
+
+dX{1} = one_div_W .* (dP - X .* dW);
+
+clear dP;
+
+d2X = []; d3X = []; d4X = [];
+
+if (max_der < 2)
+    return;
 end
-if (nargout >= 4)
-  varargout{4} = third_der;
+
+[d2P, d2W] = nrbeval(dnurbs2, tt);
+d2W = d2W(ones(3,1), :, :, :);
+
+d2X{1} = one_div_W .* (d2P - dX{1} .* dW - dX{1} .* dW - X .* d2W);
+
+if (max_der < 3)
+  return;
+end
+
+clear d2P;
+
+
+[d3P, d3W] = nrbeval(dnurbs3, tt);
+d3W = d3W(ones(3,1), :, :, :);
+
+d3X{1} = one_div_W .* (d3P - 3 * d2X{1} .* dW - 3 * dX{1} .* d2W - X .* d3W);
+
+
+if (max_der < 4)
+  return;
+end
+
+
+[d4P, d4W] = nrbeval(dnurbs4, tt);
+d4W = d4W(ones(3,1), :, :, :);
+
+d4X{1} = one_div_W .* (d4P - 4 * d3X{1} .* dW - 6 * d2X{1} .* d2W - 4 * dX{1} 
.* d3W - X .* d4W);
+
+
+end
+
+function [X, dX, d2X, d3X, d4X] = nrbdeval_srf_rational (nurbs, dnurbs, 
dnurbs2, dnurbs3, dnurbs4, tt, max_der)
+
+[P, W] = nrbeval(nurbs, tt);
+W = W(ones(3,1), :, :, :);
+one_div_W = 1.0 ./ W;
+
+X = one_div_W .* P;
+
+clear P;
+
+dP = cell(1, 2); dW = cell(1, 2);
+[dP{1}, dW{1}] = nrbeval(dnurbs{1}, tt);
+[dP{2}, dW{2}] = nrbeval(dnurbs{2}, tt);
+dW{1} = dW{1}(ones(3,1), :, :, :);
+dW{2} = dW{2}(ones(3,1), :, :, :);
+
+dX{1} = one_div_W .* (dP{1} - X .* dW{1});
+dX{2} = one_div_W .* (dP{2} - X .* dW{2});
+
+d2X = []; d3X = []; d4X = [];
+
+if (max_der < 2)
+    return;
+end
+
+clear dP;
+
+d2P = cell(2, 2); d2W = cell(2, 2);
+[d2P{1,1}, d2W{1,1}] = nrbeval(dnurbs2{1,1}, tt);
+[d2P{1,2}, d2W{1,2}] = nrbeval(dnurbs2{1,2}, tt);
+[d2P{2,2}, d2W{2,2}] = nrbeval(dnurbs2{2,2}, tt);
+d2W{1,1} = d2W{1,1}(ones(3,1), :, :, :);
+d2W{1,2} = d2W{1,2}(ones(3,1), :, :, :);
+d2W{2,2} = d2W{2,2}(ones(3,1), :, :, :);
+
+d2X{1, 1} = one_div_W .* (d2P{1, 1} - dX{1} .* dW{1} - dX{1} .* dW{1} - X .* 
d2W{1, 1});
+d2X{1, 2} = one_div_W .* (d2P{1, 2} - dX{1} .* dW{2} - dX{2} .* dW{1} - X .* 
d2W{1, 2});
+d2X{2, 2} = one_div_W .* (d2P{2, 2} - dX{2} .* dW{2} - dX{2} .* dW{2} - X .* 
d2W{2, 2});
+
+d2X{2, 1} = d2X{1, 2};
+
+if (max_der < 3)
+    return;
+end
+
+clear d2P;
+
+d3P = cell(2, 2, 2); d3W = cell(2, 2, 2);
+[d3P{1,1,1}, d3W{1,1,1}] = nrbeval(dnurbs3{1,1,1}, tt);
+[d3P{1,1,2}, d3W{1,1,2}] = nrbeval(dnurbs3{1,1,2}, tt);
+[d3P{1,2,2}, d3W{1,2,2}] = nrbeval(dnurbs3{1,2,2}, tt);
+[d3P{2,2,2}, d3W{2,2,2}] = nrbeval(dnurbs3{2,2,2}, tt);
+d3W{1,1,1} = d3W{1,1,1}(ones(3,1), :, :, :);
+d3W{1,1,2} = d3W{1,1,2}(ones(3,1), :, :, :);
+d3W{1,2,2} = d3W{1,2,2}(ones(3,1), :, :, :);
+d3W{2,2,2} = d3W{2,2,2}(ones(3,1), :, :, :);
+
+d3X{1, 1, 1} = one_div_W .* (d3P{1, 1, 1} - 3 * d2X{1, 1} .* dW{1} - 3 * dX{1} 
.* d2W{1, 1} - X .* d3W{1, 1, 1});
+d3X{1, 1, 2} = one_div_W .* (d3P{1, 1, 2} - d2X{1, 1} .* dW{2} - 2 * d2X{1, 2} 
.* dW{1} - 2 * dX{1} .* d2W{1, 2} - dX{2} .* d2W{1, 1} - X .* d3W{1, 1, 2});
+d3X{1, 2, 2} = one_div_W .* (d3P{1, 2, 2} - 2 * d2X{1, 2} .* dW{2} - d2X{2, 2} 
.* dW{1} - dX{1} .* d2W{2, 2} - 2 * dX{2} .* d2W{1, 2} - X .* d3W{1, 2, 2});
+d3X{2, 2, 2} = one_div_W .* (d3P{2, 2, 2} - 3 * d2X{2, 2} .* dW{2} - 3 * dX{2} 
.* d2W{2, 2} - X .* d3W{2, 2, 2});
+
+d3X{2, 1, 1} = d3X{1, 1, 2};
+d3X{1, 2, 1} = d3X{1, 1, 2};
+d3X{2, 2, 1} = d3X{1, 2, 2};
+d3X{2, 1, 2} = d3X{1, 2, 2};
+
+if (max_der < 4)
+    return;
 end
-if (nargout == 5)
-  varargout{5} = fourth_der;
+
+clear d3P;
+
+
+d4P = cell(2, 2, 2, 2); d4W = cell(2, 2, 2, 2);
+[d4P{1,1,1,1}, d4W{1,1,1,1}] = nrbeval(dnurbs4{1,1,1,1}, tt);
+[d4P{1,1,1,2}, d4W{1,1,1,2}] = nrbeval(dnurbs4{1,1,1,2}, tt);
+[d4P{1,1,2,2}, d4W{1,1,2,2}] = nrbeval(dnurbs4{1,1,2,2}, tt);
+[d4P{1,2,2,2}, d4W{1,2,2,2}] = nrbeval(dnurbs4{1,2,2,2}, tt);
+[d4P{2,2,2,2}, d4W{2,2,2,2}] = nrbeval(dnurbs4{2,2,2,2}, tt);
+d4W{1,1,1,1} = d4W{1,1,1,1}(ones(3,1), :, :, :);
+d4W{1,1,1,2} = d4W{1,1,1,2}(ones(3,1), :, :, :);
+d4W{1,1,2,2} = d4W{1,1,2,2}(ones(3,1), :, :, :);
+d4W{1,2,2,2} = d4W{1,2,2,2}(ones(3,1), :, :, :);
+d4W{2,2,2,2} = d4W{2,2,2,2}(ones(3,1), :, :, :);
+
+d4X{1, 1, 1, 1} = one_div_W .* (d4P{1, 1, 1, 1} - 4 * d3X{1, 1, 1} .* dW{1} - 
6 * d2X{1, 1} .* d2W{1, 1} - 4 * dX{1} .* d3W{1, 1, 1} - X .* d4W{1, 1, 1, 1});
+d4X{1, 1, 1, 2} = one_div_W .* (d4P{1, 1, 1, 2} - d3X{1, 1, 1} .* dW{2} - 3 * 
d3X{1, 1, 2} .* dW{1} - 3 * d2X{1, 1} .* d2W{1, 2} - 3 * d2X{1, 2} .* d2W{1, 1} 
- 3 * dX{1} .* d3W{1, 1, 2} - dX{2} .* d3W{1, 1, 1} - X .* d4W{1, 1, 1, 2});
+d4X{1, 1, 2, 2} = one_div_W .* (d4P{1, 1, 2, 2} - 2 * d3X{1, 1, 2} .* dW{2} - 
2 * d3X{1, 2, 2} .* dW{1} - d2X{1, 1} .* d2W{2, 2} - 4 * d2X{1, 2} .* d2W{1, 2} 
- d2X{2, 2} .* d2W{1, 1} - 2 * dX{1} .* d3W{1, 2, 2} - 2 * dX{2} .* d3W{1, 1, 
2} - X .* d4W{1, 1, 2, 2});
+d4X{1, 2, 2, 2} = one_div_W .* (d4P{1, 2, 2, 2} - 3 * d3X{1, 2, 2} .* dW{2} - 
d3X{2, 2, 2} .* dW{1} - 3 * d2X{1, 2} .* d2W{2, 2} - 3 * d2X{2, 2} .* d2W{1, 2} 
- dX{1} .* d3W{2, 2, 2} - 3 * dX{2} .* d3W{1, 2, 2} - X .* d4W{1, 2, 2, 2});
+d4X{2, 2, 2, 2} = one_div_W .* (d4P{2, 2, 2, 2} - 4 * d3X{2, 2, 2} .* dW{2} - 
6 * d2X{2, 2} .* d2W{2, 2} - 4 * dX{2} .* d3W{2, 2, 2} - X .* d4W{2, 2, 2, 2});
+
+d4X{2, 1, 1, 1} = d4X{1, 1, 1, 2};
+d4X{1, 2, 1, 1} = d4X{1, 1, 1, 2};
+d4X{2, 2, 1, 1} = d4X{1, 1, 2, 2};
+d4X{1, 1, 2, 1} = d4X{1, 1, 1, 2};
+d4X{2, 1, 2, 1} = d4X{1, 1, 2, 2};
+d4X{1, 2, 2, 1} = d4X{1, 1, 2, 2};
+d4X{2, 2, 2, 1} = d4X{1, 2, 2, 2};
+d4X{2, 1, 1, 2} = d4X{1, 1, 2, 2};
+d4X{1, 2, 1, 2} = d4X{1, 1, 2, 2};
+d4X{2, 2, 1, 2} = d4X{1, 2, 2, 2};
+d4X{2, 1, 2, 2} = d4X{1, 2, 2, 2};
+
+end
+
+function [X, dX, d2X, d3X, d4X] = nrbdeval_vol_rational (nurbs, dnurbs, 
dnurbs2, dnurbs3, dnurbs4, tt, max_der)
+
+[P, W] = nrbeval(nurbs, tt);
+W = W(ones(3,1), :, :, :);
+one_div_W = 1.0 ./ W;
+
+X = one_div_W .* P;
+
+
+dP = cell(1, 3); dW = cell(1, 3);
+[dP{1}, dW{1}] = nrbeval(dnurbs{1}, tt);
+[dP{2}, dW{2}] = nrbeval(dnurbs{2}, tt);
+[dP{3}, dW{3}] = nrbeval(dnurbs{3}, tt);
+dW{1} = dW{1}(ones(3,1), :, :, :);
+dW{2} = dW{2}(ones(3,1), :, :, :);
+dW{3} = dW{3}(ones(3,1), :, :, :);
+
+dX{1} = one_div_W .* (dP{1} - X .* dW{1});
+dX{2} = one_div_W .* (dP{2} - X .* dW{2});
+dX{3} = one_div_W .* (dP{3} - X .* dW{3});
+
+
+d2X = []; d3X = []; d4X = [];
+
+if (max_der < 2)
+    return;
 end
 
+clear dP;
+
+d2P = cell(3, 3); d2W = cell(3, 3);
+[d2P{1,1}, d2W{1,1}] = nrbeval(dnurbs2{1,1}, tt);
+[d2P{1,2}, d2W{1,2}] = nrbeval(dnurbs2{1,2}, tt);
+[d2P{1,3}, d2W{1,3}] = nrbeval(dnurbs2{1,3}, tt);
+[d2P{2,2}, d2W{2,2}] = nrbeval(dnurbs2{2,2}, tt);
+[d2P{2,3}, d2W{2,3}] = nrbeval(dnurbs2{2,3}, tt);
+[d2P{3,3}, d2W{3,3}] = nrbeval(dnurbs2{3,3}, tt);
+d2W{1,1} = d2W{1,1}(ones(3,1), :, :, :);
+d2W{1,2} = d2W{1,2}(ones(3,1), :, :, :);
+d2W{1,3} = d2W{1,3}(ones(3,1), :, :, :);
+d2W{2,2} = d2W{2,2}(ones(3,1), :, :, :);
+d2W{2,3} = d2W{2,3}(ones(3,1), :, :, :);
+d2W{3,3} = d2W{3,3}(ones(3,1), :, :, :);
+
+d2X{1, 1} = one_div_W .* (d2P{1, 1} - dX{1} .* dW{1} - dX{1} .* dW{1} - X .* 
d2W{1, 1});
+d2X{1, 2} = one_div_W .* (d2P{1, 2} - dX{1} .* dW{2} - dX{2} .* dW{1} - X .* 
d2W{1, 2});
+d2X{1, 3} = one_div_W .* (d2P{1, 3} - dX{1} .* dW{3} - dX{3} .* dW{1} - X .* 
d2W{1, 3});
+d2X{2, 2} = one_div_W .* (d2P{2, 2} - dX{2} .* dW{2} - dX{2} .* dW{2} - X .* 
d2W{2, 2});
+d2X{2, 3} = one_div_W .* (d2P{2, 3} - dX{2} .* dW{3} - dX{3} .* dW{2} - X .* 
d2W{2, 3});
+d2X{3, 3} = one_div_W .* (d2P{3, 3} - dX{3} .* dW{3} - dX{3} .* dW{3} - X .* 
d2W{3, 3});
+
+d2X{2, 1} = d2X{1, 2};
+d2X{3, 1} = d2X{1, 3};
+d2X{3, 2} = d2X{2, 3};
+
+if (max_der < 3)
+    return;
+end
+
+clear d2P;
+
+
+d3P = cell(3, 3, 3); d3W = cell(3, 3, 3);
+[d3P{1,1,1}, d3W{1,1,1}] = nrbeval(dnurbs3{1,1,1}, tt);
+[d3P{1,1,2}, d3W{1,1,2}] = nrbeval(dnurbs3{1,1,2}, tt);
+[d3P{1,1,3}, d3W{1,1,3}] = nrbeval(dnurbs3{1,1,3}, tt);
+[d3P{1,2,2}, d3W{1,2,2}] = nrbeval(dnurbs3{1,2,2}, tt);
+[d3P{1,2,3}, d3W{1,2,3}] = nrbeval(dnurbs3{1,2,3}, tt);
+[d3P{1,3,3}, d3W{1,3,3}] = nrbeval(dnurbs3{1,3,3}, tt);
+[d3P{2,2,2}, d3W{2,2,2}] = nrbeval(dnurbs3{2,2,2}, tt);
+[d3P{2,2,3}, d3W{2,2,3}] = nrbeval(dnurbs3{2,2,3}, tt);
+[d3P{2,3,3}, d3W{2,3,3}] = nrbeval(dnurbs3{2,3,3}, tt);
+[d3P{3,3,3}, d3W{3,3,3}] = nrbeval(dnurbs3{3,3,3}, tt);
+d3W{1,1,1} = d3W{1,1,1}(ones(3,1), :, :, :);
+d3W{1,1,2} = d3W{1,1,2}(ones(3,1), :, :, :);
+d3W{1,1,3} = d3W{1,1,3}(ones(3,1), :, :, :);
+d3W{1,2,2} = d3W{1,2,2}(ones(3,1), :, :, :);
+d3W{1,2,3} = d3W{1,2,3}(ones(3,1), :, :, :);
+d3W{1,3,3} = d3W{1,3,3}(ones(3,1), :, :, :);
+d3W{2,2,2} = d3W{2,2,2}(ones(3,1), :, :, :);
+d3W{2,2,3} = d3W{2,2,3}(ones(3,1), :, :, :);
+d3W{2,3,3} = d3W{2,3,3}(ones(3,1), :, :, :);
+d3W{3,3,3} = d3W{3,3,3}(ones(3,1), :, :, :);
+
+d3X{1, 1, 1} = one_div_W .* (d3P{1, 1, 1} - 3 * d2X{1, 1} .* dW{1} - 3 * dX{1} 
.* d2W{1, 1} - X .* d3W{1, 1, 1});
+d3X{1, 1, 2} = one_div_W .* (d3P{1, 1, 2} - d2X{1, 1} .* dW{2} - 2 * d2X{1, 2} 
.* dW{1} - 2 * dX{1} .* d2W{1, 2} - dX{2} .* d2W{1, 1} - X .* d3W{1, 1, 2});
+d3X{1, 1, 3} = one_div_W .* (d3P{1, 1, 3} - d2X{1, 1} .* dW{3} - 2 * d2X{1, 3} 
.* dW{1} - 2 * dX{1} .* d2W{1, 3} - dX{3} .* d2W{1, 1} - X .* d3W{1, 1, 3});
+d3X{1, 2, 2} = one_div_W .* (d3P{1, 2, 2} - 2 * d2X{1, 2} .* dW{2} - d2X{2, 2} 
.* dW{1} - dX{1} .* d2W{2, 2} - 2 * dX{2} .* d2W{1, 2} - X .* d3W{1, 2, 2});
+d3X{1, 2, 3} = one_div_W .* (d3P{1, 2, 3} - d2X{1, 2} .* dW{3} - d2X{1, 3} .* 
dW{2} - d2X{2, 3} .* dW{1} - dX{1} .* d2W{2, 3} - dX{2} .* d2W{1, 3} - dX{3} .* 
d2W{1, 2} - X .* d3W{1, 2, 3});
+d3X{1, 3, 3} = one_div_W .* (d3P{1, 3, 3} - 2 * d2X{1, 3} .* dW{3} - d2X{3, 3} 
.* dW{1} - dX{1} .* d2W{3, 3} - 2 * dX{3} .* d2W{1, 3} - X .* d3W{1, 3, 3});
+d3X{2, 2, 2} = one_div_W .* (d3P{2, 2, 2} - 3 * d2X{2, 2} .* dW{2} - 3 * dX{2} 
.* d2W{2, 2} - X .* d3W{2, 2, 2});
+d3X{2, 2, 3} = one_div_W .* (d3P{2, 2, 3} - d2X{2, 2} .* dW{3} - 2 * d2X{2, 3} 
.* dW{2} - 2 * dX{2} .* d2W{2, 3} - dX{3} .* d2W{2, 2} - X .* d3W{2, 2, 3});
+d3X{2, 3, 3} = one_div_W .* (d3P{2, 3, 3} - 2 * d2X{2, 3} .* dW{3} - d2X{3, 3} 
.* dW{2} - dX{2} .* d2W{3, 3} - 2 * dX{3} .* d2W{2, 3} - X .* d3W{2, 3, 3});
+d3X{3, 3, 3} = one_div_W .* (d3P{3, 3, 3} - 3 * d2X{3, 3} .* dW{3} - 3 * dX{3} 
.* d2W{3, 3} - X .* d3W{3, 3, 3});
+
+d3X{2, 1, 1} = d3X{1, 1, 2};
+d3X{3, 1, 1} = d3X{1, 1, 3};
+d3X{1, 2, 1} = d3X{1, 1, 2};
+d3X{2, 2, 1} = d3X{1, 2, 2};
+d3X{3, 2, 1} = d3X{1, 2, 3};
+d3X{1, 3, 1} = d3X{1, 1, 3};
+d3X{2, 3, 1} = d3X{1, 2, 3};
+d3X{3, 3, 1} = d3X{1, 3, 3};
+d3X{2, 1, 2} = d3X{1, 2, 2};
+d3X{3, 1, 2} = d3X{1, 2, 3};
+d3X{3, 2, 2} = d3X{2, 2, 3};
+d3X{1, 3, 2} = d3X{1, 2, 3};
+d3X{2, 3, 2} = d3X{2, 2, 3};
+d3X{3, 3, 2} = d3X{2, 3, 3};
+d3X{2, 1, 3} = d3X{1, 2, 3};
+d3X{3, 1, 3} = d3X{1, 3, 3};
+d3X{3, 2, 3} = d3X{2, 3, 3};
+
+if (max_der < 4)
+    return;
+end
+
+
+clear d3P;
+
+
+d4P = cell(3, 3, 3, 3); d4W = cell(3, 3, 3, 3);
+[d4P{1,1,1,1}, d4W{1,1,1,1}] = nrbeval(dnurbs4{1,1,1,1}, tt);
+[d4P{1,1,1,2}, d4W{1,1,1,2}] = nrbeval(dnurbs4{1,1,1,2}, tt);
+[d4P{1,1,1,3}, d4W{1,1,1,3}] = nrbeval(dnurbs4{1,1,1,3}, tt);
+[d4P{1,1,2,2}, d4W{1,1,2,2}] = nrbeval(dnurbs4{1,1,2,2}, tt);
+[d4P{1,1,2,3}, d4W{1,1,2,3}] = nrbeval(dnurbs4{1,1,2,3}, tt);
+[d4P{1,1,3,3}, d4W{1,1,3,3}] = nrbeval(dnurbs4{1,1,3,3}, tt);
+[d4P{1,2,2,2}, d4W{1,2,2,2}] = nrbeval(dnurbs4{1,2,2,2}, tt);
+[d4P{1,2,2,3}, d4W{1,2,2,3}] = nrbeval(dnurbs4{1,2,2,3}, tt);
+[d4P{1,2,3,3}, d4W{1,2,3,3}] = nrbeval(dnurbs4{1,2,3,3}, tt);
+[d4P{1,3,3,3}, d4W{1,3,3,3}] = nrbeval(dnurbs4{1,3,3,3}, tt);
+[d4P{2,2,2,2}, d4W{2,2,2,2}] = nrbeval(dnurbs4{2,2,2,2}, tt);
+[d4P{2,2,2,3}, d4W{2,2,2,3}] = nrbeval(dnurbs4{2,2,2,3}, tt);
+[d4P{2,2,3,3}, d4W{2,2,3,3}] = nrbeval(dnurbs4{2,2,3,3}, tt);
+[d4P{2,3,3,3}, d4W{2,3,3,3}] = nrbeval(dnurbs4{2,3,3,3}, tt);
+[d4P{3,3,3,3}, d4W{3,3,3,3}] = nrbeval(dnurbs4{3,3,3,3}, tt);
+d4W{1,1,1,1} = d4W{1,1,1,1}(ones(3,1), :, :, :);
+d4W{1,1,1,2} = d4W{1,1,1,2}(ones(3,1), :, :, :);
+d4W{1,1,1,3} = d4W{1,1,1,3}(ones(3,1), :, :, :);
+d4W{1,1,2,2} = d4W{1,1,2,2}(ones(3,1), :, :, :);
+d4W{1,1,2,3} = d4W{1,1,2,3}(ones(3,1), :, :, :);
+d4W{1,1,3,3} = d4W{1,1,3,3}(ones(3,1), :, :, :);
+d4W{1,2,2,2} = d4W{1,2,2,2}(ones(3,1), :, :, :);
+d4W{1,2,2,3} = d4W{1,2,2,3}(ones(3,1), :, :, :);
+d4W{1,2,3,3} = d4W{1,2,3,3}(ones(3,1), :, :, :);
+d4W{1,3,3,3} = d4W{1,3,3,3}(ones(3,1), :, :, :);
+d4W{2,2,2,2} = d4W{2,2,2,2}(ones(3,1), :, :, :);
+d4W{2,2,2,3} = d4W{2,2,2,3}(ones(3,1), :, :, :);
+d4W{2,2,3,3} = d4W{2,2,3,3}(ones(3,1), :, :, :);
+d4W{2,3,3,3} = d4W{2,3,3,3}(ones(3,1), :, :, :);
+d4W{3,3,3,3} = d4W{3,3,3,3}(ones(3,1), :, :, :);
+
+d4X{1, 1, 1, 1} = one_div_W .* (d4P{1, 1, 1, 1} - 4 * d3X{1, 1, 1} .* dW{1} - 
6 * d2X{1, 1} .* d2W{1, 1} - 4 * dX{1} .* d3W{1, 1, 1} - X .* d4W{1, 1, 1, 1});
+d4X{1, 1, 1, 2} = one_div_W .* (d4P{1, 1, 1, 2} - d3X{1, 1, 1} .* dW{2} - 3 * 
d3X{1, 1, 2} .* dW{1} - 3 * d2X{1, 1} .* d2W{1, 2} - 3 * d2X{1, 2} .* d2W{1, 1} 
- 3 * dX{1} .* d3W{1, 1, 2} - dX{2} .* d3W{1, 1, 1} - X .* d4W{1, 1, 1, 2});
+d4X{1, 1, 1, 3} = one_div_W .* (d4P{1, 1, 1, 3} - d3X{1, 1, 1} .* dW{3} - 3 * 
d3X{1, 1, 3} .* dW{1} - 3 * d2X{1, 1} .* d2W{1, 3} - 3 * d2X{1, 3} .* d2W{1, 1} 
- 3 * dX{1} .* d3W{1, 1, 3} - dX{3} .* d3W{1, 1, 1} - X .* d4W{1, 1, 1, 3});
+d4X{1, 1, 2, 2} = one_div_W .* (d4P{1, 1, 2, 2} - 2 * d3X{1, 1, 2} .* dW{2} - 
2 * d3X{1, 2, 2} .* dW{1} - d2X{1, 1} .* d2W{2, 2} - 4 * d2X{1, 2} .* d2W{1, 2} 
- d2X{2, 2} .* d2W{1, 1} - 2 * dX{1} .* d3W{1, 2, 2} - 2 * dX{2} .* d3W{1, 1, 
2} - X .* d4W{1, 1, 2, 2});
+d4X{1, 1, 2, 3} = one_div_W .* (d4P{1, 1, 2, 3} - d3X{1, 1, 2} .* dW{3} - 
d3X{1, 1, 3} .* dW{2} - 2 * d3X{1, 2, 3} .* dW{1} - d2X{1, 1} .* d2W{2, 3} - 2 
* d2X{1, 2} .* d2W{1, 3} - 2 * d2X{1, 3} .* d2W{1, 2} - d2X{2, 3} .* d2W{1, 1} 
- 2 * dX{1} .* d3W{1, 2, 3} - dX{2} .* d3W{1, 1, 3} - dX{3} .* d3W{1, 1, 2} - X 
.* d4W{1, 1, 2, 3});
+d4X{1, 1, 3, 3} = one_div_W .* (d4P{1, 1, 3, 3} - 2 * d3X{1, 1, 3} .* dW{3} - 
2 * d3X{1, 3, 3} .* dW{1} - d2X{1, 1} .* d2W{3, 3} - 4 * d2X{1, 3} .* d2W{1, 3} 
- d2X{3, 3} .* d2W{1, 1} - 2 * dX{1} .* d3W{1, 3, 3} - 2 * dX{3} .* d3W{1, 1, 
3} - X .* d4W{1, 1, 3, 3});
+d4X{1, 2, 2, 2} = one_div_W .* (d4P{1, 2, 2, 2} - 3 * d3X{1, 2, 2} .* dW{2} - 
d3X{2, 2, 2} .* dW{1} - 3 * d2X{1, 2} .* d2W{2, 2} - 3 * d2X{2, 2} .* d2W{1, 2} 
- dX{1} .* d3W{2, 2, 2} - 3 * dX{2} .* d3W{1, 2, 2} - X .* d4W{1, 2, 2, 2});
+d4X{1, 2, 2, 3} = one_div_W .* (d4P{1, 2, 2, 3} - d3X{1, 2, 2} .* dW{3} - 2 * 
d3X{1, 2, 3} .* dW{2} - d3X{2, 2, 3} .* dW{1} - 2 * d2X{1, 2} .* d2W{2, 3} - 
d2X{1, 3} .* d2W{2, 2} - d2X{2, 2} .* d2W{1, 3} - 2 * d2X{2, 3} .* d2W{1, 2} - 
dX{1} .* d3W{2, 2, 3} - 2 * dX{2} .* d3W{1, 2, 3} - dX{3} .* d3W{1, 2, 2} - X 
.* d4W{1, 2, 2, 3});
+d4X{1, 2, 3, 3} = one_div_W .* (d4P{1, 2, 3, 3} - 2 * d3X{1, 2, 3} .* dW{3} - 
d3X{1, 3, 3} .* dW{2} - d3X{2, 3, 3} .* dW{1} - d2X{1, 2} .* d2W{3, 3} - 2 * 
d2X{1, 3} .* d2W{2, 3} - 2 * d2X{2, 3} .* d2W{1, 3} - d2X{3, 3} .* d2W{1, 2} - 
dX{1} .* d3W{2, 3, 3} - dX{2} .* d3W{1, 3, 3} - 2 * dX{3} .* d3W{1, 2, 3} - X 
.* d4W{1, 2, 3, 3});
+d4X{1, 3, 3, 3} = one_div_W .* (d4P{1, 3, 3, 3} - 3 * d3X{1, 3, 3} .* dW{3} - 
d3X{3, 3, 3} .* dW{1} - 3 * d2X{1, 3} .* d2W{3, 3} - 3 * d2X{3, 3} .* d2W{1, 3} 
- dX{1} .* d3W{3, 3, 3} - 3 * dX{3} .* d3W{1, 3, 3} - X .* d4W{1, 3, 3, 3});
+d4X{2, 2, 2, 2} = one_div_W .* (d4P{2, 2, 2, 2} - 4 * d3X{2, 2, 2} .* dW{2} - 
6 * d2X{2, 2} .* d2W{2, 2} - 4 * dX{2} .* d3W{2, 2, 2} - X .* d4W{2, 2, 2, 2});
+d4X{2, 2, 2, 3} = one_div_W .* (d4P{2, 2, 2, 3} - d3X{2, 2, 2} .* dW{3} - 3 * 
d3X{2, 2, 3} .* dW{2} - 3 * d2X{2, 2} .* d2W{2, 3} - 3 * d2X{2, 3} .* d2W{2, 2} 
- 3 * dX{2} .* d3W{2, 2, 3} - dX{3} .* d3W{2, 2, 2} - X .* d4W{2, 2, 2, 3});
+d4X{2, 2, 3, 3} = one_div_W .* (d4P{2, 2, 3, 3} - 2 * d3X{2, 2, 3} .* dW{3} - 
2 * d3X{2, 3, 3} .* dW{2} - d2X{2, 2} .* d2W{3, 3} - 4 * d2X{2, 3} .* d2W{2, 3} 
- d2X{3, 3} .* d2W{2, 2} - 2 * dX{2} .* d3W{2, 3, 3} - 2 * dX{3} .* d3W{2, 2, 
3} - X .* d4W{2, 2, 3, 3});
+d4X{2, 3, 3, 3} = one_div_W .* (d4P{2, 3, 3, 3} - 3 * d3X{2, 3, 3} .* dW{3} - 
d3X{3, 3, 3} .* dW{2} - 3 * d2X{2, 3} .* d2W{3, 3} - 3 * d2X{3, 3} .* d2W{2, 3} 
- dX{2} .* d3W{3, 3, 3} - 3 * dX{3} .* d3W{2, 3, 3} - X .* d4W{2, 3, 3, 3});
+d4X{3, 3, 3, 3} = one_div_W .* (d4P{3, 3, 3, 3} - 4 * d3X{3, 3, 3} .* dW{3} - 
6 * d2X{3, 3} .* d2W{3, 3} - 4 * dX{3} .* d3W{3, 3, 3} - X .* d4W{3, 3, 3, 3});
+
+d4X{2, 1, 1, 1} = d4X{1, 1, 1, 2};
+d4X{3, 1, 1, 1} = d4X{1, 1, 1, 3};
+d4X{1, 2, 1, 1} = d4X{1, 1, 1, 2};
+d4X{2, 2, 1, 1} = d4X{1, 1, 2, 2};
+d4X{3, 2, 1, 1} = d4X{1, 1, 2, 3};
+d4X{1, 3, 1, 1} = d4X{1, 1, 1, 3};
+d4X{2, 3, 1, 1} = d4X{1, 1, 2, 3};
+d4X{3, 3, 1, 1} = d4X{1, 1, 3, 3};
+d4X{1, 1, 2, 1} = d4X{1, 1, 1, 2};
+d4X{2, 1, 2, 1} = d4X{1, 1, 2, 2};
+d4X{3, 1, 2, 1} = d4X{1, 1, 2, 3};
+d4X{1, 2, 2, 1} = d4X{1, 1, 2, 2};
+d4X{2, 2, 2, 1} = d4X{1, 2, 2, 2};
+d4X{3, 2, 2, 1} = d4X{1, 2, 2, 3};
+d4X{1, 3, 2, 1} = d4X{1, 1, 2, 3};
+d4X{2, 3, 2, 1} = d4X{1, 2, 2, 3};
+d4X{3, 3, 2, 1} = d4X{1, 2, 3, 3};
+d4X{1, 1, 3, 1} = d4X{1, 1, 1, 3};
+d4X{2, 1, 3, 1} = d4X{1, 1, 2, 3};
+d4X{3, 1, 3, 1} = d4X{1, 1, 3, 3};
+d4X{1, 2, 3, 1} = d4X{1, 1, 2, 3};
+d4X{2, 2, 3, 1} = d4X{1, 2, 2, 3};
+d4X{3, 2, 3, 1} = d4X{1, 2, 3, 3};
+d4X{1, 3, 3, 1} = d4X{1, 1, 3, 3};
+d4X{2, 3, 3, 1} = d4X{1, 2, 3, 3};
+d4X{3, 3, 3, 1} = d4X{1, 3, 3, 3};
+d4X{2, 1, 1, 2} = d4X{1, 1, 2, 2};
+d4X{3, 1, 1, 2} = d4X{1, 1, 2, 3};
+d4X{1, 2, 1, 2} = d4X{1, 1, 2, 2};
+d4X{2, 2, 1, 2} = d4X{1, 2, 2, 2};
+d4X{3, 2, 1, 2} = d4X{1, 2, 2, 3};
+d4X{1, 3, 1, 2} = d4X{1, 1, 2, 3};
+d4X{2, 3, 1, 2} = d4X{1, 2, 2, 3};
+d4X{3, 3, 1, 2} = d4X{1, 2, 3, 3};
+d4X{2, 1, 2, 2} = d4X{1, 2, 2, 2};
+d4X{3, 1, 2, 2} = d4X{1, 2, 2, 3};
+d4X{3, 2, 2, 2} = d4X{2, 2, 2, 3};
+d4X{1, 3, 2, 2} = d4X{1, 2, 2, 3};
+d4X{2, 3, 2, 2} = d4X{2, 2, 2, 3};
+d4X{3, 3, 2, 2} = d4X{2, 2, 3, 3};
+d4X{1, 1, 3, 2} = d4X{1, 1, 2, 3};
+d4X{2, 1, 3, 2} = d4X{1, 2, 2, 3};
+d4X{3, 1, 3, 2} = d4X{1, 2, 3, 3};
+d4X{1, 2, 3, 2} = d4X{1, 2, 2, 3};
+d4X{2, 2, 3, 2} = d4X{2, 2, 2, 3};
+d4X{3, 2, 3, 2} = d4X{2, 2, 3, 3};
+d4X{1, 3, 3, 2} = d4X{1, 2, 3, 3};
+d4X{2, 3, 3, 2} = d4X{2, 2, 3, 3};
+d4X{3, 3, 3, 2} = d4X{2, 3, 3, 3};
+d4X{2, 1, 1, 3} = d4X{1, 1, 2, 3};
+d4X{3, 1, 1, 3} = d4X{1, 1, 3, 3};
+d4X{1, 2, 1, 3} = d4X{1, 1, 2, 3};
+d4X{2, 2, 1, 3} = d4X{1, 2, 2, 3};
+d4X{3, 2, 1, 3} = d4X{1, 2, 3, 3};
+d4X{1, 3, 1, 3} = d4X{1, 1, 3, 3};
+d4X{2, 3, 1, 3} = d4X{1, 2, 3, 3};
+d4X{3, 3, 1, 3} = d4X{1, 3, 3, 3};
+d4X{2, 1, 2, 3} = d4X{1, 2, 2, 3};
+d4X{3, 1, 2, 3} = d4X{1, 2, 3, 3};
+d4X{3, 2, 2, 3} = d4X{2, 2, 3, 3};
+d4X{1, 3, 2, 3} = d4X{1, 2, 3, 3};
+d4X{2, 3, 2, 3} = d4X{2, 2, 3, 3};
+d4X{3, 3, 2, 3} = d4X{2, 3, 3, 3};
+d4X{2, 1, 3, 3} = d4X{1, 2, 3, 3};
+d4X{3, 1, 3, 3} = d4X{1, 3, 3, 3};
+d4X{3, 2, 3, 3} = d4X{2, 3, 3, 3};
+
+
+end
+
+function rational = is_rational(nurbs)
+if (size(nurbs.coefs, 1) < 4)
+    rational = false;
+else
+    tolerance = 1.0e-15;
+    rational = any(abs(nurbs.coefs(4, :) - 1) > tolerance);
+end
 end
 
 %!demo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/nrbinverse.m 
new/nurbs-1.4.4/inst/nrbinverse.m
--- old/nurbs-1.4.3/inst/nrbinverse.m   2021-03-29 12:11:45.795919320 +0200
+++ new/nurbs-1.4.4/inst/nrbinverse.m   2025-02-10 14:35:08.000000000 +0100
@@ -59,7 +59,7 @@
   % Default options
   options = struct ('u0'      , .5*ones (ndim, 1), ...
                     'MaxIter' , 10, ...
-                    'Display' , true, ...
+                    'Display' , false, ...
                     'TolX',     1e-8, ...
                     'TolFun',   1e-8);
 
@@ -85,8 +85,9 @@
   x = x(:);
   
   % Define functions for Newton iteration
+  ders = nrbderiv (nrb);
   f = @(U) nrbeval (nrb, num2cell (U)) - x;
-  jac = @(U) nrbjacobian (nrb, num2cell (U));
+  jac = @(U) nrbjacobian (nrb, ders, num2cell (U));
   
   % Newton cycle
   u_old = options.u0(:);
@@ -128,9 +129,9 @@
 
 end
 
-function jac = nrbjacobian (nrb, u)
+function jac = nrbjacobian (nrb, ders, u)
 
-  ders = nrbderiv (nrb);
+%   ders = nrbderiv (nrb);
   [~, jac] = nrbdeval (nrb, ders, u);
   jac = [jac{:}];  
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/inst/nrbmeasure.m 
new/nurbs-1.4.4/inst/nrbmeasure.m
--- old/nurbs-1.4.3/inst/nrbmeasure.m   2021-03-29 12:11:45.795919320 +0200
+++ new/nurbs-1.4.4/inst/nrbmeasure.m   2025-02-10 14:35:08.000000000 +0100
@@ -84,9 +84,9 @@
 
 function l = len (u, nrb, ders)
   [~, d] = nrbdeval (nrb, ders, u);
-  f = d(1, :);
-  g = d(2, :);
-  h = d(3, :);
+  f = d{1}(1, :);
+  g = d{1}(2, :);
+  h = d{1}(3, :);
   l = sqrt (f.^2 + g.^2 + h.^2);
 end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/src/low_level_functions.cc 
new/nurbs-1.4.4/src/low_level_functions.cc
--- old/nurbs-1.4.3/src/low_level_functions.cc  2021-03-29 12:11:45.811919565 
+0200
+++ new/nurbs-1.4.4/src/low_level_functions.cc  2025-02-10 14:35:08.000000000 
+0100
@@ -17,6 +17,8 @@
 */
 
 
+#include <cassert>
+
 #include <octave/oct.h>
 #include "low_level_functions.h"
 #include <iostream>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/src/nrbsurfderiveval.cc 
new/nurbs-1.4.4/src/nrbsurfderiveval.cc
--- old/nurbs-1.4.3/src/nrbsurfderiveval.cc     2021-03-29 12:11:45.815919627 
+0200
+++ new/nurbs-1.4.4/src/nrbsurfderiveval.cc     2025-02-10 14:35:08.000000000 
+0100
@@ -14,6 +14,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <cassert>
 #include <iostream>
 #include <octave/oct.h>
 #include <octave/oct-map.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nurbs-1.4.3/src/tbasisfun.cc 
new/nurbs-1.4.4/src/tbasisfun.cc
--- old/nurbs-1.4.3/src/tbasisfun.cc    2021-03-29 12:11:45.815919627 +0200
+++ new/nurbs-1.4.4/src/tbasisfun.cc    2025-02-10 14:35:08.000000000 +0100
@@ -15,6 +15,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <cassert>
+
 #include <octave/oct.h>
 #include <iostream>
 

Reply via email to