Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/29/20 15:24:40 (4 years ago)
Author:
gkronber
Message:

#3022: made a few changes while reviewing the code.

Location:
branches/3022-FastFunctionExtraction/FFX
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • branches/3022-FastFunctionExtraction/FFX/Approach.cs

    r17737 r17779  
    44namespace HeuristicLab.Algorithms.DataAnalysis.FastFunctionExtraction {
    55    internal struct Approach {
    6         public bool AllowInter { get; set; }
    7         public bool AllowDenom { get; set; }
     6        public bool AllowInteractions { get; set; }
     7        public bool AllowDenominators { get; set; }
    88        public bool AllowExp { get; set; }
    9         public bool AllowNonlinFuncs { get; set; }
     9        public bool AllowNonLinearFunctions { get; set; }
    1010        public bool AllowHinge { get; set; }
    1111        public HashSet<double> Exponents { get; set; }
    12         public HashSet<NonlinearOperator> NonlinFuncs { get; set; }
    13         public double MinHingeThr { get; set; }
    14         public double MaxHingeThr { get; set; }
    15         public int NumHingeThrs { get; set; }
    16         public double ElnetPenalty { get; set; }
     12        public HashSet<NonlinearOperator> NonLinearFunctions { get; set; }
     13        public double MinHingeThreshold { get; set; }
     14        public double MaxHingeThreshold { get; set; }
     15        public int NumHingeThresholds { get; set; }
     16        public double ElasticNetPenalty { get; set; }
    1717        public int MaxNumBases { get; set; }
    1818
    19         private static int Int(bool b) => b ? 1 : 0;
    20 
    2119        public override string ToString() {
    22             return $"Inter{Int(AllowInter)} Denom{Int(AllowDenom)} Exp{Int((AllowExp))} Nonlin{Int(AllowNonlinFuncs)} Hinge{Int(AllowHinge)}";
     20            return $"Interactions{AllowInteractions} Denominator{AllowDenominators} Exponential{AllowExp} NonLinearFunctions{AllowNonLinearFunctions} HingeFunctions{AllowHinge}";
    2321        }
    2422
    25         public Approach(bool inter, bool denom, bool exp, bool nonlin, bool hinge, HashSet<double> exponents, HashSet<NonlinearOperator> nonlinFuncs, int maxNumBases, double penalty, double minHingeThr, double maxHingeThr, int numHingeThrs) {
    26             this.AllowInter = inter;
    27             this.AllowDenom = denom;
    28             this.AllowExp = exp;
    29             this.AllowNonlinFuncs = nonlin;
    30             this.AllowHinge = hinge;
     23        public Approach(bool allowInteractions, bool allowDenominators, bool allowExp, bool allowNonLinearFunctions, bool allowHingeFunctions, HashSet<double> exponents, HashSet<NonlinearOperator> nonLinearFunctions, int maxNumBases, double elasticNetPenality, double minHingeThreshold, double maxHingeThreshold, int numHingeThresholds) {
     24            this.AllowInteractions = allowInteractions;
     25            this.AllowDenominators = allowDenominators;
     26            this.AllowExp = allowExp;
     27            this.AllowNonLinearFunctions = allowNonLinearFunctions;
     28            this.AllowHinge = allowHingeFunctions;
    3129            if (AllowExp && exponents == null) throw new ArgumentNullException(nameof(exponents));
    3230            Exponents = exponents;
    33             if (AllowNonlinFuncs && nonlinFuncs == null) throw new ArgumentNullException(nameof(nonlinFuncs));
    34             NonlinFuncs = nonlinFuncs;
    35             MinHingeThr = minHingeThr;
    36             MaxHingeThr = maxHingeThr;
    37             NumHingeThrs = numHingeThrs;
    38             ElnetPenalty = penalty;
     31            if (AllowNonLinearFunctions && nonLinearFunctions == null) throw new ArgumentNullException(nameof(nonLinearFunctions));
     32            NonLinearFunctions = nonLinearFunctions;
     33            MinHingeThreshold = minHingeThreshold;
     34            MaxHingeThreshold = maxHingeThreshold;
     35            NumHingeThresholds = numHingeThresholds;
     36            ElasticNetPenalty = elasticNetPenality;
    3937            MaxNumBases = maxNumBases;
    4038        }
  • branches/3022-FastFunctionExtraction/FFX/BFUtils.cs

    r17740 r17779  
    1414        public static IEnumerable<IBasisFunction> CreateBasisFunctions(IRegressionProblemData data, Approach approach) {
    1515            var exponents = approach.AllowExp ? approach.Exponents : new HashSet<double> { 1 };
    16             var funcs = approach.AllowNonlinFuncs ? approach.NonlinFuncs : new HashSet<NonlinearOperator> { NonlinearOperator.None };
     16            var funcs = approach.AllowNonLinearFunctions ? approach.NonLinearFunctions : new HashSet<NonlinearOperator> { NonlinearOperator.None };
    1717            var simpleBasisFuncs = CreateSimpleBases(data, exponents, funcs);
    1818
     
    2020                // only allow hinge functions for features with exponent = 1 (deemed too complex otherwise)
    2121                var linearSimpleBasisFuncs = simpleBasisFuncs.Where(simpleBf => simpleBf.Exponent == 1 && simpleBf.Operator.Equals(NonlinearOperator.None));
    22                 simpleBasisFuncs = simpleBasisFuncs.Concat(CreateHingeBases(data, linearSimpleBasisFuncs, approach.MinHingeThr, approach.MaxHingeThr, approach.NumHingeThrs));
     22                simpleBasisFuncs = simpleBasisFuncs.Concat(CreateHingeBases(data, linearSimpleBasisFuncs, approach.MinHingeThreshold, approach.MaxHingeThreshold, approach.NumHingeThresholds));
    2323            }
    2424
    2525            IEnumerable<IBasisFunction> functions = simpleBasisFuncs;
    2626
    27             if (approach.AllowInter) {
     27            if (approach.AllowInteractions) {
    2828                var multivariateBases = CreateMultivariateBases(data, simpleBasisFuncs.ToArray());
    2929                functions = functions.Concat(multivariateBases);
    3030            }
    3131
    32             if (approach.AllowDenom) {
     32            if (approach.AllowDenominators) {
    3333                var denominatorBases = CreateDenominatorBases(functions);
    3434                functions = functions.Concat(denominatorBases);
     
    3737        }
    3838
    39         public static IEnumerable<ISimpleBasisFunction> CreateSimpleBases(IRegressionProblemData problemData, HashSet<double> exponents, HashSet<NonlinearOperator> nonlinFuncs) {
     39        public static IEnumerable<ISimpleBasisFunction> CreateSimpleBases(IRegressionProblemData problemData, HashSet<double> exponents, HashSet<NonlinearOperator> nonLinearFunctions) {
    4040            var simpleBasisFunctions = new List<ISimpleBasisFunction>();
    4141            foreach (var variableName in problemData.AllowedInputVariables) {
     
    4545                    var simpleBase = new SimpleBasisFunction(variableName, exp, NonlinearOperator.None);
    4646                    // if the basis function is not valid without any operator, then it won't be valid in combination with any nonlinear operator -> skip
    47                     if (!Ok(simpleBase.Simulate(problemData))) continue;
    48 
    49                     foreach (NonlinearOperator op in nonlinFuncs) {
     47                    if (!Ok(simpleBase.Evaluate(problemData))) continue;
     48
     49                    foreach (NonlinearOperator op in nonLinearFunctions) {
    5050                        // ignore cases where op has no effect
    51                         if (op.Equals(NonlinearOperator.Abs) && new[] { -2.0, 2.0 }.Contains(exp) && nonlinFuncs.Contains(NonlinearOperator.None)) continue;
     51                        if (op.Equals(NonlinearOperator.Abs) && new[] { -2.0, 2.0 }.Contains(exp) && nonLinearFunctions.Contains(NonlinearOperator.None)) continue;
    5252                        if (op.Equals(NonlinearOperator.Abs) && min >= 0) continue;
    5353                        var nonsimpleBase = (SimpleBasisFunction)simpleBase.DeepCopy();
    5454                        nonsimpleBase.Operator = op;
    55                         if (!Ok(nonsimpleBase.Simulate(problemData))) continue;
     55                        if (!Ok(nonsimpleBase.Evaluate(problemData))) continue;
    5656                        simpleBasisFunctions.Add(nonsimpleBase);
    5757                    }
     
    7777                    if (b_j.Operator != NonlinearOperator.None) continue; // disallow op() * op(); deemed to complex
    7878                    var b_inter = new ProductBaseFunction(b_i, b_j, true);
    79                     if (!Ok(b_inter.Simulate(data))) continue;
     79                    if (!Ok(b_inter.Evaluate(data))) continue;
    8080                    multivariateBases.Add(b_inter);
    8181                    if (multivariateBases.Count() >= maxSize)
     
    9898        }
    9999
    100         public static IList<ISimpleBasisFunction> CreateHingeBases(IRegressionProblemData data, IEnumerable<ISimpleBasisFunction> simple_bfs, double relative_start_thr = 0.0, double relative_end_thr = 1.0, int num_thrs = 3, IntRange trainingPartition = null) {
     100        public static IList<ISimpleBasisFunction> CreateHingeBases(IRegressionProblemData data, IEnumerable<ISimpleBasisFunction> simple_bfs,
     101          double relative_start_thr = 0.0, double relative_end_thr = 1.0, int num_thrs = 3, IntRange trainingPartition = null) {
    101102            var hingeBases = new List<ISimpleBasisFunction>();
    102103
     
    107108        }
    108109
    109         private static IEnumerable<ISimpleBasisFunction> CreateHingeBases(IRegressionProblemData data, ISimpleBasisFunction simple_bf, double relative_start_thr, double relative_end_thr, int num_thrs, IntRange trainingPartition) {
     110        private static IEnumerable<ISimpleBasisFunction> CreateHingeBases(IRegressionProblemData data, ISimpleBasisFunction simple_bf,
     111          double relative_start_thr, double relative_end_thr, int num_thrs, IntRange trainingPartition) {
    110112            if (relative_start_thr >= relative_end_thr) throw new ArgumentException($"{nameof(relative_start_thr)} must be smaller than {nameof(relative_end_thr)}.");
    111113            var ans = new List<ISimpleBasisFunction>();
    112114
    113             var vals = simple_bf.Simulate(data);
     115            var vals = simple_bf.Evaluate(data);
    114116            var temp = trainingPartition ?? data.TrainingPartition;
    115117            double min = Double.MaxValue;
     
    126128
    127129            foreach (var thr in thresholds) {
    128                 ans.Add(new SimpleBasisFunction(simple_bf.Feature, 1, NonlinearOperator.Gth, true, thr));
    129                 ans.Add(new SimpleBasisFunction(simple_bf.Feature, 1, NonlinearOperator.Lth, true, thr));
     130                ans.Add(new SimpleBasisFunction(simple_bf.Feature, 1, NonlinearOperator.GT_Hinge, true, thr));
     131                ans.Add(new SimpleBasisFunction(simple_bf.Feature, 1, NonlinearOperator.LT_Hinge, true, thr));
    130132            }
    131133            return ans;
     
    135137            List<IBasisFunction> ans = new List<IBasisFunction>();
    136138            foreach (var bf in basisFunctions) {
    137                 if (!bf.IsNominator) continue;
     139                if (!bf.IsDenominator) continue;
    138140                var denomFunc = bf.DeepCopy();
    139                 denomFunc.IsNominator = false;
     141                denomFunc.IsDenominator = false;
    140142                ans.Add(denomFunc);
    141143            }
     
    151153            int col = 0;
    152154            foreach (var basisFunc in basisFunctions) {
    153                 allowedInputVars.Add(basisFunc.ToString() + (!basisFunc.IsNominator ? " * " + problemData.TargetVariable : ""));
    154                 var vals = basisFunc.Simulate(problemData);
     155                allowedInputVars.Add(basisFunc.ToString() + (!basisFunc.IsDenominator ? " * " + problemData.TargetVariable : ""));
     156                var vals = basisFunc.Evaluate(problemData);
    155157                for (int i = 0; i < numRows; i++) {
    156158                    variableValues[i, col] = vals[i];
  • branches/3022-FastFunctionExtraction/FFX/FFXModel.cs

    r17737 r17779  
    1818        public IEnumerable<(double coeff, IBasisFunction function)> BasisFunctions { get; set; }
    1919        public IEnumerable<(double coeff, IBasisFunction function)> NominatorFunctions =>
    20             BasisFunctions.Where(bf => bf.function.IsNominator);
     20            BasisFunctions.Where(bf => bf.function.IsDenominator);
    2121        public IEnumerable<(double coeff, IBasisFunction function)> DenominatorFunctions =>
    22             BasisFunctions.Where(bf => !bf.function.IsNominator);
     22            BasisFunctions.Where(bf => !bf.function.IsDenominator);
    2323
    2424        public int NumNumeratorFunctions => NominatorFunctions != null ? NominatorFunctions.Count() : 0;
  • branches/3022-FastFunctionExtraction/FFX/FastFunctionExtraction.cs

    r17762 r17779  
    1212using System.Collections.Generic;
    1313using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    14 using HeuristicLab.Problems.DataAnalysis.Symbolic;
     14using System.Collections;
    1515
    1616namespace HeuristicLab.Algorithms.DataAnalysis.FastFunctionExtraction {
    1717
    18     [Item(Name = "FastFunctionExtraction", Description = "An FFX algorithm.")]
     18    [Item(Name = "FastFunctionExtraction", Description = "Implementation of the Fast Function Extraction (FFX) algorithm in C#.")]
    1919    [Creatable(Category = CreatableAttribute.Categories.Algorithms, Priority = 999)]
    20     [StorableType("689280F7-E371-44A2-98A5-FCEDF22CA343")] // for persistence (storing your algorithm to a files or transfer to HeuristicLab.Hive
     20    [StorableType("689280F7-E371-44A2-98A5-FCEDF22CA343")]
    2121    public sealed class FastFunctionExtraction : FixedDataAnalysisAlgorithm<IRegressionProblem> {
    2222
     
    156156                .SelectMany(approach => CreateFFXModels(data, approach)).ToList();
    157157
    158             // Final pareto filter over all generated models from all different approaches
     158            // Final Pareto filter over all generated models from all different approaches
    159159            var nondominatedFFXModels = NondominatedModels(data, allFFXModels);
    160160
     
    199199            var normalizedElnetData = BFUtils.Normalize(elnetData, out var X_avgs, out var X_stds, out var y_avg, out var y_std);
    200200           
    201             ElasticNetLinearRegression.RunElasticNetLinearRegression(normalizedElnetData, approach.ElnetPenalty, out var _, out var _, out var _, out var candidateCoeffsNorm, out var interceptNorm, maxVars: approach.MaxNumBases);
     201            ElasticNetLinearRegression.RunElasticNetLinearRegression(normalizedElnetData, approach.ElasticNetPenalty, out var _, out var _, out var _, out var candidateCoeffsNorm, out var interceptNorm, maxVars: approach.MaxNumBases);
    202202
    203203            var coefs = RebiasCoefs(candidateCoeffsNorm, interceptNorm, X_avgs, X_stds, y_avg, y_std, out var intercept);
     
    251251
    252252            // return true if ALL indices of true values of arr1 also have true values in arr2
    253             bool follows(bool[] arr1, bool[] arr2) {
     253            bool follows(BitArray arr1, bool[] arr2) {
    254254                if (arr1.Length != arr2.Length) throw new ArgumentException("invalid lengths");
    255255                for (int i = 0; i < arr1.Length; i++) {
     
    259259            }
    260260
     261
    261262            for (int i = 0; i < 32; i++) { // Iterate all combinations of 5 bools.
    262                 // map i to a bool array of length 5
    263                 var arr = i.ToBoolArray(5);
     263                // map i to a bool array of length 5               
     264                var v = i;
     265                int b = 0;
     266                var arr = new BitArray(5);
     267                var popCount = 0;
     268                while (v>0) { if (v % 2 == 1) { arr[b++] = true; popCount++; } ; v /= 2; }
     269
    264270                if (!follows(arr, valids)) continue;
    265                 int sum = arr.Where(b => b).Count(); // how many features are enabled?
    266                 if (sum >= 4) continue; // not too many features at once
     271                if (popCount >= 4) continue; // not too many features at once
    267272                if (arr[0] && arr[2]) continue; // never need both exponent and inter
    268273                approaches.Add(new Approach(arr[0], arr[1], arr[2], arr[3], arr[4], exponents, nonlinFuncs, maxNumBases, penalty, minHingeThr, maxHingeThr, numHingeThrs));
  • branches/3022-FastFunctionExtraction/FFX/IBasisFunction.cs

    r17737 r17779  
    44    internal interface IBasisFunction {
    55        int Complexity { get; }
    6         bool IsNominator { get; set; }
    7         double[] Simulate(IRegressionProblemData data);
     6        bool IsDenominator { get; set; }
     7        double[] Evaluate(IRegressionProblemData data);
    88        IBasisFunction DeepCopy();
    99    }
  • branches/3022-FastFunctionExtraction/FFX/NonlinearOperator.cs

    r17737 r17779  
    22namespace HeuristicLab.Algorithms.DataAnalysis.FastFunctionExtraction {
    33    enum NonlinearOperator {
    4         None, Abs, Log, Sin, Cos, Gth, Lth
     4        None, Abs, Log, Sin, Cos, GT_Hinge, LT_Hinge
    55    }
    66}
  • branches/3022-FastFunctionExtraction/FFX/Plugin.cs

    r17762 r17779  
    55  [PluginFile("HeuristicLab.Algorithms.DataAnalysis.FastFunctionExtraction.dll", PluginFileType.Assembly)] // each plugin represents a collection of files. The minimum is one file; the assembly.
    66
    7   // Usually your plugin references other HeuristicLab dlls. If you are referencing files (e.g. assemblies)
    8   // from another plugin the corresponding plugin should be added as a dependency.
    9   // Usually, if this information is incorrect you will still be able to use you plugin, but HL functionality
    10   // which uses plugin dependency resolution will not work correctly. For instance if plugin dependencies are
    11   // not correct then your plugin cannot be used on HeuristicLab.Hive
    12   //
    137  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
    148  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis.Glmnet", "3.4")]
     
    2822  [PluginDependency("HeuristicLab.Random", "3.3")]
    2923
    30   // HL plugin infrastructure discovers plugins on startup by trying to load all .dll and .exe files and looking for
    31   // classes deriving from PluginBase. The meta-information for the plugin class is specified in the attributes
    32   // above, and used by plugin infrastructure primarily for plugin dependency resolution.
    33 
    34   // Steps:
    35   // (1) Check out HL source code (e.g. the trunk version)
    36   // (2) Build external libraries HeuristicLab.ExtLibs.sln using the Build.cmd (in the path of the HL source code)
    37   // (3) Build HeuristicLab 3.3.sln using the Build.cmd
    38   // (4) Build this project. The output path for binaries is set to "".
    39   //     this assumes you have the following folder structure
    40   //    <ROOT>
    41   //    |..hl
    42   //       |..branches
    43   //       |  |..Templates
    44   //       |     |..EmptyPlugin
    45   //       |..trunk
    46   //          |.. bin
    47 
    48   //  (5) Check that the output file has been added to the HL binaries folder (hl/trunk/bin/EmptyPlugin.dll)
    49   //  (6) Start hl/trunk/bin/HeuristicLab.exe and open the "Plugin Manager".
    50   //      Make sure your EmptyPlugin appears in the list of loaded plugins
    5124  public class Plugin : PluginBase {
    5225  }
  • branches/3022-FastFunctionExtraction/FFX/ProductBaseFunction.cs

    r17737 r17779  
    88        public IBasisFunction B2 { get; set; }
    99
    10         public int Complexity
    11             => 1 + B1.Complexity + B2.Complexity;
     10        public int Complexity => 1 + B1.Complexity + B2.Complexity;
    1211
    13         public bool IsNominator { get; set; }
     12        public bool IsDenominator { get; set; }
    1413
    15         public ProductBaseFunction(IBasisFunction b1, IBasisFunction b2, bool nominator) {
     14        public ProductBaseFunction(IBasisFunction b1, IBasisFunction b2, bool isDenominator) {
    1615            B1 = b1 ?? throw new ArgumentNullException(nameof(b1));
    1716            B2 = b2 ?? throw new ArgumentNullException(nameof(b2));
    18             IsNominator = nominator;
     17            IsDenominator = isDenominator;
    1918        }
    2019
    21         public double[] Simulate(IRegressionProblemData data) {
    22             return B1.Simulate(data).Zip(B2.Simulate(data), (a, b) => a * b).ToArray();
     20        public double[] Evaluate(IRegressionProblemData data) {
     21            return B1.Evaluate(data).Zip(B2.Evaluate(data), (a, b) => a * b).ToArray();
    2322        }
    2423
     
    2827
    2928        public IBasisFunction DeepCopy() {
    30             return new ProductBaseFunction(B1, B2, IsNominator);
     29            return new ProductBaseFunction(B1, B2, IsDenominator);
    3130        }
    3231    }
  • branches/3022-FastFunctionExtraction/FFX/SimpleBasisFunction.cs

    r17737 r17779  
    1111        public double Exponent { get; set; }
    1212        public NonlinearOperator Operator { get; set; }
    13         public bool IsNominator { get; set; }
     13        public bool IsDenominator { get; set; }
    1414        public string Feature { get; set; }
    1515        public double Threshold { get; set; } // only relevant for hinge function
    16         public bool HasExponent => !Exponent.IsAlmost(1.0);
     16        public bool HasExponent => !(Exponent == 1.0);
    1717        public bool HasOperator => Operator != NonlinearOperator.None;
    18         public int Complexity => Operator == NonlinearOperator.Gth || Operator == NonlinearOperator.Lth ? 3 : 1;
     18        public int Complexity => Operator == NonlinearOperator.GT_Hinge || Operator == NonlinearOperator.LT_Hinge ? 3 : 1;
    1919
    20         public SimpleBasisFunction(string feature, double exponent = 1, NonlinearOperator op = NonlinearOperator.None, bool isNominator = true, double thr = 0) {
     20        public SimpleBasisFunction(string feature, double exponent = 1, NonlinearOperator op = NonlinearOperator.None, bool isNominator = true, double threshold = 0) {
    2121            Feature = feature ?? throw new ArgumentNullException(nameof(feature));
    2222            Exponent = exponent;
    2323            Operator = op;
    24             IsNominator = isNominator;
    25             Threshold = thr;
     24            IsDenominator = isNominator;
     25            Threshold = threshold;
    2626        }
    2727
    2828        public IBasisFunction DeepCopy() {
    29             return new SimpleBasisFunction(Feature, Exponent, Operator, IsNominator, Threshold);
     29            return new SimpleBasisFunction(Feature, Exponent, Operator, IsDenominator, Threshold);
    3030        }
    3131
     
    4646
    4747            var thr = Threshold.ToString(culture);
    48             if (Operator == NonlinearOperator.Lth) {
     48            if (Operator == NonlinearOperator.LT_Hinge) {
    4949                var expr = $"{str} {((Threshold >= 0) ? " - " + Math.Abs(Threshold).ToString(culture) : " + " + Math.Abs(Threshold).ToString(culture))}";
    5050                str = $"IF(GT(0, {expr}), 0, {expr})";
    51             } else if (Operator == NonlinearOperator.Gth) {
     51            } else if (Operator == NonlinearOperator.GT_Hinge) {
    5252                var expr = $"{thr} - {str}";
    5353                str = $"IF(GT(0, {expr}), 0, {expr})";
     
    5858        }
    5959
    60         public double[] Simulate(IRegressionProblemData data) {
     60        public double[] Evaluate(IRegressionProblemData data) {
    6161            var exp = Exponent;
    6262            // exponentVals : e.g. "x3^2"
     
    6767            var vals = Eval(exponentVals);
    6868
    69             if (!IsNominator) {
     69            if (!IsDenominator) {
    7070                var y = data.TargetVariableValues;
    7171                vals = vals.Zip(y, (a, b) => -a * b).ToArray();
     
    8787                case NonlinearOperator.Cos:
    8888                    return x.Select(val => Math.Cos(val)).ToArray();
    89                 case NonlinearOperator.Gth:
     89                case NonlinearOperator.GT_Hinge:
    9090                    return x.Select(val => Math.Max(0, thr - val)).ToArray();
    91                 case NonlinearOperator.Lth:
     91                case NonlinearOperator.LT_Hinge:
    9292                    return x.Select(val => Math.Max(0, val - thr)).ToArray();
    9393                default:
  • branches/3022-FastFunctionExtraction/FFX/Utils.cs

    r17737 r17779  
    2525        }
    2626
    27         // find the array containing n (linearly) evenly spaced double values ranging from start to end (including both)
    2827        public static IEnumerable<double> Linspace(double start, double end, int n) {
    2928            if (end < start) throw new ArgumentException("end must be higher that start");
     
    3534
    3635        public static double[] Normalize(double[] vals)
    37             => Bias(vals, 0, 1);
     36            => Transform(vals, mean: 0, stdDev: 1);
    3837
    39         public static double[] Bias(double[] vals, double targetAvg, double targetStd) {
     38        public static double[] Transform(double[] vals, double mean, double stdDev) {
    4039            var result = new double[vals.Length];
    4140
    42             // bias standard deviation
    43             var stdRatio = vals.StandardDeviationPop() / targetStd;
     41            var scale = vals.StandardDeviationPop() / stdDev;
    4442            for (int i = 0; i < vals.Length; i++) {
    45                 result[i] = vals[i] / stdRatio;
     43                result[i] = vals[i] / scale;
    4644            }
    4745
    48             // bias average
    49             var avgDiff = result.Average() - targetAvg;
     46            var offset = result.Average() - mean;
    5047            for (int i = 0; i < vals.Length; i++) {
    51                 result[i] = result[i] - avgDiff;
     48                result[i] = result[i] - offset;
    5249            }
    5350
    5451            return result;
    5552        }
    56 
    57         public static bool[] ToBoolArray(this int val, int min_length) {
    58             var temp = Convert.ToString(val, 2).Select(s => s.Equals('1')).ToArray();
    59             if (temp.Length >= min_length) return temp;
    60 
    61             var ans = new bool[min_length];
    62             for(int i = 0; i < min_length - temp.Length; i++) {
    63                 ans[i] = false;
    64             }
    65             for(int i = 0; i < temp.Length; i++) {
    66                 ans[i + min_length - temp.Length] = temp[i];
    67             }
    68             return ans;
    69         }
    7053    }
    7154}
Note: See TracChangeset for help on using the changeset viewer.