aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authoralondria2008-02-10 21:28:41 +0000
committeralondria2008-02-10 21:28:41 +0000
commit758458121eda330b960731d044adeac8a6661a85 (patch)
tree0a7b47afae12983f80ccff03082aa94ed781b0f8
parent* This updates adds locking capability. Thanks, lbsa71 for pointing out my b... (diff)
downloadopensim-SC-758458121eda330b960731d044adeac8a6661a85.zip
opensim-SC-758458121eda330b960731d044adeac8a6661a85.tar.gz
opensim-SC-758458121eda330b960731d044adeac8a6661a85.tar.bz2
opensim-SC-758458121eda330b960731d044adeac8a6661a85.tar.xz
Implements llListStatistics() and a bunch-o-LSL_Types.list statistical methods. Added LIST_STAT_HARMONIC_MEAN in addition to LL's LIST_STAT_*
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs44
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_Types.cs229
3 files changed, 282 insertions, 4 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
index 905ba7f..3aea72b 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
@@ -2186,9 +2186,20 @@ namespace OpenSim.Region.ScriptEngine.Common
2186 public const int STRING_TRIM_HEAD = 1; 2186 public const int STRING_TRIM_HEAD = 1;
2187 public const int STRING_TRIM_TAIL = 2; 2187 public const int STRING_TRIM_TAIL = 2;
2188 public const int STRING_TRIM = 3; 2188 public const int STRING_TRIM = 3;
2189 public const int LIST_STAT_RANGE = 0;
2190 public const int LIST_STAT_MIN = 1;
2191 public const int LIST_STAT_MAX = 2;
2192 public const int LIST_STAT_MEAN = 3;
2193 public const int LIST_STAT_MEDIAN = 4;
2194 public const int LIST_STAT_STD_DEV = 5;
2195 public const int LIST_STAT_SUM = 6;
2196 public const int LIST_STAT_SUM_SQUARES = 7;
2197 public const int LIST_STAT_NUM_COUNT = 8;
2198 public const int LIST_STAT_GEOMETRIC_MEAN = 9;
2199 public const int LIST_STAT_HARMONIC_MEAN = 100;
2189 // Can not be public const? 2200 // Can not be public const?
2190 public vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0); 2201 public vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0);
2191 public rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0); 2202 public rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0);
2192 2203
2193 } 2204 }
2194} \ No newline at end of file 2205} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index fee36f0..441d2fd 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -2134,7 +2134,7 @@ namespace OpenSim.Region.ScriptEngine.Common
2134 string ret = String.Empty; 2134 string ret = String.Empty;
2135 foreach (object o in src.Data) 2135 foreach (object o in src.Data)
2136 { 2136 {
2137 ret = ret + o.ToString() + ","; 2137 ret = ret + o.ToString() + ", ";
2138 } 2138 }
2139 ret = ret.Substring(0, ret.Length - 2); 2139 ret = ret.Substring(0, ret.Length - 2);
2140 return ret; 2140 return ret;
@@ -3376,8 +3376,46 @@ namespace OpenSim.Region.ScriptEngine.Common
3376 public double llListStatistics(int operation, LSL_Types.list src) 3376 public double llListStatistics(int operation, LSL_Types.list src)
3377 { 3377 {
3378 m_host.AddScriptLPS(1); 3378 m_host.AddScriptLPS(1);
3379 NotImplemented("llListStatistics"); 3379 LSL_Types.list nums = LSL_Types.list.ToDoubleList(src);
3380 return 0; 3380 switch (operation)
3381 {
3382 case LSL_BaseClass.LIST_STAT_RANGE:
3383 return nums.Range();
3384 break;
3385 case LSL_BaseClass.LIST_STAT_MIN:
3386 return nums.Min();
3387 break;
3388 case LSL_BaseClass.LIST_STAT_MAX:
3389 return nums.Max();
3390 break;
3391 case LSL_BaseClass.LIST_STAT_MEAN:
3392 return nums.Mean();
3393 break;
3394 case LSL_BaseClass.LIST_STAT_MEDIAN:
3395 return nums.Median();
3396 break;
3397 case LSL_BaseClass.LIST_STAT_NUM_COUNT:
3398 return nums.NumericLength();
3399 break;
3400 case LSL_BaseClass.LIST_STAT_STD_DEV:
3401 return nums.StdDev();
3402 break;
3403 case LSL_BaseClass.LIST_STAT_SUM:
3404 return nums.Sum();
3405 break;
3406 case LSL_BaseClass.LIST_STAT_SUM_SQUARES:
3407 return nums.SumSqrs();
3408 break;
3409 case LSL_BaseClass.LIST_STAT_GEOMETRIC_MEAN:
3410 return nums.GeometricMean();
3411 break;
3412 case LSL_BaseClass.LIST_STAT_HARMONIC_MEAN:
3413 return nums.HarmonicMean();
3414 break;
3415 default:
3416 return 0.0;
3417 break;
3418 }
3381 } 3419 }
3382 3420
3383 public int llGetUnixTime() 3421 public int llGetUnixTime()
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs
index 77ca769..3cc45ba 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs
@@ -28,6 +28,7 @@
28 28
29using System; 29using System;
30using System.Text.RegularExpressions; 30using System.Text.RegularExpressions;
31using System.Collections;
31 32
32namespace OpenSim.Region.ScriptEngine.Common 33namespace OpenSim.Region.ScriptEngine.Common
33{ 34{
@@ -435,6 +436,199 @@ namespace OpenSim.Region.ScriptEngine.Common
435 } 436 }
436 } 437 }
437 438
439 #region CSV Methods
440
441 public static list FromCSV(string csv)
442 {
443 return new list(csv.Split(','));
444 }
445
446 public string ToCSV()
447 {
448 string ret = "";
449 foreach(object o in this.Data)
450 {
451 if(ret == "")
452 {
453 ret = o.ToString();
454 }
455 else
456 {
457 ret = ret + ", " + o.ToString();
458 }
459 }
460 return ret;
461 }
462 #endregion
463
464 #region Statistic Methods
465
466 public double Min()
467 {
468 double minimum = double.PositiveInfinity;
469 double entry;
470 for (int i = 0; i < Data.Length; i++)
471 {
472 if (double.TryParse(Data[i].ToString(), out entry))
473 {
474 if (entry < minimum) minimum = entry;
475 }
476 }
477 return minimum;
478 }
479
480 public double Max()
481 {
482 double maximum = double.NegativeInfinity;
483 double entry;
484 for (int i = 0; i < Data.Length; i++)
485 {
486 if (double.TryParse(Data[i].ToString(), out entry))
487 {
488 if (entry > maximum) maximum = entry;
489 }
490 }
491 return maximum;
492 }
493
494 public double Range()
495 {
496 return (this.Max() / this.Min());
497 }
498
499 public int NumericLength()
500 {
501 int count = 0;
502 double entry;
503 for (int i = 0; i < Data.Length; i++)
504 {
505 if (double.TryParse(Data[i].ToString(), out entry))
506 {
507 count++;
508 }
509 }
510 return count;
511 }
512
513 public static list ToDoubleList(list src)
514 {
515 list ret = new list();
516 double entry;
517 for (int i = 0; i < src.Data.Length - 1; i++)
518 {
519 if (double.TryParse(src.Data[i].ToString(), out entry))
520 {
521 ret.Add(entry);
522 }
523 }
524 return ret;
525 }
526
527 public double Sum()
528 {
529 double sum = 0;
530 double entry;
531 for (int i = 0; i < Data.Length; i++)
532 {
533 if (double.TryParse(Data[i].ToString(), out entry))
534 {
535 sum = sum + entry;
536 }
537 }
538 return sum;
539 }
540
541 public double SumSqrs()
542 {
543 double sum = 0;
544 double entry;
545 for (int i = 0; i < Data.Length; i++)
546 {
547 if (double.TryParse(Data[i].ToString(), out entry))
548 {
549 sum = sum + Math.Pow(entry, 2);
550 }
551 }
552 return sum;
553 }
554
555 public double Mean()
556 {
557 return (this.Sum() / this.NumericLength());
558 }
559
560 public void NumericSort()
561 {
562 IComparer Numeric = new NumericComparer();
563 Array.Sort(Data, Numeric);
564 }
565
566 public void AlphaSort()
567 {
568 IComparer Alpha = new AlphaCompare();
569 Array.Sort(Data, Alpha);
570 }
571
572 public double Median()
573 {
574 return Qi(0.5);
575 }
576
577 public double GeometricMean()
578 {
579 double ret = 1.0;
580 list nums = list.ToDoubleList(this);
581 for (int i = 0; i < nums.Data.Length; i++)
582 {
583 ret *= (double)nums.Data[i];
584 }
585 return Math.Exp(Math.Log(ret) / (double)nums.Data.Length);
586 }
587
588 public double HarmonicMean()
589 {
590 double ret = 0.0;
591 list nums = list.ToDoubleList(this);
592 for (int i = 0; i < nums.Data.Length; i++)
593 {
594 ret += 1.0 / (double)nums.Data[i];
595 }
596 return ((double)nums.Data.Length / ret);
597 }
598
599 public double Variance()
600 {
601 double s = 0;
602 list num = list.ToDoubleList(this);
603 for (int i = 0; i < num.Data.Length; i++)
604 {
605 s += Math.Pow((double)num.Data[i], 2);
606 }
607 return (s - num.Data.Length * Math.Pow(num.Mean(), 2)) / (num.Data.Length - 1);
608 }
609
610 public double StdDev()
611 {
612 return Math.Sqrt(this.Variance());
613 }
614
615 public double Qi(double i)
616 {
617 list j = this;
618 j.NumericSort();
619 double ret;
620 if (Math.Ceiling(this.Length * i) == this.Length * i)
621 {
622 return (double)((double)j.Data[(int)(this.Length * i - 1)] + (double)j.Data[(int)(this.Length * i)]) / 2;
623 }
624 else
625 {
626 return (double)j.Data[((int)(Math.Ceiling(this.Length * i))) - 1];
627 }
628 }
629
630 #endregion
631
438 public string ToPrettyString() 632 public string ToPrettyString()
439 { 633 {
440 string output; 634 string output;
@@ -459,7 +653,42 @@ namespace OpenSim.Region.ScriptEngine.Common
459 return output; 653 return output;
460 } 654 }
461 655
656 public class AlphaCompare : IComparer
657 {
658 int IComparer.Compare(object x, object y)
659 {
660 return string.Compare(x.ToString(), y.ToString());
661 }
662 }
462 663
664 public class NumericComparer : IComparer
665 {
666 int IComparer.Compare(object x, object y)
667 {
668 double a;
669 double b;
670 if (!double.TryParse(x.ToString(), out a))
671 {
672 a = 0.0;
673 }
674 if (!double.TryParse(y.ToString(), out b))
675 {
676 b = 0.0;
677 }
678 if (a < b)
679 {
680 return -1;
681 }
682 else if (a == b)
683 {
684 return 0;
685 }
686 else
687 {
688 return 1;
689 }
690 }
691 }
463 692
464 public override string ToString() 693 public override string ToString()
465 { 694 {