Skip to content

Commit 29f1b87

Browse files
committed
Doc changes and tridiagonal determinant test.
1 parent a109110 commit 29f1b87

File tree

11 files changed

+165
-87
lines changed

11 files changed

+165
-87
lines changed

Examples/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"preLaunchTask": "build",
1212
// If you have changed target frameworks, make sure to update the program path.
1313
"program": "${workspaceFolder}/bin/Debug/netcoreapp2.0/Examples.dll",
14-
"args": ["FitToDistribution"],
14+
"args": [],
1515
"cwd": "${workspaceFolder}",
1616
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
1717
"console": "internalConsole",

Examples/Data.cs

Lines changed: 105 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,79 @@
99
using Meta.Numerics.Statistics;
1010
using Meta.Numerics.Statistics.Distributions;
1111

12+
using Newtonsoft.Json;
13+
1214
namespace Examples {
1315

1416
public static class Data {
1517

18+
public static void ConstructTestCsv () {
19+
20+
using (TextWriter writer = new StreamWriter(File.OpenWrite("test.csv"))) {
21+
writer.WriteLine("Id, Name, Sex, Birthdate, Height, Weight, Result");
22+
writer.WriteLine("1, John, M, 1970-01-02, 190.0, 75.0, True");
23+
writer.WriteLine("2, Mary, F, 1980-02-03, 155.0, 40.0, True");
24+
writer.WriteLine("3, Luke, M, 1990-03-04, 180.0, 60.0, False");
25+
}
26+
27+
}
28+
29+
[ExampleMethod]
30+
public static void ImportingData () {
31+
32+
FrameTable data;
33+
using (TextReader reader = File.OpenText("test.csv")) {
34+
data = FrameTable.FromCsv(reader);
35+
}
36+
37+
Console.WriteLine($"Imported CSV file with {data.Rows.Count} rows.");
38+
Console.WriteLine("The names and types of the columns are:");
39+
foreach (FrameColumn column in data.Columns) {
40+
Console.WriteLine($" {column.Name} of type {column.StorageType}");
41+
}
42+
43+
FrameTable titanic;
44+
Uri url = new Uri("https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv");
45+
WebRequest request = WebRequest.Create(url);
46+
using (WebResponse response = request.GetResponse()) {
47+
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
48+
titanic = FrameTable.FromCsv(reader);
49+
}
50+
}
51+
52+
Uri jsonUrl = new Uri("https://raw.githubusercontent.com/dcwuser/metanumerics/master/Examples/Data/example.json");
53+
WebClient client = new WebClient();
54+
string input = client.DownloadString(jsonUrl);
55+
List<Dictionary<string,object>> output = JsonConvert.DeserializeObject<List<Dictionary<string,object>>>(input);
56+
FrameTable jsonExample = FrameTable.FromDictionaries(output);
57+
58+
// Define the schema.
59+
FrameTable table = new FrameTable();
60+
table.AddColumn<int>("Id");
61+
table.AddColumn<string>("Name");
62+
table.AddColumn<string>("Sex");
63+
table.AddColumn<DateTime>("Birthdate");
64+
table.AddColumn<double>("Height");
65+
table.AddColumn<double?>("Weight");
66+
table.AddColumn<bool>("Result");
67+
68+
// Add rows using as arrays of objects.
69+
table.AddRow(1, "John", "M", DateTime.Parse("1970-01-02"), 190.0, 75.0, true);
70+
table.AddRow(2, "Mary", "F", DateTime.Parse("1980-02-03"), 155.0, null, true);
71+
72+
// Add a row using a dictionary. This is more verbose, but very clear.
73+
table.AddRow(new Dictionary<string,object>(){
74+
{"Id", 3},
75+
{"Name", null},
76+
{"Sex", "M"},
77+
{"Birthdate", DateTime.Parse("1990-03-04")},
78+
{"Height", 180.0},
79+
{"Weight", 60.0},
80+
{"Result", false}
81+
});
82+
83+
}
84+
1685
[ExampleMethod]
1786
public static void ManipulatingData () {
1887

@@ -82,8 +151,18 @@ public static void AnalyzingData () {
82151
table = FrameTable.FromCsv(reader);
83152
}
84153
}
154+
FrameView view = table.WhereNotNull();
155+
156+
// Get the column with (zero-based) index 4.
157+
FrameColumn column4 = view.Columns[4];
158+
// Get the column named "Height".
159+
FrameColumn heightsColumn = view.Columns["Height"];
160+
// Even easier way to get the column named "Height".
161+
FrameColumn alsoHeightsColumn = view["Height"];
85162

86-
SummaryStatistics summary = new SummaryStatistics(table["Height"].As<double>());
163+
IReadOnlyList<double> heights = view["Height"].As<double>();
164+
165+
SummaryStatistics summary = new SummaryStatistics(view["Height"].As<double>());
87166
Console.WriteLine($"Count = {summary.Count}");
88167
Console.WriteLine($"Mean = {summary.Mean}");
89168
Console.WriteLine($"Standard Deviation = {summary.StandardDeviation}");
@@ -92,74 +171,77 @@ public static void AnalyzingData () {
92171
Console.WriteLine($"Estimated population standard deviation = {summary.PopulationStandardDeviation}");
93172

94173
IReadOnlyList<double> maleHeights =
95-
table.Where<string>("Sex", s => s == "M").Columns["Height"].As<double>();
174+
view.Where<string>("Sex", s => s == "M").Columns["Height"].As<double>();
96175
IReadOnlyList<double> femaleHeights =
97-
table.Where<string>("Sex", s => s == "F").Columns["Height"].As<double>();
176+
view.Where<string>("Sex", s => s == "F").Columns["Height"].As<double>();
98177
TestResult test = Univariate.StudentTTest(maleHeights, femaleHeights);
99-
Console.WriteLine($"{test.Statistic.Name} = {test.Statistic.Value}, P = {test.Probability}");
178+
Console.WriteLine($"{test.Statistic.Name} = {test.Statistic.Value}");
179+
Console.WriteLine($"P = {test.Probability}");
100180

101181
TestResult maleHeightNormality = maleHeights.ShapiroFranciaTest();
102-
TestResult totalHeightNormality = table["Height"].As<double>().ShapiroFranciaTest();
182+
TestResult totalHeightNormality = view["Height"].As<double>().ShapiroFranciaTest();
103183
TestResult heightCompatibility = Univariate.KolmogorovSmirnovTest(maleHeights, femaleHeights);
104184

105185
LinearRegressionResult fit =
106-
table["Weight"].As<double>().LinearRegression(table["Height"].As<double>());
186+
view["Weight"].As<double>().LinearRegression(view["Height"].As<double>());
107187
Console.WriteLine($"Model weight = ({fit.Slope}) * height + ({fit.Intercept}).");
108188
Console.WriteLine($"Model explains {fit.RSquared * 100.0}% of variation.");
109189

110190
ContingencyTable<string, bool> contingency =
111-
Bivariate.Crosstabs(table["Sex"].As<string>(), table["Result"].As<bool>());
191+
Bivariate.Crosstabs(view["Sex"].As<string>(), view["Result"].As<bool>());
112192
Console.WriteLine($"Male incidence: {contingency.ProbabilityOfColumnConditionalOnRow(true, "M")}");
113-
Console.WriteLine($"Female incidence: {contingency.ProbabilityOfColumnConditionalOnRow(false, "F")}");
193+
Console.WriteLine($"Female incidence: {contingency.ProbabilityOfColumnConditionalOnRow(true, "F")}");
114194
Console.WriteLine($"Log odds ratio = {contingency.Binary.LogOddsRatio}");
115195

116-
table.AddComputedColumn("Bmi", r => ((double) r["Weight"])/MoreMath.Sqr((double) r["Height"] / 100.0));
117-
table.AddComputedColumn("Age", r=> (DateTime.Now - (DateTime) r["Birthdate"]).TotalDays / 365.24);
196+
view.AddComputedColumn("Bmi", r => ((double) r["Weight"])/MoreMath.Sqr((double) r["Height"] / 100.0));
197+
view.AddComputedColumn("Age", r=> (DateTime.Now - (DateTime) r["Birthdate"]).TotalDays / 365.24);
118198

119199
MultiLinearLogisticRegressionResult result =
120-
table["Result"].As<bool>().MultiLinearLogisticRegression(
121-
table["Bmi"].As<double>(),
122-
table["Sex"].As<string, double>(s => s == "M" ? 1.0 : 0.0)
200+
view["Result"].As<bool>().MultiLinearLogisticRegression(
201+
view["Bmi"].As<double>(),
202+
view["Sex"].As<string, double>(s => s == "M" ? 1.0 : 0.0)
123203
);
124204
foreach (Parameter parameter in result.Parameters) {
125205
Console.WriteLine($"{parameter.Name} = {parameter.Estimate}");
126206
}
127207

128-
//TestResult ageResultPearson = Bivariate.PearsonRTest(table["Age"].As<double>(), table["Result"].As<double>());
129-
TestResult spearman = Bivariate.SpearmanRhoTest(table["Age"].As<double>(), table["Result"].As<double>());
208+
TestResult spearman = Bivariate.SpearmanRhoTest(view["Age"].As<double>(), view["Result"].As<double>());
130209
Console.WriteLine($"{spearman.Statistic.Name} = {spearman.Statistic.Value} P = {spearman.Probability}");
131210

132211
}
133212

134-
public static void ConstructData () {
213+
public static void ConstructExampleData () {
135214

136215
FrameTable table = new FrameTable();
137216
table.AddColumn<int>("Id");
138217
table.AddColumn<string>("Name");
139218
table.AddColumn<string>("Sex");
140219
table.AddColumn<DateTime>("Birthdate");
141-
table.AddColumns<double>("Height", "Weight");
220+
table.AddColumn<double>("Height");
221+
table.AddColumns<double?>("Weight");
142222
table.AddColumn<bool>("Result");
143223

144-
//Random rng = new Random(3);
145-
//Random rng = new Random(314159);
146-
// Random rng = new Random(271828);
147224
Random rng = new Random(1000001);
148225

149-
//string[] maleNames = new string[1024];
150226
string[] maleNames = new string[] {"Alex", "Chris", "David", "Eric", "Frederic", "George", "Hans", "Igor", "John", "Kevin", "Luke", "Mark", "Oscar", "Peter", "Richard", "Stephan", "Thomas", "Vincent" };
151227
AddRows(table, maleNames, "M", 175.0, 12.0, 24.0, 3.0, 1, rng);
152228

153-
//string[] femaleNames = new string[1024];
154229
string[] femaleNames = new string[] {"Anne", "Belle", "Dorothy", "Elizabeth", "Fiona", "Helen", "Julia", "Kate", "Louise", "Mary", "Natalie", "Olivia", "Ruth", "Sarah", "Theresa", "Viola" };
155230
AddRows(table, femaleNames, "F", 160.0, 10.0, 24.0, 3.0, 0, rng);
156231

157-
string path = @"C:\Users\dawright\Documents\example.csv";
232+
// add rows with nulls
233+
table.AddRow(table.Rows.Count, null, "M", DateTime.Parse("1970-07-27"), 183.0, 74.0, false);
234+
table.AddRow(table.Rows.Count, "Zoey", "F", DateTime.Parse("2007-09-17"), 138.0, null, false);
235+
236+
string path = @"example.csv";
158237
using (StreamWriter writer = new StreamWriter(File.OpenWrite(path))) {
159238
table.ToCsv(writer);
160239
}
161240
Console.WriteLine(File.Exists(path));
162241

242+
string json = JsonConvert.SerializeObject(table.ToDictionaries(), Formatting.Indented);
243+
File.WriteAllText("example.json", json);
244+
163245
}
164246

165247
private static void AddRows(FrameTable table, IReadOnlyList<string> names, string sex, double meanHeight, double stddevHeight, double meanBmi, double stddevBmi, int flag, Random rng) {

Examples/Examples.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
</PropertyGroup>
66
<ItemGroup>
77
<PackageReference Include="Meta.Numerics" Version="4.0.5-alpha"/>
8+
<PackageReference Include="Newtonsoft.Json" Version="11.0.2"/>
89
</ItemGroup>
910
</Project>

Examples/Program.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ private static MethodInfo[] GetExampleMethods () {
2323

2424
static void Main(string[] args)
2525
{
26-
2726
MethodInfo[] methods = GetExampleMethods();
2827
Dictionary<string, MethodInfo> index = new Dictionary<string, MethodInfo>();
2928
foreach (MethodInfo method in methods) {

Numerics/Analysis/EvaluationSettings.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
namespace Meta.Numerics.Analysis {
66

77
/// <summary>
8-
/// Contains settings controling the evaluation of a function.
8+
/// Contains settings governing the evaluation of a function.
99
/// </summary>
10+
/// <remarks>
11+
/// <para>Negative values of <see cref="EvaluationBudget"/>,
12+
/// <see cref="RelativePrecision"/>, and <see cref="AbsolutePrecision"/>
13+
/// indicate that the analysis method should use its defaults for
14+
/// that property. Override the default for a property by
15+
/// setting it explicitly. If you set values for some properties
16+
/// but not others, your setting will be applied to the property
17+
/// you set and the others will use defaults.</para>
18+
/// <para>When an analysis method returns an <see cref="EvaluationResult"/>
19+
/// object, its evaluation setting object will contain the specific
20+
/// settings used, so you can see which default values were applied.</para>
21+
/// </remarks>
1022
public class EvaluationSettings {
1123

1224
/// <summary>
13-
/// Initializes a new set of default evaulation settings.
25+
/// Initializes a new set of default evaluation settings.
1426
/// </summary>
1527
public EvaluationSettings () {
1628
evaluationBudget = -1;

Numerics/Data/FrameTable.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace Meta.Numerics.Data
1313
// Additional flags could include: iid, series, circular
1414

1515
/// <summary>
16-
/// A modify-able array of data.
16+
/// Represents a modify-able array of data.
1717
/// </summary>
1818
/// <remarks>
1919
/// <para>This is the central class for storing data in our data frame system.</para>
2020
/// <para>Use the <see cref="FromCsv"/> method to create a frame table from a comma-separated values
2121
/// file or the <see cref="FromDictionaries"/> method to create a frame table from JSON or another
2222
/// collection-of-dictionaries representation. Or create one programmatically by using the
2323
/// <see cref="FrameTable()"/> constructor to instantiate an empty data frame and
24-
/// <see cref="AddColumn{T}(string)"/> and <see cref="AddRow(object[])"/> to add columns and rows.</para>
24+
/// <see cref="AddColumn{T}(string)" autoUpgrade="true"/> and <see cref="AddRow(object[])" autoUpgrade="true"/> to add columns and rows.</para>
2525
/// <para>Using the methods inherited from the <see cref="FrameView"/> class, you can filter, re-order,
2626
/// manipulate, and analyze data without incurring the space or time costs of copying the stored data.</para>
2727
/// </remarks>
@@ -165,7 +165,7 @@ public void AddColumn<T>(string name, List<T> storage) {
165165
}
166166

167167
/// <summary>
168-
/// Adds the new columns with the given names.
168+
/// Adds new columns with the given names.
169169
/// </summary>
170170
/// <typeparam name="T">The type of the columns.</typeparam>
171171
/// <param name="names">The names of the columns.</param>

Numerics/Data/FrameView.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public enum SortOrder {
2929

3030

3131
/// <summary>
32-
/// A read-only view of an array of data.
32+
/// Represents a read-only view of an array of data.
3333
/// </summary>
3434
/// <remarks>
3535
/// <para>This is the central class for viewing data in our data frame system.</para>
@@ -50,10 +50,14 @@ public enum SortOrder {
5050
/// <see cref="this[string]"/> accessor to get a column, together with the <see cref="FrameColumn.As{T}"/>
5151
/// caster to expose it as a collection of the required type.
5252
/// For example, to obtain a estimate of the mean of the population from the sample in the
53-
/// column named "heights", write <tt>view["height"].As&lt;double&gt;().PopulationMean()</tt>.</para>
53+
/// column named "heights", write <tt>view["height"].As&lt;double&gt;().PopulationMean()</tt>.
54+
/// Note that, for this to succeed, the underlying storage type of the heights column need not be double. As
55+
/// long as the data are convertible to the target type, no problems will arise. For example,
56+
/// the underlying storage type might be int, or double? as long as no null values are present in the view.</para>
5457
/// <para>To create the original array of data that will be manipulated, use the <see cref="FrameTable"/>
5558
/// class. Note that, because the underlying data is not copied when a new view is generated, changes
56-
/// to the original table may not be reflected in the views that have been generated from it.</para>
59+
/// to the original table may have unexpected consequences for the views linked to it. Best practice
60+
/// is not to change the underlying data after generating views based on it.</para>
5761
/// <para>You can export a view to CSV or JSON formats using the <see cref="ToCsv(TextWriter)"/>
5862
/// and <see cref="ToDictionaries"/> methods.</para>
5963
/// </remarks>

Numerics/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@
4646
//
4747
// You can specify all the values or you can default the Revision and Build Numbers
4848
// by using the '*' as shown below:
49-
[assembly: AssemblyVersion("4.0.5.0")]
50-
[assembly: AssemblyFileVersion("4.0.5.0")]
49+
[assembly: AssemblyVersion("4.0.7.0")]
50+
[assembly: AssemblyFileVersion("4.0.7.0")]
5151

Numerics/Statistics/Distributions/PearsonRDistribution.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public override double ProbabilityDensity (double x) {
2525
if (Math.Abs(x) > 1.0) {
2626
return (0.0);
2727
} else {
28-
return (Math.Pow(1.0 - x * x, (n - 4) / 2.0) / AdvancedMath.Beta(0.5, (n - 2) / 2.0));
28+
return (Math.Pow((1.0 - x) * (1.0 + x), (n - 4) / 2.0) / AdvancedMath.Beta(0.5, (n - 2) / 2.0));
2929
}
3030
}
3131

@@ -89,7 +89,7 @@ public override double LeftProbability (double x) {
8989
if (x <= -1.0) {
9090
return (0.0);
9191
} else if (x < 0.0) {
92-
return (AdvancedMath.Beta((n - 2) / 2.0, 0.5, 1.0 - x * x) / AdvancedMath.Beta((n-2) / 2.0, 0.5) / 2.0);
92+
return (AdvancedMath.Beta((n - 2) / 2.0, 0.5, (1.0 - x) * (1.0 + x)) / AdvancedMath.Beta((n-2) / 2.0, 0.5) / 2.0);
9393
} else if (x < 1.0) {
9494
return ((1.0 + AdvancedMath.Beta(0.5, (n - 2) / 2.0, x * x) / AdvancedMath.Beta(0.5, (n-2) / 2.0)) / 2.0);
9595
} else {

Test/BivariateSampleTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ public void BivariateLinearRegressionNullDistribution () {
371371

372372
Assert.IsTrue(TestUtilities.IsNearlyEqual(
373373
result.R.Probability, result.F.Probability,
374-
new EvaluationSettings() { RelativePrecision = 1.0E-14, AbsolutePrecision = 1.0E-16 }
374+
new EvaluationSettings() { RelativePrecision = 1.0E-13, AbsolutePrecision = 1.0E-16 }
375375
));
376376

377377
}

0 commit comments

Comments
 (0)