Skip to content

Commit

Permalink
Added Precision attribute to Normal Distribution Data Type.
Browse files Browse the repository at this point in the history
  • Loading branch information
aevans84 committed Mar 28, 2016
1 parent f48960a commit 2d5b996
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 202 deletions.
223 changes: 113 additions & 110 deletions plugins/dataTypes/NormalDistribution/NormalDistribution.class.php
@@ -1,110 +1,113 @@
<?php

/**
* @author Ben Keen <ben.keen@gmail.com>
* @package DataTypes
*/
class DataType_NormalDistribution extends DataTypePlugin {

/**#@+
* @access protected
*/
protected $isEnabled = true;
protected $dataTypeName = "Standard Normal Distribution";
protected $dataTypeFieldGroup = "math";
protected $dataTypeFieldGroupOrder = 10;
protected $jsModules = array("NormalDistribution.js");
protected $randMax = null;


public function generate($generator, $generationContextData) {
$mean = (float) $generationContextData["generationOptions"]["mean"];
$stddev = (float) $generationContextData["generationOptions"]["stddev"];

return array(
"display" => $this->gauss_ms($mean, $stddev)
);
}


public function getRowGenerationOptionsUI($generator, $postdata, $colNum, $numCols) {
if ((empty($postdata["dtOptionMean_$colNum"]) && $postdata["dtOptionMean_$colNum"] !== "0") ||
(empty($postdata["dtOptionSigma_$colNum"]) && $postdata["dtOptionSigma_$colNum"] !== "0")) {
return false;
}
$this->randMax = (float) getrandmax();

return array(
"mean" => $postdata["dtOptionMean_$colNum"],
"stddev" => $postdata["dtOptionSigma_$colNum"]
);
}

public function getRowGenerationOptionsAPI($generator, $json, $numCols) {
$this->randMax = (float) getrandmax();

return array(
"mean" => $json->settings->mean,
"stddev" => $json->settings->sigma
);
}

public function getOptionsColumnHTML() {
$options =<<< END
<label for="dtOptionMean_%ROW%">{$this->L["mean"]}</label>
<input type="text" name="dtOptionMean_%ROW%" id="dtOptionMean_%ROW%" style="width: 30px" value="0" />
<label for="dtOptionSigma_%ROW%">{$this->L["standard_deviation"]}</label>
<input type="text" name="dtOptionSigma_%ROW%" id="dtOptionSigma_%ROW%" style="width: 30px" value="1" />
END;

return $options;
}

public function getDataTypeMetadata() {
return array(
"SQLField" => "varchar(100)"
);
}

// returns random number using mt_rand() with a flat distribution from -1 to 1 inclusive
public function random_PN() {
return (2.0 * $this->random_0_1()) - 1.0;
}

public function random_0_1() {
return (float) mt_rand() / (float) mt_getrandmax() ;
}

public function gauss() {
static $useExists = false;
static $useValue;

if ($useExists) {
// Use value from a previous call to this function
$useExists = false;
return $useValue;
} else {
// Polar form of the Box-Muller transformation
$w = 2.0 ;
while (($w >= 1.0) || ($w == 0.0)) {
$x = $this->random_PN();
$y = $this->random_PN();
$w = ($x * $x) + ($y * $y);
}
$w = sqrt((-2.0 * log($w)) / $w);

// Set value for next call to this function
$useValue = $y * $w;
$useExists = true;

return $x * $w;
}
}

public function gauss_ms($mean, $stddev) {
// Adjust our gaussian random to fit the mean and standard deviation
// The division by 4 is an arbitrary value to help fit the distribution
// within our required range, and gives a best fit for $stddev = 1.0
return $this->gauss() * ($stddev / 4) + $mean;
}
}
<?php
/**
* @author Ben Keen <ben.keen@gmail.com>
* @package DataTypes
*/
class DataType_NormalDistribution extends DataTypePlugin {

/**#@+
* @access protected
*/
protected $isEnabled = true;
protected $dataTypeName = "Standard Normal Distribution";
protected $dataTypeFieldGroup = "math";
protected $dataTypeFieldGroupOrder = 10;
protected $jsModules = array("NormalDistribution.js");
protected $randMax = null;


public function generate($generator, $generationContextData) {
$mean = (float) $generationContextData["generationOptions"]["mean"];
$stddev = (float) $generationContextData["generationOptions"]["stddev"];
$precision = (integer) $generationContextData["generationOptions"]["precision"];
return array(
"display" => round($this->gauss_ms($mean, $stddev), $precision, PHP_ROUND_HALF_UP)
);
}


public function getRowGenerationOptionsUI($generator, $postdata, $colNum, $numCols) {
if ((empty($postdata["dtOptionMean_$colNum"]) && $postdata["dtOptionMean_$colNum"] !== "0") ||
(empty($postdata["dtOptionSigma_$colNum"]) && $postdata["dtOptionSigma_$colNum"] !== "0")) {
return false;
}
$this->randMax = (float) getrandmax();

return array(
"mean" => $postdata["dtOptionMean_$colNum"],
"stddev" => $postdata["dtOptionSigma_$colNum"],
"precision" => $postdata["dtOptionPrecision_$colNum"]
);
}

public function getRowGenerationOptionsAPI($generator, $json, $numCols) {
$this->randMax = (float) getrandmax();

return array(
"mean" => $json->settings->mean,
"stddev" => $json->settings->sigma,
"precision" => $json->settings->precision
);
}

public function getOptionsColumnHTML() {
$options =<<< END
<label for="dtOptionMean_%ROW%">{$this->L["mean"]}</label>
<input type="text" name="dtOptionMean_%ROW%" id="dtOptionMean_%ROW%" style="width: 30px" value="0" />
<label for="dtOptionSigma_%ROW%">{$this->L["standard_deviation"]}</label>
<input type="text" name="dtOptionSigma_%ROW%" id="dtOptionSigma_%ROW%" style="width: 30px" value="1" />
<label for="dtOptionPrecision_%ROW%" title="Number of decimal places.">{$this->L["precision"]}</label>
<input type="text" name="dtOptionPrecision_%ROW%" id="dtOptionPrecision_%ROW%" style="width: 30px" value="0" />
END;

return $options;
}

public function getDataTypeMetadata() {
return array(
"SQLField" => "varchar(100)"
);
}

// returns random number using mt_rand() with a flat distribution from -1 to 1 inclusive
public function random_PN() {
return (2.0 * $this->random_0_1()) - 1.0;
}

public function random_0_1() {
return (float) mt_rand() / (float) mt_getrandmax() ;
}

public function gauss() {
static $useExists = false;
static $useValue;

if ($useExists) {
// Use value from a previous call to this function
$useExists = false;
return $useValue;
} else {
// Polar form of the Box-Muller transformation
$w = 2.0 ;
while (($w >= 1.0) || ($w == 0.0)) {
$x = $this->random_PN();
$y = $this->random_PN();
$w = ($x * $x) + ($y * $y);
}
$w = sqrt((-2.0 * log($w)) / $w);

// Set value for next call to this function
$useValue = $y * $w;
$useExists = true;

return $x * $w;
}
}

public function gauss_ms($mean, $stddev) {
// Adjust our gaussian random to fit the mean and standard deviation
// The division by 4 is an arbitrary value to help fit the distribution
// within our required range, and gives a best fit for $stddev = 1.0
return $this->gauss() * ($stddev / 4) + $mean;
}
}
152 changes: 79 additions & 73 deletions plugins/dataTypes/NormalDistribution/NormalDistribution.js
@@ -1,74 +1,80 @@
/*global $:false*/
define([
"manager",
"constants",
"lang",
"generator"
], function(manager, C, L, generator) {

"use strict";

/**
* @name NormalDistribution
* @description JS code for the NormalDistribution Data Type.
* @see DataType
* @namespace
*/

var MODULE_ID = "data-type-NormalDistribution";
var LANG = L.dataTypePlugins.NormalDistribution;
var subscriptions = {};

var _init = function() {
};

var _saveRow = function(rowNum) {
return {
"mean": $("#dtOptionMean_" + rowNum).val(),
"sigma": $("#dtOptionSigma_" + rowNum).val()
};
};

var _loadRow = function(rowNum, data) {
return {
execute: function() {
$("#dtOptionMean_" + rowNum).val(data.mean);
$("#dtOptionSigma_" + rowNum).val(data.sigma);
},
isComplete: function() { return $("#dtOptionSigma_" + rowNum).length > 0; }
};
};

var _validate = function(rows) {
var visibleProblemRows = [];
var problemFields = [];
for (var i=0; i<rows.length; i++) {
var currMean = $("#dtOptionMean_" + rows[i]);
var currSigma = $("#dtOptionSigma_" + rows[i]);

var visibleRowNum = generator.getVisibleRowOrderByRowNum(rows[i]);
if ($.trim(currMean.val()) === "" || $.trim(currSigma.val()) === "") {
visibleProblemRows.push(visibleRowNum);

if ($.trim(currMean.val()) === "") {
problemFields.push(currMean);
}
if ($.trim(currSigma.val()) === "") {
problemFields.push(currSigma);
}
}
}
var errors = [];
if (visibleProblemRows.length) {
errors.push({ els: problemFields, error: LANG.incomplete_fields + " <b>" + visibleProblemRows.join(", ") + "</b>"});
}
return errors;
};

manager.registerDataType(MODULE_ID, {
init: _init,
validate: _validate,
saveRow: _saveRow,
loadRow: _loadRow
});
/*global $:false*/
define([
"manager",
"constants",
"lang",
"generator"
], function(manager, C, L, generator) {

"use strict";

/**
* @name NormalDistribution
* @description JS code for the NormalDistribution Data Type.
* @see DataType
* @namespace
*/

var MODULE_ID = "data-type-NormalDistribution";
var LANG = L.dataTypePlugins.NormalDistribution;
var subscriptions = {};

var _init = function() {
};

var _saveRow = function(rowNum) {
return {
"mean": $("#dtOptionMean_" + rowNum).val(),
"sigma": $("#dtOptionSigma_" + rowNum).val(),
"precision": $("#dtOptionPrecision_" + rowNum).val()
};
};

var _loadRow = function(rowNum, data) {
return {
execute: function() {
$("#dtOptionMean_" + rowNum).val(data.mean);
$("#dtOptionSigma_" + rowNum).val(data.sigma);
$("#dtOptionPrecision_" + rowNum).val(data.precision);
},
isComplete: function() { return $("#dtOptionSigma_" + rowNum).length > 0; }
};
};

var _validate = function(rows) {
var visibleProblemRows = [];
var problemFields = [];
for (var i=0; i<rows.length; i++) {
var currMean = $("#dtOptionMean_" + rows[i]);
var currSigma = $("#dtOptionSigma_" + rows[i]);
var currPrecision = $("#dtOptionPrecision_" + rows[i]);

var visibleRowNum = generator.getVisibleRowOrderByRowNum(rows[i]);
if ($.trim(currMean.val()) === "" || $.trim(currSigma.val()) === "") {
visibleProblemRows.push(visibleRowNum);

if ($.trim(currMean.val()) === "") {
problemFields.push(currMean);
}
if ($.trim(currSigma.val()) === "") {
problemFields.push(currSigma);
}
if ($.trim(currPrecision.val()) === "") {
problemFields.push(currPrecision);
}
}
}
var errors = [];
if (visibleProblemRows.length) {
errors.push({ els: problemFields, error: LANG.incomplete_fields + " <b>" + visibleProblemRows.join(", ") + "</b>"});
}
return errors;
};

manager.registerDataType(MODULE_ID, {
init: _init,
validate: _validate,
saveRow: _saveRow,
loadRow: _loadRow
});
});
1 change: 1 addition & 0 deletions plugins/dataTypes/NormalDistribution/lang/de.php
Expand Up @@ -9,3 +9,4 @@

$L["incomplete_fields"] = "Der Mittelwert und Sigma Felder sind für alle Normal Distribution Zeilen erforderlich. Bitte beheben Sie die folgenden Zeilen:";
$L["mean"] = "Bedeuten";
$L["precision"] = "Präzision";
1 change: 1 addition & 0 deletions plugins/dataTypes/NormalDistribution/lang/en.php
Expand Up @@ -8,4 +8,5 @@

$L["mean"] = "Mean";
$L["standard_deviation"] = "Standard Deviation";
$L["precision"] = "Precision";
$L["incomplete_fields"] = "The Mean and Sigma fields are required for all Normal Distribution rows. Please fix the following rows:";
1 change: 1 addition & 0 deletions plugins/dataTypes/NormalDistribution/lang/es.php
Expand Up @@ -9,4 +9,5 @@

$L["mean"] = "Media";
$L["standard_deviation"] = "Desviación estándar";
$L{"precision"} = "Precisión";
$L["incomplete_fields"] = "Los campos Media y Sigma son obligatorios para todas las filas de Distribución normal. Por favor, corrija las siguientes filas:";

0 comments on commit 2d5b996

Please sign in to comment.