misc.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*************************************************************************
  2. * *
  3. * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
  4. * All rights reserved. Email: [email protected] Web: www.q12.org *
  5. * *
  6. * This library is free software; you can redistribute it and/or *
  7. * modify it under the terms of EITHER: *
  8. * (1) The GNU Lesser General Public License as published by the Free *
  9. * Software Foundation; either version 2.1 of the License, or (at *
  10. * your option) any later version. The text of the GNU Lesser *
  11. * General Public License is included with this library in the *
  12. * file LICENSE.TXT. *
  13. * (2) The BSD-style license that is included with this library in *
  14. * the file LICENSE-BSD.TXT. *
  15. * *
  16. * This library is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
  19. * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
  20. * *
  21. *************************************************************************/
  22. #include <ode/odeconfig.h>
  23. #include <ode/misc.h>
  24. #include "config.h"
  25. #include "matrix.h"
  26. #include "error.h"
  27. #include "odeou.h"
  28. //****************************************************************************
  29. // random numbers
  30. static volatile duint32 seed = 0;
  31. unsigned long dRand()
  32. {
  33. duint32 origSeed, newSeed;
  34. #if !dTHREADING_INTF_DISABLED
  35. do {
  36. #endif
  37. origSeed = seed;
  38. newSeed = ((duint32)1664525 * origSeed + (duint32)1013904223) & (duint32)0xffffffff;
  39. #if dTHREADING_INTF_DISABLED
  40. seed = newSeed;
  41. #else
  42. } while (!AtomicCompareExchange((volatile atomicord32 *)&seed, origSeed, newSeed));
  43. #endif
  44. return newSeed;
  45. }
  46. unsigned long dRandGetSeed()
  47. {
  48. return seed;
  49. }
  50. void dRandSetSeed (unsigned long s)
  51. {
  52. seed = s;
  53. }
  54. int dTestRand()
  55. {
  56. unsigned long oldseed = seed;
  57. int ret = 1;
  58. seed = 0;
  59. if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 ||
  60. dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 ||
  61. dRand() != 0x6252e503) ret = 0;
  62. seed = oldseed;
  63. return ret;
  64. }
  65. // adam's all-int straightforward(?) dRandInt (0..n-1)
  66. int dRandInt (int n)
  67. {
  68. int result;
  69. // Since there is no memory barrier macro in ODE assign via volatile variable
  70. // to prevent compiler reusing seed as value of `r'
  71. volatile unsigned long raw_r = dRand();
  72. duint32 r = (duint32)raw_r;
  73. duint32 un = n;
  74. dIASSERT(sizeof(n) == sizeof(un));
  75. // note: probably more aggressive than it needs to be -- might be
  76. // able to get away without one or two of the innermost branches.
  77. // if (un <= 0x00010000UL) {
  78. // r ^= (r >> 16);
  79. // if (un <= 0x00000100UL) {
  80. // r ^= (r >> 8);
  81. // if (un <= 0x00000010UL) {
  82. // r ^= (r >> 4);
  83. // if (un <= 0x00000004UL) {
  84. // r ^= (r >> 2);
  85. // if (un <= 0x00000002UL) {
  86. // r ^= (r >> 1);
  87. // }
  88. // }
  89. // }
  90. // }
  91. // }
  92. // Optimized version of above
  93. if (un <= (duint32)0x00000010) {
  94. r ^= (r >> 16);
  95. r ^= (r >> 8);
  96. r ^= (r >> 4);
  97. if (un <= (duint32)0x00000002) {
  98. r ^= (r >> 2);
  99. r ^= (r >> 1);
  100. result = (r/* & (duint32)0x01*/) & (un >> 1);
  101. } else {
  102. if (un <= (duint32)0x00000004) {
  103. r ^= (r >> 2);
  104. result = ((r & (duint32)0x03) * un) >> 2;
  105. } else {
  106. result = ((r & (duint32)0x0F) * un) >> 4;
  107. }
  108. }
  109. } else {
  110. if (un <= (duint32)0x00000100) {
  111. r ^= (r >> 16);
  112. r ^= (r >> 8);
  113. result = ((r & (duint32)0xFF) * un) >> 8;
  114. } else {
  115. if (un <= (duint32)0x00010000) {
  116. r ^= (r >> 16);
  117. result = ((r & (duint32)0xFFFF) * un) >> 16;
  118. } else {
  119. result = (int)(((duint64)r * un) >> 32);
  120. }
  121. }
  122. }
  123. return result;
  124. }
  125. dReal dRandReal()
  126. {
  127. return (dReal)(((double) dRand()) / ((double) 0xffffffff));
  128. }
  129. //****************************************************************************
  130. // matrix utility stuff
  131. void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f)
  132. {
  133. int skip = dPAD(m);
  134. const dReal *Arow = A;
  135. for (int i=0; i<n; Arow+=skip, ++i) {
  136. for (int j=0; j<m; ++j) fprintf (f,fmt,Arow[j]);
  137. fprintf (f,"\n");
  138. }
  139. }
  140. void dMakeRandomVector (dReal *A, int n, dReal range)
  141. {
  142. int i;
  143. for (i=0; i<n; i++) A[i] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
  144. }
  145. void dMakeRandomMatrix (dReal *A, int n, int m, dReal range)
  146. {
  147. int skip = dPAD(m);
  148. // dSetZero (A,n*skip);
  149. dReal *Arow = A;
  150. for (int i=0; i<n; Arow+=skip, ++i) {
  151. for (int j=0; j<m; ++j) Arow[j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
  152. }
  153. }
  154. void dClearUpperTriangle (dReal *A, int n)
  155. {
  156. int skip = dPAD(n);
  157. dReal *Arow = A;
  158. for (int i=0; i<n; Arow+=skip, ++i) {
  159. for (int j=i+1; j<n; ++j) Arow[j] = 0;
  160. }
  161. }
  162. dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m)
  163. {
  164. int skip = dPAD(m);
  165. dReal max = REAL(0.0);
  166. const dReal *Arow = A, *Brow = B;
  167. for (int i=0; i<n; Arow+=skip, Brow +=skip, ++i) {
  168. for (int j=0; j<m; ++j) {
  169. dReal diff = dFabs(Arow[j] - Brow[j]);
  170. if (diff > max) max = diff;
  171. }
  172. }
  173. return max;
  174. }
  175. dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n)
  176. {
  177. int skip = dPAD(n);
  178. dReal max = REAL(0.0);
  179. const dReal *Arow = A, *Brow = B;
  180. for (int i=0; i<n; Arow+=skip, Brow+=skip, ++i) {
  181. for (int j=0; j<=i; ++j) {
  182. dReal diff = dFabs(Arow[j] - Brow[j]);
  183. if (diff > max) max = diff;
  184. }
  185. }
  186. return max;
  187. }