/projects/OG-Analytics/src/com/opengamma/math/surface/InterpolatedDoublesSurface.java

https://github.com/gsteri1/OG-Platform · Java · 513 lines · 244 code · 46 blank · 223 comment · 10 complexity · ce967dd10c66d4ebf31c381dc6fcf3ea MD5 · raw file

  1. /**
  2. * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
  3. *
  4. * Please see distribution for license.
  5. */
  6. package com.opengamma.math.surface;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.TreeMap;
  10. import org.apache.commons.lang.ObjectUtils;
  11. import org.apache.commons.lang.Validate;
  12. import com.opengamma.math.interpolation.GridInterpolator2D;
  13. import com.opengamma.math.interpolation.Interpolator2D;
  14. import com.opengamma.math.interpolation.data.Interpolator1DDataBundle;
  15. import com.opengamma.util.tuple.DoublesPair;
  16. import com.opengamma.util.tuple.Pair;
  17. import com.opengamma.util.tuple.Triple;
  18. /**
  19. * A surface that is defined by a set of nodal points (i.e. <i>x-y-z</i> data) and an interpolator to return values of <i>z</i> for values
  20. * of <i>(x, y)</i> that do not lie on nodal <i>(x, y)</i> values.
  21. */
  22. public class InterpolatedDoublesSurface extends DoublesSurface {
  23. /**
  24. * @param xData An array of <i>x</i> data points, not null
  25. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  26. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  27. * @param interpolator The interpolator, not null
  28. * @return An interpolated surface with automatically-generated name
  29. */
  30. public static InterpolatedDoublesSurface from(final double[] xData, final double[] yData, final double[] zData, final Interpolator2D interpolator) {
  31. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator);
  32. }
  33. /**
  34. * @param xData An array of <i>x</i> data points, not null
  35. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  36. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  37. * @param interpolator The interpolator, not null
  38. * @return An interpolated surface with automatically-generated name
  39. */
  40. public static InterpolatedDoublesSurface from(final Double[] xData, final Double[] yData, final Double[] zData, final Interpolator2D interpolator) {
  41. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator);
  42. }
  43. /**
  44. * @param xData A list of <i>x</i> data points, not null
  45. * @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  46. * @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  47. * @param interpolator The interpolator, not null
  48. * @return An interpolated surface with automatically-generated name
  49. */
  50. public static InterpolatedDoublesSurface from(final List<Double> xData, final List<Double> yData, final List<Double> zData, final Interpolator2D interpolator) {
  51. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator);
  52. }
  53. /**
  54. * @param xyData An array of <i>x-y</i> data points, not null
  55. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  56. * @param interpolator The interpolator, not null
  57. * @return An interpolated surface with automatically-generated name
  58. */
  59. public static InterpolatedDoublesSurface from(final DoublesPair[] xyData, final Double[] zData, final Interpolator2D interpolator) {
  60. return new InterpolatedDoublesSurface(xyData, zData, interpolator);
  61. }
  62. /**
  63. * @param xyData An array of <i>x-y</i> data points, not null
  64. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  65. * @param interpolator The interpolator, not null
  66. * @return An interpolated surface with automatically-generated name
  67. */
  68. public static InterpolatedDoublesSurface from(final DoublesPair[] xyData, final double[] zData, final Interpolator2D interpolator) {
  69. return new InterpolatedDoublesSurface(xyData, zData, interpolator);
  70. }
  71. /**
  72. * @param xyData A list of <i>x-y</i> data points, not null
  73. * @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  74. * @param interpolator The interpolator, not null
  75. * @return An interpolated surface with automatically-generated name
  76. */
  77. public static InterpolatedDoublesSurface from(final List<DoublesPair> xyData, final List<Double> zData, final Interpolator2D interpolator) {
  78. return new InterpolatedDoublesSurface(xyData, zData, interpolator);
  79. }
  80. /**
  81. * @param xyzData A map of <i>x-y</i> data points to <i>z</i> data points, not null
  82. * @param interpolator The interpolator, not null
  83. * @return An interpolated surface with automatically-generated name
  84. */
  85. public static InterpolatedDoublesSurface from(final Map<DoublesPair, Double> xyzData, final Interpolator2D interpolator) {
  86. return new InterpolatedDoublesSurface(xyzData, interpolator);
  87. }
  88. /**
  89. * @param xyzData A list of <i>x-y-z</i> data points, not null
  90. * @param interpolator The interpolator, not null
  91. * @return An interpolated surface with automatically-generated name
  92. */
  93. public static InterpolatedDoublesSurface from(final List<Triple<Double, Double, Double>> xyzData, final Interpolator2D interpolator) {
  94. return new InterpolatedDoublesSurface(xyzData, interpolator);
  95. }
  96. /**
  97. * @param xData An array of <i>x</i> data points, not null
  98. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  99. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  100. * @param interpolator The interpolator, not null
  101. * @param name The name of the surface
  102. * @return An interpolated surface with automatically-generated name
  103. */
  104. public static InterpolatedDoublesSurface from(final double[] xData, final double[] yData, final double[] zData, final Interpolator2D interpolator,
  105. final String name) {
  106. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator, name);
  107. }
  108. /**
  109. * @param xData An array of <i>x</i> data points, not null
  110. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  111. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  112. * @param interpolator The interpolator, not null
  113. * @param name The name of the surface
  114. * @return An interpolated surface with automatically-generated name
  115. */
  116. public static InterpolatedDoublesSurface from(final Double[] xData, final Double[] yData, final Double[] zData, final Interpolator2D interpolator,
  117. final String name) {
  118. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator, name);
  119. }
  120. /**
  121. * @param xData A list of <i>x</i> data points, not null
  122. * @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  123. * @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  124. * @param interpolator The interpolator, not null
  125. * @param name The name of the surface
  126. * @return An interpolated surface with automatically-generated name
  127. */
  128. public static InterpolatedDoublesSurface from(final List<Double> xData, final List<Double> yData, final List<Double> zData, final Interpolator2D interpolator,
  129. final String name) {
  130. return new InterpolatedDoublesSurface(xData, yData, zData, interpolator, name);
  131. }
  132. /**
  133. * @param xyData An array of <i>x-y</i> data points, not null
  134. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  135. * @param interpolator The interpolator, not null
  136. * @param name The name of the surface
  137. * @return An interpolated surface with automatically-generated name
  138. */
  139. public static InterpolatedDoublesSurface from(final DoublesPair[] xyData, final Double[] zData, final Interpolator2D interpolator, final String name) {
  140. return new InterpolatedDoublesSurface(xyData, zData, interpolator, name);
  141. }
  142. /**
  143. * @param xyData An array of <i>x-y</i> data points, not null
  144. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  145. * @param interpolator The interpolator, not null
  146. * @param name The name of the surface
  147. * @return An interpolated surface with automatically-generated name
  148. */
  149. public static InterpolatedDoublesSurface from(final DoublesPair[] xyData, final double[] zData, final Interpolator2D interpolator, final String name) {
  150. return new InterpolatedDoublesSurface(xyData, zData, interpolator, name);
  151. }
  152. /**
  153. * @param xyData A list of <i>x-y</i> data points, not null
  154. * @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x-y</i>
  155. * @param interpolator The interpolator, not null
  156. * @param name The name of the surface
  157. * @return An interpolated surface with automatically-generated name
  158. */
  159. public static InterpolatedDoublesSurface from(final List<DoublesPair> xyData, final List<Double> zData, final Interpolator2D interpolator, final String name) {
  160. return new InterpolatedDoublesSurface(xyData, zData, interpolator, name);
  161. }
  162. /**
  163. * @param xyzData A map of <i>x-y</i> data points to <i>z</i> data points, not null
  164. * @param interpolator The interpolator, not null
  165. * @param name The name of the surface
  166. * @return An interpolated surface with automatically-generated name
  167. */
  168. public static InterpolatedDoublesSurface from(final Map<DoublesPair, Double> xyzData, final Interpolator2D interpolator, final String name) {
  169. return new InterpolatedDoublesSurface(xyzData, interpolator, name);
  170. }
  171. /**
  172. * @param xyzData A list of <i>x-y-z</i> data points, not null
  173. * @param interpolator The interpolator, not null
  174. * @param name The name of the surface
  175. * @return An interpolated surface with automatically-generated name
  176. */
  177. public static InterpolatedDoublesSurface from(final List<Triple<Double, Double, Double>> xyzData, final Interpolator2D interpolator, final String name) {
  178. return new InterpolatedDoublesSurface(xyzData, interpolator, name);
  179. }
  180. /**
  181. * Creates a surface based on a regular grid.
  182. * @param xVector The x data of the grid. Not null.
  183. * @param yVector The x data of the grid. Not null.
  184. * @param zData The z data. Not null. Contains a number of entries which is the product of the number of entries of xVector and yVector.
  185. * @param interpolator The interpolator, not null
  186. * @return An interpolated surface with automatically-generated name.
  187. */
  188. public static InterpolatedDoublesSurface fromGrid(final double[] xVector, final double[] yVector, final double[] zData, final Interpolator2D interpolator) {
  189. int nX = xVector.length;
  190. int nY = yVector.length;
  191. Validate.isTrue(zData.length == nX * nY, "Sizes not compatible");
  192. double[] xData = new double[nX * nY];
  193. double[] yData = new double[nX * nY];
  194. for (int loopy = 0; loopy < nY; loopy++) {
  195. System.arraycopy(xVector, 0, xData, loopy * nX, nX);
  196. }
  197. for (int loopx = 0; loopx < nX; loopx++) {
  198. for (int loopy = 0; loopy < nY; loopy++) {
  199. yData[loopx + loopy * nX] = yVector[loopy];
  200. }
  201. }
  202. return from(xData, yData, zData, interpolator);
  203. }
  204. private final GridInterpolator2D _interpolator;
  205. private Map<Double, Interpolator1DDataBundle> _data;
  206. /**
  207. * @param xData An array of <i>x</i> data points, not null
  208. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  209. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  210. * @param interpolator The interpolator, not null
  211. */
  212. public InterpolatedDoublesSurface(final double[] xData, final double[] yData, final double[] zData, final Interpolator2D interpolator) {
  213. super(xData, yData, zData);
  214. Validate.notNull(interpolator, "interpolator");
  215. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  216. _interpolator = (GridInterpolator2D) interpolator;
  217. init();
  218. }
  219. /**
  220. * @param xData An array of <i>x</i> data points, not null, no null elements
  221. * @param yData An array of <i>y</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  222. * @param zData An array of <i>z</i> data points, not null, not null elements. Contains same number of entries as <i>x</i>
  223. * @param interpolator The interpolator, not null
  224. */
  225. public InterpolatedDoublesSurface(final Double[] xData, final Double[] yData, final Double[] zData, final Interpolator2D interpolator) {
  226. super(xData, yData, zData);
  227. Validate.notNull(interpolator, "interpolator");
  228. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  229. _interpolator = (GridInterpolator2D) interpolator;
  230. init();
  231. }
  232. /**
  233. * @param xData A list of <i>x</i> data points, not null, no null elements
  234. * @param yData A list of <i>y</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  235. * @param zData A list of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  236. * @param interpolator The interpolator, not null
  237. */
  238. public InterpolatedDoublesSurface(final List<Double> xData, final List<Double> yData, final List<Double> zData, final Interpolator2D interpolator) {
  239. super(xData, yData, zData);
  240. Validate.notNull(interpolator, "interpolator");
  241. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  242. _interpolator = (GridInterpolator2D) interpolator;
  243. init();
  244. }
  245. /**
  246. * @param xyData An array of <i>x-y</i> data points, not null, no null elements
  247. * @param zData An array of <i>z</i> data points, not null. Contains same number of entries as <i>x-y</i>
  248. * @param interpolator The interpolator, not null
  249. */
  250. public InterpolatedDoublesSurface(final DoublesPair[] xyData, final double[] zData, final Interpolator2D interpolator) {
  251. super(xyData, zData);
  252. Validate.notNull(interpolator, "interpolator");
  253. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  254. _interpolator = (GridInterpolator2D) interpolator;
  255. init();
  256. }
  257. /**
  258. * @param xyData An array of <i>x-y</i> data points, not null, no null elements
  259. * @param zData An array of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x-y</i>
  260. * @param interpolator The interpolator, not null
  261. */
  262. public InterpolatedDoublesSurface(final DoublesPair[] xyData, final Double[] zData, final Interpolator2D interpolator) {
  263. super(xyData, zData);
  264. Validate.notNull(interpolator, "interpolator");
  265. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  266. _interpolator = (GridInterpolator2D) interpolator;
  267. init();
  268. }
  269. /**
  270. * @param xyData A list of <i>x-y</i> data points, not null, no null elements
  271. * @param zData A list of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x-y</i>
  272. * @param interpolator The interpolator, not null
  273. */
  274. public InterpolatedDoublesSurface(final List<DoublesPair> xyData, final List<Double> zData, final Interpolator2D interpolator) {
  275. super(xyData, zData);
  276. Validate.notNull(interpolator, "interpolator");
  277. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  278. _interpolator = (GridInterpolator2D) interpolator;
  279. init();
  280. }
  281. /**
  282. * @param xyzData A map of <i>x-y</i> data points to <i>z</i> data points, not null, no null elements
  283. * @param interpolator The interpolator, not null
  284. */
  285. public InterpolatedDoublesSurface(final Map<DoublesPair, Double> xyzData, final Interpolator2D interpolator) {
  286. super(xyzData);
  287. Validate.notNull(interpolator, "interpolator");
  288. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  289. _interpolator = (GridInterpolator2D) interpolator;
  290. init();
  291. }
  292. /**
  293. * @param xyzData A list of <i>x-y-z</i> data points, not null, no null elements
  294. * @param interpolator The interpolator, not null
  295. */
  296. public InterpolatedDoublesSurface(final List<Triple<Double, Double, Double>> xyzData, final Interpolator2D interpolator) {
  297. super(xyzData);
  298. Validate.notNull(interpolator, "interpolator");
  299. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  300. _interpolator = (GridInterpolator2D) interpolator;
  301. init();
  302. }
  303. /**
  304. * @param xData An array of <i>x</i> data points, not null
  305. * @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
  306. * @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
  307. * @param interpolator The interpolator, not null
  308. * @param name The name of the surface
  309. */
  310. public InterpolatedDoublesSurface(final double[] xData, final double[] yData, final double[] zData, final Interpolator2D interpolator, final String name) {
  311. super(xData, yData, zData, name);
  312. Validate.notNull(interpolator, "interpolator");
  313. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  314. _interpolator = (GridInterpolator2D) interpolator;
  315. init();
  316. }
  317. /**
  318. * @param xData An array of <i>x</i> data points, not null, no null elements
  319. * @param yData An array of <i>y</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  320. * @param zData An array of <i>z</i> data points, not null, not null elements. Contains same number of entries as <i>x</i>
  321. * @param interpolator The interpolator, not null
  322. * @param name The name of the surface
  323. */
  324. public InterpolatedDoublesSurface(final Double[] xData, final Double[] yData, final Double[] zData, final Interpolator2D interpolator, final String name) {
  325. super(xData, yData, zData, name);
  326. Validate.notNull(interpolator, "interpolator");
  327. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  328. _interpolator = (GridInterpolator2D) interpolator;
  329. init();
  330. }
  331. /**
  332. * @param xData A list of <i>x</i> data points, not null, no null elements
  333. * @param yData A list of <i>y</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  334. * @param zData A list of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x</i>
  335. * @param interpolator The interpolator, not null
  336. * @param name The name of the surface
  337. */
  338. public InterpolatedDoublesSurface(final List<Double> xData, final List<Double> yData, final List<Double> zData, final Interpolator2D interpolator,
  339. final String name) {
  340. super(xData, yData, zData, name);
  341. Validate.notNull(interpolator, "interpolator");
  342. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  343. _interpolator = (GridInterpolator2D) interpolator;
  344. init();
  345. }
  346. /**
  347. * @param xyData An array of <i>x-y</i> data points, not null, no null elements
  348. * @param zData An array of <i>z</i> data points, not null. Contains same number of entries as <i>x-y</i>
  349. * @param interpolator The interpolator, not null
  350. * @param name The name of the surface
  351. */
  352. public InterpolatedDoublesSurface(final DoublesPair[] xyData, final double[] zData, final Interpolator2D interpolator, final String name) {
  353. super(xyData, zData, name);
  354. Validate.notNull(interpolator, "interpolator");
  355. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  356. _interpolator = (GridInterpolator2D) interpolator;
  357. init();
  358. }
  359. /**
  360. * @param xyData An array of <i>x-y</i> data points, not null, no null elements
  361. * @param zData An array of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x-y</i>
  362. * @param interpolator The interpolator, not null
  363. * @param name The name of the surface
  364. */
  365. public InterpolatedDoublesSurface(final DoublesPair[] xyData, final Double[] zData, final Interpolator2D interpolator, final String name) {
  366. super(xyData, zData, name);
  367. Validate.notNull(interpolator, "interpolator");
  368. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  369. _interpolator = (GridInterpolator2D) interpolator;
  370. init();
  371. }
  372. /**
  373. * @param xyData A list of <i>x-y</i> data points, not null, no null elements
  374. * @param zData A list of <i>z</i> data points, not null, no null elements. Contains same number of entries as <i>x-y</i>
  375. * @param interpolator The interpolator, not null
  376. * @param name The name of the surface
  377. */
  378. public InterpolatedDoublesSurface(final List<DoublesPair> xyData, final List<Double> zData, final Interpolator2D interpolator, final String name) {
  379. super(xyData, zData, name);
  380. Validate.notNull(interpolator, "interpolator");
  381. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  382. _interpolator = (GridInterpolator2D) interpolator;
  383. init();
  384. }
  385. /**
  386. * @param xyzData A map of <i>x-y</i> data points to <i>z</i> data points, not null, no null elements
  387. * @param interpolator The interpolator, not null
  388. * @param name The name of the surface
  389. */
  390. public InterpolatedDoublesSurface(final Map<DoublesPair, Double> xyzData, final Interpolator2D interpolator, final String name) {
  391. super(xyzData, name);
  392. Validate.notNull(interpolator, "interpolator");
  393. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  394. _interpolator = (GridInterpolator2D) interpolator;
  395. init();
  396. }
  397. /**
  398. * @param xyzData A list of <i>x-y-z</i> data points, not null, no null elements
  399. * @param interpolator The interpolator, not null
  400. * @param name The name of the surface
  401. */
  402. public InterpolatedDoublesSurface(final List<Triple<Double, Double, Double>> xyzData, final Interpolator2D interpolator, final String name) {
  403. super(xyzData, name);
  404. Validate.notNull(interpolator, "interpolator");
  405. Validate.isTrue(interpolator instanceof GridInterpolator2D); //TODO remove me
  406. _interpolator = (GridInterpolator2D) interpolator;
  407. init();
  408. }
  409. // TODO this logic should be in the interpolator
  410. private void init() {
  411. final Map<DoublesPair, Double> map = new TreeMap<DoublesPair, Double>();
  412. final double[] x = getXDataAsPrimitive();
  413. final double[] y = getYDataAsPrimitive();
  414. final double[] z = getZDataAsPrimitive();
  415. for (int i = 0; i < size(); i++) {
  416. map.put(DoublesPair.of(x[i], y[i]), z[i]);
  417. }
  418. _data = _interpolator.getDataBundle(map);
  419. }
  420. /**
  421. * {@inheritDoc}
  422. */
  423. @Override
  424. public Double getZValue(final Double x, final Double y) {
  425. Validate.notNull(x, "x");
  426. Validate.notNull(y, "y");
  427. return _interpolator.interpolate(_data, new DoublesPair(x, y));
  428. }
  429. /**
  430. * {@inheritDoc}
  431. */
  432. @Override
  433. public Double getZValue(final Pair<Double, Double> xy) {
  434. Validate.notNull(xy, "xy");
  435. return _interpolator.interpolate(_data, DoublesPair.of(xy));
  436. }
  437. /**
  438. * @return The interpolator
  439. */
  440. public Interpolator2D getInterpolator() {
  441. return _interpolator;
  442. }
  443. public Map<Double, ? extends Interpolator1DDataBundle> getInterpolatorData() {
  444. return _data;
  445. }
  446. @Override
  447. public int hashCode() {
  448. final int prime = 31;
  449. int result = super.hashCode();
  450. result = prime * result + _interpolator.hashCode();
  451. return result;
  452. }
  453. @Override
  454. public boolean equals(final Object obj) {
  455. if (this == obj) {
  456. return true;
  457. }
  458. if (!super.equals(obj)) {
  459. return false;
  460. }
  461. if (getClass() != obj.getClass()) {
  462. return false;
  463. }
  464. final InterpolatedDoublesSurface other = (InterpolatedDoublesSurface) obj;
  465. return ObjectUtils.equals(_interpolator, other._interpolator);
  466. }
  467. }