예제 #1
0
        public OptionalValue <BitcodeModule> Generate(IAstNode ast)
        {
            ast.ValidateNotNull(nameof(ast));
            ast.Accept(this);

            if (AnonymousFunctions.Count > 0)
            {
                var mainFunction = Module.CreateFunction("main", Context.GetFunctionType(Context.VoidType));
                var block        = mainFunction.AppendBasicBlock("entry");
                var irBuilder    = new InstructionBuilder(block);
                var printdFunc   = Module.CreateFunction("printd", Context.GetFunctionType(Context.DoubleType, Context.DoubleType));
                foreach (var anonFunc in AnonymousFunctions)
                {
                    var value = irBuilder.Call(anonFunc);
                    irBuilder.Call(printdFunc, value);
                }

                irBuilder.Return( );

                // Use always inline and Dead Code Elimination module passes to inline all of the
                // anonymous functions. This effectively strips all the calls just generated for main()
                // and inlines each of the anonymous functions directly into main, dropping the now
                // unused original anonymous functions all while retaining all of the original source
                // debug information locations.
                using var mpm = new ModulePassManager( );
                mpm.AddAlwaysInlinerPass( )
                .AddGlobalDCEPass( )
                .Run(Module);

                Module.DIBuilder.Finish( );
            }

            return(OptionalValue.Create(Module));
        }
예제 #2
0
        public static void Samples([CallerFilePath] string file = "")
        {
            var root = Path.GetDirectoryName(file);

            // ------------------------------------------------------------
            // Creating time series
            // ------------------------------------------------------------

            // [create-builder]
            var numNames = new SeriesBuilder <int, string>()
            {
                { 1, "one" }, { 2, "two" }, { 3, "three" }
            }.Series;

            numNames.Print();
            // [/create-builder]

            // [create-heterogen]
            // Create series builder and use it via 'dynamic'
            var     nameNumsBuild = new SeriesBuilder <string, int>();
            dynamic nameNumsDyn   = nameNumsBuild;

            nameNumsDyn.One   = 1;
            nameNumsDyn.Two   = 2;
            nameNumsDyn.Three = 3;

            // Build series and print it
            var nameNums = nameNumsBuild.Series;

            nameNums.Print();
            // [/create-heterogen]

            // [create-ordinal]
            var rnd      = new Random();
            var randNums = Enumerable.Range(0, 100)
                           .Select(_ => rnd.NextDouble()).ToOrdinalSeries();

            randNums.Print();
            // [/create-ordinal]

            // [create-kvp]
            var sin = Enumerable.Range(0, 1000)
                      .Select(x => KeyValue.Create(x, Math.Sin(x / 100.0)))
                      .ToSeries();

            sin.Print();
            // [/create-kvp]

            // [create-sparse]
            var opts = Enumerable.Range(0, 10)
                       .Select(x => KeyValue.Create(x, OptionalValue.OfNullable <int>(x)))
                       .ToSparseSeries();

            opts.Print();
            // [/create-sparse]

            // [create-csv]
            var frame     = Frame.ReadCsv(Path.Combine(root, "../data/stocks/msft.csv"));
            var frameDate = frame.IndexRows <DateTime>("Date").SortRowsByKey();
            var msftOpen  = frameDate.GetColumn <double>("Open");

            msftOpen.Print();
            // [/create-csv]

            // ------------------------------------------------------------
            // Lookup and slicing
            // ------------------------------------------------------------

            // [lookup-key]
            // Get value for a specified int and string key
            var tenth = randNums[10];
            var one   = nameNums["One"];

            // Get first and last value using index
            var fst = nameNums.GetAt(0);
            var lst = nameNums.GetAt(nameNums.KeyCount - 1);
            // [/lookup-key]

            // [lookup-opt]
            // Get value as OptionalValue<T> and use it
            var opt = opts.TryGet(5);

            if (opt.HasValue)
            {
                Console.Write(opt.Value);
            }

            // For value types, we can convert to nullable type
            int?value1 = opts.TryGet(5).AsNullable();
            int?value2 = opts.TryGetAt(0).AsNullable();
            // [/lookup-opt]

            // [lookup-ord]
            // Get value exactly at the specified key
            var jan3 = msftOpen
                       .Get(new DateTime(2012, 1, 3));

            // Get value at a key or for the nearest previous date
            var beforeJan1 = msftOpen
                             .Get(new DateTime(2012, 1, 1), Lookup.ExactOrSmaller);

            // Get value at a key or for the nearest later date
            var afterJan1 = msftOpen
                            .Get(new DateTime(2012, 1, 1), Lookup.ExactOrGreater);
            // [/lookup-ord]

            // [lookup-slice]
            // Get a series starting/ending at
            // the specified date (inclusive)
            var msftStartIncl = msftOpen.StartAt(new DateTime(2012, 1, 1));
            var msftEndIncl   = msftOpen.EndAt(new DateTime(2012, 12, 31));

            // Get a series starting/ending after/before
            // the specified date (exclusive)
            var msftStartExcl = msftOpen.After(new DateTime(2012, 1, 1));
            var msftEndExcl   = msftOpen.Before(new DateTime(2012, 12, 31));

            // Get prices for 2012 (both keys are inclusive)
            var msft2012 = msftOpen.Between
                               (new DateTime(2012, 1, 1), new DateTime(2012, 12, 31));
            // [/lookup-slice]

            // ------------------------------------------------------------
            // Statistics and calculations
            // ------------------------------------------------------------

            // [calc-stat]
            // Calculate median & mean price
            var msftMed = msft2012.Median();
            var msftAvg = msft2012.Mean();

            // Calculate sum of square differences
            var msftDiff = msft2012 - msftAvg;
            var msftSq   = (msftDiff * msftDiff).Sum();
            // [/calc-stat]

            // [calc-diff]
            // Subtract previous day value from current day
            var msftChange = msft2012 - msft2012.Shift(1);

            // Use built-in Diff method to do the same
            var msftChangeAlt = msft2012.Diff(1);

            // Get biggest loss and biggest gain
            var minMsChange = msftChange.Min();
            var maxMsChange = msftChange.Max();
            // [/calc-diff]

            // [calc-custom]
            var wackyStat = msft2012.Observations.Select(kvp =>
                                                         kvp.Value / (kvp.Key - msft2012.FirstKey()).TotalDays).Sum();
            // [/calc-custom]

            // ------------------------------------------------------------
            // Missing data
            // ------------------------------------------------------------

            // [fill-const-drop]
            // Fill missing data with constant
            var fillConst = opts.FillMissing(-1);

            fillConst.Print();

            // Drop keys with no value from the series
            var drop = opts.DropMissing();

            drop.Print();
            // [/fill-const-drop]

            // [fill-dir]
            // Fill with previous available value
            var fillFwd = opts.FillMissing(Direction.Forward);

            fillFwd.Print();

            // Fill with the next available value
            var fillBwd = opts.FillMissing(Direction.Backward);

            fillBwd.Print();
            // [/fill-dir]

            // ------------------------------------------------------------
            // Windows and chunks, grouping
            // ------------------------------------------------------------

            // [aggreg-group]
            // Group random numbers by the first digit & get distribution
            var buckets = randNums
                          .GroupBy(kvp => (int)(kvp.Value * 10))
                          .Select(kvp => OptionalValue.Create(kvp.Value.KeyCount));

            buckets.Print();
            // [/aggreg-group]

            // [aggreg-win]
            // Average over 25 element floating window
            var monthlyWinMean = msft2012.WindowInto(25, win => win.Mean());

            // Get floating window over 5 elements as series of series
            // and then apply average on each series individually
            var weeklyWinMean = msft2012.Window(5).Select(kvp =>
                                                          kvp.Value.Mean());
            // [/aggreg-win]

            // [aggreg-chunk]
            // Get chunks of size 25 and mean each (disjoint) chunk
            var monthlyChunkMean = msft2012.ChunkInto(25, win => win.Mean());

            // Get series containing individual chunks (as series)
            var weeklyChunkMean = msft2012.Chunk(5).Select(kvp =>
                                                           kvp.Value.Mean());
            // [/aggreg-chunk]

            // [aggreg-pair]
            // For each key, get the previous value and average them
            var twoDayAvgs = msft2012.Pairwise().Select(kvp =>
                                                        (kvp.Value.Item1 + kvp.Value.Item2) / 2.0);

            // [/aggreg-pair]

            // [aggreg-any]
            msft2012.Aggregate
                (                 // Get chunks while the month & year of the keys are the same
                Aggregation.ChunkWhile <DateTime>((k1, k2) =>
                                                  k1.Month == k2.Month && k2.Year == k1.Year),
                // For each chunk, return the first key as the key and
                // either average value or missing value if it was empty
                chunk => KeyValue.Create
                    (chunk.Data.FirstKey(),
                    chunk.Data.ValueCount > 0 ?
                    OptionalValue.Create(chunk.Data.Mean()) :
                    OptionalValue.Empty <double>()));
            // [/aggreg-any]


            // ------------------------------------------------------------
            // Operations (Select, where)
            // ------------------------------------------------------------

            // [linq-methods]
            var overMean = msft2012
                           .Select(kvp => kvp.Value - msftAvg)
                           .Where(kvp => kvp.Value > 0.0).KeyCount;
            // [/linq-methods]

            // [linq-query]
            var underMean =
                (from kvp in msft2012
                 where kvp.Value - msftAvg < 0.0
                 select kvp).KeyCount;

            // [/linq-query]

            Console.WriteLine(overMean);
            Console.WriteLine(underMean);

            // ------------------------------------------------------------
            // Indexing and sampling & resampling
            // ------------------------------------------------------------

            // [index-keys]
            // Turn DateTime keys into DateTimeOffset keys
            var byOffs = msft2012.SelectKeys(kvp =>
                                             new DateTimeOffset(kvp.Key));

            // Replace keys with ordinal numbers 0 .. KeyCount-1
            var byInt = msft2012.IndexOrdinally();
            // [/index-keys]

            // [index-with]
            // Replace keys with explictly specified new keys
            var byDays = numNames.IndexWith(new[] {
                DateTime.Today,
                DateTime.Today.AddDays(1.0),
                DateTime.Today.AddDays(2.0)
            });
            // [/index-with]
        }
예제 #3
0
 public OptionalValue <IAstNode> Generate(IAstNode ast)
 {
     return(OptionalValue.Create(ast));
 }