POV-Ray : Newsgroups : povray.general : Why only a +1 clamp with VAngle, VAngleD macros in math.inc? : Re: Why only a +1 clamp with VAngle, VAngleD macros in math.inc? Server Time29 Jul 2021 18:44:08 EDT (-0400)
 Re: Why only a +1 clamp with VAngle, VAngleD macros in math.inc?
 From: Tor Olav Kristensen Date: 8 May 2021 19:10:00 Message:
```William F Pokorny <ano### [at] anonymousorg> wrote:
> On 5/6/21 10:58 AM, Tor Olav Kristensen wrote:
> >...
> > My opinion is that several of the other math related macros in the include files
> > need some rework.
> >
>
> I'd consider alternatives for my branch if you want to offer details.

That sounds good.

Today I looked at the statistical macros in math.inc.

Here's how they could be rewritten:
(Please note that have not tested these thoroughly yet.)

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

#version 3.8;

// Does also work for vectors
#macro Mean(Values)

#local N = dimension_size(Values, 1);
#local Sum = Values[0];
#for (I, 1, N - 1)
#local Sum = Sum + Values[I];
#end // for

(Sum/N)

#end // macro Mean

// Does also work for vectors
#macro Variance(Values)

#local N = dimension_size(Values, 1);
#local M = Mean(Values);
#local D = Values[0] - M;
#local SquareSum = D*D;
#for (I, 1, N - 1)
#local D = Values[I] - M;
#local SquareSum = SquareSum + D*D;
#end

(SquareSum/N)

#end // macro Variance

#macro Minimum(Values)

#local N = dimension_size(Values, 1);
#local Min = Values[0];
#for (I, 1, N - 1)
#local Min = min(Min, Values[I]);
#end // for

Min

#end // macro Minimum

#macro Maximum(Values)

#local N = dimension_size(Values, 1);
#local Max = Values[0];
#for (I, 1, N - 1)
#local Max = max(Max, Values[I]);
#end // for

Max

#end // macro Maximum

// For population
#macro StandardDeviation(Values)

sqrt(Variance(Values))

#end // macro StandardDeviation

#macro Statistics(Values)

#local N = dimension_size(Values, 1);
#local Value = Values[0];
#local Min = Value;
#local Max = Value;
#local Sum = Value;
#local SquareSum = pow(Value, 2);
#for (I, 1,  N - 1)
#local Value = Values[I];
#local Min = min(Min, Value);
#local Max = max(Max, Value);
#local Sum = Sum + Value;
#local SquareSum = SquareSum + pow(Value, 2);
#end // for
#local M = Sum/N;
#local Var = SquareSum/N - pow(M, 2);

dictionary {
.Count: N,
.Min: Min,
.Max: Max,
.Mean: M,
.Var: Var,
.StdDev: sqrt(Var)
}

#end // macro Statistics

#macro PrintStatistics(Stats)

#local S = array[6] { "Count", "Min", "Max", "Mean", "Var", "StdDev" };
#debug "\n"
#for (I, 0, 5)
#debug concat(S[I], " = ", str(Stats[S[I]], 0, -1), "\n")
#end // for
#debug "\n"

#end // macro PrintStatistics

#macro Histogram(Values, NoOfBins)

#local Stats = Statistics(Values);
#local N = Stats.Count;
#local Min = Stats.Min;
#local Max = Stats.Max;
#local BinWidth = (Max - Min)/NoOfBins;
#local Bins = array[NoOfBins][3];
#local BinLimitLow = Min;
#for (I, 0, NoOfBins - 1)
#local BinLimitHigh = BinLimitLow + BinWidth;
#local Bins[I][0] = BinLimitLow;
#local Bins[I][1] = BinLimitHigh;
#local Bins[I][2] = 0; // Set count for bin to zero
#local BinLimitLow = BinLimitHigh;
#end // for
#for (I, 0, N - 1)
// Find the right bin for the value
#local BinNo = int((Values[I] - Min)/BinWidth);
// Make sure rounding errors do not lead to a non existent bin
#local BinNo = min(max(0, BinNo), NoOfBins - 1);
// Increase the count for the bin
#local Bins[BinNo][2] = Bins[BinNo][2] + 1;
#end // for

Bins

#end // macro Histogram

// ===== 1 ======= 2 ======= 3 ======= 4 ======= 5 ======= 6 ======= 7

> Suppose I could compare to forms in skvectors?
>...

I'm not sure what you mean here.

I'll comment further on the math related macros in the include files later.

--
Tor Olav
http://subcube.com
https://github.com/t-o-k
```