25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Up   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music  

mylib.js - JavaScript function library

While creating JavaScript versions of some of my C and C++ programs to run on web pages, I'll need to convert utility functions from mylib.cpp. The source code is listed on this page.

You can copy the code below, or download (Save) the file.

mylib.js

 
/*	mylib.js			2012-05-21
	Copyright (C)2012 Steven Whitney.
	Initially published by http://25yearsofprogramming.com.

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License (GPL)
	Version 3 as published by the Free Software Foundation.
	This program 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
	GNU General Public License for more details.
	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Library of utility functions.

*/
//----------------------------------------------------------------------------------------------
// RANDOM NUMBERS
//----------------------------------------------------------------------------
// Random integer.
// Examples: 
// RandomInt(2) returns 0 or 1
// var x = -1 + RandomInt(3); // produces -1 or 0 or +1

function RandomInt(top)
{
top = Math.max(top, 0);
return Math.floor(Math.random() * top);
}

//----------------------------------------------------------------------------------------------
// Returns a normally distributed random number from the distribution with the given mean and standard deviation. 
// That is, values close to the mean are returned often, values far from the mean are returned rarely.
// To get nearest integer: Math.round(NormalRandom(mean,stddev)).
function NormalRandom(mean, stddev)
{
	return Math.sqrt(-2 * Math.log(Math.random())) * Math.cos(2 * Math.PI * Math.random()) * stddev + mean;
}

//============================================================================
// OTHER MATH FUNCTIONS
//----------------------------------------------------------------------------
// TWO TRIG FUNCTIONS TAKING DEGREES INSTEAD OF RADIANS.

function sine(degrees)
{
// return Math.sin(degrees * Math.PI / 180);		// MAXIMUM PRECISION, BUT SLOWER
return Math.sin(degrees * 0.017453292519943295);	// PRECALCULATED
}

//----------------------------------------------------------------------------

function cosine(degrees)
{
// return Math.cos(degrees * Math.PI / 180);
return Math.cos(degrees * 0.017453292519943295);
}

//============================================================================
// CLEANING, VALIDATION FUNCTIONS
// --------------------------------------------------------------------------------
// CLEAN USER-ENTERED TEXT SUCH AS FROM AN INPUT CONTROL PRIOR TO VALIDATION

function TrimCleanCompressTextLine(s)
{
// [[:space:]][[:graph:]] DON'T WORK. NO POSIX IN JAVASCRIPT REGEX.
s = s.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');	// DELETE NONSPACE CONTROL CHARS 
s = s.replace(/^\s+/, '');								// DELETE LEADING SPACE
s = s.replace(/\s+$/, '');								// DELETE TRAILING SPACE
s = s.replace(/\s+/g, ' ');								// COMPRESS INTERNAL SPACE
return s;
}

//============================================================================
// COLOR RELATED FUNCTIONS
//----------------------------------------------------------------------------
// RETURNS A RANDOM COLOR (R, G, B) COMPONENT (INT 0-255) THAT IS A RANDOM WALK FROM THE 
// GIVEN ONE AND WRAPPED INTO LEGAL RANGE FOR A COLOR.

function MakeRandomWalkColorComponent(oldval, MaxStep)
{
// oldval = STARTING COLOR COMPONENT VALUE (0-255)
oldval = Math.max(oldval, 0);
oldval = Math.min(oldval, 255);

// MaxStep = MAXIMUM AMOUNT TO ADD TO IT (INT)
// MaxStep MUST BE >= 2 SO THAT RandomInt(MaxStep) CAN POTENTIALLY BE > 0.
// THE CALLER IS SUPPOSED TO ENFORCE THAT RULE. THIS IS A SECOND CHECK.
MaxStep = Math.max(MaxStep, 2);

// ADD A RANDOM AMOUNT, THEN WRAP INTO RANGE
return (oldval + RandomInt(MaxStep)) % 256;
}          						//MakeRandomWalkColorComponent

//----------------------------------------------------------------------------
// RETURNS AN ARRAY CONTAINING THE COMPONENTS (R G B) FROM A CSS FORMATTED COLOR, 
// OR FALSE ON ERROR.
// INPUT VALUE IS 6 HEX DIGITS WITH OR WITHOUT A LEADING #.

function ExtractColorComponentsCSS(color)
{
var rgb = new Array();
var m = color.match(/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i);
if(m)
{
	// Number() would work the same as parseInt.
	rgb.push(parseInt("0X" + m[1]));	
	rgb.push(parseInt("0X" + m[2]));
	rgb.push(parseInt("0X" + m[3]));

	return rgb;
}
return false;		
}								//ExtractColorComponentsCSS

//----------------------------------------------------------------------------
// RETURNS A STRING FORMATTING A CSS COLOR INTO R G B FORMAT.
// OR FALSE IF CSSCOLOR COULD NOT BE PARSED AS A COLOR.

function FormatColorRGB(csscolor)
{
var a = ExtractColorComponentsCSS(csscolor);
if(a)
	return a.join(" ");
return false;
}

//----------------------------------------------------------------------------
// RETURNS A STRING FORMATTING AN (R, G, B) COLOR INTO CSS COMPATIBLE #XXXXXX.

function FormatColorCSS(r, g, b)
{
r = Math.max(r, 0);
r = Math.min(r, 255);

g = Math.max(g, 0);
g = Math.min(g, 255);

b = Math.max(b, 0);
b = Math.min(b, 255);

r = Number(r).toString(16);
g = Number(g).toString(16);
b = Number(b).toString(16);

while(r.length < 2) { r = "0" + r; }
while(g.length < 2) { g = "0" + g; }
while(b.length < 2) { b = "0" + b; }

return ('#' + r + g + b).toUpperCase();
}								//FormatColorCSS

//----------------------------------------------------------------------------
// A LEGAL CSS COLOR IS A POUND SIGN FOLLOWED BY 6 HEX DIGITS.
// (THE 3 DIGIT OPTION IS NOT ALLOWED HERE).
// RETURNS THE COLOR STRING WITH # PREPENDED IF NECESSARY, OR FALSE.

function IsLegalColorCSS(s)
{
if(s.match(/^#?[0-9A-F]{6}$/i))
{
	if(s.charAt(0) != "#")
		s = "#" + s;
	return s;
}
return false;
}								//IsLegalColorCSS

//----------------------------------------------------------------------------
// A LEGAL .MAP COLOR IS 3 DECIMAL NUMBERS BETWEEN 0-255 SEPARATED BY SPACE.
// RETURNS AN ARRAY CONTAINING THE R,G,B COMPONENTS, OR FALSE.

function IsLegalColorMAP(s)
{
var m = s.match(/^(\d{1,3})\s+(\d{1,3})\s+(\d{1,3})/);
if(m)
{
	if(  (m[1] >= 0) && (m[1] <= 255) && 
		 (m[2] >= 0) && (m[2] <= 255) &&
		 (m[3] >= 0) && (m[3] <= 255))
	{
		return m;
	}
}
return false;
}								//IsLegalColorMAP

//----------------------------------------------------------------------------
// RETURNS A RANDOM RGB COLOR FORMATTED IN CSS STYLE

function RandomColorCSS()
{
return FormatColorCSS(RandomInt(256), RandomInt(256), RandomInt(256));
}

//----------------------------------------------------------------------------------------------
// DATE AND TIME
//----------------------------------------------------------------------------------------------
// Number of calendar days between two dates.
// StartDate and EndDate must be Date objects. If StartDate > EndDate, returns negative.
function CalendarDaysBetween(StartDate, EndDate)
{
	// Explicitly set time to 0, even though a date specified with mm/dd/yyyy has 0 in all its time components.
	StartDate.setHours(0,0,0,0);
	EndDate.setHours(0,0,0,0); 
	return Math.round((EndDate - StartDate) / 86400000); //milliseconds in a day. round ensures it's an integer. 
}


////////////////////////////////////////////////////////////////////////////////////////////////
//	MODIFIED GNU SCIENTIFIC LIBRARY FUNCTIONS
//----------------------------------------------------------------------------------------------
/*
	The functions in this section are copied and greatly modified from the 
	GNU Scientific Library version 1.12, specifically from exponential.c, levy.c. 
	Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 James Theiler, Brian Gough
	Copyright (C) 2009 Steven Whitney. The following modifications made:
	2-27-2009:
	Converted my C++ conversions of these functions to JavaScript; 
	substituted JavaScript methods for calls to external GSL functions;
	used different function names, condensed, reorganized, reformatted.
*/	
//----------------------------------------------------------------------------
// RANDOM NUMBER FROM EXPONENTIAL DISTRIBUTION
//----------------------------------------------------------------------------
// The exponential distribution has the form p(x) dx = exp(-x/mu) dx/mu, for x = 0 to +infinity 
function GSLRandomExponential(mu)
{
var u;
do			// emulate gsl_rng_uniform_pos()
{
	u = Math.random()	// returns [0-1)
}
while(u == 0);			// discard 0
return -mu * Math.log(u);
}
//----------------------------------------------------------------------------
//	RANDOM NUMBER FROM LEVY ALPHA-STABLE DISTRIBUTION
//----------------------------------------------------------------------------
/*
	The stable Levy probability distributions have the form
	p(x) dx = (1/(2 pi)) \int dt exp(- it x - |c t|^alpha)
	with 0 < alpha <= 2. 

	For alpha = 1, we get the Cauchy distribution
	For alpha = 2, we get the Gaussian distribution with sigma = sqrt(2) c.

	From Chapter 5 of Bratley, Fox and Schrage "A Guide to Simulation". The original reference given there is,
	J.M. Chambers, C.L. Mallows and B. W. Stuck. "A method for simulating stable random variates". 
	Journal of the American Statistical Association, JASA 71 340-344 (1976).

	See also: 
	http://en.wikipedia.org/wiki/Stable_distributions 
	http://en.wikipedia.org/wiki/L%C3%A9vy_distribution
	Apparent properties of the values returned: 
	mean (mu) = 0; 
	c = scale (dispersion) parameter, analogous to standard deviation in a normal distribution.
	alpha = kurtosis. High alpha -> broad peak, platykurtotic. Low alpha -> pointy with fat tails, leptokurtotic.
	This function does not provide for a beta (skewness) value.
*/
function GSLRandomLevy(c, alpha)
{
// enforce limits by returning a value that will be obviously wrong (all zeroes)
if((alpha <= 0) || (alpha > 2))	
	return 0;
	
var u;
do			// emulate gsl_rng_uniform_pos()
{
	u = Math.random()	// returns [0-1)
}
while(u == 0);				// discard 0
u = Math.PI * (u - 0.5);

if(alpha == 1)				// Cauchy case 
	return c * Math.tan(u);

var v;
do			// emulate gsl_ran_exponential()
{
	v = GSLRandomExponential(1);
}
while(v == 0);

if(alpha == 2)				// Gaussian case 
	return c * (2 * Math.sin(u) * Math.sqrt(v));

// general case
var t = Math.sin(alpha * u) / Math.pow(Math.cos(u), 1 / alpha);
var s = Math.pow(Math.cos((1 - alpha) * u) / v, (1 - alpha) / alpha);
return c * t * s;
}
//----------------------------------------------------------------------------
// END OF MODIFIED GNU SCIENTIFIC LIBRARY FUNCTIONS
////////////////////////////////////////////////////////////////////////////////////////////////

 

Valid HTML 4.01 Transitional
Yahoo! Search
Search the web Search this site
Valid CSS