Implements llListStatistics() and a bunch-o-LSL_Types.list statistical methods. Added LIST_STAT_HARMONIC_MEAN in addition to LL's LIST_STAT_*

ThreadPoolClientBranch
alondria 2008-02-10 21:28:41 +00:00
parent 38f0615ffe
commit 758458121e
3 changed files with 282 additions and 4 deletions

View File

@ -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);

View File

@ -2134,7 +2134,7 @@ namespace OpenSim.Region.ScriptEngine.Common
string ret = String.Empty; string ret = String.Empty;
foreach (object o in src.Data) foreach (object o in src.Data)
{ {
ret = ret + o.ToString() + ","; ret = ret + o.ToString() + ", ";
} }
ret = ret.Substring(0, ret.Length - 2); ret = ret.Substring(0, ret.Length - 2);
return ret; return ret;
@ -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()

View File

@ -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()
{ {