GiNaC-devel
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
April 2005
- 6 participants
- 7 discussions
This is the end of previous patch.
--
Vladimir V. Kisil email: kisilv(a)maths.leeds.ac.uk
-- www: http://maths.leeds.ac.uk/~kisilv/
Index: check/exam_clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/check/exam_clifford.cpp,v
retrieving revision 1.24
diff -r1.24 exam_clifford.cpp
24a25,26
> const numeric half(1, 2);
>
27c29
< ex e = e1 - e2;
---
> ex e = normal(e1 - e2);
29,30c31,32
< clog << e1 << "-" << e2 << " erroneously returned "
< << e << " instead of 0" << endl;
---
> clog << "(" << e1 << ") - (" << e2 << ") erroneously returned "
> << e << " instead of 0" << endl;
38c40
< ex e = simplify_indexed(e1) - e2;
---
> ex e = normal(simplify_indexed(e1) - e2);
40,41c42,43
< clog << "simplify_indexed(" << e1 << ")-" << e2 << " erroneously returned "
< << e << " instead of 0" << endl;
---
> clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned "
> << e << " instead of 0" << endl;
46a49,88
> static unsigned check_equal_lst(const ex &e1, const ex &e2)
> {
> for(int i = 0; i++; i < e1.nops()) {
> ex e = e1.op(i) - e2.op(i);
> if (!e.is_zero()) {
> clog << "(" << e1 << ") - (" << e2 << ") erroneously returned "
> << e << " instead of 0 (in the entry " << i << ")" << endl;
> return 1;
> }
> }
> return 0;
> }
>
> static unsigned check_equal_simplify_term(const ex &e1, const ex &e2, varidx &mu)
> {
> ex e = expand_dummy_sum(normal(simplify_indexed(e1) - e2), true);
>
> for (int j=0; j<4; j++) {
> ex esub = e.subs(lst(mu == idx(j, mu.get_dim()), mu.toggle_variance() == idx(j, mu.get_dim())));
> if (!(canonicalize_clifford(esub).is_zero())) {
> clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned "
> << canonicalize_clifford(esub) << " instead of 0 for mu=" << j << endl;
> return 1;
> }
> }
> return 0;
> }
>
> static unsigned check_equal_simplify_term2(const ex &e1, const ex &e2)
> {
> ex e = expand_dummy_sum(normal(simplify_indexed(e1) - e2), true);
> if (!(canonicalize_clifford(e).is_zero())) {
> clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned "
> << canonicalize_clifford(e) << " instead of 0" << endl;
> return 1;
> }
> return 0;
> }
>
>
264a307
>
271c314,316
< ex G = A;
---
> matrix A_symm(4,4), A2(4, 4);
> A_symm = A.add(A.transpose()).mul(half);
> A2 = A_symm.mul(A_symm);
273,274d317
< matrix A2(4, 4);
< A2 = A.mul(A);
276c319
<
---
> bool anticommuting = ex_to<clifford>(clifford_unit(nu, A)).is_anticommuting();
280,281c323,324
< e = dirac_ONE() * clifford_unit(mu, G) * dirac_ONE();
< result += check_equal(e, clifford_unit(mu, G));
---
> e = dirac_ONE(2) * clifford_unit(mu, A, 2) * dirac_ONE(2);
> result += check_equal(e, clifford_unit(mu, A, 2));
283,284c326,327
< e = clifford_unit(varidx(2, 4), G) * clifford_unit(varidx(1, 4), G)
< * clifford_unit(varidx(1, 4), G) * clifford_unit(varidx(2, 4), G);
---
> e = clifford_unit(idx(2, 4), A) * clifford_unit(idx(1, 4), A)
> * clifford_unit(idx(1, 4), A) * clifford_unit(idx(2, 4), A);
287c330,334
< e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G);
---
> e = clifford_unit(varidx(2, 4), A) * clifford_unit(varidx(1, 4), A)
> * clifford_unit(varidx(1, 4), A) * clifford_unit(varidx(2, 4), A);
> result += check_equal(e, A(1, 1) * A(2, 2) * dirac_ONE());
>
> e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A);
290,291c337,338
< e = clifford_unit(nu, G) * clifford_unit(nu, G);
< result += check_equal_simplify(e, indexed(G, sy_symm(), nu, nu) * dirac_ONE());
---
> e = clifford_unit(nu, A) * clifford_unit(nu, A);
> result += check_equal_simplify(e, indexed(A_symm, sy_symm(), nu, nu) * dirac_ONE());
293,294c340,341
< e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu, G);
< result += check_equal_simplify(e, A.trace() * clifford_unit(mu, G));
---
> e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A) * clifford_unit(mu, A);
> result += check_equal_simplify(e, A.trace() * clifford_unit(mu, A));
296,297c343,347
< e = clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(nu.toggle_variance(), G);
< result += check_equal_simplify(e, 2*indexed(G, sy_symm(), mu, mu)*clifford_unit(mu, G) - A.trace()*clifford_unit(mu, G));
---
> e = clifford_unit(nu, A) * clifford_unit(mu, A) * clifford_unit(nu.toggle_variance(), A);
> if (anticommuting)
> result += check_equal_simplify(e, 2*indexed(A_symm, sy_symm(), mu, mu)*clifford_unit(mu, A) - A.trace()*clifford_unit(mu, A));
>
> result += check_equal_simplify_term(e, 2 * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu) *clifford_unit(nu, A)-A.trace()*clifford_unit(mu, A), mu);
299,300c349,350
< e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G)
< * clifford_unit(mu, G) * clifford_unit(mu.toggle_variance(), G);
---
> e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A)
> * clifford_unit(mu, A) * clifford_unit(mu.toggle_variance(), A);
303,304c353,354
< e = clifford_unit(mu, G) * clifford_unit(nu, G)
< * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu.toggle_variance(), G);
---
> e = clifford_unit(mu, A) * clifford_unit(nu, A)
> * clifford_unit(nu.toggle_variance(), A) * clifford_unit(mu.toggle_variance(), A);
307,323c357,370
< e = clifford_unit(mu, G) * clifford_unit(nu, G)
< * clifford_unit(mu.toggle_variance(), G) * clifford_unit(nu.toggle_variance(), G);
< result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE());
<
< e = clifford_unit(mu.toggle_variance(), G) * clifford_unit(nu, G)
< * clifford_unit(mu, G) * clifford_unit(nu.toggle_variance(), G);
< result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE());
<
< e = clifford_unit(nu.toggle_variance(), G) * clifford_unit(rho.toggle_variance(), G)
< * clifford_unit(mu, G) * clifford_unit(rho, G) * clifford_unit(nu, G);
< e = e.simplify_indexed().collect(clifford_unit(mu, G));
< result += check_equal(e, (pow(A.trace(), 2)+4-4*A.trace()*indexed(A, mu, mu)) * clifford_unit(mu, G));
<
< e = clifford_unit(nu.toggle_variance(), G) * clifford_unit(rho, G)
< * clifford_unit(mu, G) * clifford_unit(rho.toggle_variance(), G) * clifford_unit(nu, G);
< e = e.simplify_indexed().collect(clifford_unit(mu, G));
< result += check_equal(e, (pow(A.trace(), 2)+4-4*A.trace()*indexed(A, mu, mu))* clifford_unit(mu, G));
---
> e = clifford_unit(mu, A) * clifford_unit(nu, A)
> * clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu.toggle_variance(), A);
> if (anticommuting)
> result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE());
>
> result += check_equal_simplify_term2(e, 2*indexed(A_symm, sy_symm(), nu.toggle_variance(), mu.toggle_variance()) * clifford_unit(mu, A) * clifford_unit(nu, A) - pow(A.trace(), 2)*dirac_ONE());
>
> e = clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu, A)
> * clifford_unit(mu, A) * clifford_unit(nu.toggle_variance(), A);
> if (anticommuting) {
> result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE());
> e1 = remove_dirac_ONE(simplify_indexed(e));
> result += check_equal(e1, 2*A2.trace() - pow(A.trace(), 2));
> }
325,327c372
< // canonicalize_clifford() checks
< e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
< result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G, sy_symm(), mu, nu));
---
> result += check_equal_simplify_term2(e, 2*indexed(A_symm, nu, mu) * clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu.toggle_variance(), A) - pow(A.trace(), 2)*dirac_ONE());
329,338c374,406
< e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
< + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
< + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G)
< - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
< - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
< - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
< + indexed(G, sy_symm(), mu, nu) * clifford_unit(lam, G)
< - indexed(G, sy_symm(), mu, lam) * clifford_unit(nu, G)
< + indexed(G, sy_symm(), nu, lam) * clifford_unit(mu, G)
< - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
---
> e = clifford_unit(nu.toggle_variance(), A) * clifford_unit(rho.toggle_variance(), A)
> * clifford_unit(mu, A) * clifford_unit(rho, A) * clifford_unit(nu, A);
> e = e.simplify_indexed().collect(clifford_unit(mu, A));
> if (anticommuting)
> result += check_equal(e, (4*indexed(A2, sy_symm(), mu, mu) - 4 * indexed(A_symm, sy_symm(), mu, mu)*A.trace() +pow(A.trace(), 2)) * clifford_unit(mu, A));
>
> result += check_equal_simplify_term(e, 4* indexed(A_symm, sy_symm(), nu.toggle_variance(), rho)*indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) *clifford_unit(nu, A)
> - 2*A.trace() * (clifford_unit(rho, A) * indexed(A_symm, sy_symm(), rho.toggle_variance(), mu)
> +clifford_unit(nu, A) * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu)) + pow(A.trace(),2)* clifford_unit(mu, A), mu);
>
> e = clifford_unit(nu.toggle_variance(), A) * clifford_unit(rho, A)
> * clifford_unit(mu, A) * clifford_unit(rho.toggle_variance(), A) * clifford_unit(nu, A);
> e = e.simplify_indexed().collect(clifford_unit(mu, A));
> if (anticommuting)
> result += check_equal(e, (4*indexed(A2, sy_symm(), mu, mu) - 4*indexed(A_symm, sy_symm(), mu, mu)*A.trace() +pow(A.trace(), 2))* clifford_unit(mu, A));
>
> result += check_equal_simplify_term(e, 4* indexed(A_symm, sy_symm(), nu.toggle_variance(), rho)*indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) *clifford_unit(nu, A)
> - 2*A.trace() * (clifford_unit(rho, A) * indexed(A_symm, sy_symm(), rho.toggle_variance(), mu)
> +clifford_unit(nu, A) * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu)) + pow(A.trace(),2)* clifford_unit(mu, A), mu);
>
> e = clifford_unit(mu, A) * clifford_unit(nu, A) + clifford_unit(nu, A) * clifford_unit(mu, A);
> result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(A_symm, sy_symm(), mu, nu));
>
> e = (clifford_unit(mu, A) * clifford_unit(nu, A) * clifford_unit(lam, A)
> + clifford_unit(nu, A) * clifford_unit(lam, A) * clifford_unit(mu, A)
> + clifford_unit(lam, A) * clifford_unit(mu, A) * clifford_unit(nu, A)
> - clifford_unit(nu, A) * clifford_unit(mu, A) * clifford_unit(lam, A)
> - clifford_unit(lam, A) * clifford_unit(nu, A) * clifford_unit(mu, A)
> - clifford_unit(mu, A) * clifford_unit(lam, A) * clifford_unit(nu, A)) / 6
> + indexed(A_symm, sy_symm(), mu, nu) * clifford_unit(lam, A)
> - indexed(A_symm, sy_symm(), mu, lam) * clifford_unit(nu, A)
> + indexed(A_symm, sy_symm(), nu, lam) * clifford_unit(mu, A)
> - clifford_unit(mu, A) * clifford_unit(nu, A) * clifford_unit(lam, A);
344,345c412,413
< ex c = clifford_unit(nu, G, 1);
< e = lst_to_clifford(lst(t, x, y, z), mu, G, 1) * lst_to_clifford(lst(1, 2, 3, 4), c);
---
> ex c = clifford_unit(nu, A, 1);
> e = lst_to_clifford(lst(t, x, y, z), mu, A, 1) * lst_to_clifford(lst(1, 2, 3, 4), c);
347c415,443
< result += check_equal((e*e1).simplify_indexed().normal(), dirac_ONE(1));
---
> result += check_equal_lst((e*e1).simplify_indexed(), dirac_ONE(1));
>
> // Moebius map (both forms) checks for symmetric metrics only
> matrix M1(2, 2), M2(2, 2);
> c = clifford_unit(nu, A);
>
> e = clifford_moebius_map(0, dirac_ONE(),
> dirac_ONE(), 0, lst(t, x, y, z), A); // this is just the inversion
> M1 = 0, dirac_ONE(),
> dirac_ONE(), 0;
> e1 = clifford_moebius_map(M1, lst(t, x, y, z), A); // the inversion again
> result += check_equal_lst(e, e1);
>
> e1 = clifford_to_lst(clifford_inverse(lst_to_clifford(lst(t, x, y, z), mu, A)), c);
> result += check_equal_lst(e, e1);
>
> e = clifford_moebius_map(dirac_ONE(), lst_to_clifford(lst(1, 2, 3, 4), nu, A),
> 0, dirac_ONE(), lst(t, x, y, z), A); //this is just a shift
> M2 = dirac_ONE(), lst_to_clifford(lst(1, 2, 3, 4), c),
> 0, dirac_ONE();
> e1 = clifford_moebius_map(M2, lst(t, x, y, z), c); // the same shift
> result += check_equal_lst(e, e1);
>
> result += check_equal(e, lst(t+1, x+2, y+3, z+4));
>
> // Check the group law for Moebius maps
> e = clifford_moebius_map(M1, ex_to<lst>(e1), c); //composition of M1 and M2
> e1 = clifford_moebius_map(M1.mul(M2), lst(t, x, y, z), c); // the product M1*M2
> result += check_equal_lst(e, e1);
352c448,449
< static unsigned clifford_check7()
---
>
> static unsigned clifford_check7(const ex & G, const symbol & dim)
358d454
< symbol dim("D");
362c458
< ex e;
---
> ex e, G_base;
364c460,463
< ex G = minkmetric();
---
> if (is_a<indexed>(G))
> G_base = G.op(0);
> else
> G_base = G;
389,404c488,519
< // canonicalize_clifford() checks
< e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
< result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G, sy_symm(), mu, nu));
<
< e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
< + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
< + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G)
< - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
< - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
< - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
< + indexed(G, sy_symm(), mu, nu) * clifford_unit(lam, G)
< - indexed(G, sy_symm(), mu, lam) * clifford_unit(nu, G)
< + indexed(G, sy_symm(), nu, lam) * clifford_unit(mu, G)
< - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
< result += check_equal(canonicalize_clifford(e), 0);
<
---
> // canonicalize_clifford() checks, only for symmetric metrics
> if (ex_to<symmetry>(ex_to<indexed>(ex_to<clifford>(clifford_unit(mu, G)).get_metric()).get_symmetry()).has_symmetry()) {
> e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
> result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G_base, sy_symm(), nu, mu));
>
> e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
> + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
> + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G)
> - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
> - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
> - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
> + indexed(G_base, sy_symm(), mu, nu) * clifford_unit(lam, G)
> - indexed(G_base, sy_symm(), mu, lam) * clifford_unit(nu, G)
> + indexed(G_base, sy_symm(), nu, lam) * clifford_unit(mu, G)
> - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
> result += check_equal(canonicalize_clifford(e), 0);
> } else {
> e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G);
> result += check_equal(canonicalize_clifford(e), dirac_ONE()*(indexed(G_base, mu, nu) + indexed(G_base, nu, mu)));
>
> e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G)
> + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G)
> + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G)
> - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G)
> - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G)
> - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6
> + half * (indexed(G_base, mu, nu) + indexed(G_base, nu, mu)) * clifford_unit(lam, G)
> - half * (indexed(G_base, mu, lam) + indexed(G_base, lam, mu)) * clifford_unit(nu, G)
> + half * (indexed(G_base, nu, lam) + indexed(G_base, lam, nu)) * clifford_unit(mu, G)
> - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G);
> result += check_equal(canonicalize_clifford(e), 0);
> }
420a536,545
> // anticommuting, symmetric examples
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-1, 1, 1, 1)))); cout << '.' << flush;
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-1, -1, -1, -1)))); cout << '.' << flush;
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-1, 1, 1, -1)))); cout << '.' << flush;
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-1, 0, 1, -1)))); cout << '.' << flush;
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-3, 0, 2, -1)))); cout << '.' << flush;
>
> realsymbol s("s"), t("t"); // symbolic entries in matric
> result += clifford_check6(ex_to<matrix>(diag_matrix(lst(-1, 1, s, t)))); cout << '.' << flush;
>
422,425c547,550
< A = -1, 0, 0, 0,
< 0, 1, 0, 0,
< 0, 0, 1, 0,
< 0, 0, 0, 1;
---
> A = 1, 0, 0, 0, // anticommuting, not symmetric, Tr=0
> 0, -1, 0, 0,
> 0, 0, 0, -1,
> 0, 0, 1, 0;
428,431c553,556
< A = -1, 0, 0, 0,
< 0,-1, 0, 0,
< 0, 0,-1, 0,
< 0, 0, 0,-1;
---
> A = 1, 0, 0, 0, // anticommuting, not symmetric, Tr=2
> 0, 1, 0, 0,
> 0, 0, 0, -1,
> 0, 0, 1, 0;
433,437c558,562
<
< A = -1, 0, 0, 0,
< 0, 1, 0, 0,
< 0, 0, 1, 0,
< 0, 0, 0,-1;
---
>
> A = 1, 0, 0, 0, // not anticommuting, symmetric, Tr=0
> 0, -1, 0, 0,
> 0, 0, 0, -1,
> 0, 0, -1, 0;
440,443c565,568
< A = -1, 0, 0, 0,
< 0, 0, 0, 0,
< 0, 0, 1, 0,
< 0, 0, 0,-1;
---
> A = 1, 0, 0, 0, // not anticommuting, symmetric, Tr=2
> 0, 1, 0, 0,
> 0, 0, 0, -1,
> 0, 0, -1, 0;
446c571,581
< result += clifford_check7(); cout << '.' << flush;
---
> A = 1, 1, 0, 0, // not anticommuting, not symmetric, Tr=4
> 0, 1, 1, 0,
> 0, 0, 1, 1,
> 0, 0, 0, 1;
> result += clifford_check6(A); cout << '.' << flush;
>
> symbol dim("D");
> result += clifford_check7(minkmetric(), dim); cout << '.' << flush;
>
> varidx chi(symbol("chi"), dim), xi(symbol("xi"), dim);
> result += clifford_check7(lorentz_g(xi, chi), dim); cout << '.' << flush;
1
0
Dear All,
Here is a new patch for the clifford.cpp, which is even too
large to fin in one message. Thus the tail is sent separately.
It relays on two other additions:
1. A patch to add.cpp, which I posted here on Wed Apr 20 12:07:29 CEST
2005. It seems that a more fundamental solutions is required here, so
my code is only a temporary one.
2. An additional function expand_dummy_sum() in indexed.cpp. It shares
a portion of common code with simplify_indexed() and I put this piece
into a separate auxiliary procedure product_to_exvector().
The main changes to clifford.cpp itself are as follows:
1. There are now two different simplifications paths in
clifford::contract_with() depending on if Clifford units are
anticommuting or not. This information is now stored in a new member
variable
bool anticommuting;
The difference in results of contractions can be seen from
exam_clifford.cpp.
2. The present code should work now with non-symmetric metric as
well. At present it always result in a symmetrised metric
M(i,j)+M(j,i), but this should change when more functions from
geometric algebras will be added.
3. Exams in exam_clifford.cpp cover now all defined functions in the
majority of possible parameter variations.
4. Many small corrections.
5. Those changes are reflected in ginac.texi
Best wishes,
Vladimir
--
Vladimir V. Kisil email: kisilv(a)maths.leeds.ac.uk
-- www: http://maths.leeds.ac.uk/~kisilv/
Index: doc/tutorial/ginac.texi
===================================================================
RCS file: /home/cvs/GiNaC/doc/tutorial/ginac.texi,v
retrieving revision 1.165
diff -r1.165 ginac.texi
2569a2570,2610
> @cindex @code{expand_dummy_sum()}
> A dummy index summation like
> @tex
> $ a_i b^i$
> @end tex
> @ifnottex
> a.i b~i
> @end ifnottex
> can be expanded for indexes with numeric
> dimensions (e.g. 3) into the explicit sum like
> @tex
> $a_1b^1+a_2b^2+a_3b^3 $.
> @end tex
> @ifnottex
> a.1 b~1 + a.2 b~2 + a.3 b~3.
> @end ifnottex
> This performed by the function
>
> @example
> ex expand_dummy_sum(const ex & e, bool subs_idx = false);
> @end example
>
> which takes an expression @code{e} and returns the expanded sum for all
> dummy indexes with numeric dimensions. If the parameter @code{subs_idx}
> is set to @code{true} then all substitutions are made by @code{idx} class
> indexes, i.e. without variance. In this case the above sum
> @tex
> $ a_i b^i$
> @end tex
> @ifnottex
> a.i b~i
> @end ifnottex
> will be expanded to
> @tex
> $a_1b_1+a_2b_2+a_3b_3 $.
> @end tex
> @ifnottex
> a.1 b.1 + a.2 b.2 + a.3 b.3.
> @end ifnottex
>
>
3192c3233
< $e_i e_j + e_j e_i = M(i, j) $
---
> $e_i e_j + e_j e_i = M(i, j) + M(j, i) $
3195c3236
< e~i e~j + e~j e~i = M(i, j)
---
> e~i e~j + e~j e~i = M(i, j) + M(j, i)
3197,3199c3238,3241
< for some matrix (@code{metric})
< @math{M(i, j)}, which may be non-symmetric and containing symbolic
< entries. Such generators are created by the function
---
> for some bilinear form (@code{metric})
> @math{M(i, j)}, which may be non-symmetric (see arXiv:math.QA/9911180)
> and contain symbolic entries. Such generators are created by the
> function
3202c3244,3245
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0,
> bool anticommuting = false);
3206c3249,3251
< generators, @code{metr} defines the metric @math{M(i, j)} and can be
---
> generators, an index @code{mu} with a numeric value may be of type
> @code{idx} as well.
> Parameter @code{metr} defines the metric @math{M(i, j)} and can be
3208,3212c3253,3277
< object, optional parameter @code{rl} allows to distinguish different
< Clifford algebras (which will commute with each other). Note that the call
< @code{clifford_unit(mu, minkmetric())} creates something very close to
< @code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns a
< metric defining this Clifford number.
---
> object. Optional parameter @code{rl} allows to distinguish different
> Clifford algebras, which will commute with each other. The last
> optional parameter @code{anticommuting} defines if the anticommuting
> assumption (i.e.
> @tex
> $e_i e_j + e_j e_i = 0$)
> @end tex
> @ifnottex
> e~i e~j + e~j e~i = 0)
> @end ifnottex
> will be used for contraction of Clifford units. If the @code{metric} is
> supplied by a @code{matrix} object, then the value of
> @code{anticommuting} is calculated automatically and the supplied one
> will be ignored. One can overcome this by giving @code{metric} through
> matrix wrapped into an @code{indexed} object.
>
> Note that the call @code{clifford_unit(mu, minkmetric())} creates
> something very close to @code{dirac_gamma(mu)}, although
> @code{dirac_gamma} have more efficient simplification mechanism.
> @cindex @code{clifford::get_metric()}
> The method @code{clifford::get_metric()} returns a metric defining this
> Clifford number.
> @cindex @code{clifford::is_anticommuting()}
> The method @code{clifford::is_anticommuting()} returns the
> @code{anticommuting} property of a unit.
3221c3286,3288
< since this may yield some further automatic simplifications.
---
> since this may yield some further automatic simplifications. Again, for a
> metric defined through a @code{matrix} such a symmetry is detected
> automatically.
3246c3313,3314
< @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and @code{pow(e3, 2) = s}.
---
> @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and
> @code{pow(e3, 2) = s}.
3254c3322
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3276c3344
< @code{clifford_unit(mu, metr, rl)}. The previous code may be rewritten
---
> @code{clifford_unit(mu, metr, rl, anticommuting)}. The previous code may be rewritten
3324c3392
< is zero or is not a @code{numeric} for some @samp{k}
---
> is zero or is not @code{numeric} for some @samp{k}
3413c3481
< The last provided function is
---
> The next provided function is
3419c3487
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3421c3489
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3427,3436c3495,3518
< the metric of the surrounding (pseudo-)Euclidean space. This can be a
< matrix or a Clifford unit, in the later case the parameter @code{rl} is
< ignored even if supplied. The returned value of this function is a list
< of components of the resulting vector.
<
< LaTeX output for Clifford units looks like @code{\clifford[1]@{e@}^@{@{\nu@}@}},
< where @code{1} is the @code{representation_label} and @code{\nu} is the
< index of the corresponding unit. This provides a flexible typesetting
< with a suitable defintion of the @code{\clifford} command. For example, the
< definition
---
> the metric of the surrounding (pseudo-)Euclidean space. This can be an
> indexed object, tensormetric, matrix or a Clifford unit, in the later
> case the optional parameters @code{rl} and @code{anticommuting} are ignored
> even if supplied. The returned value of this function is a list of
> components of the resulting vector.
>
> @cindex @code{clifford_max_label()}
> Finally the function
>
> @example
> char clifford_max_label(const ex & e, bool ignore_ONE = false);
> @end example
>
> can detect a presence of Clifford objects in the expression @code{e}: if
> such objects are found it returns the maximal
> @code{representation_label} of them, otherwise @code{-1}. The optional
> parameter @code{ignore_ONE} indicates if @code{dirac_ONE} objects should
> be ignored during the search.
>
> LaTeX output for Clifford units looks like
> @code{\clifford[1]@{e@}^@{@{\nu@}@}}, where @code{1} is the
> @code{representation_label} and @code{\nu} is the index of the
> corresponding unit. This provides a flexible typesetting with a suitable
> defintion of the @code{\clifford} command. For example, the definition
Index: ginac/add.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/add.cpp,v
retrieving revision 1.76
diff -r1.76 add.cpp
31a32,33
> #include "clifford.h"
> #include "ncmul.h"
293a296,298
> std::auto_ptr<epvector> coeffseq_cliff(new epvector);
> char rl = clifford_max_label(s);
> bool do_clifford = (rl != -1), nonscalar = false;
299c304,311
< if (!restcoeff.is_zero())
---
> if (!restcoeff.is_zero()) {
> if (do_clifford)
> if (clifford_max_label(restcoeff) == -1)
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i->coeff));
> else {
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff));
> nonscalar = true;
> }
300a313
> }
304c317,318
< return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
---
> return (new add(nonscalar? coeffseq_cliff : coeffseq,
> n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
Index: ginac/indexed.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/indexed.h,v
retrieving revision 1.50
diff -r1.50 indexed.h
252a253,263
> /** This function returns the given expression with expanded sums
> * for all dummy indexes summation, where dimensionality of
> * the dummy index is numeric.
> * Optionally all indexes with a variance will be substituted by
> * indices with the corresponding numeric values without variance.
> *
> * @param e the given expression
> * @param subs_idx indicates if variance of dummy indixes should be neglected
> */
> ex expand_dummy_sum(const ex & e, bool subs_idx = false);
>
Index: ginac/indexed.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/indexed.cpp,v
retrieving revision 1.94
diff -r1.94 indexed.cpp
672,674c672,674
< /** Simplify product of indexed expressions (commutative, noncommutative and
< * simple squares), return list of free indices. */
< ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp)
---
> /* An auxiliary function used by simplify_indexed() and expand_dummy_sum()
> * It returns an exvector of factors from the supplied product*/
> static void product_to_exvector(const ex &e, exvector &v, bool &non_commutative)
678c678
< bool non_commutative = is_exactly_a<ncmul>(e);
---
> non_commutative = is_exactly_a<ncmul>(e);
681d680
< exvector v;
703a703,715
> }
>
> /** Simplify product of indexed expressions (commutative, noncommutative and
> * simple squares), return list of free indices. */
> ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp)
> {
> // Collect factors in an exvector
> exvector v;
>
> // Remember whether the product was commutative or noncommutative
> // (because we chop it into factors and need to reassemble later)
> bool non_commutative;
> product_to_exvector(e, v, non_commutative);
1278a1291,1352
> }
>
> ex expand_dummy_sum(const ex &e, bool subs_idx)
> {
> ex e_expanded = e.expand();
> pointer_to_map_function_1arg<bool> fcn(expand_dummy_sum, subs_idx);
> if (is_a<add>(e_expanded))
> return e_expanded.map(fcn);
> else if (is_a<ncmul>(e_expanded) || is_a<mul>(e_expanded) || is_a<power>(e_expanded)) {
> exvector p;
> bool nc;
> product_to_exvector(e_expanded, p, nc);
> exvector::const_iterator ip = p.begin(), ipend = p.end();
> exvector v;
> while (ip != ipend) {
> if (is_a<indexed>(*ip)) {
> v = ex_to<indexed>(*ip).get_dummy_indices();
> exvector::const_iterator ip1 = ip+1;
> while (ip1 != ipend) {
> if (is_a<indexed>(*ip1)) {
> exvector v1 = ex_to<indexed>(*ip).get_dummy_indices(ex_to<indexed>(*ip1));
> v.insert(v.end(), v1.begin(), v1.end());
> }
> ip1++;
> }
> exvector::const_iterator it = v.begin(), itend = v.end();
> while (it != itend) {
> varidx nu = ex_to<varidx>(*it);
> if (nu.is_dim_numeric()) {
> ex en = 0;
> for (int i=0; i < ex_to<numeric>(nu.get_dim()).to_int(); i++)
> if (is_a<varidx>(nu) && !subs_idx)
> en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim())));
> else
> en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim())));
> return expand_dummy_sum(en, subs_idx);
> }
> it++;
> }
> }
> ip++;
> }
> return e;
> } else if (is_a<indexed>(e_expanded)) {
> exvector v = ex_to<indexed>(e_expanded).get_dummy_indices();
> exvector::const_iterator it = v.begin(), itend = v.end();
> while (it != itend) {
> varidx nu = ex_to<varidx>(*it);
> if (nu.is_dim_numeric()) {
> ex en = 0;
> for (int i=0; i < ex_to<numeric>(nu.get_dim()).to_int(); i++)
> if (is_a<varidx>(nu) && !subs_idx)
> en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim())));
> else
> en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim())));
> return expand_dummy_sum(en, subs_idx);
> }
> it++;
> }
> return e;
> } else
> return e;
Index: ginac/clifford.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.h,v
retrieving revision 1.57
diff -r1.57 clifford.h
47,48c47,48
< clifford(const ex & b, unsigned char rl = 0);
< clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0);
---
> clifford(const ex & b, unsigned char rl = 0, bool anticommut = false);
> clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommut = false);
51,52c51,52
< clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable = false);
< clifford(unsigned char rl, const ex & metr, std::auto_ptr<exvector> vp);
---
> clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable = false);
> clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr<exvector> vp);
69c69
< ex get_metric(const ex & i, const ex & j) const;
---
> ex get_metric(const ex & i, const ex & j, bool symmetrised = false) const;
70a71
> bool is_anticommuting() const { return anticommuting; } //**< See the member variable anticommuting */
79c80,81
< ex metric;
---
> ex metric; /**< Metric of the space, all constructors make it an indexed object */
> bool anticommuting; /**< Simplifications for anticommuting units is much simpler and we need this info readily available */
196c198
< * @param metr Metric (should be of class tensmetric or a derived class, or a matrix)
---
> * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix)
199c201
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false);
287a290,296
> /** Returns the maximal representation label of a clifford object
> * if e contains at least one, otherwise returns -1
> *
> * @param e Expression to be processed
> * @ignore_ONE defines if clifford_ONE should be ignored in the search*/
> char clifford_max_label(const ex & e, bool ignore_ONE = false);
>
298c307
< * @param metr Metric (should be of class tensmetric or a derived class, or a matrix)
---
> * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix)
302c311
< ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false);
329a339
> * @param anticommuting indicates if Clifford units anticommutes
331c341
< ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl = 0);
---
> ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl = 0, bool anticommuting = false);
339a350
> * @param anticommuting indicates if Clifford units anticommutes
341c352
< ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0);
---
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0, bool anticommuting = false);
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.88
diff -r1.88 clifford.cpp
80,81c80,81
<
< clifford::clifford() : representation_label(0), metric(default_metric())
---
>
> clifford::clifford() : representation_label(0), metric(default_metric()), anticommuting(false)
100c100
< clifford::clifford(const ex & b, unsigned char rl) : inherited(b), representation_label(rl), metric(0)
---
> clifford::clifford(const ex & b, unsigned char rl, bool anticommut) : inherited(b), representation_label(rl), metric(0), anticommuting(anticommut)
109c109
< clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl) : inherited(b, mu), representation_label(rl), metric(metr)
---
> clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl, bool anticommut) : inherited(b, mu), representation_label(rl), metric(metr), anticommuting(anticommut)
115c115
< clifford::clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr)
---
> clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr), anticommuting(anticommut)
120c120
< clifford::clifford(unsigned char rl, const ex & metr, std::auto_ptr<exvector> vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr)
---
> clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr<exvector> vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr), anticommuting(anticommut)
134a135
> n.find_bool("anticommuting", anticommuting);
141a143
> n.add_bool("anticommuting", anticommuting);
156c158
< ex clifford::get_metric(const ex & i, const ex & j) const
---
> ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const
158c160,170
< return indexed(metric, symmetric2(), i, j);
---
> if (is_a<indexed>(metric)) {
> if (symmetrised && !(ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()).has_symmetry())) {
> if (is_a<matrix>(metric.op(0)))
> return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(metric.op(0)).transpose())).mul(numeric(1,2)),
> symmetric2(), i, j);
> else
> return simplify_indexed(indexed(metric.op(0)*_ex1_2, i, j) + indexed(metric.op(0)*_ex1_2, j, i));
> } else
> return indexed(metric.op(0), ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()), i, j);
> } else // should not really happen since all constructors but clifford() make the metric an indexed object
> return indexed(metric, i, j);
164c176
< return get_metric().is_equal(ex_to<clifford>(other).get_metric());
---
> return same_metric(ex_to<clifford>(other).get_metric());
378,384c390,396
< for (int i=0; i<v.size();i++) {
< if (!is_a<clifford>(v[i]) && is_a<indexed>(v[i])
< && ex_to<clifford>(c).same_metric(v[i])
< && (ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[0]
< || ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0])) {
< return ++i; // next to found
< }
---
> for (size_t i=0; i<v.size(); i++) {
> if (is_a<indexed>(v[i]) && !is_a<clifford>(v[i])
> && ((ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[0]
> && ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[1])
> || (ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0]
> && ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[1])))
> return i; // the index of the found
386c398
< return 0; //nothing found
---
> return -1; //nothing found
397c409
<
---
>
406,408c418,430
< int prev_square = find_same_metric(v, self[0]);
< varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim());
< ex squared_metric = unit.get_metric(self->op(1), d) * unit.get_metric(d.toggle_variance(), other->op(1));
---
> int prev_square = find_same_metric(v, *self);
> const varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim()),
> in1((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim()),
> in2((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim());
> ex squared_metric;
> if (prev_square > -1)
> squared_metric = simplify_indexed(indexed(v[prev_square].op(0), in1, d)
> * unit.get_metric(d.toggle_variance(), in2, true)).op(0);
>
> exvector::iterator before_other = other - 1;
> const varidx & mu = ex_to<varidx>(self->op(1));
> const varidx & mu_toggle = ex_to<varidx>(other->op(1));
> const varidx & alpha = ex_to<varidx>(before_other->op(1));
412,414c434,436
< if (prev_square != 0) {
< *self = squared_metric;
< v[prev_square-1] = _ex1;
---
> if (prev_square > -1) {
> *self = indexed(squared_metric, mu, mu_toggle);
> v[prev_square] = _ex1;
416c438
< *self = unit.get_metric(self->op(1), other->op(1));
---
> *self = unit.get_metric(mu, mu_toggle, true);
420,436c442,469
< // e~mu e~alpha e.mu = (2e~alpha^2-Tr) e~alpha
< } else if (other - self == 2
< && is_a<clifford>(self[1])) {
<
< const ex & ia = self[1].op(1);
< const ex & ib = self[1].op(1);
< if (is_a<tensmetric>(unit.get_metric()))
< *self = 2 - unit.get_metric(self->op(1), other->op(1));
< else if (prev_square != 0) {
< *self = 2-squared_metric;
< v[prev_square-1] = _ex1;
< } else
< *self = 2*unit.get_metric(ia, ib) - unit.get_metric(self->op(1), other->op(1));
< *other = _ex1;
< return true;
<
< // e~mu S e~alpha e.mu = 2 e~alpha^3 S - e~mu S e.mu e~alpha
---
> } else if (other - self == 2) {
> if (is_a<clifford>(*before_other) && ex_to<clifford>(*before_other).get_representation_label() == rl) {
> if (ex_to<clifford>(*self).is_anticommuting()) {
> // e~mu e~alpha e.mu = (2*pow(e~alpha, 2) -Tr(B)) e~alpha
> if (prev_square > -1) {
> *self = 2 * indexed(squared_metric, alpha, alpha)
> - indexed(squared_metric, mu, mu_toggle);
> v[prev_square] = _ex1;
> } else
> *self = 2 * unit.get_metric(alpha, alpha, true) - unit.get_metric(mu, mu_toggle, true);
> *other = _ex1;
> return true;
>
> } else {
> // e~mu e~alpha e.mu = 2*e~mu B(alpha, mu.toggle_variance())-Tr(B) e~alpha
> *self = 2 * (*self) * unit.get_metric(alpha, mu_toggle, true) - unit.get_metric(mu, mu_toggle, true) * (*before_other);
> *before_other = _ex1;
> *other = _ex1;
> return true;
> }
> } else {
> // e~mu S e.mu = Tr S ONE
> *self = unit.get_metric(mu, mu_toggle, true);
> *other = dirac_ONE(rl);
> return true;
> }
> } else {
> // e~mu S e~alpha e.mu = 2 e~mu S B(alpha, mu.toggle_variance()) - e~mu S e.mu e~alpha
439,452c472,475
< } else {
< exvector::iterator it = self + 1, next_to_last = other - 1;
< while (it != other) {
< if (!is_a<clifford>(*it))
< return false;
< ++it;
< }
<
< it = self + 1;
< ex S = _ex1;
< while (it != next_to_last) {
< S *= *it;
< *it++ = _ex1;
< }
---
> if (std::find_if(self + 1, other, is_not_a_clifford()) != other)
> return false;
>
> ex S = ncmul(exvector(self + 1, before_other), true);
454,464c477,490
< const ex & ia = next_to_last->op(1);
< const ex & ib = next_to_last->op(1);
< if (is_a<tensmetric>(unit.get_metric()))
< *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last);
< else if (prev_square != 0) {
< *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last)*unit.get_metric(self->op(1),self->op(1));
< v[prev_square-1] = _ex1;
< } else
< *self = 2 * (*next_to_last) * S* unit.get_metric(ia,ib) - (*self) * S * (*other) * (*next_to_last);
< *next_to_last = _ex1;
< *other = _ex1;
---
> if (is_a<clifford>(*before_other) && ex_to<clifford>(*before_other).get_representation_label() == rl)
> if (ex_to<clifford>(*self).is_anticommuting())
> if (prev_square > -1)
> *self = 2 * (*before_other) * S * indexed(squared_metric, alpha, alpha)
> - (*self) * S * (*other) * (*before_other);
> else
> *self = 2 * (*before_other) * S * unit.get_metric(alpha, alpha, true) - (*self) * S * (*other) * (*before_other);
> else
> *self = 2 * (*self) * S * unit.get_metric(alpha, mu_toggle, true) - (*self) * S * (*other) * (*before_other);
> else
> // simply commutes
> *self = (*self) * S * (*other) * (*before_other);
>
> std::fill(self + 1, other + 1, _ex1);
467d492
<
469d493
<
583c607
< a = ex_to<clifford>(a).get_metric(ia, ib);
---
> a = ex_to<clifford>(a).get_metric(ia, ib, true);
633c657
< return clifford(diracone(), representation_label) * sign;
---
> return dirac_ONE(representation_label) * sign;
642c666
< return clifford(representation_label, get_metric(), v);
---
> return clifford(representation_label, get_metric(), is_anticommuting(), v);
647c671
< return clifford(representation_label, get_metric(), vp);
---
> return clifford(representation_label, get_metric(), is_anticommuting(), vp);
672c696
< return clifford(ONE, rl);
---
> return clifford(ONE, rl, false);
675c699
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticommuting)
679,680c703,704
< if (!is_a<varidx>(mu))
< throw(std::invalid_argument("index of Clifford unit must be of type varidx"));
---
> if (!is_a<idx>(mu))
> throw(std::invalid_argument("clifford_unit(): index of Clifford unit must be of type idx or varidx"));
682,687c706,739
< if (is_a<indexed>(metr))
< return clifford(unit, mu, metr.op(0), rl);
< else if(is_a<tensmetric>(metr) || is_a<matrix>(metr))
< return clifford(unit, mu, metr, rl);
< else
< throw(std::invalid_argument("metric for Clifford unit must be of type indexed, tensormetric or matrix"));
---
> if (ex_to<idx>(mu).is_symbolic() && !is_a<varidx>(mu))
> throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)"));
>
> if (is_a<indexed>(metr)) {
> exvector indices = ex_to<indexed>(metr).get_indices();
> if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(indices[1]))
> return clifford(unit, mu, metr, rl, anticommuting);
> else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be indexed exactly by two indices of same type as the given index"));
> } else if (is_a<tensmetric>(metr)) {
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
> chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
> return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
> } else if (is_a<matrix>(metr)) {
> matrix M = ex_to<matrix>(metr);
> unsigned n = M.rows();
> bool symmetric = true;
> anticommuting = true;
>
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), n),
> chi((new symbol)->setflag(status_flags::dynallocated), n);
> if ((n == M.cols()) && (n == ex_to<varidx>(mu).get_dim())) {
> for (unsigned i = 0; i < n; i++)
> for (unsigned j = i+1; j < n; j++) {
> if (M(i, j) != M(j, i))
> symmetric = false;
> if (M(i, j) != -M(j, i))
> anticommuting = false;
> }
> return clifford(unit, mu, indexed(metr, symmetric?symmetric2():not_symmetric(), xi, chi), rl, anticommuting);
> } else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be a square matrix with the same dimensions as index"));
> } else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type indexed, tensormetric or matrix"));
695c747
< throw(std::invalid_argument("index of Dirac gamma must be of type varidx"));
---
> throw(std::invalid_argument("dirac_gamma(): index of Dirac gamma must be of type varidx"));
697c749,751
< return clifford(gamma, mu, default_metric(), rl);
---
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
> chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
> return clifford(gamma, mu, indexed(default_metric(), symmetric2(), xi, chi), rl, true);
987c1041
< it[0] = (ex_to<clifford>(save0).get_metric(i1, i2) * b1 * b2).simplify_indexed();
---
> it[0] = (ex_to<clifford>(save0).get_metric(i1, i2, true) * b1 * b2).simplify_indexed();
1019c1073
< ex remove_dirac_ONE(const ex & e, unsigned char rl)
---
> ex remove_dirac_ONE(const ex & e, unsigned char rl)
1026c1080
< throw(std::invalid_argument("Expression is a non-scalar Clifford number!"));
---
> throw(std::invalid_argument("remove_dirac_ONE(): expression is a non-scalar Clifford number!"));
1035a1090,1105
> char clifford_max_label(const ex & e, bool ignore_ONE)
> {
> if (is_a<clifford>(e))
> if (ignore_ONE && is_a<diracone>(e.op(0)))
> return -1;
> else
> return ex_to<clifford>(e).get_representation_label();
> else {
> char rl = -1;
> for (size_t i=0; i < e.nops(); i++)
> rl = (rl > clifford_max_label(e.op(i), ignore_ONE)) ? rl : clifford_max_label(e.op(i), ignore_ONE);
> return rl;
> }
> }
>
>
1047c1117
< throw(std::invalid_argument("Cannot find inverse of Clifford number with zero norm!"));
---
> throw(std::invalid_argument("clifford_inverse(): cannot find inverse of Clifford number with zero norm!"));
1050c1120
< ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl)
---
> ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl, bool anticommuting)
1053,1054c1123,1124
< throw(std::invalid_argument("Index should have a numeric dimension"));
< ex e = clifford_unit(mu, metr, rl);
---
> throw(std::invalid_argument("lst_to_clifford(): Index should have a numeric dimension"));
> ex e = clifford_unit(mu, metr, rl, anticommuting);
1077c1147
< throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch"));
---
> throw(std::invalid_argument("lst_to_clifford(): dimensions of vector and clifford unit mismatch"));
1079c1149
< throw(std::invalid_argument("First argument should be a vector vector"));
---
> throw(std::invalid_argument("lst_to_clifford(): first argument should be a vector vector"));
1084c1154
< throw(std::invalid_argument("List length and dimension of clifford unit mismatch"));
---
> throw(std::invalid_argument("lst_to_clifford(): list length and dimension of clifford unit mismatch"));
1086c1156
< throw(std::invalid_argument("Cannot construct from anything but list or vector"));
---
> throw(std::invalid_argument("lst_to_clifford(): cannot construct from anything but list or vector"));
1088c1158
< throw(std::invalid_argument("The second argument should be a Clifford unit"));
---
> throw(std::invalid_argument("lst_to_clifford(): the second argument should be a Clifford unit"));
1090c1160
<
---
>
1109c1179
< throw(std::invalid_argument("Expression is a Clifford multi-vector"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is a Clifford multi-vector"));
1134c1204
< throw(std::invalid_argument("Expression is not a Clifford vector to the given units"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is not a Clifford vector to the given units"));
1144c1214
< throw(std::invalid_argument("Expression is not usable as a Clifford vector"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is not usable as a Clifford vector"));
1153c1223
< throw(std::invalid_argument("Index should have a numeric dimension"));
---
> throw(std::invalid_argument("clifford_to_lst(): index should have a numeric dimension"));
1176c1246
< ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl)
---
> ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl, bool anticommuting)
1181c1251
< throw(std::invalid_argument("parameter v should be either vector or list"));
---
> throw(std::invalid_argument("clifford_moebius_map(): parameter v should be either vector or list"));
1190c1260
< else throw(std::invalid_argument("metric should be an indexed object, matrix, or a Clifford unit"));
---
> else throw(std::invalid_argument("clifford_moebius_map(): metric should be an indexed object, matrix, or a Clifford unit"));
1193c1263
< cu = clifford_unit(mu, G, rl);
---
> cu = clifford_unit(mu, G, rl, anticommuting);
1195c1265
<
---
>
1201c1271
< ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl)
---
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl, bool anticommuting)
1205c1275
< ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G, rl);
---
> ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G, rl, anticommuting);
1207c1277
< throw(std::invalid_argument("parameter M should be a matrix"));
---
> throw(std::invalid_argument("clifford_moebius_map(): parameter M should be a matrix"));
1
0
Dear All,
Working on further patches to clifford.cpp I found that such a
simple program
#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;
#include <stdexcept>
int main(){
realsymbol a("a");
varidx nu(symbol("nu", "\\nu"), 2), mu(symbol("mu", "\\mu"), 2);
try {
ex e = a* dirac_gamma(nu) + 2*dirac_gamma(nu);
cout << e.collect(dirac_gamma(nu)) << endl;
// -> (2+a)*gamma~nu
e = dirac_gamma(mu)* dirac_gamma(nu) + dirac_gamma(nu);
cout << e.collect(dirac_gamma(nu)) << endl;
// Raised exception:
// add::eval(): sum of non-commutative objects has non-zero numeric term
} catch (exception &p) {
cerr << "Got problem: " << p.what() << endl;
}
}
raises an exception in the second output statement. I think everyone
would like it can produce something like "(ONE+gamma~mu)*gamma~nu"
instead. And first output should remain "(2+a)*gamma~nu" and not
became "(2*ONE+a*ONE)*gamma~nu" on the other hand.
I am not sure that is the best way to achieve it but propose a patch
which seems to solve it. It introduces one more utility function
clifford_max_label() at clifford.cpp, which returns the maximal
representation label of non-commutative Clifford object in the
expression. Besides that there is also a patch to add::coeff() in
add.cpp. I wrote it in mind to reduce unwonted overheads for
expression without any Clifford numbers.
After this issue will be rectified some more patches to clifford.cpp
will follow.
Best wishes,
Vladimir
--
Vladimir V. Kisil email: kisilv(a)maths.leeds.ac.uk
-- www: http://maths.leeds.ac.uk/~kisilv/
Index: ginac/clifford.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.h,v
retrieving revision 1.56
diff -r1.56 clifford.h
285a286,292
> /** Returns the maximal representation label of a clifford object
> * if e contains at least one, otherwise returns -1
> *
> * @param e Expression to be processed
> * @ignore_ONE defines if clifford_ONE should be ignored in the search*/
> ex clifford_max_label(const ex & e, bool ignore_ONE = false);
>
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.86
diff -r1.86 clifford.cpp
1035a1084,1100
> ex clifford_max_label(const ex & e, bool ignore_ONE)
> {
> if (is_a<clifford>(e))
> if (ignore_ONE && is_a<diracone>(e.op(0)))
> return _ex_1;
> else
> return ex_to<clifford>(e).get_representation_label();
> else {
> ex rl = _ex_1;
> for (size_t i=0; i < e.nops(); i++)
> rl = ex_to<numeric>(rl - clifford_max_label(e.op(i), ignore_ONE)).is_positive()?
> rl : clifford_max_label(e.op(i), ignore_ONE);
> return rl;
> }
> }
Index: ginac/add.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/add.cpp,v
retrieving revision 1.76
diff -r1.76 add.cpp
31a32
> #include "clifford.h"
293a295,297
> std::auto_ptr<epvector> coeffseq_cliff(new epvector);
> ex rl = clifford_max_label(s);
> bool do_clifford = (!rl.is_equal(_ex_1)), nonscalar = false;
299c303,310
< if (!restcoeff.is_zero())
---
> if (!restcoeff.is_zero()) {
> if (do_clifford)
> if (clifford_max_label(restcoeff).is_equal(_ex_1))
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(mul(restcoeff,dirac_ONE(ex_to<numeric>(rl).to_int())), i->coeff));
> else {
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff));
> nonscalar = true;
> }
300a312
> }
304c316,317
< return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
---
> return (new add(nonscalar? coeffseq_cliff : coeffseq,
> n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
3
3
Dear developers,
I found out that dirac_slash(p+q,4) is printed as "q+p\". I think this is
confusing and that "(q+p)\" would be much clearer. A patch is attached.
Best wishes,
Chris
2
1
Hi Fausto,
I am not sure about your problem, but maybe the following might help
you.
On Sat, Apr 09, 2005 at 12:13:30PM +0200, Fausto Saporito wrote:
> I'm using autoconf 2.59 is it the right version?
That version works fine with GiNaC.
> What is the exact procedure to generate a configure? I didn't find any
> autogen.sh script, so I tried to use the autogen.sh present in GiNaC
> cvs tree.
Use
autoreconf -i
That does the job those autogen.sh scripts normally take care of.
It's part of the autoconf package.
> /sw/share/aclocal/pth.m4:55: warning: underquoted definition of
> _AC_PTH_VERBOSE
> /sw/share/aclocal/pth.m4:61: warning: underquoted definition of
> AC_CHECK_PTH
> /sw/share/aclocal/pkg.m4:5: warning: underquoted definition of
> PKG_CHECK_MODULES
> /sw/share/aclocal/libgcrypt.m4:23: warning: underquoted definition of
> AM_PATH_LIBGCRYPT
> /sw/share/aclocal/gtk.m4:7: warning: underquoted definition of
> AM_PATH_GTK
> /sw/share/aclocal/glib.m4:8: warning: underquoted definition of
> AM_PATH_GLIB
The automake files of GiNaC are set up for older versions of automake,
like automake 1.4. Newer versions (and there are plenty of them!)
produce these warnings. It's kind of annoying but basically harmless.
> + Running autoheader: autoheader: warning: missing template: CL_USE_GMP
> autoheader: Use AC_DEFINE([CL_USE_GMP], [], [Description])
> autoheader: warning: missing template: CL_VERSION
> autoheader: warning: missing template: CL_VERSION_MAJOR
> autoheader: warning: missing template: CL_VERSION_MINOR
> autoheader: warning: missing template: CL_VERSION_PATCHLEVEL
> done.
> + Running automake: configure.ac: no proper invocation of
> AM_INIT_AUTOMAKE was found.
> configure.ac: You should verify that configure.ac invokes
> AM_INIT_AUTOMAKE,
> configure.ac: that aclocal.m4 is present in the top-level directory,
> configure.ac: and that aclocal.m4 was recently regenerated (using
> aclocal).
> configure.ac: installing `autoconf/missing'
> automake: no `Makefile.am' found for any configure output
> done.
This is not harmless anymore ;-) What's your version of automake?
Regards,
Jens
2
1
Hello,
I have a problem generating configure under Mac OS X 1.3 with Fink.
When I run autoconf I don't receive any errors, but when I run
configure script I have after a while,
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking how to run the C preprocessor... gcc -E
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking how to run the C++ preprocessor... g++ -E
./configure: line 3318: CL_AS_UNDERSCORE: command not found
checking for ranlib... ranlib
checking for a BSD-compatible install... /usr/bin/install -c
./configure: line 3478: syntax error near unexpected token `autoconf'
./configure: line 3478: `
CL_CANONICAL_HOST(autoconf)'
I'm using autoconf 2.59 is it the right version?
What is the exact procedure to generate a configure? I didn't find any
autogen.sh script, so I tried to use the autogen.sh present in GiNaC
cvs tree.
When I run autogen.sh I have some warnings:
+ Running aclocal: /sw/share/aclocal/pth.m4:43: warning: underquoted
definition of _AC_PTH_ERROR
run info '(automake)Extending aclocal'
or see
http://sources.redhat.com/automake/automake.html#Extending-aclocal
/sw/share/aclocal/pth.m4:55: warning: underquoted definition of
_AC_PTH_VERBOSE
/sw/share/aclocal/pth.m4:61: warning: underquoted definition of
AC_CHECK_PTH
/sw/share/aclocal/pkg.m4:5: warning: underquoted definition of
PKG_CHECK_MODULES
/sw/share/aclocal/libgcrypt.m4:23: warning: underquoted definition of
AM_PATH_LIBGCRYPT
/sw/share/aclocal/gtk.m4:7: warning: underquoted definition of
AM_PATH_GTK
/sw/share/aclocal/glib.m4:8: warning: underquoted definition of
AM_PATH_GLIB
done.
+ Running libtoolize: done.
+ Running autoheader: autoheader: warning: missing template: CL_USE_GMP
autoheader: Use AC_DEFINE([CL_USE_GMP], [], [Description])
autoheader: warning: missing template: CL_VERSION
autoheader: warning: missing template: CL_VERSION_MAJOR
autoheader: warning: missing template: CL_VERSION_MINOR
autoheader: warning: missing template: CL_VERSION_PATCHLEVEL
done.
+ Running automake: configure.ac: no proper invocation of
AM_INIT_AUTOMAKE was found.
configure.ac: You should verify that configure.ac invokes
AM_INIT_AUTOMAKE,
configure.ac: that aclocal.m4 is present in the top-level directory,
configure.ac: and that aclocal.m4 was recently regenerated (using
aclocal).
configure.ac: installing `autoconf/missing'
automake: no `Makefile.am' found for any configure output
done.
+ Running autoconf: done.
Any idea?
thanks a lot,
Fausto
2
1
Hi Vladimir,
I applied your and C.Dams' patch now. But I also applied a forgotten
patch from you from December that changes
ex clifford::get_metric(const ex & i, const ex & j) const
from
return indexed(metric, symmetric2(), i, j);
to
return indexed(metric, i, j);
With this December patch the exams for clifford fail with
----------clifford objects:
2*ONE*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu-2*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*ONE
erroneously return ed
2*ONE*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu-2*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*ONE
instead of 0
[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*e~lambda-[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu*e~lambda-0
erroneousl y returned
[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*e~lambda-[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu*e~lambda
i nstead of 0
Without it, it produces no error.
The December patch makes sense to me, because the tutorial promises that
one can use non-symmetric metrics. Am I wrong here? So, what should I do
about it?
Regards,
Jens
1
0