Modular arithmetic does not work in Threshold signature (TSS) implementation - javascript

I was implementing threshold signatures protocol described in this paper and I run into a case where it fails and I don't understand reasons why. In the end, u and x should be the same, but they are not. I would appreciate any advice that will help me to find the bug.
This is JS code, it can be executed in browser console
/// TSS 2-of-2 case
// Field modulus, secp2561k
n = 115792089237316195423570985008687907852837564279074904382605163141518161494337n
// party 1 Polynomial coeff of degree 1
coeff_1 = 103808273981011494448342588544071102049904991793672697167547228275701563388858n
// coeff_1 = 10380827398101149444834258854407110204990499179367269716754722827570156338885n // Working coeff
// party 1 Polynomial coeff of degree 1
coeff_2 = 49961718147812071312795198333632033669565055597187655909241672498689891015278n
// coeff_2 = 4996171814781207131279519833363203366956505559718765590924167249868989101527n // Working coeff
// Party 1 secret
u_1 = 6989964936015280241594720270850184250394589151026058230978623558313385587815n
// Party 2 secret
u_2 = 91492373973552717359377053249757253672786176158857596037729237022345023720795n
// Party 1 Shamir points
y1_x = 1n
y1_1 = (y1_x * coeff_1 + u_1) % n
// 110798238917026774689937308814921286300299580944698755398525851834014948976673n
y1_2 = (y1_x * coeff_2 + u_2) % n
// 25662002884048593248601266574701379489513667476970347564365746379516753241736n
// Party 2 Shamir points
y2_x = 2n
y2_1 = (y2_x * coeff_1 + u_1) % n
// 98814423660722073714708912350304480497367008459296548183467916968198350871194n
y2_2 = (y2_x * coeff_2 + u_2) % n
// 75623721031860664561396464908333413159078723074158003473607418878206644257014n
// Party 1 point (y1_x, y1)
y1 = (y1_1 + y1_2) % n
// Party 2 point (y1_x, y1)
y2 = (y2_1 + y2_2) % n
// Common secret
u = (u_1 + u_2) % n
// Same secret, that went though Shamir schema
x = (y1*2n - y2) % n
// Checking calculations, should be 0
u - x
```

Your code is almost correct, just missing the final modulus at the end. Change the last line to
(u - x) % n;
The (u -x) is exactly n.
115792089237316195423570985008687907852837564279074904382605163141518161494337

Related

A DFT analysis in a low speed data sampling

I have some sample data of vibrations analysis from sensors installed on electrical motors. The sampling is made once or, at most, 3 times per day. The values can be expressed in g, gE or mm/s.
I’m developing a personal algorithm in JavaScript to process some samples and perform a DFT. It’s a simple code that uses brute force to process my results. I compared the results (real and imaginary parts) from JavaScript and from MATLAB results and they matched perfectly.
However, my sampling rate is very slow. Because of this, I have a lot of questions which I couldn’t find the answers on my searches:
Is it possible to apply a DFT analysis on a slow sampling data as this?
How can I determine the correct frequency scale for the X axis? It’s complicated for me because I don’t have an explicit Fs (sampling rate) value.
In my case, would it be interesting to apply some window function like Hanning Window (suitable for vibrations analyses)?
JavaScriptCode:
//Signal is a pure one-dimensional of real data (vibration values)
const fft = (signal) => {
const pi2 = 6.2832 //pi const
let inputLength = signal.length;
let Xre = new Array(inputLength); //DFT real part
let Xim = new Array(inputLength); //DFT imaginary part
let P = new Array(inputLength); //Power of spectrum
let M = new Array(inputLength); //Magnitude of spectrum
let angle = 2 * Math.PI / inputLength;
//Hann Window
signal = signal.map((x, index) => {
return x * 0.5 * (1 - Math.cos((2 * Math.PI * index) / (inputLength - 1)));
});
for (let k = 0; k < inputLength; ++k) { // For each output element
Xre[k] = 0; Xim[k] = 0;
for (let n = 0; n < inputLength; ++n) { // For each input element
Xre[k] += signal[n] * Math.cos(angle * k * n);
Xim[k] -= signal[n] * Math.sin(angle * k * n);
}
P[k] = Math.pow(Xre[k], 2) + Math.pow(Xim[k], 2);
M[k] = Math.sqrt(Math.pow(Xre[k], 2) + Math.pow(Xim[k], 2));
}
return { Xre: Xre, Xim: Xim, P: P, M: M.slice(0, Math.round((inputLength / 2) + 1)) };
}
The first figure shows the charts results (time domain on the left side and frequency domain on the right side).
The second figure shows a little bit of my data samples:
Obs.: I'm sorry for the writing. I'm still a beginner English student.
The frequency doesn't matter. A frequency as low as 1/day is just as fine as any other frequency. But consider the Nyquist-Shannon theorem.
This is problematic. You need a fix sampling frequency for a DFT. You could do interpolation as preprocessing. But better would be to do the sampling at fix times.

What is the reverse of the Modulo operator

I have hard time wrapping my head around how to get this to work so I came to ask the help of the brilliant minds in here.
The thing is, I want to reverse the process of the below equation so that I get X from the given Y and Z.
Z = [ ( X * 30 ) % Y ]
For the use-case, a user inputs number Y and then presses ENTER, the system get's the current server time and then multiplies that by 30. The user will then be given the remainder of the server time in format HHMMssxxx, (hmm, xxx here is the millisecond.. I don't know the format letter for millisecond.. hehe..), divided by Y - that is (X*30) % Y where X is the current server time converted to int.
How can I do this in reverse?
The catch is, X should not be greater than 2359999 -> (23:59:59.999) the maximum time value for a 24-hour clock.
Supposedly I have Z = 32, Y = 400, how can I find X?
I know that it's possible to have multiple answers. Here's what I came up so far but I think this is not very optimal in terms of performance.
function getTimeIDx(rem, codeIndexer) {
var times = [];
for(var i = 0; i < 2400000; i++) {
if((i * 30) % codeIndexer == rem) {
var str = i.toString(),
l = str.length;
if(l < 9)
str = '000000000'.substr(0, 9 - l) + str;
str = str.substr(0, 2) + ':' + str.substr(2, 2) + ':' + str.substr(4, 2) + '.' + str.substr(6);
if(/^(?:[0-1]?\d|2[0-3]):(?:[0-5]?\d):(?:[0-5]+\d)/.test(str))
times.push(str);
}
}
return times;
}
Is there some way to do this more efficiently? Is there something like a inverse modulo?
EDIT:
Updated code to check if the string is a valid time.
You cannot reverse it. Modulo is the remainder from a division operation.
Simplifying your equation. Z = Y % 2
Z is 0 for half of the values and 1 for the rest.
You can not solve for the dividend with just the remainder and the divisor.
Lets fill it into the equation:
32 = ( X * 30 ) % 400
Then this means that X * 30 is a multiple of 400 plus 32:
32
432
832
...
Now we could divide that by 30 to get x. That could be done in js like this:
function* reverse(Z, Y) {
for(let n = 0; ; n++)
yield (Z + Y * n) / 30;
}
Usable as:
for(let X of reverse(32, 400))
console.log(X);
Note that this loop will run forever as there are infinite results. Try it

Any obvious pitfalls in this Student's t-distribution CDF computation?

I have been looking for an efficient function that computes the CDF (cumulative distribution function) for the Student's t-distribution.
Here's what I have settled with after looking at another stackoverflow question, JStat library, the_subtprob function on Line 317 here.
Looking at the notes in the last reference led me to an out of print book, which does not help
If you are interested in more precise algorithms you
could look at: StatLib: http://lib.stat.cmu.edu/apstat/ ;
Applied Statistics Algorithms by Griffiths, P. and Hill, I.D.
Ellis Horwood: Chichester (1985)
The cmu site had a FORTRAN function that I translated as I show below.
Looking at the other sources, I find higher order functions like the incomplete beta, log gamma, and the implementation seems more complex, and in one case iterative.
I'm wondering if there are any known pitfalls of this implementation. It appears to produce the same results as the others. Any thoughts on how one would go about evaluating this would be helpful as well.
function tcdf (t, v) {
//
// ALGORITHM AS 3 APPL. STATIST. (1968) VOL.17, P.189
// STUDENT T PROBABILITY (LOWER TAIL)
//
var b = v / (v + t * t),
c = 1,
s = 1,
ioe = v % 2,
k = 2 + ioe;
if (v < 1) {
return 0;
}
if (v >= 4) {
while (k <= v - 2) {
c *= b - b / k;
s += c;
k += 2;
}
}
c = t / Math.sqrt(v);
if (1 !== ioe) {
return 0.5 + 0.5 * Math.sqrt(b) * c * s;
}
return 0.5 + ((1 === v ? 0 : b * c * s) + Math.atan(c)) / Math.PI;
}
Two possible issue with this algorithm.
Handling large values of v. When v becomes large, we should recover the standard normal distribution. However, you have a while loop over v. So v=1000000 say, becomes slow
Tail accuracy. How does the algorithm cope in the extreme tails? typically, we need to work with log to avoid rounding errors.

JavaScript Math.random Normal distribution (Gaussian bell curve)?

I want to know if the JavaScript function Math.random uses a normal (vs. uniform) distribution or not.
If not, how can I get numbers which use a normal distribution? I haven't found a clear answer on the Internet, for an algorithm to create random normally-distributed numbers.
I want to rebuild a Schmidt-machine (German physicist). The machine produces random numbers of 0 or 1, and they have to be normally-distributed so that I can draw them as a Gaussian bell curve.
For example, the random function produces 120 numbers (0 or 1) and the average (mean) of these summed values has to be near 60.
Since this is the first Google result for "js gaussian random" in my experience, I feel an obligation to give an actual answer to that query.
The Box-Muller transform converts two independent uniform variates on (0, 1) into two standard Gaussian variates (mean 0, variance 1). This probably isn't very performant because of the sqrt, log, and cos calls, but this method is superior to the central limit theorem approaches (summing N uniform variates) because it doesn't restrict the output to the bounded range (-N/2, N/2). It's also really simple:
// Standard Normal variate using Box-Muller transform.
function gaussianRandom(mean=0, stdev=1) {
let u = 1 - Math.random(); //Converting [0,1) to (0,1)
let v = Math.random();
let z = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
// Transform to the desired mean and standard deviation:
return z * stdev + mean;
}
Normal Distribution Between 0 and 1
Building on Maxwell's Answer, this code uses the Box–Muller transform to give you a normal distribution between 0 and 1 inclusive. It just resamples the values if it's more than 3.6 standard deviations away (less than 0.02% chance).
function randn_bm() {
let u = 0, v = 0;
while(u === 0) u = Math.random(); //Converting [0,1) to (0,1)
while(v === 0) v = Math.random();
let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
num = num / 10.0 + 0.5; // Translate to 0 -> 1
if (num > 1 || num < 0) return randn_bm() // resample between 0 and 1
return num
}
Visualizations
n = 100
n = 10,000
n = 10,000,000
Normal Distribution With Min, Max, Skew
This version allows you to give a min, max, and skew factor. See my usage examples at the bottom.
function randn_bm(min, max, skew) {
let u = 0, v = 0;
while(u === 0) u = Math.random() //Converting [0,1) to (0,1)
while(v === 0) v = Math.random()
let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v )
num = num / 10.0 + 0.5 // Translate to 0 -> 1
if (num > 1 || num < 0)
num = randn_bm(min, max, skew) // resample between 0 and 1 if out of range
else{
num = Math.pow(num, skew) // Skew
num *= max - min // Stretch to fill range
num += min // offset to min
}
return num
}
randn_bm(-500, 1000, 1);
randn_bm(10, 20, 0.25);
randn_bm(10, 20, 3);
Here is the JSFiddle for these screenshots: https://jsfiddle.net/2uc346hp/
I want to know if the JavaScript function Math.random is normal distribution or not
Javascript Math.random is not a Normal Distribution(Gaussian bell curve). From ES 2015, 20.2.2.27 "Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. This function takes no arguments." So the provided collection when n is high enough we will get approximately uniform distribution. All values in the interval will have equal probability of appearance(straight line parallel to the x axis, denoting number between 0.0 and 1.0).
how can I get numbers which are normal distribution
There are several ways of getting collection of numbers with a normal distribution. As answered by Maxwell Collard the Box-Muller transform
does transform uniform distribution to normal distribution(the code can be found in Maxwell Collard answer).
An answer to another stackoverflow answer to a question has a reply with other uniform distribution to normal distribution algorithms. Such as:
Ziggurat,
Ratio-of-uniforms,
Inverting the CDF
Besides one of the answers says that: says:
The Ziggurat algorithm is pretty efficient for this, although the Box-Muller transform is easier to implement from scratch (and not crazy slow).
And finally
I want to rebuilt a Schmidt-machine (German physicist), the machine produces random numbers of 0 or 1 and they have to be normal distributed so I can draw them in Gaussian bell curve.
When we have only two values (0 or 1) Gaussian curve looks the same as uniform distribution with 2 possible values. That is why a simple
function randomZero_One(){
return Math.round(Math.random());
}
would suffice. It would return pseudo-randomly with approximately equal probability values 0 and 1.
I wanted to have approximately gaussian random numbers between 0 and 1, and after many tests I found this to be the best:
function gaussianRand() {
var rand = 0;
for (var i = 0; i < 6; i += 1) {
rand += Math.random();
}
return rand / 6;
}
And as a bonus:
function gaussianRandom(start, end) {
return Math.floor(start + gaussianRand() * (end - start + 1));
}
The Javascript Math.random() pseudorandom function returns variates that are equally distributed between 0 and 1. To get a Gaussian distribution I use this:
// returns a gaussian random function with the given mean and stdev.
function gaussian(mean, stdev) {
var y2;
var use_last = false;
return function() {
var y1;
if (use_last) {
y1 = y2;
use_last = false;
} else {
var x1, x2, w;
do {
x1 = 2.0 * Math.random() - 1.0;
x2 = 2.0 * Math.random() - 1.0;
w = x1 * x1 + x2 * x2;
} while (w >= 1.0);
w = Math.sqrt((-2.0 * Math.log(w)) / w);
y1 = x1 * w;
y2 = x2 * w;
use_last = true;
}
var retval = mean + stdev * y1;
if (retval > 0)
return retval;
return -retval;
}
}
// make a standard gaussian variable.
var standard = gaussian(100, 15);
// make a bunch of standard variates
for (i = 0; i < 1000; i++) {
console.log( standard() )
}
I think I got this from Knuth.
Plot can be seen here
Function that utilises the central limit theorem.
function normal(mu, sigma, nsamples){
if(!nsamples) nsamples = 6
if(!sigma) sigma = 1
if(!mu) mu=0
var run_total = 0
for(var i=0 ; i<nsamples ; i++){
run_total += Math.random()
}
return sigma*(run_total - nsamples/2)/(nsamples/2) + mu
}
From the spec:
15.8.2.14 random ( )
Returns a Number value with positive sign, greater than or equal to 0
but less than 1, chosen randomly or pseudo randomly with
approximately uniform distribution over that range, using an
implementation-dependent algorithm or strategy. This function takes no
arguments.
So, it's a uniform distribution, not normal or Gaussian. That's what you're going to find in just about any standard random number facility in any basic language runtime outside of specialized statistics libraries.
You are confusing the output of the function (which is a uniform distribution between 0 and 1) with the need to generate a Gaussian distribution by repeatedly drawing random numbers that are either 0 or 1 - after a large number of trials, their sum will be approximately normally distributed.
You can use the Math.random() function, then round the result to an integer: if it's < 0.5, return 0; if its >= 0.5, return 1. Now you have equal probabilities of zero and one, and you can continue with the approach you described in your question.
Just to clarify: I don't think it's possible to have an algorithm that produces either 0's or 1's in a normally distributed way - normal distribution requires a continuous variable.
When you do the above for say 120 numbers, you will on average get 60 1's and 60 0's. The actual distribution you get will be the binomial distribution with a mean of 60 and a standard deviation of
stdev = sqrt(p(1-p)N) = 5.48
The probability of a particular number k when you have n samples with probability p (which we fixed at 0.5) is
p = n! / ((n-k)! k!) p^k (1-p)^(n-k)
When p = 0.5, you end up with just the binomial coefficients - which approach the normal distribution for n > 30, typically.
And a single line example:
Math.sqrt(-2 * Math.log(Math.random()))*Math.cos((2*Math.PI) * Math.random())
and a Fiddle
https://jsfiddle.net/rszgjqf8/
For those interested in generating values of a normal distrubution, I would recommend checking this implementation of the Ziggurat algorithm in JavaScript: https://www.npmjs.com/package/node-ziggurat
The code of found in the author's page is:
function Ziggurat(){
var jsr = 123456789;
var wn = Array(128);
var fn = Array(128);
var kn = Array(128);
function RNOR(){
var hz = SHR3();
var iz = hz & 127;
return (Math.abs(hz) < kn[iz]) ? hz * wn[iz] : nfix(hz, iz);
}
this.nextGaussian = function(){
return RNOR();
}
function nfix(hz, iz){
var r = 3.442619855899;
var r1 = 1.0 / r;
var x;
var y;
while(true){
x = hz * wn[iz];
if( iz == 0 ){
x = (-Math.log(UNI()) * r1);
y = -Math.log(UNI());
while( y + y < x * x){
x = (-Math.log(UNI()) * r1);
y = -Math.log(UNI());
}
return ( hz > 0 ) ? r+x : -r-x;
}
if( fn[iz] + UNI() * (fn[iz-1] - fn[iz]) < Math.exp(-0.5 * x * x) ){
return x;
}
hz = SHR3();
iz = hz & 127;
if( Math.abs(hz) < kn[iz]){
return (hz * wn[iz]);
}
}
}
function SHR3(){
var jz = jsr;
var jzr = jsr;
jzr ^= (jzr << 13);
jzr ^= (jzr >>> 17);
jzr ^= (jzr << 5);
jsr = jzr;
return (jz+jzr) | 0;
}
function UNI(){
return 0.5 * (1 + SHR3() / -Math.pow(2,31));
}
function zigset(){
// seed generator based on current time
jsr ^= new Date().getTime();
var m1 = 2147483648.0;
var dn = 3.442619855899;
var tn = dn;
var vn = 9.91256303526217e-3;
var q = vn / Math.exp(-0.5 * dn * dn);
kn[0] = Math.floor((dn/q)*m1);
kn[1] = 0;
wn[0] = q / m1;
wn[127] = dn / m1;
fn[0] = 1.0;
fn[127] = Math.exp(-0.5 * dn * dn);
for(var i = 126; i >= 1; i--){
dn = Math.sqrt(-2.0 * Math.log( vn / dn + Math.exp( -0.5 * dn * dn)));
kn[i+1] = Math.floor((dn/tn)*m1);
tn = dn;
fn[i] = Math.exp(-0.5 * dn * dn);
wn[i] = dn / m1;
}
}
zigset();
}
Create a Ziggurat.js file and then:
var z = new Ziggurat();
z.nextGaussian();
For me it's working just perfect and as I had read in Wikipedia, this is a more efficient algorithm than the Box-Muller.
enter link description here
I have tested several functions with the right configuration all work similarly and well.
http://jsfiddle.net/p3y40gf3/29/
Central limit is nice, must be with (n=3 for 6) and 12 for 12 to look as others. I configured others also to (6) or 12 or 1/12 as standard deviation, not sure why 12.
Central limit is a tiny bit less centered than Box/Muller and Ziggurat.
Box/Muller and Ziggurat look exactly the same
this variant by Joe(https://stackoverflow.com/a/33567961/466363) does standard deviation correctly:
function normal(mu, sigma, nsamples){ // using central limit
if(!nsamples) nsamples = 3
if(!sigma) sigma = 1
if(!mu) mu=0
var run_total = 0
for(var i=0 ; i<nsamples ; i++){
run_total += Math.random()
}
return sigma*(run_total - nsamples/2)/(nsamples/2) + mu
}
Ziggurat is also nice but needs to be adjusted from z score to from 0 to 1 looks like it makes good numbers.
Box/Muller clipped is good but gives few repeated numbers at clipped edges
but it is very similar to others,
incorrect random numbers should be discarded not clipped.
function randn_bm() {
var u = 0, v = 0;
while(u === 0) u = Math.random(); //Converting [0,1) to (0,1)
while(v === 0) v = Math.random();
let num = Math.sqrt( -2.0 * Math.log( u ) ) * Math.cos( 2.0 * Math.PI * v );
num = num / 6.0 + 0.5; // Translate to 0 -> 1 // changed here 10 to 6
if(num>1||num<0) return randn_bm(); return num; // bad random numbers should be discared not clipped
//return Math.max(Math.min(num, 1), 0); // cap between 0 and 1
}
Central limit variant it is called Bates distribution that is average
https://en.wikipedia.org/wiki/Bates_distribution
not confused with Irwin Hall that is a sum
https://en.wikipedia.org/wiki/Irwin%E2%80%93Hall_distribution
https://en.wikipedia.org/wiki/Normal_distribution#Generating_values_from_normal_distribution
A non verbose function to sample a random value from a Gaussian distribution I wrote some time ago:
function gaussianRandom(mean, sigma) {
let u = Math.random()*0.682;
return ((u % 1e-8 > 5e-9 ? 1 : -1) * (Math.sqrt(-Math.log(Math.max(1e-9, u)))-0.618))*1.618 * sigma + mean;
}
It should work if you clamp the values to the range you want.
skewnormal from normal and normal01
skewnormal(min, max, ..) returns a random number from the normal distribution that has been streched and offset to range from min to max, exponentially skewed with skew, and truncated to sigma standard deviations (in reverse order). Broken up into logical steps normal and normal01 for clarity and to generate random numbers directly from these intermediate functions if desired. (Plus a bonus lognormal!)
/// skewnormal(..) returns a random number from the normal distribution that has
/// been streched and offset to range from `min` to `max`, skewed with `skew`,
/// and truncated to `sigma` standard deviations. See https://stackoverflow.com/a/74258559/213246
const skewnormal = (min, max, skew = 1, sigma = 8) => {
/// normal() returns a random number from the standard normal distribution.
/// Uses the Box-Muller transform.
const normal = () => Math.sqrt(-2.0 * Math.log(Math.random())) * Math.cos(2.0 * Math.PI * Math.random());
/// normal01(..) returns normally distributed random number, whose range is
/// truncated at `sigma` standard deviations and shifted to interval `[0, 1]`.
const normal01 = (sigma) => {
while (true) {
let num = normal() / (sigma + 0.0) + 0.5; // translate to [0, 1]
if (0 <= num && num <= 1) return num; // ok if in range, else resample
}
}
var num = normal01(sigma);
num = Math.pow(num, skew) // skew
num *= max - min // stretch to fill range
num += min // offset to min
return num;
}
/// lognormal() returns a random number from the log-normal distribution.
const lognormal = () => Math.exp(normal());
Based on another popular answer by joshuakcockrell. You may prefer this implementation because: 1. it's factored to portray intermediate functions, 2. it exposes mathematically relevant and useful sigma parameter, 3. it has better names and comments.
See the JSFiddle for the complete demo environment, which makes it easy to define then test and visualize your own random distribution functions as pictured below:
View interactive charts: https://jsfiddle.net/rgefzusq/34/show/ Playground: https://jsfiddle.net/rgefzusq/34/
This is my JavaScript implementation of Algorithm P (Polar method for normal deviates) from Section 3.4.1 of Donald Knuth's book The Art of Computer Programming:
function gaussian(mean, stddev) {
return function() {
var V1
var V2
var S
do{
var U1 = Math.random()
var U2 = Math.random()
V1 = 2*U1-1
V2 = 2*U2-1
S = V1*V1+V2*V2
}while(S >= 1)
if(S===0) return 0
return mean+stddev*(V1*Math.sqrt(-2*Math.log(S)/S))
}
}
Use it like that:
var standard_normal = gaussian(0,1)
var a_standard_normal_deviate = standard_normal()
I found this library that includes lots of useful Random functions. You can either install it via simjs from npm, or just take the random-node-*.js file out directly for what you need.
http://www.simjs.com/random.html
http://www.simjs.com/download.html
This is my solution to the problem, using the Marsaglia polar method. The range depends on the parameters you give, without parameters it almost never generates anything outside of the range.
As it generates two normally distributed numbers per iteration, I declared a variable under window.temp.spareNormal to grab the spare one if it's there. Might not be the best location for it, but hey.
You'd probably have to round the result in order to get what you want.
window.temp = {
spareNormal: undefined
};
Math.normal = function (mean, standardDeviation) {
let q, u, v, p;
mean = mean || 0.5;
standardDeviation = standardDeviation || 0.125;
if (typeof temp.spareNormal !== 'undefined') {
v = mean + standardDeviation * temp.spareNormal;
temp.spareNormal = undefined;
return v;
}
do {
u = 2.0 * Math.random() - 1.0;
v = 2.0 * Math.random() - 1.0;
q = u * u + v * v;
} while (q >= 1.0 || q === 0);
p = Math.sqrt(-2.0 * Math.log(q) / q);
temp.spareNormal = v * p;
return mean + standardDeviation * u * p;
}
for finding normal distribution of value:
getNormal = (x, mean, standardDeviation, ) => {
return (1 / standardDeviation * Math.sqrt(2 * (3, 14))) * Math.pow(Math.E, -Math.pow(x - mean, 2) / (2 * (standardDeviation * standardDeviation)));
}
The only sort of qualifications I have for this is having taken a single statistics class. If I get something wrong, please tell me, I'd like to learn more about statistics and I don't want to keep thinking something wrong.
If you want to create a random number generator that produces numbers in a normal distribution, you should be able to take samples from a uniform distribution, which is no problem. If you set up a basic random number generator that generates numbers in range a to b, the distribution of values produced will have µ = (a+b)/2 and σ = (b-a)/√12. If the mean of a a few sample of values (≥30) taken from this distribution is taken for many such samples, then for the sampling distribution µ (sample means) = µ (population mean) and σ (sample means' stdev) = σ (population stdev)/√n (number of values in the sample).
By controlling the mean and stdev of the original distribution, you can control the ending mean and standard deviation of a random number generator that produces a normal distribution.
function all_normal(mu, sigma, nsamp)
{
var total = 0;
for (var a = 0; a < nsamp; a ++)
{
total += rand_int(mu - (sigma * Math.sqrt(3 * nsamp)), mu + (sigma * Math.sqrt(3 * nsamp)));
}
return Math.ceil(total / nsamp);
}
Just in case: Math.pow(Math.random(), p).
For example:
function testR(max = 100, min = 0, p = 1, c = 20)
{
let t = [];
for (let i = 0; i < c; ++i)
{
t.push(Math.floor(Math.pow(Math.random(), p) * (max - min + 1) + min));
}
console.log(
`p = ${String(p).padStart(5)}`, '|',
t.sort(function (a, b) { return a - b; }).join(', ')
);
}
testR(9, 0, 10);
testR(9, 0, 2);
testR(9, 0, 1);
testR(9, 0, 0.5);
testR(9, 0, 0.1);
testR(9, 0, 0.05);
Results in client/JS console
jsFiddle graph test:
let iset = 0;
let gset;
function randn() {
let v1, v2, fac, rsq;
if (iset == 0) {
do {
v1 = 2.0*Math.random() - 1.0;
v2 = 2.0*Math.random() - 1.0;
rsq = v1*v1+v2*v2;
} while ((rsq >= 1.0) || (rsq == 0));
fac = Math.sqrt(-2.0*Math.log(rsq)/rsq);
gset = v1*fac;
iset = 1;
return v2*fac;
} else {
iset = 0;
return gset;
}
}
//This is what I use for a Normal-ish distribution random function.
function normal_random(){
var pos = [ Math.random(), Math.random() ];
while ( Math.sin( pos[0] * Math.PI ) > pos[1] ){
pos = [ Math.random(), Math.random() ];
}
return pos[0];
};
This function returns a value between 0 and 1. Values near 0.5 are returned most often.

Developing Formula/Pattern To Determine Position

I'll try to ask as clearly as possible, but please comment if some part is not clear to you.
I'm trying to develop a formula to determine the position of an element based on that element's value in a sequence. More specifically, I am using JavaScript to split a string of this nature: c-c c-c-c c into an array and iterate over that array using an interval of 2i to extract the c values. For example, let's say my string is as previously posted (6 c values in length). I wish to place these c values in the following manner where the number refers to the value of i in my loop (I prepended an extra 0 to make it symmetrical due to the 10):
00 ## 02
##
06 ## 04
##
08 ## 10
I'm trying to find a pattern/formula using the value of i which will result in the above positioning. For simplicity's sake, let's assume an x,y coordinate system such that the position of the c value at 00 is (0,0), 02 is (1,0), 04 is (1,1), 06 is (0,1), 08 is (0,2), and 10 is (1,2).
Can anyone help in developing a pattern/formula/algorithm to determine the positioning using i values? I'm trying not to have to write (in this example) six different if statements.
Using your x,y coordinate system:
y = Math.floor(i / 2);
x = y % 2 == 0 ? i % 2 : (i + 1) % 2;
Or if you want it more concise (but very unclear):
y = Math.floor(i / 2);
x = (i + y % 2) % 2;
The above code is based on the assumption that the code is something like this:
for (var i = 0; i < theString.length / 2; i++) {
var character = theString.charAt(2 * i);
// work out the coordinates
}
If the code is more like this:
for (var i = 0; i < theString.length; i += 2) {
var character = theString.charAt(i);
// work out the coordinates
}
Then we need to do modify it a bit to be like this:
j = i / 2;
y = Math.floor(j / 2);
x = y % 2 == 0 ? j % 2 : (j + 1) % 2;
Or if you want it more concise (but very unclear):
j = i / 2;
y = Math.floor(j / 2);
x = (j + y % 2) % 2;

Categories

Resources