bspy 3.0.1__py3-none-any.whl → 4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,9 +35,9 @@ def add(self, other, indMap = None):
35
35
  permutation.append(i + 1) # Add 1 to account for dependent variables.
36
36
  for i in range(other.nInd - 1, -1, -1):
37
37
  if i not in otherMapped:
38
- order.append(other.order[i])
39
- nCoef.append(other.nCoef[i])
40
- knots.append(other.knots[i])
38
+ order.append(other.order[other.nInd - 1 - i])
39
+ nCoef.append(other.nCoef[other.nInd - 1 - i])
40
+ knots.append(other.knots[other.nInd - 1 - i])
41
41
  permutation.append(self.nInd + i + 1) # Add 1 to account for dependent variables.
42
42
  nInd += 1
43
43
  else:
@@ -67,19 +67,19 @@ def confine(self, range_bounds):
67
67
  degree = order - 1
68
68
  domain = spline.domain()
69
69
  unique, counts = np.unique(spline.knots[0], return_counts=True)
70
- machineEpsilon = 10.0 * np.finfo(self.coefs.dtype).eps
70
+ machineEpsilon = np.finfo(self.coefs.dtype).eps
71
71
  epsilon = np.sqrt(machineEpsilon)
72
72
  intersections = [] # List of tuples (u, boundaryPoint, headingOutside)
73
73
 
74
74
  def addIntersection(u, headedOutside = False):
75
75
  boundaryPoint = spline(np.atleast_1d(u))
76
76
  for i in range(spline.nDep):
77
- if boundaryPoint[i] < range_bounds[i][0] + machineEpsilon:
77
+ if boundaryPoint[i] < range_bounds[i][0]:
78
78
  headedOutside = True if boundaryPoint[i] < range_bounds[i][0] - epsilon else headedOutside
79
- boundaryPoint[i] = range_bounds[i][0] + machineEpsilon # Avoids error in spline evaluation
80
- if boundaryPoint[i] > range_bounds[i][1] - machineEpsilon:
79
+ boundaryPoint[i] = range_bounds[i][0]
80
+ if boundaryPoint[i] > range_bounds[i][1]:
81
81
  headedOutside = True if boundaryPoint[i] > range_bounds[i][1] + epsilon else headedOutside
82
- boundaryPoint[i] = range_bounds[i][1] - machineEpsilon # Avoids error in spline evaluation
82
+ boundaryPoint[i] = range_bounds[i][1]
83
83
  intersections.append((u, boundaryPoint, headedOutside))
84
84
 
85
85
  def intersectBoundary(i, j):
@@ -163,7 +163,7 @@ def confine(self, range_bounds):
163
163
  def contract(self, uvw):
164
164
  domain = self.domain()
165
165
  section = [slice(None)]
166
- indices = []
166
+ bValues = []
167
167
  contracting = False
168
168
  for iv in range(self.nInd):
169
169
  if uvw[iv] is not None:
@@ -171,12 +171,12 @@ def contract(self, uvw):
171
171
  raise ValueError(f"Spline evaluation outside domain: {uvw}")
172
172
 
173
173
  # Grab all of the appropriate coefficients
174
- ix = np.searchsorted(self.knots[iv], uvw[iv], 'right')
175
- ix = min(ix, self.nCoef[iv])
176
- indices.append(ix)
174
+ ix, indValues = bspy.Spline.bspline_values(None, self.knots[iv], self.order[iv], uvw[iv])
175
+ bValues.append(indValues)
177
176
  section.append(slice(ix - self.order[iv], ix))
178
177
  contracting = True
179
178
  else:
179
+ bValues.append([])
180
180
  section.append(slice(None))
181
181
 
182
182
  if not contracting:
@@ -194,9 +194,8 @@ def contract(self, uvw):
194
194
  del order[ix]
195
195
  del nCoef[ix]
196
196
  del knots[ix]
197
- bValues = bspy.Spline.bspline_values(indices.pop(0), self.knots[iv], self.order[iv], uvw[iv])
198
197
  coefs = np.moveaxis(coefs, ix + 1, -1)
199
- coefs = coefs @ bValues
198
+ coefs = coefs @ bValues[iv]
200
199
  else:
201
200
  ix += 1
202
201
 
@@ -267,14 +266,6 @@ def graph(self):
267
266
  dep[i] = knotAverage
268
267
  return type(self)(self.nInd, self.nInd + self.nDep, self.order, self.nCoef, self.knots, coefs, self.metadata)
269
268
 
270
- def greville(self, ind = 0):
271
- if ind < 0 or ind >= self.nInd: raise ValueError("Invalid independent variable")
272
- myKnots = self.knots[ind]
273
- knotAverages = 0
274
- for ix in range(1, self.order[ind]):
275
- knotAverages = knotAverages + myKnots[ix : ix + self.nCoef[ind]]
276
- return knotAverages / (self.order[ind] - 1)
277
-
278
269
  def integrate(self, with_respect_to = 0):
279
270
  if not(0 <= with_respect_to < self.nInd): raise ValueError("Invalid with_respect_to")
280
271
 
@@ -317,6 +308,8 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
317
308
  # Construct new spline parameters.
318
309
  nInd = self.nInd + other.nInd
319
310
  nDep = other.nDep
311
+ if productType == 'C' and nDep == 2:
312
+ nDep = 1
320
313
  order = [*self.order, *other.order]
321
314
  nCoef = [*self.nCoef, *other.nCoef]
322
315
  knots = [*self.knots, *other.knots]
@@ -521,12 +514,12 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
521
514
  taylorCoefs = (coefs[ix1 - order1:ix1, ix2 - order2:ix2]).T # Transpose so we multiply on the left (due to matmul rules)
522
515
  bValues = np.empty((order1, order1), knots1.dtype)
523
516
  for derivativeOrder in range(order1):
524
- bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
517
+ ix1, bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
525
518
  taylorCoefs = taylorCoefs @ bValues
526
519
  taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
527
520
  bValues = np.empty((order2, order2), knots2.dtype)
528
521
  for derivativeOrder in range(order2):
529
- bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, yLeft, derivativeOrder, True)
522
+ ix2, bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, yLeft, derivativeOrder, True)
530
523
  taylorCoefs = taylorCoefs @ bValues
531
524
  taylorCoefs = (np.moveaxis(taylorCoefs, 0, -1)).T # Move ind1's taylor coefficients back to the right side, and re-transpose
532
525
 
@@ -597,22 +590,20 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
597
590
  # Next step in multiply:
598
591
  # 2) Convert each spline segment into a polynomial (Taylor series).
599
592
  # Isolate the appropriate segment coefficients
600
- ix1 = np.searchsorted(self.knots[ind1], knot, 'right')
601
- ix1 = min(ix1, self.nCoef[ind1])
602
- ix2 = np.searchsorted(other.knots[ind2], knot, 'right')
603
- ix2 = min(ix2, other.nCoef[ind2])
593
+ ix1 = None
594
+ ix2 = None
604
595
 
605
596
  # Compute taylor coefficients for the segment
606
- taylorCoefs = (coefs[ix1 - order1:ix1, ix2 - order2:ix2]).T # Transpose so we multiply on the left (due to matmul rules)
607
- bValues = np.empty((order1, order1), knots1.dtype)
597
+ bValues1 = np.empty((order1, order1), knots1.dtype)
608
598
  for derivativeOrder in range(order1):
609
- bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
610
- taylorCoefs = taylorCoefs @ bValues
611
- taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
612
- bValues = np.empty((order2, order2), knots2.dtype)
599
+ ix1, bValues1[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
600
+ bValues2 = np.empty((order2, order2), knots2.dtype)
613
601
  for derivativeOrder in range(order2):
614
- bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, knot, derivativeOrder, True)
615
- taylorCoefs = taylorCoefs @ bValues
602
+ ix2, bValues2[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, knot, derivativeOrder, True)
603
+ taylorCoefs = (coefs[ix1 - order1:ix1, ix2 - order2:ix2]).T # Transpose so we multiply on the left (due to matmul rules)
604
+ taylorCoefs = taylorCoefs @ bValues1
605
+ taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
606
+ taylorCoefs = taylorCoefs @ bValues2
616
607
  taylorCoefs = (np.moveaxis(taylorCoefs, 0, -1)).T # Move ind1's taylor coefficients back to the right side, and re-transpose
617
608
 
618
609
  # 3) Sum coefficients of matching polynomial degree (the coefficients have already been multiplied together by the outer product).
@@ -703,7 +694,12 @@ def normal_spline(self, indices=None):
703
694
  # using that calculation to span uvw from the starting knot to the end for each variable.
704
695
  nCoef = len(newKnots[-1]) - newOrder[-1]
705
696
  totalCoefs.append(totalCoefs[-1] * nCoef)
706
- uvwValues.append(bspy.Spline(1, 0, [newOrd], [nCoef], [newKnots[-1]], []).greville())
697
+ knotAverages = bspy.Spline(1, 0, [newOrd], [nCoef], [newKnots[-1]], []).greville()
698
+ for iKnot in range(1, len(knotAverages) - 1):
699
+ if knotAverages[iKnot] == knotAverages[iKnot + 1]:
700
+ knotAverages[iKnot] = 0.5 * (knotAverages[iKnot - 1] + knotAverages[iKnot])
701
+ knotAverages[iKnot + 1] = 0.5 * (knotAverages[iKnot + 1] + knotAverages[iKnot + 2])
702
+ uvwValues.append(knotAverages)
707
703
  nCoefs.append(nCoef)
708
704
  points = []
709
705
  ijk = [0 for order in self.order]
@@ -721,7 +717,6 @@ def normal_spline(self, indices=None):
721
717
  points = np.reshape(points, [nDep] + nCoefs)
722
718
  points = np.transpose(points, [0] + list(range(self.nInd, 0, -1)))
723
719
  return bspy.Spline.least_squares(uvwValues, points, order = newOrder, knots = newKnots, metadata = self.metadata)
724
- # return bspy.Spline.least_squares(self.nInd, nDep, newOrder, points, newKnots, 0, self.metadata)
725
720
 
726
721
  def rotate(self, vector, angle):
727
722
  vector = np.atleast_1d(vector)