| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: [email protected] Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
- #include <ode/odeconfig.h>
- #include <ode/misc.h>
- #include "config.h"
- #include "matrix.h"
- #include "error.h"
- #include "odeou.h"
- //****************************************************************************
- // random numbers
- static volatile duint32 seed = 0;
- unsigned long dRand()
- {
- duint32 origSeed, newSeed;
- #if !dTHREADING_INTF_DISABLED
- do {
- #endif
- origSeed = seed;
- newSeed = ((duint32)1664525 * origSeed + (duint32)1013904223) & (duint32)0xffffffff;
- #if dTHREADING_INTF_DISABLED
- seed = newSeed;
- #else
- } while (!AtomicCompareExchange((volatile atomicord32 *)&seed, origSeed, newSeed));
- #endif
- return newSeed;
- }
- unsigned long dRandGetSeed()
- {
- return seed;
- }
- void dRandSetSeed (unsigned long s)
- {
- seed = s;
- }
- int dTestRand()
- {
- unsigned long oldseed = seed;
- int ret = 1;
- seed = 0;
- if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 ||
- dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 ||
- dRand() != 0x6252e503) ret = 0;
- seed = oldseed;
- return ret;
- }
- // adam's all-int straightforward(?) dRandInt (0..n-1)
- int dRandInt (int n)
- {
- int result;
- // Since there is no memory barrier macro in ODE assign via volatile variable
- // to prevent compiler reusing seed as value of `r'
- volatile unsigned long raw_r = dRand();
- duint32 r = (duint32)raw_r;
-
- duint32 un = n;
- dIASSERT(sizeof(n) == sizeof(un));
- // note: probably more aggressive than it needs to be -- might be
- // able to get away without one or two of the innermost branches.
- // if (un <= 0x00010000UL) {
- // r ^= (r >> 16);
- // if (un <= 0x00000100UL) {
- // r ^= (r >> 8);
- // if (un <= 0x00000010UL) {
- // r ^= (r >> 4);
- // if (un <= 0x00000004UL) {
- // r ^= (r >> 2);
- // if (un <= 0x00000002UL) {
- // r ^= (r >> 1);
- // }
- // }
- // }
- // }
- // }
- // Optimized version of above
- if (un <= (duint32)0x00000010) {
- r ^= (r >> 16);
- r ^= (r >> 8);
- r ^= (r >> 4);
- if (un <= (duint32)0x00000002) {
- r ^= (r >> 2);
- r ^= (r >> 1);
- result = (r/* & (duint32)0x01*/) & (un >> 1);
- } else {
- if (un <= (duint32)0x00000004) {
- r ^= (r >> 2);
- result = ((r & (duint32)0x03) * un) >> 2;
- } else {
- result = ((r & (duint32)0x0F) * un) >> 4;
- }
- }
- } else {
- if (un <= (duint32)0x00000100) {
- r ^= (r >> 16);
- r ^= (r >> 8);
- result = ((r & (duint32)0xFF) * un) >> 8;
- } else {
- if (un <= (duint32)0x00010000) {
- r ^= (r >> 16);
- result = ((r & (duint32)0xFFFF) * un) >> 16;
- } else {
- result = (int)(((duint64)r * un) >> 32);
- }
- }
- }
- return result;
- }
- dReal dRandReal()
- {
- return (dReal)(((double) dRand()) / ((double) 0xffffffff));
- }
- //****************************************************************************
- // matrix utility stuff
- void dPrintMatrix (const dReal *A, int n, int m, const char *fmt, FILE *f)
- {
- int skip = dPAD(m);
- const dReal *Arow = A;
- for (int i=0; i<n; Arow+=skip, ++i) {
- for (int j=0; j<m; ++j) fprintf (f,fmt,Arow[j]);
- fprintf (f,"\n");
- }
- }
- void dMakeRandomVector (dReal *A, int n, dReal range)
- {
- int i;
- for (i=0; i<n; i++) A[i] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
- }
- void dMakeRandomMatrix (dReal *A, int n, int m, dReal range)
- {
- int skip = dPAD(m);
- // dSetZero (A,n*skip);
- dReal *Arow = A;
- for (int i=0; i<n; Arow+=skip, ++i) {
- for (int j=0; j<m; ++j) Arow[j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
- }
- }
- void dClearUpperTriangle (dReal *A, int n)
- {
- int skip = dPAD(n);
- dReal *Arow = A;
- for (int i=0; i<n; Arow+=skip, ++i) {
- for (int j=i+1; j<n; ++j) Arow[j] = 0;
- }
- }
- dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m)
- {
- int skip = dPAD(m);
- dReal max = REAL(0.0);
- const dReal *Arow = A, *Brow = B;
- for (int i=0; i<n; Arow+=skip, Brow +=skip, ++i) {
- for (int j=0; j<m; ++j) {
- dReal diff = dFabs(Arow[j] - Brow[j]);
- if (diff > max) max = diff;
- }
- }
- return max;
- }
- dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n)
- {
- int skip = dPAD(n);
- dReal max = REAL(0.0);
- const dReal *Arow = A, *Brow = B;
- for (int i=0; i<n; Arow+=skip, Brow+=skip, ++i) {
- for (int j=0; j<=i; ++j) {
- dReal diff = dFabs(Arow[j] - Brow[j]);
- if (diff > max) max = diff;
- }
- }
- return max;
- }
|