Implements llListStatistics() and a bunch-o-LSL_Types.list statistical methods. Added LIST_STAT_HARMONIC_MEAN in addition to LL's LIST_STAT_*
parent
38f0615ffe
commit
758458121e
|
@ -2186,6 +2186,17 @@ namespace OpenSim.Region.ScriptEngine.Common
|
||||||
public const int STRING_TRIM_HEAD = 1;
|
public const int STRING_TRIM_HEAD = 1;
|
||||||
public const int STRING_TRIM_TAIL = 2;
|
public const int STRING_TRIM_TAIL = 2;
|
||||||
public const int STRING_TRIM = 3;
|
public const int STRING_TRIM = 3;
|
||||||
|
public const int LIST_STAT_RANGE = 0;
|
||||||
|
public const int LIST_STAT_MIN = 1;
|
||||||
|
public const int LIST_STAT_MAX = 2;
|
||||||
|
public const int LIST_STAT_MEAN = 3;
|
||||||
|
public const int LIST_STAT_MEDIAN = 4;
|
||||||
|
public const int LIST_STAT_STD_DEV = 5;
|
||||||
|
public const int LIST_STAT_SUM = 6;
|
||||||
|
public const int LIST_STAT_SUM_SQUARES = 7;
|
||||||
|
public const int LIST_STAT_NUM_COUNT = 8;
|
||||||
|
public const int LIST_STAT_GEOMETRIC_MEAN = 9;
|
||||||
|
public const int LIST_STAT_HARMONIC_MEAN = 100;
|
||||||
// Can not be public const?
|
// Can not be public const?
|
||||||
public vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0);
|
public vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0);
|
||||||
public rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0);
|
public rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0);
|
||||||
|
|
|
@ -3376,8 +3376,46 @@ namespace OpenSim.Region.ScriptEngine.Common
|
||||||
public double llListStatistics(int operation, LSL_Types.list src)
|
public double llListStatistics(int operation, LSL_Types.list src)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
NotImplemented("llListStatistics");
|
LSL_Types.list nums = LSL_Types.list.ToDoubleList(src);
|
||||||
return 0;
|
switch (operation)
|
||||||
|
{
|
||||||
|
case LSL_BaseClass.LIST_STAT_RANGE:
|
||||||
|
return nums.Range();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_MIN:
|
||||||
|
return nums.Min();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_MAX:
|
||||||
|
return nums.Max();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_MEAN:
|
||||||
|
return nums.Mean();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_MEDIAN:
|
||||||
|
return nums.Median();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_NUM_COUNT:
|
||||||
|
return nums.NumericLength();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_STD_DEV:
|
||||||
|
return nums.StdDev();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_SUM:
|
||||||
|
return nums.Sum();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_SUM_SQUARES:
|
||||||
|
return nums.SumSqrs();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_GEOMETRIC_MEAN:
|
||||||
|
return nums.GeometricMean();
|
||||||
|
break;
|
||||||
|
case LSL_BaseClass.LIST_STAT_HARMONIC_MEAN:
|
||||||
|
return nums.HarmonicMean();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0.0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int llGetUnixTime()
|
public int llGetUnixTime()
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.Common
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
{
|
{
|
||||||
|
@ -435,6 +436,199 @@ namespace OpenSim.Region.ScriptEngine.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region CSV Methods
|
||||||
|
|
||||||
|
public static list FromCSV(string csv)
|
||||||
|
{
|
||||||
|
return new list(csv.Split(','));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToCSV()
|
||||||
|
{
|
||||||
|
string ret = "";
|
||||||
|
foreach(object o in this.Data)
|
||||||
|
{
|
||||||
|
if(ret == "")
|
||||||
|
{
|
||||||
|
ret = o.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = ret + ", " + o.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Statistic Methods
|
||||||
|
|
||||||
|
public double Min()
|
||||||
|
{
|
||||||
|
double minimum = double.PositiveInfinity;
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
if (entry < minimum) minimum = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minimum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Max()
|
||||||
|
{
|
||||||
|
double maximum = double.NegativeInfinity;
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
if (entry > maximum) maximum = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maximum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Range()
|
||||||
|
{
|
||||||
|
return (this.Max() / this.Min());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int NumericLength()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static list ToDoubleList(list src)
|
||||||
|
{
|
||||||
|
list ret = new list();
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < src.Data.Length - 1; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(src.Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
ret.Add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Sum()
|
||||||
|
{
|
||||||
|
double sum = 0;
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
sum = sum + entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double SumSqrs()
|
||||||
|
{
|
||||||
|
double sum = 0;
|
||||||
|
double entry;
|
||||||
|
for (int i = 0; i < Data.Length; i++)
|
||||||
|
{
|
||||||
|
if (double.TryParse(Data[i].ToString(), out entry))
|
||||||
|
{
|
||||||
|
sum = sum + Math.Pow(entry, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Mean()
|
||||||
|
{
|
||||||
|
return (this.Sum() / this.NumericLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NumericSort()
|
||||||
|
{
|
||||||
|
IComparer Numeric = new NumericComparer();
|
||||||
|
Array.Sort(Data, Numeric);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AlphaSort()
|
||||||
|
{
|
||||||
|
IComparer Alpha = new AlphaCompare();
|
||||||
|
Array.Sort(Data, Alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Median()
|
||||||
|
{
|
||||||
|
return Qi(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GeometricMean()
|
||||||
|
{
|
||||||
|
double ret = 1.0;
|
||||||
|
list nums = list.ToDoubleList(this);
|
||||||
|
for (int i = 0; i < nums.Data.Length; i++)
|
||||||
|
{
|
||||||
|
ret *= (double)nums.Data[i];
|
||||||
|
}
|
||||||
|
return Math.Exp(Math.Log(ret) / (double)nums.Data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double HarmonicMean()
|
||||||
|
{
|
||||||
|
double ret = 0.0;
|
||||||
|
list nums = list.ToDoubleList(this);
|
||||||
|
for (int i = 0; i < nums.Data.Length; i++)
|
||||||
|
{
|
||||||
|
ret += 1.0 / (double)nums.Data[i];
|
||||||
|
}
|
||||||
|
return ((double)nums.Data.Length / ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Variance()
|
||||||
|
{
|
||||||
|
double s = 0;
|
||||||
|
list num = list.ToDoubleList(this);
|
||||||
|
for (int i = 0; i < num.Data.Length; i++)
|
||||||
|
{
|
||||||
|
s += Math.Pow((double)num.Data[i], 2);
|
||||||
|
}
|
||||||
|
return (s - num.Data.Length * Math.Pow(num.Mean(), 2)) / (num.Data.Length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double StdDev()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(this.Variance());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Qi(double i)
|
||||||
|
{
|
||||||
|
list j = this;
|
||||||
|
j.NumericSort();
|
||||||
|
double ret;
|
||||||
|
if (Math.Ceiling(this.Length * i) == this.Length * i)
|
||||||
|
{
|
||||||
|
return (double)((double)j.Data[(int)(this.Length * i - 1)] + (double)j.Data[(int)(this.Length * i)]) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (double)j.Data[((int)(Math.Ceiling(this.Length * i))) - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public string ToPrettyString()
|
public string ToPrettyString()
|
||||||
{
|
{
|
||||||
string output;
|
string output;
|
||||||
|
@ -459,7 +653,42 @@ namespace OpenSim.Region.ScriptEngine.Common
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AlphaCompare : IComparer
|
||||||
|
{
|
||||||
|
int IComparer.Compare(object x, object y)
|
||||||
|
{
|
||||||
|
return string.Compare(x.ToString(), y.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NumericComparer : IComparer
|
||||||
|
{
|
||||||
|
int IComparer.Compare(object x, object y)
|
||||||
|
{
|
||||||
|
double a;
|
||||||
|
double b;
|
||||||
|
if (!double.TryParse(x.ToString(), out a))
|
||||||
|
{
|
||||||
|
a = 0.0;
|
||||||
|
}
|
||||||
|
if (!double.TryParse(y.ToString(), out b))
|
||||||
|
{
|
||||||
|
b = 0.0;
|
||||||
|
}
|
||||||
|
if (a < b)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (a == b)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue