/*****

*Property of the University of British Columbia (UBC),

*Copyright 2001, by UBC.

*

*By receiving this code, you are agreeing to the following terms:

*1. You will use this code for academic purposes only.

*2. For academic use only, you may distribute the binary or executable code

*   to persons at UBC or the Univ. of Western Australia who have previously 

*   read and agreed to these terms, but you must distribute the SOURCE code

*   with it. 

*3. Each file of source code so distributed must have this header attached.

*4. If the code is revised, the programmer's name and revision date must be added

*   to the Revision List below, as well as the revisions identified in the code.

*5. You will not make this code more widely available via any method such as 

*   publishing in print, email mail-list, usenet posting, website etc.

*6. UBC reserves all rights to this work and all derivative works.

*

*For other proposed purposes please contact:

*The University-Industry Liaison Office 

*IRC Room 331 - 2194 Health Sciences Mall 

*University of British Columbia 

*Vancouver, BC, Canada V6T 1Z3 

*Tel: (604) 822-8580 

*Fax: (604) 822-8589 

*

*or contact: 

*Peter D. Lawrence, Professor at peterl@ece.ubc.ca or 

*Greg Z. Grudic, Assistant Professor, at grudic@cs.colorado.edu

*

*Revision List: 

*Greg Grudic, August 28, 1998.

*****/



/*

%

% File:		rand.c

% Program: 	Random Number functions for Functional Approximation code

%

% Author:	Greg Grudic 

%

*/



#include "b_pc.h"



double Greg_Rand(unsigned short xsubi[3])

{

  float ran4(long *idum);



  double t1;



  static int Initialize = 0;



  static long my_idum;



  if ( Initialize == 0 )

    {

      my_idum = (long)xsubi[0] * (long)xsubi[1] * (long)xsubi[2];



      Initialize = 1;

    }



  t1 = (double)ran4(&my_idum);



  return(t1);

}









#define NITER 4



void psdes(unsigned long *lword, unsigned long *irword)

{

	unsigned long i,ia,ib,iswap,itmph=0,itmpl=0;

	static unsigned long c1[NITER]={

		0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L};

	static unsigned long c2[NITER]={

		0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L};



	for (i=0;i<NITER;i++) {

		ia=(iswap=(*irword)) ^ c1[i];

		itmpl = ia & 0xffff;

		itmph = ia >> 16;

		ib=itmpl*itmpl+ ~(itmph*itmph);

		*irword=(*lword) ^ (((ia = (ib >> 16) |

			((ib & 0xffff) << 16)) ^ c2[i])+itmpl*itmph);

		*lword=iswap;

	}

}

#undef NITER







/* (C) Copr. 1986-92 Numerical Recipes Software 'j''25E#. */

float ran4(long *idum)

{

	void psdes(unsigned long *lword, unsigned long *irword);

	unsigned long irword,itemp,lword;

	static long idums = 0;

#if defined(vax) || defined(_vax_) || defined(__vax__) || defined(VAX)

	static unsigned long jflone = 0x00004080;

	static unsigned long jflmsk = 0xffff007f;

#else

	static unsigned long jflone = 0x3f800000;

	static unsigned long jflmsk = 0x007fffff;

#endif



	if (*idum < 0) {

		idums = -(*idum);

		*idum=1;

	}

	irword=(*idum);

	lword=idums;

	psdes(&lword,&irword);

	itemp=jflone | (jflmsk & irword);

	++(*idum);

	return (*(float *)&itemp)-(float)1.0;

}

/* (C) Copr. 1986-92 Numerical Recipes Software 'j''25E#. */

