00001 namespace Tests
00002 {
00003 using System;
00004 using System.IO;
00005 using System.Text;
00006 using Microsoft.VisualStudio.TestTools.UnitTesting;
00007 using NewGamePhysics.Mathematics;
00008 using NewGamePhysics.Utilities;
00009
00013 [TestClass]
00014 public class UnitTestLegendre
00015 {
00016 public UnitTestLegendre()
00017 {
00018 }
00019
00020 private TestContext testContextInstance;
00021
00026 public TestContext TestContext
00027 {
00028 get
00029 {
00030 return testContextInstance;
00031 }
00032 set
00033 {
00034 testContextInstance = value;
00035 }
00036 }
00037
00041 [TestMethod]
00042 public void LegendrePolynomial()
00043 {
00044
00045
00046
00047 string[] testdata = {
00048 "3 0 0",
00049 "2 0.5 -0.125",
00050 "10 0.3333333333333333 0.23026638893122660841",
00051 "21 -0.75 0.12110918341200137011"
00052 };
00053
00054 Scanf scanf = new Scanf();
00055 object[] t;
00056 for (int i = 0; i < testdata.Length; i++)
00057 {
00058 t = scanf.Scan(testdata[i],"%i %lf %lf");
00059 int n = (int)t[0];
00060 double x = (double)t[1];
00061 double expected = (double)t[2];
00062 double value = Legendre.Polynomial(n, x);
00063 double error = Math.Abs(value - expected);
00064 Console.WriteLine(
00065 "Legendre.Polynomial({0},{1}): expected {2} got {3} error {4}",
00066 n,
00067 x,
00068 expected,
00069 value,
00070 error);
00071 Assert.IsTrue(error <= 1e-10);
00072 }
00073 }
00074
00078 [TestMethod]
00079 public void LegendreAssociatedFunction()
00080 {
00081
00082
00083
00084 string[] testdata ={
00085 "1 0 0.0 0.00000",
00086 "1 0 0.5 0.500000",
00087 "1 0 0.75 0.75",
00088 "1 0 1.0 1.0",
00089 "1 1 0.5000 -0.86602540378443864676",
00090 "2 0 0.5000 -0.125",
00091 "2 1 0.5000 -1.2990381056766579701",
00092 "2 2 0.5000 2.25",
00093 "3 0 0.5000 -0.4375",
00094 "3 1 0.5000 -0.32475952641916449254",
00095 "3 2 0.5000 5.625",
00096 "3 3 0.5000 -9.7427857925749347761",
00097 "4 2 0.5000 4.21875",
00098 "5 2 0.5000 -4.921875",
00099 "6 3 0.5000 12.787406352754601894",
00100 "7 3 0.5000 116.68508296888574228",
00101 "8 4 0.5000 -1050.66650390625",
00102 "9 4 0.5000 -2078.492431640625",
00103 "10 5 0.5000 30086.169706116174977",
00104 "9 5 -0.5 9771.5764857471337533",
00105 "12 8 0.2 -2.9361651664394649600E07",
00106 "20 18 0.25 3.2974276572126079987E21"
00107 };
00108
00109 Scanf scanf = new Scanf();
00110 object[] t;
00111 for (int i = 0; i < testdata.Length; i++)
00112 {
00113 t = scanf.Scan(testdata[i], "%i %i %lf %lf");
00114 int n = (int)t[0];
00115 int m = (int)t[1];
00116 double x = (double)t[2];
00117 double expected = (double)t[3];
00118 double value = Legendre.AssociatedFunction(n, m, x);
00119 double error;
00120 if (Math.Abs(expected) > 0.0)
00121 {
00122 error = Math.Abs(value - expected) / Math.Abs(expected);
00123 }
00124 else
00125 {
00126 error = Math.Abs(value - expected);
00127 }
00128 Console.WriteLine(
00129 "Legendre.AssociatedFunction({0},{1},{2}): expected {3} got {4} rel_error {5}",
00130 n,
00131 m,
00132 x,
00133 expected,
00134 value,
00135 error);
00136 Assert.IsTrue(error <= 1e-15);
00137 }
00138 }
00139
00143 [TestMethod]
00144 public void LegendreSphericalAssociatedFunction()
00145 {
00146
00147
00148
00149 string[] testdata ={
00150 "1 0 0.0 0.48860251190291992159",
00151 "1 0 0.5 0.42878904414183579379",
00152 "1 0 0.75 0.35750501926315508333",
00153 "1 0 1.0 0.26399306383411281647",
00154 "1 1 0.5000 -0.16563871869489602941",
00155 "2 0 0.5000 0.41330596756220761898",
00156 "2 1 0.5000 -0.32503853318233770541",
00157 "2 2 0.5000 0.088784679986342305024",
00158 "3 0 0.5000 0.27861659336351639787",
00159 "3 1 0.5000 -0.44169847523833372956",
00160 "3 2 0.5000 0.20614605996878713307",
00161 "3 3 0.5000 -0.045976149181370300989",
00162 "4 2 0.5000 0.33762752561059228279",
00163 "5 2 0.5000 0.44798449902914186851"
00164 };
00165
00166 Scanf scanf = new Scanf();
00167 object[] t;
00168 for (int i = 0; i < testdata.Length; i++)
00169 {
00170 t = scanf.Scan(testdata[i], "%i %i %lf %lf");
00171 int n = (int)t[0];
00172 int m = (int)t[1];
00173 double x = (double)t[2];
00174 double expected = (double)t[3];
00175 double value = Legendre.SphericalAssociatedFunction(n, m, x);
00176 double error = Math.Abs(value - expected);
00177 Console.WriteLine(
00178 "Legendre.SphericalAssociatedFunction({0},{1},{2}): expected {3} got {4} error {5}",
00179 n,
00180 m,
00181 x,
00182 expected,
00183 value,
00184 error);
00185 Assert.IsTrue(error <= 1e-10);
00186 }
00187 }
00188
00193 [TestMethod]
00194 public void LegendreNormalizedAssociatedFunctionAndDerivative()
00195 {
00196
00197
00198
00199
00200
00201
00202 string[] testfiles = {
00203 @"normalizedLegendre1.dat",
00204 @"normalizedLegendre2.dat"
00205 };
00206
00207 Scanf scanf = new Scanf();
00208 object[] t;
00209 for (int i = 0; i < testfiles.Length; i++)
00210 {
00211 string[] testdata = null;
00212
00213
00214 testdata = File.ReadAllLines(testfiles[i], Encoding.ASCII);
00215 Console.WriteLine("Read {0} lines from file {1}", testdata.Length, testfiles[i]);
00216
00217
00218 t = scanf.Scan(testdata[0], "%i %lf");
00219 int lmax = (int)t[0];
00220 double z = (double)t[1];
00221 Console.WriteLine("lmax={0} z={1}", lmax, z);
00222
00223
00224 int n_expected = (lmax + 1 ) * (lmax + 2 ) / 2;
00225 Console.WriteLine("n_expected={0}", n_expected);
00226 int[] l = new int[n_expected + 1];
00227 int[] m = new int[n_expected + 1];
00228 double[] p_expected = new double[n_expected + 1];
00229 double[] dp_expected = new double[n_expected + 1];
00230 for (int j = 1; j <= n_expected; j++)
00231 {
00232 t = scanf.Scan(testdata[j], " %i %i %lf %lf");
00233 l[j] = (int)t[0];
00234 m[j] = (int)t[1];
00235 p_expected[j] = (double)t[2];
00236 dp_expected[j] = (double)t[3];
00237 }
00238
00239
00240 double[][] p;
00241 double[][] dp;
00242 Legendre.NormalizedAssociatedFunctionAndDerivative(lmax, z, out p, out dp);
00243 Console.WriteLine(
00244 "Legendre.NormalizedAssociatedFunctionAndDerivative({0},{1},p,dp)",
00245 lmax,
00246 z);
00247
00248
00249 double error;
00250 for (int k = 1; k < l.Length; k++)
00251 {
00252 error = Math.Abs(p[l[k]][m[k]] - p_expected[k]);
00253 Console.WriteLine("l={0} m={1} p_lm={2} expected {3} error {4}", l[k], m[k], p[l[k]][m[k]], p_expected[k], error);
00254 Assert.IsTrue(error <= 1e-12);
00255 }
00256 for (int k = 1; k < l.Length; k++)
00257 {
00258 error = Math.Abs(dp[l[k]][m[k]] - dp_expected[k]);
00259 Console.WriteLine("l={0} m={1} dp_lm={2} expected {3} error {4}", l[k], m[k], dp[l[k]][m[k]], dp_expected[k], error);
00260 Assert.IsTrue(error <= 1e-12);
00261 }
00262 }
00263 }
00264 }
00265 }