Exemple #1
0
        public void ThreeJRecursion()
        {
            foreach (ThreeJSymbol symbol in GenerateRandomThreeJSymbols(50.0, 10))
            {
                double j1 = symbol.Column1.J;
                double m1 = symbol.Column1.M;
                double j2 = symbol.Column2.J;
                double m2 = symbol.Column2.M;
                double j3 = symbol.Column3.J;
                double m3 = symbol.Column3.M;

                double s1 = SpinMath.ThreeJ(new SpinState(j1, m1), new SpinState(j2, m2), new SpinState(j3, m3));

                double s2 = 0.0;
                if ((Math.Abs(m2 - 1.0) <= j2) && (Math.Abs(m3 + 1.0) <= j3))
                {
                    s2 = SpinMath.ThreeJ(new SpinState(j1, m1), new SpinState(j2, m2 - 1.0), new SpinState(j3, m3 + 1.0));
                }
                double s3 = 0.0;
                if ((Math.Abs(m1 - 1.0) <= j1) && (Math.Abs(m3 + 1.0) <= j3))
                {
                    s3 = SpinMath.ThreeJ(new SpinState(j1, m1 - 1.0), new SpinState(j2, m2), new SpinState(j3, m3 + 1.0));
                }

                double c1 = Math.Sqrt((j3 + m3 + 1.0) * (j3 - m3));
                double c2 = Math.Sqrt((j2 - m2 + 1.0) * (j2 + m2));
                double c3 = Math.Sqrt((j1 - m1 + 1.0) * (j1 + m1));

                Assert.IsTrue(TestUtilities.IsSumNearlyEqual(c1 * s1, c2 * s2, -c3 * s3));
            }
        }
Exemple #2
0
        public void ThreeJRacahSymmetry()
        {
            foreach (ThreeJSymbol symbol in GenerateRandomThreeJSymbols(50.0, 10))
            {
                // compute the 3j symbol
                SpinState s1 = symbol.Column1;
                SpinState s2 = symbol.Column2;
                SpinState s3 = symbol.Column3;
                double    C  = SpinMath.ThreeJ(s1, s2, s3);

                // form other 3j symbols related by Racah symmetry

                double    k1, k2, k3, n1, n2, n3;
                SpinState t1, t2, t3;

                // rows 1->2->3

                k1 = (s2.J + s2.M + s3.J + s3.M) / 2.0;
                k2 = (s1.J + s1.M + s3.J + s3.M) / 2.0;
                k3 = (s1.J + s1.M + s2.J + s2.M) / 2.0;
                n1 = s1.J - s1.M - k1;
                n2 = s2.J - s2.M - k2;
                n3 = s3.J - s3.M - k3;

                t1 = new SpinState(k1, n1);
                t2 = new SpinState(k2, n2);
                t3 = new SpinState(k3, n3);
                double CC = SpinMath.ThreeJ(t1, t2, t3);

                Assert.IsTrue(TestUtilities.IsNearlyEqual(C, CC));

                // transpose rows and columns

                /*
                 * k1 = s1.J;
                 * k2 = (s2.J + s3.J + s1.M) / 2.0;
                 * k3 = (s2.J + s3.J - s1.M) / 2.0;
                 * n1 = s2.J - s3.J;
                 * n2 = s3.J - s3.M - k2;
                 * n3 = s3.J + s3.M - k2;
                 *
                 * t1 = new SpinState(k1, n1);
                 * t2 = new SpinState(k2, n2);
                 * t3 = new SpinState(k3, n3);
                 * double CT = SpinMath.ThreeJ(t1, t2, t3);
                 *
                 * Assert.IsTrue(TestUtilities.IsNearlyEqual(C, CT));
                 */
            }
        }
Exemple #3
0
        public void ThreeJLegendreIntegral()
        {
            // pick three legendre polynomials

            foreach (int l1 in TestUtilities.GenerateUniformIntegerValues(0, 16, 8))
            {
                foreach (int l2 in TestUtilities.GenerateUniformIntegerValues(0, 16, 4))
                {
                    foreach (int l3 in TestUtilities.GenerateUniformIntegerValues(0, 16, 2))
                    {
                        Console.WriteLine("{0} {1} {2}", l1, l2, l3);

                        // do the integral over their product

                        Func <double, double> f = delegate(double x) {
                            return(
                                OrthogonalPolynomials.LegendreP(l1, x) *
                                OrthogonalPolynomials.LegendreP(l2, x) *
                                OrthogonalPolynomials.LegendreP(l3, x)
                                );
                        };
                        double I = FunctionMath.Integrate(f, Interval.FromEndpoints(-1.0, 1.0));

                        // it should be the same as 2 ( l1 l2 l3 )^2
                        //                            ( 0  0  0  )

                        double S = SpinMath.ThreeJ(new SpinState(l1, 0), new SpinState(l2, 0), new SpinState(l3, 0));

                        Console.WriteLine("  {0} {1}", I, 2.0 * S * S);

                        if (Math.Abs(S) < TestUtilities.TargetPrecision)
                        {
                            Assert.IsTrue(I < TestUtilities.TargetPrecision);
                        }
                        else
                        {
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(I, 2.0 * S * S));
                        }
                    }
                }
            }
        }
Exemple #4
0
        public void ThreeJExchangeSymmetry()
        {
            foreach (ThreeJSymbol symbol in GenerateRandomThreeJSymbols(50.0, 10))
            {
                SpinState s1 = symbol.Column1;
                SpinState s2 = symbol.Column2;
                SpinState s3 = symbol.Column3;

                Console.WriteLine("( {0} {1} {2} )", s1.J, s2.J, s3.J);
                Console.WriteLine("( {0} {1} {2} )", s1.M, s2.M, s3.M);

                double s123 = SpinMath.ThreeJ(s1, s2, s3);
                double s231 = SpinMath.ThreeJ(s2, s3, s1);
                double s312 = SpinMath.ThreeJ(s3, s1, s2);

                Console.WriteLine("{0},{1},{2}", s123, s231, s312);

                Assert.IsTrue(TestUtilities.IsNearlyEqual(s123, s231));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(s123, s312));

                int P;
                if (((int)(s1.J + s2.J + s3.J)) % 2 == 0)
                {
                    P = 1;
                }
                else
                {
                    P = -1;
                }

                double s132 = SpinMath.ThreeJ(s1, s3, s2);
                double s213 = SpinMath.ThreeJ(s2, s1, s3);
                double s321 = SpinMath.ThreeJ(s3, s2, s1);

                Console.WriteLine("{0},{1},{2}", s132, s213, s321);


                Assert.IsTrue(TestUtilities.IsNearlyEqual(s123, P * s132));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(s123, P * s213));
                Assert.IsTrue(TestUtilities.IsNearlyEqual(s123, P * s321));
            }
        }
Exemple #5
0
        public void SixJThreeJRelation()
        {
            SixJSymbol[] symbols = GenerateRandomSixJSymbols(50.0, 5);
            foreach (SixJSymbol symbol in symbols)
            {
                Spin a = symbol.J1;
                Spin b = symbol.J2;
                Spin c = symbol.J3;
                Spin d = symbol.J4;
                Spin e = symbol.J5;
                Spin f = symbol.J6;

                SpinState[] ams = GenerateRandomSpinStates(a, 2);
                SpinState[] bms = GenerateRandomSpinStates(b, 2);
                foreach (SpinState am in ams)
                {
                    foreach (SpinState bm in bms)
                    {
                        if (Math.Abs(am.M + bm.M) > c.J)
                        {
                            continue;
                        }
                        SpinState cm = new SpinState(c, -(am.M + bm.M));

                        double g1 = SpinMath.ThreeJ(am, bm, cm);
                        double g2 = SpinMath.SixJ(a, b, c, d, e, f);
                        double p  = g1 * g2;

                        double        q   = 0.0;
                        List <double> ts  = new List <double>();
                        SpinState[]   dms = d.States();
                        foreach (SpinState dm in dms)
                        {
                            if (Math.Abs(dm.M + cm.M) > e.J)
                            {
                                continue;
                            }
                            SpinState em  = new SpinState(e, dm.M + cm.M);
                            SpinState mem = new SpinState(e, -em.M);
                            double    f1  = SpinMath.ThreeJ(dm, mem, cm);

                            if (Math.Abs(em.M + am.M) > f.J)
                            {
                                continue;
                            }
                            SpinState fm  = new SpinState(f, em.M + am.M);
                            SpinState mfm = new SpinState(f, -fm.M);
                            double    f2  = SpinMath.ThreeJ(em, mfm, am);

                            SpinState mdm = new SpinState(d, -dm.M);
                            double    f3  = SpinMath.ThreeJ(fm, mdm, bm);

                            double t = f1 * f2 * f3;

                            int s = (int)Math.Round(dm.J + dm.M + em.J + em.M + fm.J + fm.M);
                            if (s % 2 != 0)
                            {
                                t = -t;
                            }

                            q += t;
                            ts.Add(t);
                        }

                        Console.WriteLine("{0} v. {1}", p, q);
                        //Assert.IsTrue(TestUtilities.IsNearlyEqual(p, q));
                        Assert.IsTrue(TestUtilities.IsSumNearlyEqual(ts, p));
                    }
                }
            }
        }