BeginPackage["UVW`Pseugene`"]
(* Version 2.0, 08/15/97 *) 

CongruGenerator::usage = "
CongruGenerator[seed,a,c,m,n] returns a list of the n first iterates of the 
congruential generator
		  x(n+1) = a x(n) + c  Modulo m .
seed is the first element x(0). If seed is an integer, the result will 
be a list of integers between 0 and m . If seed is real, all the results
will be divided by m to return a list of reals between 0 and 1 ."


MidsquareGenerator::usage = " 
MidsquareGenerator[seed,n] returns a list of the first iterates of the 
midsquare generator, starting with seed (four digits integer)."


CongruentialLoop::usage = " 
CongruentialLoop[seed,a,c,m] returns in a list the loop of the congruential 
generator
		 x(n+1) = a x(n) + c  Modulo m ,
starting with x(0)=seed ."


MidsquareLoop::usage =" 
MidsquareLoop[seed] returns in a list the loop of the midsquare generator, 
starting with seed."




Begin["`Private`"]


CongruGenerator[seed_,a_,c_,m_,n_]:= 

   Block[ {f, y, res},

	 f[y_]:= Mod[ a y + c, m ];
	 
	 If[ IntegerQ[seed],
	     res = NestList[ f, seed, n-1 ] ,
	     res = NestList[ f, m*(seed-Floor[seed]) , n-1 ] /m  
	   ];

	 Return[res];
       ];



MidsquareGenerator[seed_,n_]:= 

   Block[ {mids,x},

	mids[x_]:=Block[{res},
		     res = Floor[x*x/100];
		     res = res - (10000*Floor[res/10000]);
		     Return[res];
		       ];
	Return[ NestList[ mids , seed , n-1 ] ];  
	
	];
 


CongruentialLoop[seed_,a_,c_,m_]:= 

   Block[ {f, y , pos , element , loop={} },


	  f[y_]:= Mod[ a y + c, m ];

	  loop = Append[loop,seed];
	  element= f[ seed ];

	  While[ !MemberQ[loop,element],
		 (
		 loop  = Append[loop,element];
		 element = f[element]
		 )
	       ];

	  pos    = First[Flatten[Position[loop,element]]]; 
	  loop = Drop[ loop, pos-1 ];
	  loop = Append[loop,element];
	  Return[loop];
  
	];

 
MidsquareLoop[seed_]:= 

   Block[ {f, x , pos , element , loop={} },

	  f[x_]:=Block[{res},
		     res = Floor[x*x/100];
		     res = res - (10000*Floor[res/10000]);
		     Return[res];
		      ];
	  loop  = Append[loop,seed];
	  element = f[ seed ];

	  While[ !MemberQ[loop,element],
		 (
		 loop  = Append[loop,element];
		 element = f[element]
		 )
	       ];

	  pos    = First[Flatten[Position[loop,element]]]; 
	  loop = Drop[ loop, pos-1 ];
	  loop = Append[loop,element];
	  Return[loop];

	];  


End[ ]


EndPackage[ ]
