PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/IJ_Mobile/src/net/imglib2/util/Util.java

https://github.com/msteptoe/FURI_Code
Java | 1217 lines | 746 code | 212 blank | 259 comment | 161 complexity | 1e70042524b6026fd0f8a5da3cadfbc7 MD5 | raw file
  1. /*
  2. * #%L
  3. * ImgLib2: a general-purpose, multidimensional image processing library.
  4. * %%
  5. * Copyright (C) 2009 - 2012 Stephan Preibisch, Stephan Saalfeld, Tobias
  6. * Pietzsch, Albert Cardona, Barry DeZonia, Curtis Rueden, Lee Kamentsky, Larry
  7. * Lindsey, Johannes Schindelin, Christian Dietz, Grant Harris, Jean-Yves
  8. * Tinevez, Steffen Jaensch, Mark Longair, Nick Perry, and Jan Funke.
  9. * %%
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. *
  31. * The views and conclusions contained in the software and documentation are
  32. * those of the authors and should not be interpreted as representing official
  33. * policies, either expressed or implied, of any organization.
  34. * #L%
  35. */
  36. package net.imglib2.util;
  37. import java.util.List;
  38. import net.imglib2.Interval;
  39. import net.imglib2.IterableInterval;
  40. import net.imglib2.Localizable;
  41. import net.imglib2.RandomAccess;
  42. import net.imglib2.RandomAccessible;
  43. import net.imglib2.RandomAccessibleInterval;
  44. import net.imglib2.RealInterval;
  45. import net.imglib2.RealLocalizable;
  46. import net.imglib2.RealRandomAccess;
  47. import net.imglib2.RealRandomAccessible;
  48. import net.imglib2.RealRandomAccessibleRealInterval;
  49. import net.imglib2.type.Type;
  50. import net.imglib2.type.numeric.ExponentialMathType;
  51. /**
  52. * TODO
  53. *
  54. * @author Stephan Preibisch
  55. * @author Stephan Saalfeld
  56. */
  57. public class Util
  58. {
  59. @SuppressWarnings( "unchecked" )
  60. public static < T > T[] genericArray( final int length )
  61. {
  62. return ( T[] ) ( new Object[ length ] );
  63. }
  64. public static double log2( final double value )
  65. {
  66. return Math.log( value ) / Math.log( 2.0 );
  67. }
  68. public static double[] getArrayFromValue( final double value, final int numDimensions )
  69. {
  70. final double[] values = new double[ numDimensions ];
  71. for ( int d = 0; d < numDimensions; ++d )
  72. values[ d ] = value;
  73. return values;
  74. }
  75. public static float[] getArrayFromValue( final float value, final int numDimensions )
  76. {
  77. final float[] values = new float[ numDimensions ];
  78. for ( int d = 0; d < numDimensions; ++d )
  79. values[ d ] = value;
  80. return values;
  81. }
  82. public static int[] getArrayFromValue( final int value, final int numDimensions )
  83. {
  84. final int[] values = new int[ numDimensions ];
  85. for ( int d = 0; d < numDimensions; ++d )
  86. values[ d ] = value;
  87. return values;
  88. }
  89. public static long[] getArrayFromValue( final long value, final int numDimensions )
  90. {
  91. final long[] values = new long[ numDimensions ];
  92. for ( int d = 0; d < numDimensions; ++d )
  93. values[ d ] = value;
  94. return values;
  95. }
  96. final public static float computeDistance( final RealLocalizable position1, final RealLocalizable position2 )
  97. {
  98. float dist = 0;
  99. final int n = position1.numDimensions();
  100. for ( int d = 0; d < n; ++d )
  101. {
  102. final float pos = position2.getFloatPosition( d ) - position1.getFloatPosition( d );
  103. dist += pos * pos;
  104. }
  105. return ( float ) Math.sqrt( dist );
  106. }
  107. final public static float computeDistance( final int[] position1, final int[] position2 )
  108. {
  109. float dist = 0;
  110. for ( int d = 0; d < position1.length; ++d )
  111. {
  112. final int pos = position2[ d ] - position1[ d ];
  113. dist += pos * pos;
  114. }
  115. return ( float ) Math.sqrt( dist );
  116. }
  117. final public static float computeDistance( final long[] position1, final long[] position2 )
  118. {
  119. float dist = 0;
  120. for ( int d = 0; d < position1.length; ++d )
  121. {
  122. final long pos = position2[ d ] - position1[ d ];
  123. dist += pos * pos;
  124. }
  125. return ( float ) Math.sqrt( dist );
  126. }
  127. final public static float computeLength( final int[] position )
  128. {
  129. float dist = 0;
  130. for ( int d = 0; d < position.length; ++d )
  131. {
  132. final int pos = position[ d ];
  133. dist += pos * pos;
  134. }
  135. return ( float ) Math.sqrt( dist );
  136. }
  137. final public static float computeLength( final long[] position )
  138. {
  139. float dist = 0;
  140. for ( int d = 0; d < position.length; ++d )
  141. {
  142. final long pos = position[ d ];
  143. dist += pos * pos;
  144. }
  145. return ( float ) Math.sqrt( dist );
  146. }
  147. public static long computeMedian( final long[] values )
  148. {
  149. final long temp[] = values.clone();
  150. long median;
  151. final int length = temp.length;
  152. quicksort( temp, 0, length - 1 );
  153. if ( length % 2 == 1 ) // odd length
  154. median = temp[ length / 2 ];
  155. else
  156. // even length
  157. median = ( temp[ length / 2 ] + temp[ ( length / 2 ) - 1 ] ) / 2;
  158. return median;
  159. }
  160. public static double computeMedian( final double[] values )
  161. {
  162. final double temp[] = values.clone();
  163. double median;
  164. final int length = temp.length;
  165. quicksort( temp, 0, length - 1 );
  166. if ( length % 2 == 1 ) // odd length
  167. median = temp[ length / 2 ];
  168. else
  169. // even length
  170. median = ( temp[ length / 2 ] + temp[ ( length / 2 ) - 1 ] ) / 2;
  171. return median;
  172. }
  173. /**
  174. * Computes the percentile of a collection of doubles (percentile 0.5
  175. * roughly corresponds to median)
  176. *
  177. * @param values
  178. * - the values
  179. * @param percentile
  180. * - the percentile [0...1]
  181. * @return the corresponding value
  182. */
  183. public static double computePercentile( final double[] values, final double percentile )
  184. {
  185. final double temp[] = values.clone();
  186. final int length = temp.length;
  187. quicksort( temp );
  188. return temp[ Math.min( length - 1, Math.max( 0, ( int ) Math.round( ( length - 1 ) * percentile ) ) ) ];
  189. }
  190. public static double computeAverageDouble( final List< Double > values )
  191. {
  192. final double size = values.size();
  193. double avg = 0;
  194. for ( final double v : values )
  195. avg += v / size;
  196. return avg;
  197. }
  198. public static float computeAverageFloat( final List< Float > values )
  199. {
  200. final double size = values.size();
  201. double avg = 0;
  202. for ( final double v : values )
  203. avg += v / size;
  204. return ( float ) avg;
  205. }
  206. public static float computeMinimum( final List< Float > values )
  207. {
  208. float min = Float.MAX_VALUE;
  209. for ( final float v : values )
  210. if ( v < min )
  211. min = v;
  212. return min;
  213. }
  214. public static float computeMaximum( final List< Float > values )
  215. {
  216. float max = -Float.MAX_VALUE;
  217. for ( final float v : values )
  218. if ( v > max )
  219. max = v;
  220. return max;
  221. }
  222. public static float computeAverage( final float[] values )
  223. {
  224. final double size = values.length;
  225. double avg = 0;
  226. for ( final float v : values )
  227. avg += v / size;
  228. return ( float ) avg;
  229. }
  230. public static double computeAverage( final double[] values )
  231. {
  232. final double size = values.length;
  233. double avg = 0;
  234. for ( final double v : values )
  235. avg += v / size;
  236. return avg;
  237. }
  238. public static double computeMin( final double[] values )
  239. {
  240. double min = values[ 0 ];
  241. for ( final double v : values )
  242. if ( v < min )
  243. min = v;
  244. return min;
  245. }
  246. public static double computeMax( final double[] values )
  247. {
  248. double max = values[ 0 ];
  249. for ( final double v : values )
  250. if ( v > max )
  251. max = v;
  252. return max;
  253. }
  254. public static float computeMedian( final float[] values )
  255. {
  256. final float temp[] = values.clone();
  257. float median;
  258. final int length = temp.length;
  259. quicksort( temp, 0, length - 1 );
  260. if ( length % 2 == 1 ) // odd length
  261. median = temp[ length / 2 ];
  262. else
  263. // even length
  264. median = ( temp[ length / 2 ] + temp[ ( length / 2 ) - 1 ] ) / 2;
  265. return median;
  266. }
  267. public static void quicksort( final long[] data, final int left, final int right )
  268. {
  269. if ( data == null || data.length < 2 )
  270. return;
  271. int i = left, j = right;
  272. final long x = data[ ( left + right ) / 2 ];
  273. do
  274. {
  275. while ( data[ i ] < x )
  276. i++;
  277. while ( x < data[ j ] )
  278. j--;
  279. if ( i <= j )
  280. {
  281. final long temp = data[ i ];
  282. data[ i ] = data[ j ];
  283. data[ j ] = temp;
  284. i++;
  285. j--;
  286. }
  287. }
  288. while ( i <= j );
  289. if ( left < j )
  290. quicksort( data, left, j );
  291. if ( i < right )
  292. quicksort( data, i, right );
  293. }
  294. public static void quicksort( final double[] data )
  295. {
  296. quicksort( data, 0, data.length - 1 );
  297. }
  298. public static void quicksort( final double[] data, final int left, final int right )
  299. {
  300. if ( data == null || data.length < 2 )
  301. return;
  302. int i = left, j = right;
  303. final double x = data[ ( left + right ) / 2 ];
  304. do
  305. {
  306. while ( data[ i ] < x )
  307. i++;
  308. while ( x < data[ j ] )
  309. j--;
  310. if ( i <= j )
  311. {
  312. final double temp = data[ i ];
  313. data[ i ] = data[ j ];
  314. data[ j ] = temp;
  315. i++;
  316. j--;
  317. }
  318. }
  319. while ( i <= j );
  320. if ( left < j )
  321. quicksort( data, left, j );
  322. if ( i < right )
  323. quicksort( data, i, right );
  324. }
  325. public static void quicksort( final float[] data )
  326. {
  327. quicksort( data, 0, data.length - 1 );
  328. }
  329. public static void quicksort( final float[] data, final int left, final int right )
  330. {
  331. if ( data == null || data.length < 2 )
  332. return;
  333. int i = left, j = right;
  334. final float x = data[ ( left + right ) / 2 ];
  335. do
  336. {
  337. while ( data[ i ] < x )
  338. i++;
  339. while ( x < data[ j ] )
  340. j--;
  341. if ( i <= j )
  342. {
  343. final float temp = data[ i ];
  344. data[ i ] = data[ j ];
  345. data[ j ] = temp;
  346. i++;
  347. j--;
  348. }
  349. }
  350. while ( i <= j );
  351. if ( left < j )
  352. quicksort( data, left, j );
  353. if ( i < right )
  354. quicksort( data, i, right );
  355. }
  356. public static void quicksort( final double[] data, final int[] sortAlso, final int left, final int right )
  357. {
  358. if ( data == null || data.length < 2 )
  359. return;
  360. int i = left, j = right;
  361. final double x = data[ ( left + right ) / 2 ];
  362. do
  363. {
  364. while ( data[ i ] < x )
  365. i++;
  366. while ( x < data[ j ] )
  367. j--;
  368. if ( i <= j )
  369. {
  370. final double temp = data[ i ];
  371. data[ i ] = data[ j ];
  372. data[ j ] = temp;
  373. final int temp2 = sortAlso[ i ];
  374. sortAlso[ i ] = sortAlso[ j ];
  375. sortAlso[ j ] = temp2;
  376. i++;
  377. j--;
  378. }
  379. }
  380. while ( i <= j );
  381. if ( left < j )
  382. quicksort( data, sortAlso, left, j );
  383. if ( i < right )
  384. quicksort( data, sortAlso, i, right );
  385. }
  386. public static double gLog( final double z, final double c )
  387. {
  388. if ( c == 0 )
  389. return z;
  390. return Math.log10( ( z + Math.sqrt( z * z + c * c ) ) / 2.0 );
  391. }
  392. public static float gLog( final float z, final float c )
  393. {
  394. if ( c == 0 )
  395. return z;
  396. return ( float ) Math.log10( ( z + Math.sqrt( z * z + c * c ) ) / 2.0 );
  397. }
  398. public static double gLogInv( final double w, final double c )
  399. {
  400. if ( c == 0 )
  401. return w;
  402. return Math.pow( 10, w ) - ( ( ( c * c ) * Math.pow( 10, -w ) ) / 4.0 );
  403. }
  404. public static double gLogInv( final float w, final float c )
  405. {
  406. if ( c == 0 )
  407. return w;
  408. return Math.pow( 10, w ) - ( ( ( c * c ) * Math.pow( 10, -w ) ) / 4.0 );
  409. }
  410. public static boolean isApproxEqual( final float a, final float b, final float threshold )
  411. {
  412. if ( a == b )
  413. return true;
  414. else if ( a + threshold > b && a - threshold < b )
  415. return true;
  416. else
  417. return false;
  418. }
  419. public static boolean isApproxEqual( final double a, final double b, final double threshold )
  420. {
  421. if ( a == b )
  422. return true;
  423. else if ( a + threshold > b && a - threshold < b )
  424. return true;
  425. else
  426. return false;
  427. }
  428. public static int round( final float value )
  429. {
  430. return ( int ) ( value + ( 0.5f * Math.signum( value ) ) );
  431. }
  432. public static long round( final double value )
  433. {
  434. return ( long ) ( value + ( 0.5d * Math.signum( value ) ) );
  435. }
  436. /**
  437. * This method creates a gaussian kernel
  438. *
  439. * @param sigma
  440. * Standard Derivation of the gaussian function
  441. * @param normalize
  442. * Normalize integral of gaussian function to 1 or not...
  443. * @return double[] The gaussian kernel
  444. *
  445. */
  446. public static double[] createGaussianKernel1DDouble( final double sigma, final boolean normalize )
  447. {
  448. int size = 3;
  449. final double[] gaussianKernel;
  450. if ( sigma <= 0 )
  451. {
  452. gaussianKernel = new double[ 3 ];
  453. gaussianKernel[ 1 ] = 1;
  454. }
  455. else
  456. {
  457. size = Math.max( 3, ( 2 * ( int ) ( 3 * sigma + 0.5 ) + 1 ) );
  458. final double two_sq_sigma = 2 * sigma * sigma;
  459. gaussianKernel = new double[ size ];
  460. for ( int x = size / 2; x >= 0; --x )
  461. {
  462. final double val = Math.exp( -( x * x ) / two_sq_sigma );
  463. gaussianKernel[ size / 2 - x ] = val;
  464. gaussianKernel[ size / 2 + x ] = val;
  465. }
  466. }
  467. if ( normalize )
  468. {
  469. double sum = 0;
  470. for ( final double value : gaussianKernel )
  471. sum += value;
  472. for ( int i = 0; i < gaussianKernel.length; ++i )
  473. gaussianKernel[ i ] /= sum;
  474. }
  475. return gaussianKernel;
  476. }
  477. /**
  478. * This method creates a gaussian kernel
  479. *
  480. * @param sigma
  481. * Standard Derivation of the gaussian function in the desired
  482. * {@link Type}
  483. * @param normalize
  484. * Normalize integral of gaussian function to 1 or not...
  485. * @return T[] The gaussian kernel
  486. *
  487. */
  488. public static < T extends ExponentialMathType< T > > T[] createGaussianKernel1D( final T sigma, final boolean normalize )
  489. {
  490. final T[] gaussianKernel;
  491. int kernelSize;
  492. final T zero = sigma.createVariable();
  493. final T two = sigma.createVariable();
  494. final T one = sigma.createVariable();
  495. final T minusOne = sigma.createVariable();
  496. final T two_sq_sigma = zero.createVariable();
  497. final T sum = sigma.createVariable();
  498. final T value = sigma.createVariable();
  499. final T xPos = sigma.createVariable();
  500. final T cs = sigma.createVariable();
  501. zero.setZero();
  502. one.setOne();
  503. two.setOne();
  504. two.add( one );
  505. minusOne.setZero();
  506. minusOne.sub( one );
  507. if ( sigma.compareTo( zero ) <= 0 )
  508. {
  509. kernelSize = 3;
  510. // NB: Need explicit cast to T[] to satisfy javac;
  511. // See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
  512. gaussianKernel = ( T[] ) genericArray( 3 ); // zero.createArray1D( 3
  513. // );
  514. gaussianKernel[ 1 ].set( one );
  515. }
  516. else
  517. {
  518. // size = Math.max(3, (int) (2 * (int) (3 * sigma + 0.5) + 1));
  519. cs.set( sigma );
  520. cs.mul( 3.0 );
  521. cs.round();
  522. cs.mul( 2.0 );
  523. cs.add( one );
  524. kernelSize = Util.round( cs.getRealFloat() );
  525. // kernelsize has to be at least 3
  526. kernelSize = Math.max( 3, kernelSize );
  527. // kernelsize has to be odd
  528. if ( kernelSize % 2 == 0 )
  529. ++kernelSize;
  530. // two_sq_sigma = 2 * sigma * sigma;
  531. two_sq_sigma.set( two );
  532. two_sq_sigma.mul( sigma );
  533. two_sq_sigma.mul( sigma );
  534. // NB: Need explicit cast to T[] to satisfy javac;
  535. // See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302954
  536. gaussianKernel = ( T[] ) genericArray( kernelSize ); // zero.createArray1D(
  537. // kernelSize
  538. // );
  539. for ( int i = 0; i < gaussianKernel.length; ++i )
  540. gaussianKernel[ i ] = zero.createVariable();
  541. // set the xPos to kernelSize/2
  542. xPos.setZero();
  543. for ( int x = 1; x <= kernelSize / 2; ++x )
  544. xPos.add( one );
  545. for ( int x = kernelSize / 2; x >= 0; --x )
  546. {
  547. // final double val = Math.exp( -(x * x) / two_sq_sigma );
  548. value.set( xPos );
  549. value.mul( xPos );
  550. value.mul( minusOne );
  551. value.div( two_sq_sigma );
  552. value.exp();
  553. gaussianKernel[ kernelSize / 2 - x ].set( value );
  554. gaussianKernel[ kernelSize / 2 + x ].set( value );
  555. xPos.sub( one );
  556. }
  557. }
  558. if ( normalize )
  559. {
  560. sum.setZero();
  561. for ( final T val : gaussianKernel )
  562. sum.add( val );
  563. for ( int i = 0; i < gaussianKernel.length; ++i )
  564. gaussianKernel[ i ].div( sum );
  565. }
  566. for ( int i = 0; i < gaussianKernel.length; ++i )
  567. System.out.println( gaussianKernel[ i ] );
  568. return gaussianKernel;
  569. }
  570. public static int getSuggestedKernelDiameter( final double sigma )
  571. {
  572. int size = 3;
  573. if ( sigma > 0 )
  574. size = Math.max( 3, ( 2 * ( int ) ( 3 * sigma + 0.5 ) + 1 ) );
  575. return size;
  576. }
  577. public static String printCoordinates( final float[] value )
  578. {
  579. String out = "(Array empty)";
  580. if ( value == null || value.length == 0 )
  581. return out;
  582. out = "(" + value[ 0 ];
  583. for ( int i = 1; i < value.length; i++ )
  584. out += ", " + value[ i ];
  585. out += ")";
  586. return out;
  587. }
  588. public static String printCoordinates( final double[] value )
  589. {
  590. String out = "(Array empty)";
  591. if ( value == null || value.length == 0 )
  592. return out;
  593. out = "(" + value[ 0 ];
  594. for ( int i = 1; i < value.length; i++ )
  595. out += ", " + value[ i ];
  596. out += ")";
  597. return out;
  598. }
  599. public static String printCoordinates( final Localizable localizable )
  600. {
  601. String out = "(Localizable empty)";
  602. if ( localizable == null || localizable.numDimensions() == 0 )
  603. return out;
  604. out = "(" + localizable.getFloatPosition( 0 );
  605. for ( int i = 1; i < localizable.numDimensions(); i++ )
  606. out += ", " + localizable.getFloatPosition( i );
  607. out += ")";
  608. return out;
  609. }
  610. public static String printInterval( final Interval interval )
  611. {
  612. String out = "(Interval empty)";
  613. if ( interval == null || interval.numDimensions() == 0 )
  614. return out;
  615. out = "[" + interval.min( 0 );
  616. for ( int i = 1; i < interval.numDimensions(); i++ )
  617. out += ", " + interval.min( i );
  618. out += "] -> [" + interval.max( 0 );
  619. for ( int i = 1; i < interval.numDimensions(); i++ )
  620. out += ", " + interval.max( i );
  621. out += "], dimensions (" + interval.dimension( 0 );
  622. for ( int i = 1; i < interval.numDimensions(); i++ )
  623. out += ", " + interval.dimension( i );
  624. out += ")";
  625. return out;
  626. }
  627. public static String printCoordinates( final int[] value )
  628. {
  629. String out = "(Array empty)";
  630. if ( value == null || value.length == 0 )
  631. return out;
  632. out = "(" + value[ 0 ];
  633. for ( int i = 1; i < value.length; i++ )
  634. out += ", " + value[ i ];
  635. out += ")";
  636. return out;
  637. }
  638. public static String printCoordinates( final long[] value )
  639. {
  640. String out = "(Array empty)";
  641. if ( value == null || value.length == 0 )
  642. return out;
  643. out = "(" + value[ 0 ];
  644. for ( int i = 1; i < value.length; i++ )
  645. out += ", " + value[ i ];
  646. out += ")";
  647. return out;
  648. }
  649. public static String printCoordinates( final boolean[] value )
  650. {
  651. String out = "(Array empty)";
  652. if ( value == null || value.length == 0 )
  653. return out;
  654. out = "(";
  655. if ( value[ 0 ] )
  656. out += "1";
  657. else
  658. out += "0";
  659. for ( int i = 1; i < value.length; i++ )
  660. {
  661. out += ", ";
  662. if ( value[ i ] )
  663. out += "1";
  664. else
  665. out += "0";
  666. }
  667. out += ")";
  668. return out;
  669. }
  670. public static int pow( final int a, final int b )
  671. {
  672. if ( b == 0 )
  673. return 1;
  674. else if ( b == 1 )
  675. return a;
  676. else
  677. {
  678. int result = a;
  679. for ( int i = 1; i < b; i++ )
  680. result *= a;
  681. return result;
  682. }
  683. }
  684. public static < T extends Type< T > & Comparable< T >> T max( final T value1, final T value2 )
  685. {
  686. if ( value1.compareTo( value2 ) >= 0 )
  687. return value1;
  688. return value2;
  689. }
  690. public static < T extends Type< T > & Comparable< T >> T min( final T value1, final T value2 )
  691. {
  692. if ( value1.compareTo( value2 ) <= 0 )
  693. return value1;
  694. return value2;
  695. }
  696. public static boolean[][] getRecursiveCoordinates( final int numDimensions )
  697. {
  698. final boolean[][] positions = new boolean[ Util.pow( 2, numDimensions ) ][ numDimensions ];
  699. setCoordinateRecursive( numDimensions - 1, numDimensions, new int[ numDimensions ], positions );
  700. return positions;
  701. }
  702. /**
  703. * recursively get coordinates covering all binary combinations for the given dimensionality
  704. *
  705. * example for 3d:
  706. *
  707. * x y z index
  708. * 0 0 0 [0]
  709. * 1 0 0 [1]
  710. * 0 1 0 [2]
  711. * 1 1 0 [3]
  712. * 0 0 1 [4]
  713. * 1 0 1 [5]
  714. * 0 1 1 [6]
  715. * 1 1 1 [7]
  716. *
  717. * All typical call will look like that:
  718. *
  719. * boolean[][] positions = new boolean[ MathLib.pow( 2, numDimensions ) ][ numDimensions ];
  720. * MathLib.setCoordinateRecursive( numDimensions - 1, numDimensions, new int[ numDimensions ], positions );
  721. *
  722. * @param dimension - recusively changed current dimension, init with numDimensions - 1
  723. * @param numDimensions - the number of dimensions
  724. * @param location - recursively changed current state, init with new int[ numDimensions ]
  725. * @param result - where the result will be stored when finished, needes a boolean[ MathLib.pow( 2, numDimensions ) ][ numDimensions ]
  726. */
  727. public static void setCoordinateRecursive( final int dimension, final int numDimensions, final int[] location, final boolean[][] result )
  728. {
  729. final int[] newLocation0 = new int[ numDimensions ];
  730. final int[] newLocation1 = new int[ numDimensions ];
  731. for ( int d = 0; d < numDimensions; d++ )
  732. {
  733. newLocation0[ d ] = location[ d ];
  734. newLocation1[ d ] = location[ d ];
  735. }
  736. newLocation0[ dimension ] = 0;
  737. newLocation1[ dimension ] = 1;
  738. if ( dimension == 0 )
  739. {
  740. // compute the index in the result array ( binary to decimal
  741. // conversion )
  742. int index0 = 0, index1 = 0;
  743. for ( int d = 0; d < numDimensions; d++ )
  744. {
  745. index0 += newLocation0[ d ] * pow( 2, d );
  746. index1 += newLocation1[ d ] * pow( 2, d );
  747. }
  748. // fill the result array
  749. for ( int d = 0; d < numDimensions; d++ )
  750. {
  751. result[ index0 ][ d ] = ( newLocation0[ d ] == 1 );
  752. result[ index1 ][ d ] = ( newLocation1[ d ] == 1 );
  753. }
  754. }
  755. else
  756. {
  757. setCoordinateRecursive( dimension - 1, numDimensions, newLocation0, result );
  758. setCoordinateRecursive( dimension - 1, numDimensions, newLocation1, result );
  759. }
  760. }
  761. /**
  762. * <p>
  763. * Create a long[] with the dimensions of an {@link Interval}.
  764. * </p>
  765. *
  766. * <p>
  767. * Keep in mind that creating arrays wildly is not good practice and
  768. * consider using the interval directly.
  769. * </p>
  770. *
  771. * @param interval
  772. *
  773. * @return dimensions of the interval as a new long[]
  774. */
  775. final static public long[] intervalDimensions( final Interval interval )
  776. {
  777. final long[] dimensions = new long[ interval.numDimensions() ];
  778. interval.dimensions( dimensions );
  779. return dimensions;
  780. }
  781. final static public int[] long2int( final long[] a )
  782. {
  783. final int[] i = new int[ a.length ];
  784. for ( int d = 0; d < a.length; ++d )
  785. i[ d ] = ( int ) a[ d ];
  786. return i;
  787. }
  788. final static public long[] int2long( final int[] i )
  789. {
  790. final long[] l = new long[ i.length ];
  791. for ( int d = 0; d < l.length; ++d )
  792. l[ d ] = i[ d ];
  793. return l;
  794. }
  795. /**
  796. * <p>
  797. * Create a long[] with the max coordinates of an {@link Interval}.
  798. * </p>
  799. *
  800. * <p>
  801. * Keep in mind that creating arrays wildly is not good practice and
  802. * consider using the interval directly.
  803. * </p>
  804. *
  805. * @param interval
  806. *
  807. * @return dimensions of the interval as a new long[]
  808. */
  809. final static public long[] intervalMax( final Interval interval )
  810. {
  811. final long[] max = new long[ interval.numDimensions() ];
  812. interval.max( max );
  813. return max;
  814. }
  815. /**
  816. * <p>
  817. * Create a long[] with the min coordinates of an {@link Interval}.
  818. * </p>
  819. *
  820. * <p>
  821. * Keep in mind that creating arrays wildly is not good practice and
  822. * consider using the interval directly.
  823. * </p>
  824. *
  825. * @param interval
  826. *
  827. * @return dimensions of the interval as a new long[]
  828. */
  829. final static public long[] intervalMin( final Interval interval )
  830. {
  831. final long[] min = new long[ interval.numDimensions() ];
  832. interval.min( min );
  833. return min;
  834. }
  835. /**
  836. * <p>
  837. * Create a double[] with the dimensions of a {@link RealInterval}.
  838. * Dimensions are returned as <em>max</em> - <em>min</em>.
  839. * </p>
  840. *
  841. * <p>
  842. * Keep in mind that creating arrays wildly is not good practice and
  843. * consider using the interval directly.
  844. * </p>
  845. *
  846. * @param interval
  847. *
  848. * @return dimensions of the interval as a new double[]
  849. */
  850. final static public double[] realIntervalDimensions( final RealInterval interval )
  851. {
  852. final int n = interval.numDimensions();
  853. final double[] dimensions = new double[ interval.numDimensions() ];
  854. for ( int d = 0; d < n; ++d )
  855. dimensions[ d ] = interval.realMax( d ) - interval.realMin( d );
  856. return dimensions;
  857. }
  858. /**
  859. * <p>
  860. * Create a double[] with the max coordinates of a {@link RealInterval}.
  861. * Dimensions are returned as <em>max</em> - <em>min</em>.
  862. * </p>
  863. *
  864. * <p>
  865. * Keep in mind that creating arrays wildly is not good practice and
  866. * consider using the interval directly.
  867. * </p>
  868. *
  869. * @param interval
  870. *
  871. * @return dimensions of the interval as a new double[]
  872. */
  873. final static public double[] realIntervalMax( final RealInterval interval )
  874. {
  875. final int n = interval.numDimensions();
  876. final double[] max = new double[ interval.numDimensions() ];
  877. for ( int d = 0; d < n; ++d )
  878. max[ d ] = interval.realMax( d );
  879. return max;
  880. }
  881. /**
  882. * <p>
  883. * Create a double[] with the min coordinates of a {@link RealInterval}.
  884. * Dimensions are returned as <em>max</em> - <em>min</em>.
  885. * </p>
  886. *
  887. * <p>
  888. * Keep in mind that creating arrays wildly is not good practice and
  889. * consider using the interval directly.
  890. * </p>
  891. *
  892. * @param interval
  893. *
  894. * @return dimensions of the interval as a new double[]
  895. */
  896. final static public double[] realIntervalMin( final RealInterval interval )
  897. {
  898. final int n = interval.numDimensions();
  899. final double[] min = new double[ interval.numDimensions() ];
  900. for ( int d = 0; d < n; ++d )
  901. min[ d ] = interval.realMin( d );
  902. return min;
  903. }
  904. /**
  905. * Gets an instance of T from the {@link RandomAccessibleInterval} by
  906. * querying the value at the min coordinate
  907. *
  908. * @param <T>
  909. * - the T
  910. * @param rai
  911. * - the {@link RandomAccessibleInterval}
  912. * @return - an instance of T
  913. */
  914. final public static < T, F extends Interval & RandomAccessible< T >> T getTypeFromInterval( final F rai )
  915. {
  916. // create RandomAccess
  917. final RandomAccess< T > randomAccess = rai.randomAccess();
  918. // place it at the first pixel
  919. rai.min( randomAccess );
  920. return randomAccess.get();
  921. }
  922. /**
  923. * Gets an instance of T from the {@link RandomAccessible}
  924. *
  925. * @param <T>
  926. * - the T
  927. * @param rai
  928. * - the {@link RandomAccessible}
  929. * @return - an instance of T
  930. */
  931. final public static < T > T getTypeFromRandomAccess( final RandomAccessible< T > ra )
  932. {
  933. // test that it is not an interval, because in this case a simple get()
  934. // at the position of creation will fail
  935. if ( RandomAccessibleInterval.class.isInstance( ra ) )
  936. return getTypeFromInterval( ( RandomAccessibleInterval< T > ) ra );
  937. return ra.randomAccess().get();
  938. }
  939. /**
  940. * Gets an instance of T from the {@link RandomAccessibleInterval} by
  941. * querying the value at the min coordinate
  942. *
  943. * @param <T>
  944. * - the T
  945. * @param rai
  946. * - the {@link RandomAccessibleInterval}
  947. * @return - an instance of T
  948. */
  949. final public static < T, F extends RealInterval & RealRandomAccessible< T >> T getTypeFromRealInterval( final F rai )
  950. {
  951. // create RealRandomAccess
  952. final RealRandomAccess< T > realRandomAccess = rai.realRandomAccess();
  953. // place it at the first pixel
  954. rai.realMin( realRandomAccess );
  955. return realRandomAccess.get();
  956. }
  957. /**
  958. * Gets an instance of T from the {@link RealRandomAccessible}
  959. *
  960. * @param <T>
  961. * - the T
  962. * @param rai
  963. * - the {@link RealRandomAccessible}
  964. * @return - an instance of T
  965. */
  966. final public static < T > T getTypeFromRealRandomAccess( final RealRandomAccessible< T > ra )
  967. {
  968. // test that it is not an interval, because in this case a simple get()
  969. // at the position of creation will fail
  970. if ( RealRandomAccessibleRealInterval.class.isInstance( ra ) )
  971. return getTypeFromRealInterval( ( RealRandomAccessibleRealInterval< T > ) ra );
  972. return ra.realRandomAccess().get();
  973. }
  974. /**
  975. * (Hopefully) fast floor log<sub>2</sub> of an unsigned(!) integer value.
  976. *
  977. * @param v
  978. * unsigned integer
  979. * @return floor log<sub>2</sub>
  980. */
  981. final static public int ldu( int v )
  982. {
  983. int c = 0;
  984. do
  985. {
  986. v >>= 1;
  987. ++c;
  988. }
  989. while ( v > 1 );
  990. return c;
  991. }
  992. /**
  993. * Checks whether n {@link IterableInterval} have the same iteration order.
  994. */
  995. public static boolean equalIterationOrder( IterableInterval< ? >... intervals )
  996. {
  997. Object order = intervals[ 0 ].iterationOrder();
  998. for ( int i = 1; i < intervals.length; i++ )
  999. {
  1000. if ( !order.equals( intervals[ i ].iterationOrder() ) )
  1001. return false;
  1002. }
  1003. return true;
  1004. }
  1005. }