From be254ad747f2aee7e7ac4a908c73ab313c4a2788 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 17 Oct 2019 12:41:43 +0100 Subject: [PATCH 01/10] Remove executable bit from everything without a shebang If it doesn't have a shebang and isn't bash or a binary, it shouldn't be marked as executable Performed using `git ls-files | xargs -d '\n' git update-index --chmod=-x`, and then manually removing the three files with a shebang --- doc/galgebra.tex | 0 doc/python/BACCAB.pdf | Bin doc/python/BACCAB.py | 0 doc/python/Dirac.pdf | Bin doc/python/Dirac.py | 0 doc/python/Dop.pdf | Bin doc/python/Dop.py | 0 doc/python/EMWaves.pdf | Bin doc/python/EMWaves.py | 0 doc/python/LinearTrans.pdf | Bin doc/python/LinearTrans.py | 0 doc/python/Ltrans.pdf | Bin doc/python/Ltrans.py | 0 doc/python/Ltrans.tex | 0 doc/python/LtransInst.pdf | Bin doc/python/LtransInst.py | 0 doc/python/ReciprocalBasis.pdf | Bin doc/python/ReciprocalBasis.py | 0 doc/python/SphericalCoordinates.pdf | Bin doc/python/SphericalCoordinates.py | 0 doc/python/TensorDef.py | 0 doc/python/diffops.pdf | Bin doc/python/submanifold.py | 0 doc/python/submanifold1.pdf | Bin examples/LaTeX/Dop.pdf | Bin examples/LaTeX/Dop.py | 0 examples/LaTeX/FmtChk.pdf | Bin examples/LaTeX/FmtChk.py | 0 examples/LaTeX/curvi_linear_latex.pdf | Bin examples/LaTeX/curvi_linear_latex.py | 0 examples/LaTeX/dchk.pdf | Bin examples/LaTeX/dchk.py | 0 examples/LaTeX/diffeq_sys.py | 0 examples/LaTeX/dirac_derive.py | 0 examples/LaTeX/em_waves_latex.pdf | Bin examples/LaTeX/em_waves_latex.py | 0 examples/LaTeX/groups.pdf | Bin examples/LaTeX/groups.py | 0 examples/LaTeX/groups.tex | 0 examples/LaTeX/latex_check.py | 0 examples/LaTeX/lin_tran_check.py | 0 examples/LaTeX/linear_EM_waves.pdf | Bin examples/LaTeX/linear_EM_waves.py | 0 examples/LaTeX/manifold.py | 0 examples/LaTeX/matrix_latex.py | 0 examples/LaTeX/new_bug_grad_exp.py | 0 examples/LaTeX/physics_check_latex.pdf | Bin examples/LaTeX/physics_check_latex.py | 0 examples/LaTeX/print_check_latex.py | 0 examples/LaTeX/products_latex.py | 0 examples/LaTeX/simple_check_latex.py | 0 examples/Old Format/bad_example.py | 0 examples/Old Format/eval_check.py | 0 examples/Old Format/exp_check.py | 0 examples/Old Format/latex_check.py | 0 examples/Old Format/matrix_latex.py | 0 examples/Old Format/mv_setup_options.py | 0 examples/Old Format/physics_check_latex.py | 0 examples/Old Format/print_check_latex.py | 0 examples/Old Format/prob_not_solenoidal.py | 0 examples/Old Format/products_latex.py | 0 examples/Old Format/simple_check.py | 0 examples/Old Format/simple_check_latex.py | 0 examples/Old Format/spherical_latex.py | 0 examples/Terminal/1d_grad.py | 0 examples/Terminal/ConformalConsole.py | 0 examples/Terminal/exp_check.py | 0 examples/Terminal/mv_setup_options.py | 0 examples/Terminal/prob_not_solenoidal.py | 0 examples/Terminal/rotations.py | 0 examples/ipython/Smith Sphere.ipynb | 0 examples/ipython/dop.ipynb | 0 examples/ipython/simple_ga_test.ipynb | 0 galgebra/__init__.py | 0 galgebra/ga.py | 0 galgebra/lt.py | 0 galgebra/metric.py | 0 galgebra/mv.py | 0 galgebra/printer.py | 0 test/test_test.py | 0 80 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 doc/galgebra.tex mode change 100755 => 100644 doc/python/BACCAB.pdf mode change 100755 => 100644 doc/python/BACCAB.py mode change 100755 => 100644 doc/python/Dirac.pdf mode change 100755 => 100644 doc/python/Dirac.py mode change 100755 => 100644 doc/python/Dop.pdf mode change 100755 => 100644 doc/python/Dop.py mode change 100755 => 100644 doc/python/EMWaves.pdf mode change 100755 => 100644 doc/python/EMWaves.py mode change 100755 => 100644 doc/python/LinearTrans.pdf mode change 100755 => 100644 doc/python/LinearTrans.py mode change 100755 => 100644 doc/python/Ltrans.pdf mode change 100755 => 100644 doc/python/Ltrans.py mode change 100755 => 100644 doc/python/Ltrans.tex mode change 100755 => 100644 doc/python/LtransInst.pdf mode change 100755 => 100644 doc/python/LtransInst.py mode change 100755 => 100644 doc/python/ReciprocalBasis.pdf mode change 100755 => 100644 doc/python/ReciprocalBasis.py mode change 100755 => 100644 doc/python/SphericalCoordinates.pdf mode change 100755 => 100644 doc/python/SphericalCoordinates.py mode change 100755 => 100644 doc/python/TensorDef.py mode change 100755 => 100644 doc/python/diffops.pdf mode change 100755 => 100644 doc/python/submanifold.py mode change 100755 => 100644 doc/python/submanifold1.pdf mode change 100755 => 100644 examples/LaTeX/Dop.pdf mode change 100755 => 100644 examples/LaTeX/Dop.py mode change 100755 => 100644 examples/LaTeX/FmtChk.pdf mode change 100755 => 100644 examples/LaTeX/FmtChk.py mode change 100755 => 100644 examples/LaTeX/curvi_linear_latex.pdf mode change 100755 => 100644 examples/LaTeX/curvi_linear_latex.py mode change 100755 => 100644 examples/LaTeX/dchk.pdf mode change 100755 => 100644 examples/LaTeX/dchk.py mode change 100755 => 100644 examples/LaTeX/diffeq_sys.py mode change 100755 => 100644 examples/LaTeX/dirac_derive.py mode change 100755 => 100644 examples/LaTeX/em_waves_latex.pdf mode change 100755 => 100644 examples/LaTeX/em_waves_latex.py mode change 100755 => 100644 examples/LaTeX/groups.pdf mode change 100755 => 100644 examples/LaTeX/groups.py mode change 100755 => 100644 examples/LaTeX/groups.tex mode change 100755 => 100644 examples/LaTeX/latex_check.py mode change 100755 => 100644 examples/LaTeX/lin_tran_check.py mode change 100755 => 100644 examples/LaTeX/linear_EM_waves.pdf mode change 100755 => 100644 examples/LaTeX/linear_EM_waves.py mode change 100755 => 100644 examples/LaTeX/manifold.py mode change 100755 => 100644 examples/LaTeX/matrix_latex.py mode change 100755 => 100644 examples/LaTeX/new_bug_grad_exp.py mode change 100755 => 100644 examples/LaTeX/physics_check_latex.pdf mode change 100755 => 100644 examples/LaTeX/physics_check_latex.py mode change 100755 => 100644 examples/LaTeX/print_check_latex.py mode change 100755 => 100644 examples/LaTeX/products_latex.py mode change 100755 => 100644 examples/LaTeX/simple_check_latex.py mode change 100755 => 100644 examples/Old Format/bad_example.py mode change 100755 => 100644 examples/Old Format/eval_check.py mode change 100755 => 100644 examples/Old Format/exp_check.py mode change 100755 => 100644 examples/Old Format/latex_check.py mode change 100755 => 100644 examples/Old Format/matrix_latex.py mode change 100755 => 100644 examples/Old Format/mv_setup_options.py mode change 100755 => 100644 examples/Old Format/physics_check_latex.py mode change 100755 => 100644 examples/Old Format/print_check_latex.py mode change 100755 => 100644 examples/Old Format/prob_not_solenoidal.py mode change 100755 => 100644 examples/Old Format/products_latex.py mode change 100755 => 100644 examples/Old Format/simple_check.py mode change 100755 => 100644 examples/Old Format/simple_check_latex.py mode change 100755 => 100644 examples/Old Format/spherical_latex.py mode change 100755 => 100644 examples/Terminal/1d_grad.py mode change 100755 => 100644 examples/Terminal/ConformalConsole.py mode change 100755 => 100644 examples/Terminal/exp_check.py mode change 100755 => 100644 examples/Terminal/mv_setup_options.py mode change 100755 => 100644 examples/Terminal/prob_not_solenoidal.py mode change 100755 => 100644 examples/Terminal/rotations.py mode change 100755 => 100644 examples/ipython/Smith Sphere.ipynb mode change 100755 => 100644 examples/ipython/dop.ipynb mode change 100755 => 100644 examples/ipython/simple_ga_test.ipynb mode change 100755 => 100644 galgebra/__init__.py mode change 100755 => 100644 galgebra/ga.py mode change 100755 => 100644 galgebra/lt.py mode change 100755 => 100644 galgebra/metric.py mode change 100755 => 100644 galgebra/mv.py mode change 100755 => 100644 galgebra/printer.py mode change 100755 => 100644 test/test_test.py diff --git a/doc/galgebra.tex b/doc/galgebra.tex old mode 100755 new mode 100644 diff --git a/doc/python/BACCAB.pdf b/doc/python/BACCAB.pdf old mode 100755 new mode 100644 diff --git a/doc/python/BACCAB.py b/doc/python/BACCAB.py old mode 100755 new mode 100644 diff --git a/doc/python/Dirac.pdf b/doc/python/Dirac.pdf old mode 100755 new mode 100644 diff --git a/doc/python/Dirac.py b/doc/python/Dirac.py old mode 100755 new mode 100644 diff --git a/doc/python/Dop.pdf b/doc/python/Dop.pdf old mode 100755 new mode 100644 diff --git a/doc/python/Dop.py b/doc/python/Dop.py old mode 100755 new mode 100644 diff --git a/doc/python/EMWaves.pdf b/doc/python/EMWaves.pdf old mode 100755 new mode 100644 diff --git a/doc/python/EMWaves.py b/doc/python/EMWaves.py old mode 100755 new mode 100644 diff --git a/doc/python/LinearTrans.pdf b/doc/python/LinearTrans.pdf old mode 100755 new mode 100644 diff --git a/doc/python/LinearTrans.py b/doc/python/LinearTrans.py old mode 100755 new mode 100644 diff --git a/doc/python/Ltrans.pdf b/doc/python/Ltrans.pdf old mode 100755 new mode 100644 diff --git a/doc/python/Ltrans.py b/doc/python/Ltrans.py old mode 100755 new mode 100644 diff --git a/doc/python/Ltrans.tex b/doc/python/Ltrans.tex old mode 100755 new mode 100644 diff --git a/doc/python/LtransInst.pdf b/doc/python/LtransInst.pdf old mode 100755 new mode 100644 diff --git a/doc/python/LtransInst.py b/doc/python/LtransInst.py old mode 100755 new mode 100644 diff --git a/doc/python/ReciprocalBasis.pdf b/doc/python/ReciprocalBasis.pdf old mode 100755 new mode 100644 diff --git a/doc/python/ReciprocalBasis.py b/doc/python/ReciprocalBasis.py old mode 100755 new mode 100644 diff --git a/doc/python/SphericalCoordinates.pdf b/doc/python/SphericalCoordinates.pdf old mode 100755 new mode 100644 diff --git a/doc/python/SphericalCoordinates.py b/doc/python/SphericalCoordinates.py old mode 100755 new mode 100644 diff --git a/doc/python/TensorDef.py b/doc/python/TensorDef.py old mode 100755 new mode 100644 diff --git a/doc/python/diffops.pdf b/doc/python/diffops.pdf old mode 100755 new mode 100644 diff --git a/doc/python/submanifold.py b/doc/python/submanifold.py old mode 100755 new mode 100644 diff --git a/doc/python/submanifold1.pdf b/doc/python/submanifold1.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/Dop.pdf b/examples/LaTeX/Dop.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/Dop.py b/examples/LaTeX/Dop.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/FmtChk.pdf b/examples/LaTeX/FmtChk.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/FmtChk.py b/examples/LaTeX/FmtChk.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/curvi_linear_latex.pdf b/examples/LaTeX/curvi_linear_latex.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/curvi_linear_latex.py b/examples/LaTeX/curvi_linear_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/dchk.pdf b/examples/LaTeX/dchk.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/dchk.py b/examples/LaTeX/dchk.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/diffeq_sys.py b/examples/LaTeX/diffeq_sys.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/dirac_derive.py b/examples/LaTeX/dirac_derive.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/em_waves_latex.pdf b/examples/LaTeX/em_waves_latex.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/em_waves_latex.py b/examples/LaTeX/em_waves_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/groups.pdf b/examples/LaTeX/groups.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/groups.py b/examples/LaTeX/groups.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/groups.tex b/examples/LaTeX/groups.tex old mode 100755 new mode 100644 diff --git a/examples/LaTeX/latex_check.py b/examples/LaTeX/latex_check.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/lin_tran_check.py b/examples/LaTeX/lin_tran_check.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/linear_EM_waves.pdf b/examples/LaTeX/linear_EM_waves.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/linear_EM_waves.py b/examples/LaTeX/linear_EM_waves.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/manifold.py b/examples/LaTeX/manifold.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/matrix_latex.py b/examples/LaTeX/matrix_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/new_bug_grad_exp.py b/examples/LaTeX/new_bug_grad_exp.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/physics_check_latex.pdf b/examples/LaTeX/physics_check_latex.pdf old mode 100755 new mode 100644 diff --git a/examples/LaTeX/physics_check_latex.py b/examples/LaTeX/physics_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/print_check_latex.py b/examples/LaTeX/print_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/products_latex.py b/examples/LaTeX/products_latex.py old mode 100755 new mode 100644 diff --git a/examples/LaTeX/simple_check_latex.py b/examples/LaTeX/simple_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/bad_example.py b/examples/Old Format/bad_example.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/eval_check.py b/examples/Old Format/eval_check.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/exp_check.py b/examples/Old Format/exp_check.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/latex_check.py b/examples/Old Format/latex_check.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/matrix_latex.py b/examples/Old Format/matrix_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/mv_setup_options.py b/examples/Old Format/mv_setup_options.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/physics_check_latex.py b/examples/Old Format/physics_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/print_check_latex.py b/examples/Old Format/print_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/prob_not_solenoidal.py b/examples/Old Format/prob_not_solenoidal.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/products_latex.py b/examples/Old Format/products_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/simple_check.py b/examples/Old Format/simple_check.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/simple_check_latex.py b/examples/Old Format/simple_check_latex.py old mode 100755 new mode 100644 diff --git a/examples/Old Format/spherical_latex.py b/examples/Old Format/spherical_latex.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/1d_grad.py b/examples/Terminal/1d_grad.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/ConformalConsole.py b/examples/Terminal/ConformalConsole.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/exp_check.py b/examples/Terminal/exp_check.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/mv_setup_options.py b/examples/Terminal/mv_setup_options.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/prob_not_solenoidal.py b/examples/Terminal/prob_not_solenoidal.py old mode 100755 new mode 100644 diff --git a/examples/Terminal/rotations.py b/examples/Terminal/rotations.py old mode 100755 new mode 100644 diff --git a/examples/ipython/Smith Sphere.ipynb b/examples/ipython/Smith Sphere.ipynb old mode 100755 new mode 100644 diff --git a/examples/ipython/dop.ipynb b/examples/ipython/dop.ipynb old mode 100755 new mode 100644 diff --git a/examples/ipython/simple_ga_test.ipynb b/examples/ipython/simple_ga_test.ipynb old mode 100755 new mode 100644 diff --git a/galgebra/__init__.py b/galgebra/__init__.py old mode 100755 new mode 100644 diff --git a/galgebra/ga.py b/galgebra/ga.py old mode 100755 new mode 100644 diff --git a/galgebra/lt.py b/galgebra/lt.py old mode 100755 new mode 100644 diff --git a/galgebra/metric.py b/galgebra/metric.py old mode 100755 new mode 100644 diff --git a/galgebra/mv.py b/galgebra/mv.py old mode 100755 new mode 100644 diff --git a/galgebra/printer.py b/galgebra/printer.py old mode 100755 new mode 100644 diff --git a/test/test_test.py b/test/test_test.py old mode 100755 new mode 100644 From 20f33bb3a1fe5e0feee59456ceca613829c5f898 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 17 Oct 2019 14:02:04 +0100 Subject: [PATCH 02/10] Remove trailing spaces in main code (#47) --- galgebra/ga.py | 8 ++++---- galgebra/metric.py | 2 +- galgebra/mv.py | 8 ++++---- galgebra/printer.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/galgebra/ga.py b/galgebra/ga.py index b2eff9b1..918bde38 100644 --- a/galgebra/ga.py +++ b/galgebra/ga.py @@ -486,7 +486,7 @@ def mvr(self,norm=True): return tuple([self.r_basis_mv[i] / self.e_sq for i in self.n_range]) else: return tuple(self.r_basis_mv) - + def bases_dict(self, prefix=None): ''' returns a dictionary mapping basis element names to their MultiVector @@ -494,7 +494,7 @@ def bases_dict(self, prefix=None): if you are lazy, you might do this to populate your namespace with the variables of a given layout. - + >>> locals().update(ga.bases()) ''' if prefix is None: @@ -503,8 +503,8 @@ def bases_dict(self, prefix=None): var_names = [prefix+''.join([k for k in str(b) if k.isdigit()]) for b in bl] return {key:val for key,val in zip(var_names, bl)} - - + + def grads(self): if not self.is_ortho: diff --git a/galgebra/metric.py b/galgebra/metric.py index 3ab13b7f..e57930c1 100644 --- a/galgebra/metric.py +++ b/galgebra/metric.py @@ -432,7 +432,7 @@ def Christoffel_symbols(self,mode=1): # dg[i][j][k] = \partial_{x_{k}}g_{ij} dg = self.dg - + if mode == 1: dG = [] # dG[i][j][k] = half * (dg[j][k][i] + dg[i][k][j] - dg[i][j][k]) diff --git a/galgebra/mv.py b/galgebra/mv.py index d71f112a..6ca14be9 100644 --- a/galgebra/mv.py +++ b/galgebra/mv.py @@ -591,7 +591,7 @@ def __getitem__(self,key): get a specified grade of a multivector ''' return self.grade(key) - + def Mv_str(self): global print_replace_old, print_replace_new if self.i_grade == 0: @@ -1072,9 +1072,9 @@ def odd(self): def rev(self): self = self.blade_rep() return Mv(self.Ga.reverse(self.obj), ga=self.Ga) - + __invert__ = rev # allow `~x` to call x.rev() - + def diff(self, coord): Dself = Mv(ga=self.Ga) if self.Ga.coords is None: @@ -1294,7 +1294,7 @@ def norm(self, hint='+'): raise TypeError('"(' + str(product) + ')" is not a scalar in norm.') __abs__=norm # allow `abs(x)` to call z.norm() - + def inv(self): if self.is_scalar(): # self is a scalar return self.Ga.mv(S(1)/self.obj) diff --git a/galgebra/printer.py b/galgebra/printer.py index c724112d..eefc6138 100644 --- a/galgebra/printer.py +++ b/galgebra/printer.py @@ -348,7 +348,7 @@ def _print_Derivative(self, expr): # function, *diff_args = expr.args function = expr.args[0] diff_args = expr.args[1:] - + xi = [] ni = [] for x, n in diff_args: From 6a53f3545b40de6536ec0e699ab149492951970e Mon Sep 17 00:00:00 2001 From: utensil Date: Thu, 17 Oct 2019 21:28:41 +0800 Subject: [PATCH 03/10] Add metric.Collect for SymPy 1.4 compatibility Co-authored-by: Alan Bromborsky --- galgebra/ga.py | 7 ++++++- galgebra/lt.py | 6 +++--- galgebra/metric.py | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/galgebra/ga.py b/galgebra/ga.py index 918bde38..3723ae87 100644 --- a/galgebra/ga.py +++ b/galgebra/ga.py @@ -1479,7 +1479,12 @@ def build_reciprocal_basis(self,gsym): dual_base_rep = self.blade_to_base_rep(dual) # {E_n}^{-1} = \frac{E_n}{{E_n}^{2}} # r_basis_j = sgn * duals[j] * E_n so it's not normalized, missing a factor of {E_n}^{-2} - r_basis_j = collect(expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj))), self.blades_lst) + """ + print('blades list =',self.blades_lst) + print('debug =',expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj)))) + print('collect arg =',expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj)))) + """ + r_basis_j = metric.Collect(expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj))), self.blades_lst) self.r_basis.append(r_basis_j) # sgn = (-1)**{j-1} sgn = -sgn diff --git a/galgebra/lt.py b/galgebra/lt.py index dde5e02b..c86122e4 100644 --- a/galgebra/lt.py +++ b/galgebra/lt.py @@ -281,7 +281,7 @@ def __add__(self, LT): self_add_LT = copy(self.lt_dict) for key in list(LT.lt_dict.keys()): if key in self_add_LT: - self_add_LT[key] = collect(self_add_LT[key] + LT.lt_dict[key], self.Ga.basis) + self_add_LT[key] = metric.Collect(self_add_LT[key] + LT.lt_dict[key], self.Ga.basis) else: self_add_LT[key] = LT.lt_dict[key] return(Lt(self_add_LT, ga=self.Ga)) @@ -294,7 +294,7 @@ def __sub__(self, LT): self_add_LT = copy(self.lt_dict) for key in list(LT.lt_dict.keys()): if key in self_add_LT: - self_add_LT[key] = collect(self_add_LT[key] - LT.lt_dict[key], self.Ga.basis) + self_add_LT[key] = metric.Collect(self_add_LT[key] - LT.lt_dict[key], self.Ga.basis) else: self_add_LT[key] = -LT.lt_dict[key] return(Lt(self_add_LT, ga=self.Ga)) @@ -309,7 +309,7 @@ def __mul__(self, LT): for base in LT.lt_dict: self_mul_LT[base] = self(LT(base, obj=True), obj=True) for key in self_mul_LT: - self_mul_LT[key] = expand(self_mul_LT[key]).collect(self.Ga.basis) + self_mul_LT[key] = metric.Collect(expand(self_mul_LT[key]),self.Ga.basis) return(Lt(self_mul_LT, ga=self.Ga)) else: self_mul_LT = {} diff --git a/galgebra/metric.py b/galgebra/metric.py index e57930c1..3bc5979d 100644 --- a/galgebra/metric.py +++ b/galgebra/metric.py @@ -78,6 +78,22 @@ def linear_expand(expr, mode=True): else: return list(zip(coefs, bases)) +def Collect(A, nc_lst): + """ + A is a linear combination of noncommutative symbols with scalar + expressions as coefficients. Collect takes the terms containing + the noncommutative symbols in nc_list and sums them so no elements + of nc_list appear more than once in the sum. Collect combines all + coefficients of a given element of nc_lst into a single coefficient. + """ + (coefs,bases) = linear_expand(A) + C = S(0) + for x in nc_lst: + if x in bases: + i = bases.index(x) + C += coefs[i]*x + return C + def square_root_of_expr(expr): """ From 5dd9d6d38fbc0a47f5b01268dbc57f6512e6d729 Mon Sep 17 00:00:00 2001 From: utensil Date: Thu, 17 Oct 2019 23:07:53 +0800 Subject: [PATCH 04/10] Rename Collect to collect for consistency --- galgebra/ga.py | 2 +- galgebra/lt.py | 6 +++--- galgebra/metric.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/galgebra/ga.py b/galgebra/ga.py index 3723ae87..de8eab0a 100644 --- a/galgebra/ga.py +++ b/galgebra/ga.py @@ -1484,7 +1484,7 @@ def build_reciprocal_basis(self,gsym): print('debug =',expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj)))) print('collect arg =',expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj)))) """ - r_basis_j = metric.Collect(expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj))), self.blades_lst) + r_basis_j = metric.collect(expand(self.base_to_blade_rep(self.mul(sgn * dual_base_rep, self.e_obj))), self.blades_lst) self.r_basis.append(r_basis_j) # sgn = (-1)**{j-1} sgn = -sgn diff --git a/galgebra/lt.py b/galgebra/lt.py index c86122e4..48cf8898 100644 --- a/galgebra/lt.py +++ b/galgebra/lt.py @@ -281,7 +281,7 @@ def __add__(self, LT): self_add_LT = copy(self.lt_dict) for key in list(LT.lt_dict.keys()): if key in self_add_LT: - self_add_LT[key] = metric.Collect(self_add_LT[key] + LT.lt_dict[key], self.Ga.basis) + self_add_LT[key] = metric.collect(self_add_LT[key] + LT.lt_dict[key], self.Ga.basis) else: self_add_LT[key] = LT.lt_dict[key] return(Lt(self_add_LT, ga=self.Ga)) @@ -294,7 +294,7 @@ def __sub__(self, LT): self_add_LT = copy(self.lt_dict) for key in list(LT.lt_dict.keys()): if key in self_add_LT: - self_add_LT[key] = metric.Collect(self_add_LT[key] - LT.lt_dict[key], self.Ga.basis) + self_add_LT[key] = metric.collect(self_add_LT[key] - LT.lt_dict[key], self.Ga.basis) else: self_add_LT[key] = -LT.lt_dict[key] return(Lt(self_add_LT, ga=self.Ga)) @@ -309,7 +309,7 @@ def __mul__(self, LT): for base in LT.lt_dict: self_mul_LT[base] = self(LT(base, obj=True), obj=True) for key in self_mul_LT: - self_mul_LT[key] = metric.Collect(expand(self_mul_LT[key]),self.Ga.basis) + self_mul_LT[key] = metric.collect(expand(self_mul_LT[key]),self.Ga.basis) return(Lt(self_mul_LT, ga=self.Ga)) else: self_mul_LT = {} diff --git a/galgebra/metric.py b/galgebra/metric.py index 3bc5979d..1dd542b6 100644 --- a/galgebra/metric.py +++ b/galgebra/metric.py @@ -78,12 +78,12 @@ def linear_expand(expr, mode=True): else: return list(zip(coefs, bases)) -def Collect(A, nc_lst): +def collect(A, nc_lst): """ A is a linear combination of noncommutative symbols with scalar - expressions as coefficients. Collect takes the terms containing + expressions as coefficients. collect() takes the terms containing the noncommutative symbols in nc_list and sums them so no elements - of nc_list appear more than once in the sum. Collect combines all + of nc_list appear more than once in the sum. collect() combines all coefficients of a given element of nc_lst into a single coefficient. """ (coefs,bases) = linear_expand(A) From 04069fc19fd79da911fdf69926aafa32ada43f7b Mon Sep 17 00:00:00 2001 From: eric-wieser Date: Thu, 17 Oct 2019 23:08:24 +0800 Subject: [PATCH 05/10] Change the doc to napoleon style for collect --- galgebra/metric.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/galgebra/metric.py b/galgebra/metric.py index 1dd542b6..cca973c5 100644 --- a/galgebra/metric.py +++ b/galgebra/metric.py @@ -78,17 +78,26 @@ def linear_expand(expr, mode=True): else: return list(zip(coefs, bases)) -def collect(A, nc_lst): +def collect(A, nc_list): """ - A is a linear combination of noncommutative symbols with scalar - expressions as coefficients. collect() takes the terms containing - the noncommutative symbols in nc_list and sums them so no elements - of nc_list appear more than once in the sum. collect() combines all - coefficients of a given element of nc_lst into a single coefficient. + Parameters + ----------- + A : + a linear combination of noncommutative symbols with scalar + expressions as coefficients + nc_list : + noncommutative symbols in A to combine + + Returns + ------- + sympy.Basic + A sum of the terms containing the noncommutative symbols in `nc_list` such that no elements + of `nc_list` appear more than once in the sum. All coefficients of a given element of `nc_list` + are combined into a single coefficient. """ (coefs,bases) = linear_expand(A) C = S(0) - for x in nc_lst: + for x in nc_list: if x in bases: i = bases.index(x) C += coefs[i]*x From a1ad51857e29dfdc3658a0607087855bd48e919a Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Thu, 14 Nov 2019 17:43:11 +0000 Subject: [PATCH 06/10] Fix the docstring of `metric` to render properly (#50) This uses the numpy docstring style, which is already enabled in the sphinx config --- galgebra/metric.py | 89 +++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 36 deletions(-) diff --git a/galgebra/metric.py b/galgebra/metric.py index cca973c5..5ba5d332 100644 --- a/galgebra/metric.py +++ b/galgebra/metric.py @@ -226,33 +226,56 @@ def applymv(mv): class Metric(object): - """ - Data Variables - - - g[,]: metric tensor (sympy matrix) - g_inv[,]: inverse of metric tensor (sympy matirx) - norm: normalized diagonal metric tensor (list of sympy numbers) - coords[]: coordinate variables (list of sympy symbols) - is_ortho: True if basis is orthogonal (bool) - connect_flg: True if connection is non-zero (bool) - basis[]: basis vector symbols (list of non-commutative sympy variables) - r_symbols[]: reciprocal basis vector symbols (list of non-commutative sympy variables) - n: dimension of vector space/manifold (integer) - n_range: list of basis indices - de[][]: derivatives of basis functions. Two dimensional list. First - entry is differentiating coordiate. Second entry is basis - vector. Quantities are linear combinations of basis vector - symbols. - sig: Signature of metric (p,q) where n = p+q. If metric tensor - is numerical and orthogonal it is calculated. Otherwise the - following inputs are used - - - input signature Type - "e" (n,0) Euclidean - "m+" (n-1,1) Minkowski (One negative square) - "m-" (1,n-1) Minkowski (One positive square) - p (p,n-p) General (integer not string input) + Metric specification + + Attributes + ---------- + + g : sympy matrix[,] + metric tensor + g_inv : sympy matrix[,] + inverse of metric tensor + norm : list of sympy numbers + normalized diagonal metric tensor + coords : list[] of sympy symbols + coordinate variables + is_ortho : bool + True if basis is orthogonal + connect_flg : bool + True if connection is non-zero + basis : list[] of non-commutative sympy variables + basis vector symbols + r_symbols : list[] of non-commutative sympy variables + reciprocal basis vector symbols + n : integer + dimension of vector space/manifold + n_range : + list of basis indices + de : list[][] + derivatives of basis functions. Two dimensional list. First + entry is differentiating coordiate. Second entry is basis + vector. Quantities are linear combinations of basis vector + symbols. + sig : Tuple[int, int] + Signature of metric ``(p,q)`` where ``n = p+q``. If metric tensor + is numerical and orthogonal it is calculated. Otherwise the + following inputs are used: + + ========= =========== ================================== + Input Signature Type + ========= =========== ================================== + ``"e"`` ``(n,0)`` Euclidean + ``"m+"`` ``(n-1,1)`` Minkowski (One negative square) + ``"m-"`` ``(1,n-1)`` Minkowski (One positive square) + ``p`` ``(p,n-p)`` General (integer not string input) + ========= =========== ================================== + + gsym : str + String for symbolic metric determinant. If self.gsym = 'g' + then det(g) is sympy scalar function of coordinates with + name 'det(g)'. Useful for complex non-orthogonal coordinate + systems or for calculations with general metric. """ count = 1 @@ -585,14 +608,8 @@ def __init__(self, basis, **kwargs): coords = kwargs['coords'] # Manifold coordinates (sympy symbols) norm = kwargs['norm'] # Normalize basis vectors self.sig = kwargs['sig'] # Hint for metric signature - """ - String for symbolic metric determinant. If self.gsym = 'g' - then det(g) is sympy scalar function of coordinates with - name 'det(g)'. Useful for complex non-orthogonal coordinate - systems or for calculations with general metric. - """ self.gsym = kwargs['gsym'] - self.Isq = kwargs['Isq'] # Sign of I**2, only needed if I**2 not a number + self.Isq = kwargs['Isq'] #: Sign of I**2, only needed if I**2 not a number self.debug = debug self.is_ortho = False # Is basis othogonal @@ -602,9 +619,9 @@ def __init__(self, basis, **kwargs): else: self.connect_flg = True # Connection needed for postion dependent metric self.norm = norm # True to normalize basis vectors - self.detg = None # Determinant of g - self.g_adj = None # Adjugate of g - self.g_inv = None # Inverse of g + self.detg = None #: Determinant of g + self.g_adj = None #: Adjugate of g + self.g_inv = None #: Inverse of g # Generate list of basis vectors and reciprocal basis vectors # as non-commutative symbols From 4f0210d1e290299fe3a138e3155b37ff05f05bd8 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 19 Nov 2019 23:49:43 +0000 Subject: [PATCH 07/10] Cleanup many docstrings in ga.py (#51) * Cleanup many docstrings in ga.py Unfortunately napoleon doesn't allow us to group our members together as was intended here - so we have to abandon numpydoc in this class and use `.. attribute` directly, which is quite verbose. Also frustratingly, we cannot use headings inside `Ga.__doc__`, so have to make do with `..rubric::`. This also adds backticks and latex rendering in many places where it aids readability. * Cleanup more docstrings found in review * Cleanup more docstrings found in review --- galgebra/ga.py | 444 ++++++++++++++++++++++++++++++------------------- 1 file changed, 275 insertions(+), 169 deletions(-) diff --git a/galgebra/ga.py b/galgebra/ga.py index de8eab0a..991523ed 100644 --- a/galgebra/ga.py +++ b/galgebra/ga.py @@ -65,15 +65,20 @@ def __getitem__(self, key): def update_and_substitute(expr1, expr2, func, mul_dict): """ - Linear expand expr1 and expr2 to get (summation convention) + Linear expand expr1 and expr2 to get (summation convention):: + expr1 = coefs1[i]*bases1[i] expr2 = coefs2[j]*bases2[j] - where coefs1 and coefs2 are lists of are commutative expressions and - bases1 and bases2 are lists of bases for the geometric algebra. - Then evaluate + + where ``coefs1`` and ``coefs2`` are lists of are commutative expressions and + ``bases1`` and ``bases2`` are lists of bases for the geometric algebra. + + Then evaluate:: + expr = coefs1[i]*coefs2[j]*F(bases1[i],bases2[j]) - where F(bases1[i],bases2[j]) is a function that returns the appropriate - product of bases1[i]*bases2[j] as a linear combination of scalars and + + where ``F(bases1[i],bases2[j])`` is a function that returns the appropriate + product of ``bases1[i]*bases2[j]`` as a linear combination of scalars and bases of the geometric algebra. """ if (isinstance(expr1, numbers.Number) or expr1.is_commutative) \ @@ -135,14 +140,14 @@ def nc_subs(expr, base_keys, base_values=None): class Ga(metric.Metric): r""" The vector space (basis, metric, derivatives of basis vectors) is - defined by the base class 'Metric'. + defined by the base class :class:`~galgebra.metric.Metric`. - The instanciating the class 'Ga' constructs the geometric algebra of + The instanciating the class :class:`Ga` constructs the geometric algebra of the vector space defined by the metric. The construction includes the multivector bases, multiplication - tables or functions for the geometric (*), inner (|), outer (^) - products, plus the left (<) and right (>) contractions. The + tables or functions for the geometric (``*``), inner (``|``), outer (``^``) + products, plus the left (``<``) and right (``>``) contractions. The geometric derivative operator and any required connections for the derivative are also calculated. @@ -154,80 +159,151 @@ class Ga(metric.Metric): the products of multivector bases and connection are not calculated unless they are actually needed in the current calculation. - Only instantiate the Ga class via the Mv class or any use of enhanced - printing (text or latex) will cause the bases and multiplication + Only instantiate the :class:`Ga` class via the :class:`~galgebra.mv.Mv` class or any use + of enhanced printing (text or latex) will cause the bases and multiplication table entries to be incorrectly labeled . - Data Variables - - - Inherited from Metric class - - - g[,]: Metric tensor (sympy matrix) - g_inv[,]: Inverse of metric tensor (sympy matirx) - norm: Normalized diagonal metric tensor (list of sympy numbers) - coords[]: Coordinate variables (list of sympy symbols) - is_ortho: True if basis is orthogonal (bool) - connect_flg: True if connection is non-zero (bool) - basis[]: Basis vector symbols (list of non-commutative sympy variables) - r_symbols[]: Reciprocal basis vector symbols (list of non-commutative sympy variables) - n: Dimension of vector space/manifold (integer) - n_range: List of basis indices - de[][]: Derivatives of basis functions. Two dimensional list. First - entry is differentiating coordiate. Second entry is basis - vector. Quantities are linear combinations of basis vector - symbols. - - Basis, basis bases, and basis blades data structures - - - indexes[]: Index list for multivector bases and blades by grade (tuple of tuples). Tuple - so that indexes can be used to index dictionaries. - bases[]: List of bases (non-commutative sympy symbols). Only created for - non-orthogonal basis vectors. - blades[]: List of basis blades (non-commutative sympy symbols). For - orthogonal basis vectors the same as bases. - coord_vec: Linear combination of coordinates and basis vectors. For - example in orthogonal 3D x*e_x+y*e_y+z*e_z. - blades_to_indexes_dict{}: Map basis blades to index tuples (dictionary). - indexes_to_blades_dict{}: Map index tuples to basis blades (dictionary). - bases_to_indexes_dict{}: Map basis bases to index tuples (dictionary). - indexes_to_bases_dict{}: Map index tuples to basis bases (dictionary). - pseudoI: Symbol for pseudo scalar (non-commutative sympy symbol). - - Multiplication tables data structures - - - Keys in all multiplication tables (*,^,|,<,>) are always symbol1*symbol2. The correct operation is known - by the context (name) of the relevant list or dictionary) - - mul_table[]: Geometric products of basis blades as list of [(base1*base2, Expansion of base1*base2),...] - mul_table_dict{}: Geometric products of basis blades as dicitionary {base1*base2: Expansion of base1*base2,...} - wedge_table[]: Outer products of basis blades as list of [(base1*base2, Expansion of base1^base2),...] - wedge_table_dict{}: Outer products of basis blades as dicitionary {base1*base2: Expansion of base1^base2,...} - - Reciprocal basis data structures - - - r_symbols[]: Reciprocal basis vector symbols (list of non-commutative sympy variables) - r_basis[]: List of reciprocal basis vectors expanded as linear combination of basis vector symbols. - r_basis_dict{}: Dictionary to map reciprocal basis symbols to reciprocal basis expanded in terms of basis symbols - {reciprocal basis symbol: linear combination of basis symbols,...} - r_basis_mv[]: List of reciprocal basis vectors in terms of basis multivectors (elements of list can be used in - multivector expressions.) - - Derivative data structures - - - de[][]: Derivatives of basis functions. Two dimensional list. First entry is differentiating coordinate index. - Second entry is basis vector index. Quantities are linear combinations of basis vector symbols. - dbases{}: Dictionary of derivatives of basis blades with respect to coordinate {(coordinate index, basis blade): - derivative of basis blade with respect to coordinate,...} (Note that values in dictionary are not - multivectors, but linear combinations of basis blade symbols). - Pdop_identity: Partial differential operator identity (operates on multivector function to return function). - Pdiffs{}: Dictionary of partial differential operators (operates on multivector functions) for each coordinate - {x: \partial_{x}, ...} - sPds{}: Dictionary of scalar partial differential operators (operates on scalar functions) for each coordinate - {x: \partial_{x}, ...} - grad: Geometric derivative operator from left. grad*F returns multivector derivative, F*grad returns differential - operator. - rgrad: Geometric derivative operator from right. grad*F returns differential operator, F*grad returns multivector - derivative. + .. rubric:: Inherited from Metric class + + .. autosummary:: + + ~galgebra.metric.Metric.g + ~galgebra.metric.Metric.g_inv + ~galgebra.metric.Metric.norm + ~galgebra.metric.Metric.coords + ~galgebra.metric.Metric.is_ortho + ~galgebra.metric.Metric.connect_flg + ~galgebra.metric.Metric.basis + ~galgebra.metric.Metric.r_symbols + ~galgebra.metric.Metric.n + ~galgebra.metric.Metric.n_range + ~galgebra.metric.Metric.de + + .. rubric:: Basis, basis bases, and basis blades data structures + + .. attribute:: indexes + + Index list for multivector bases and blades by grade (tuple of tuples). Tuple + so that indexes can be used to index dictionaries. + + .. attribute:: bases + + List of bases (non-commutative sympy symbols). Only created for + non-orthogonal basis vectors. + + .. attribute:: blades + + List of basis blades (non-commutative sympy symbols). For + orthogonal basis vectors the same as bases. + + .. attribute:: coord_vec + + Linear combination of coordinates and basis vectors. For + example in orthogonal 3D :math:`x*e_x+y*e_y+z*e_z`. + + .. attribute:: blades_to_indexes_dict + + Map basis blades to index tuples (dictionary). + + .. attribute:: indexes_to_blades_dict + + Map index tuples to basis blades (dictionary). + + .. attribute:: bases_to_indexes_dict + + Map basis bases to index tuples (dictionary). + + .. attribute:: indexes_to_bases_dict + + Map index tuples to basis bases (dictionary). + + .. attribute:: pseudoI + + Symbol for pseudo scalar (non-commutative sympy symbol). + + .. rubric:: Multiplication tables data structures + + Keys in all multiplication tables (``*``, ``^``, ``|``, ``<``, ``>``) are always ``symbol1*symbol2``. + The correct operation is known by the context (name) of the relevant list or dictionary) + + .. attribute:: mul_table + + Geometric products of basis blades as list of ``[(base1*base2, Expansion of base1*base2),...]`` + + .. attribute:: mul_table_dict + + Geometric products of basis blades as dicitionary ``{base1*base2: Expansion of base1*base2,...}`` + + .. attribute:: wedge_table + + Outer products of basis blades as list of ``[(base1*base2, Expansion of base1^base2),...]`` + + .. attribute:: wedge_table_dict + + Outer products of basis blades as dicitionary ``{base1*base2: Expansion of base1^base2,...}`` + + .. rubric:: Reciprocal basis data structures + + .. attribute:: r_symbols + + Reciprocal basis vector symbols (list of non-commutative sympy variables) + + .. attribute:: r_basis + + List of reciprocal basis vectors expanded as linear combination of basis vector symbols. + + .. attribute:: r_basis_dict + + Dictionary to map reciprocal basis symbols to reciprocal basis expanded in terms of basis symbols + ``{reciprocal basis symbol: linear combination of basis symbols, ...}`` + + .. attribute:: r_basis_mv + + List of reciprocal basis vectors in terms of basis multivectors (elements of list can be used in + multivector expressions.) + + + .. rubric:: Derivative data structures + + .. attribute:: de + + Derivatives of basis functions. Two dimensional list. First entry is differentiating coordinate index. + Second entry is basis vector index. Quantities are linear combinations of basis vector symbols. + + .. attribute:: dbases + + Dictionary of derivatives of basis blades with respect to coordinate , + ``{(coordinate index, basis blade): derivative of basis blade with respect to coordinate, ...}``. + + Note that values in dictionary are not multivectors, but linear combinations of basis blade symbols. + + .. attribute:: Pdop_identity + + Partial differential operator identity (operates on multivector function to return function). + + .. attribute:: Pdiffs + + Dictionary of partial differential operators (operates on multivector functions) for each coordinate + :math:`\{x: \partial_{x}, ...\}` + + .. attribute:: sPds + + Dictionary of scalar partial differential operators (operates on scalar functions) for each coordinate + :math:`\{x: \partial_{x}, ...\}` + + .. attribute:: grad + + Geometric derivative operator from left. ``grad*F`` returns multivector + derivative, ``F*grad`` returns differential operator. + + .. attribute:: rgrad + + Geometric derivative operator from right. ``rgrad*F`` returns differential + operator, ``F*rgrad`` returns multivector derivative. + + .. Sphinx adds all the other members below this docstring + + .. rubric:: Other members """ dual_mode_value = 'I+' @@ -249,17 +325,20 @@ def dual_mode(mode='I+'): Sets mode of multivector dual function for all geometric algebras in users program. - If Ga.dual_mode(mode) not called the default mode is 'I+'. + If Ga.dual_mode(mode) not called the default mode is ``'I+'``. + ===== ============ mode return value - +I I*self - -I -I*self - I+ self*I - I- -self*I - +Iinv Iinv*self - -Iinv -Iinv*self - Iinv+ self*Iinv - Iinv- -self*Iinv + ===== ============ + +I I*self + -I -I*self + I+ self*I + I- -self*I + +Iinv Iinv*self + -Iinv -Iinv*self + Iinv+ self*Iinv + Iinv- -self*Iinv + ===== ============ """ if mode not in Ga.dual_mode_lst: raise ValueError('mode = ' + mode + ' not allowed for Ga.dual_mode.') @@ -475,9 +554,12 @@ def mvr(self,norm=True): Returns tumple of reciprocal basis vectors. If norm=True or basis vectors are orthogonal the reciprocal basis is normalized in the sense that - e_{i}\cdot e^{j} = \delta_{i}^{j}. + + .. math:: {i}\cdot e^{j} = \delta_{i}^{j}. + If the basis is not orthogonal and norm=False then - e_{i}\cdot e^{j} = I^{2}\delta_{i}^{j}. + + .. math:: e_{i}\cdot e^{j} = I^{2}\delta_{i}^{j}. """ if self.r_basis_mv is None: @@ -542,8 +624,8 @@ def lt(self, *kargs, **kwargs): def sm(self, *kargs, **kwargs): """ - Instanciate and return a submanifold for this, 'self', - geometric algebra. See 'Sm' class for instantiation inputs. + Instanciate and return a submanifold for this + geometric algebra. See :class:`Sm` for instantiation inputs. """ kwargs['ga'] = self SM = Sm(*kargs, **kwargs) @@ -567,24 +649,24 @@ def basis_vectors(self): return tuple(self.basis) def build_bases(self): - """ + r""" The bases for the multivector (geometric) algebra are formed from all combinations of the bases of the vector space and the scalars. - Each base is represented as a non-commutative symbol of the form - + Each base is represented as a non-commutative symbol of the form - e_{i_{1}}e_{i_{2}}...e_{i_{r}} + .. math:: e_{i_{1}}e_{i_{2}}...e_{i_{r}} - where 0 < i_{1} < i_{2} < ... < i_{r} and 0 < r <= n the - dimension of the vector space and 0 < i_{j} <= n. The total - number of all symbols of this form plus the scalars is 2^{n}. + where :math:`0 < i_{1} < i_{2} < ... < i_{r}` and :math:`0 < r \le n` the + dimension of the vector space and :math:`0 < i_{j} \le n`. The total + number of all symbols of this form plus the scalars is :math:`2^{n}`. Any multivector can be represented as a linear combination of these bases and the scalars. If the basis vectors are not orthogonal a second set of symbols is required given by - - e_{i_{1}}^e_{i_{2}}^...^e_{i_{r}}. + .. math:: e_{i_{1}}\wedge e_{i_{2}}\wedge ...\wedge e_{i_{r}}. These are called the blade basis for the geometric algebra and and multivector can also be represented by a linears combination @@ -741,9 +823,9 @@ def basis_product_tables(self): product) are calulated on the fly and updated and are for blade pairs. - All tables are of the form + All tables are of the form:: - [ (blade1*blade2,f(blade1,blade1)),... ] + [(blade1*blade2, f(blade1, blade1)), ...] """ self.mul_table = [] # Geometric product (*) of blades @@ -871,19 +953,21 @@ def reduce_basis(self, blst): @staticmethod def reduce_basis_loop(g, blst): - """ - blst is a list of integers [i_{1},...,i_{r}] representing the geometric - product of r basis vectors a_{{i_1}}*...*a_{{i_r}}. reduce_basis_loop - searches along the list [i_{1},...,i_{r}] untill it finds i_{j} == i_{j+1} - and in this case contracts the list, or if i_{j} > i_{j+1} it revises - the list (~i_{j} means remove i_{j} from the list) - - Case 1: If i_{j} == i_{j+1}, return a_{i_{j}}**2 and - [i_{1},..,~i_{j},~i_{j+1},...,i_{r}] - - Case 2: If i_{j} > i_{j+1}, return a_{i_{j}}.a_{i_{j+1}}, - [i_{1},..,~i_{j},~i_{j+1},...,i_{r}], and - [i_{1},..,i_{j+1},i_{j},...,i_{r}] + r""" + blst is a list of integers :math:`[i_{1},...,i_{r}]` representing the geometric + product of r basis vectors :math:`a_{{i_1}}*...*a_{{i_r}}`. :meth:`reduce_basis_loop` + searches along the list :math:`[i_{1},...,i_{r}]` untill it finds :math:`i_{j} = i_{j+1}` + and in this case contracts the list, or if :math:`i_{j} > i_{j+1}` it revises + the list (:math:`\sim i_{j}` means remove :math:`i_{j}` from the list) + + * Case 1: If :math:`i_{j} = i_{j+1}`, return + :math:`a_{i_{j}}^2` and + :math:`[i_{1},..,\sim i_{j},\sim i_{j+1},...,i_{r}]` + + * Case 2: If :math:`i_{j} > i_{j+1}`, return + :math:`a_{i_{j}}.a_{i_{j+1}}`, + :math:`[i_{1},..,\sim i_{j},\sim i_{j+1},...,i_{r}]`, and + :math:`[i_{1},..,i_{j+1},i_{j},...,i_{r}]` """ nblst = len(blst) # number of basis vectors if nblst <= 1: @@ -1179,14 +1263,22 @@ def wedge(self, A, B): return 0 return update_and_substitute(A, B, self.wedge_product_basis_blades, self.wedge_table_dict) - def dot(self, A, B): # inner products |, <, and > - """ - Let A = a + A' and B = b + B' where a and b are the scalar parts of - A and B and A' and B' are the remaining parts of A and B. Then - we have: - (a+A')<(b+B') = a(b+B') + A'(b+B') = b(a+A') + A'>B' - We use these relations to reduce AB. + def dot(self, A, B): + r""" + Inner product ``|``, ``<``, or ``>`` + + Let :math:`A = a + A'` and :math:`B = b + B'` where :math:`a` and + :math:`b` are the scalar parts of :math:`A` and :math:`B`, and + :math:`A'` and :math:`B'` are the remaining parts of :math:`A` and + :math:`B`. Then we have: + + .. math:: + + (a+A') \rfloor (b+B') &= a(b+B') + A' \rfloor B' \\ + (a+A') \lfloor (b+B') &= b(a+A') + A' \lfloor B' + + We use these relations to reduce :math:`A \rfloor B` (``AB``). """ if A == 0 or B == 0: return 0 @@ -1257,8 +1349,8 @@ def grade_decomposition(self, A): def split_multivector(self, A): """ - Split multivector A into commutative part a and non-commutative - part A' so that A = a+A' + Split multivector :math:`A` into commutative part :math:`a` and + non-commutative part :math:`A'` so that :math:`A = a+A'` """ if isinstance(A, mv.Mv): return self.split_multivector(A.obj) @@ -1282,7 +1374,7 @@ def split_multivector(self, A): def remove_scalar_part(self, A): """ - Return non-commutative part (sympy object) of A.obj. + Return non-commutative part (sympy object) of ``A.obj``. """ if isinstance(A, mv.Mv): return self.remove_scalar_part(A.obj) @@ -1427,18 +1519,23 @@ def even_odd(self, A, even=True): # Return even or odd part of A def build_reciprocal_basis(self,gsym): r""" - Calculate reciprocal basis vectors e^{j} where - e^{j}\cdot e_{k} = \delta_{k}^{j} - and \delta_{k}^{j} is the kronecker delta. We use the formula - from Doran and Lasenby 4.94 - - e^{j} = (-1)**{j-1}e_{1}^...e_{j-1}^e_{j+1}^...^e_{n}*E_{n}**{-1} - where E_{n} = e_{1}^...^e_{n}. - - For non-orthogonal basis e^{j} is not normalized and must be - divided by E_{n}**2 (self.e_sq) in any relevant calculations. - - If gsym = True then (E_{n})**2 is not evaluated, but is represented - as (E_{n})**2 = (-1)**(n*(n-1)/2)*det(g) where det(g) the determinant + Calculate reciprocal basis vectors :math:`e^{j}` where + + .. math:: e^{j}\cdot e_{k} = \delta_{k}^{j} + + and :math:`\delta_{k}^{j}` is the kronecker delta. We use the formula + from Doran and Lasenby 4.94: + + .. math:: e^{j} = (-1)^{j-1}e_{1} \wedge ...e_{j-1} \wedge e_{j+1} \wedge ... \wedge e_{n}*E_{n}^{-1} + + where :math:`E_{n} = e_{1}\wedge ...\wedge e_{n}`. + + For non-orthogonal basis :math:`e^{j}` is not normalized and must be + divided by :math:`E_{n}^2` (``self.e_sq``) in any relevant calculations. + + If ``gsym = True`` then :math:`E_{n}^2` is not evaluated, but is represented + as :math:`E_{n}^2 = (-1)^{n*(n-1)/2}\operatorname{det}(g)` where + :math:`\operatorname{det}(g)` the determinant of the metric tensor can be general scalar function of the coordinates. """ @@ -1552,13 +1649,15 @@ def build_reciprocal_basis(self,gsym): return def er_blade(self, er, blade, mode='*', left=True): - """ - Product (*,^,|,<,>) of reciprocal basis vector 'er' and basis + r""" + Product (``*``, ``^``, ``|``, ``<``, ``>``) of reciprocal basis vector + 'er' and basis blade 'blade' needed for application of derivatives to multivectors. left is 'True' means 'er' is multiplying 'blade' on the left, 'False' is for 'er' multiplying 'blade' on the - right. Symbolically for left geometric product - - e^{j}*(e_{i_{1}}^...^e_{i_{r}}) + right. Symbolically for left geometric product: + + .. math:: e^{j}*(e_{i_{1}}\wedge ...\wedge e_{i_{r}}) """ if mode == '*': base = self.blade_to_base_rep(blade) @@ -1672,10 +1771,10 @@ def pDiff(self, A, coord): return dA def grad_sqr(self, A, grad_sqr_mode, mode, left): - """ - Caclulate '(grad *_{1} grad) *_{2} A' or 'A *_{2} (grad *_{1} grad)' - where grad_sqr_mode = *_{1} = *, ^, or | and - mode = *_{2} = *, ^, or |. + r""" + Calculate :math:`(grad *_{1} grad) *_{2} A` or :math:`A *_{2} (grad *_{1} grad)` + where ``grad_sqr_mode`` = :math:`*_{1}` = ``*``, ``^``, or ``|`` and + ``mode`` = :math:`*_{2}` = ``*``, ``^``, or ``|``. """ (Sop, Bop) = Ga.DopFop[(grad_sqr_mode, mode)] print('(Sop, Bop) =', Sop, Bop) @@ -1728,10 +1827,10 @@ def grad_sqr(self, A, grad_sqr_mode, mode, left): def connection(self, rbase, key_base, mode, left): """ Compute required multivector connections of the form - (Einstein summation convention) e^{j}*(D_{j}e_{i_{1}...i_{r}}) - and (D_{j}e_{i_{1}...i_{r}})*e^{j} where * could be *, ^, |, - <, or > depending upon the mode and e^{j} are reciprocal - basis vectors + (Einstein summation convention) :math:`e^{j}*(D_{j}e_{i_{1}...i_{r}})` + and :math:`(D_{j}e_{i_{1}...i_{r}})*e^{j}` where :math:`*` could be + ``*``, ``^``, ``|``, ``<``, or ``>`` depending upon the mode, and + :math:`e^{j}` are reciprocal basis vectors. """ mode_key = (mode, left) keys = [i for i, j in self.connect[mode_key]] @@ -1803,26 +1902,33 @@ class Sm(Ga): the coordinates of the submanifold. The inputs required to define the submanifold are: - u {kargs[0]} The coordinate map defining the submanifold - which is a list of functions of coordinates of the base - manifold in terms of the coordinates of the submanifold. - for example if the manifold is a unit sphere then - - 'u = [sin(u)*cos(v),sin(u)*sin(v),cos(u)]'. - - Alternatively {kargs[0]} is a parametric vector function - of the basis vectors of the base manifold. The - coefficients of the bases are functions of the coordinates - {kargs[1]}. In this case we would call the submanifold - a "vector" manifold and additional characteristics of the - manifold can be calculated since we have given an explicit - embedding of the manifold in the base manifold. - - coords {kargs[1]} The coordinate list for the submanifold, for - example '[u,v]'. + Parameters + ---------- + u : + (``kargs[0]``) The coordinate map defining the submanifold + which is a list of functions of coordinates of the base + manifold in terms of the coordinates of the submanifold. + for example if the manifold is a unit sphere then - + ``u = [sin(u)*cos(v),sin(u)*sin(v),cos(u)]``. + + Alternatively (``kargs[0]``) is a parametric vector function + of the basis vectors of the base manifold. The + coefficients of the bases are functions of the coordinates + (``kargs[1]``). In this case we would call the submanifold + a "vector" manifold and additional characteristics of the + manifold can be calculated since we have given an explicit + embedding of the manifold in the base manifold. + + coords : + (``kargs[1]``) The coordinate list for the submanifold, for + example ``[u, v]``. + + Notes + ----- See 'init_slots' for possible other inputs. The 'Ga' member function 'sm' can be used to instantiate the submanifold via (o3d is the base - manifold) + manifold):: coords = (u,v) = symbols(',v',real=True) sm_example = o3d.sm([sin(u)*cos(v),sin(u)*sin(v),cos(u)],coords) From 01a73af5c4749469433bf916d9e674d4425c823c Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 19 Nov 2019 19:22:10 +0000 Subject: [PATCH 08/10] Rename kargs to args The typical python function signature is `f(*args, **kwargs)` not `f(*kargs, **kwargs)`. The `kw` in `kwargs` stands for `keyword`, but the first `k` doesn't mean anything. --- galgebra/ga.py | 66 +++++++++++----------- galgebra/lt.py | 16 +++--- galgebra/mv.py | 150 ++++++++++++++++++++++++------------------------- 3 files changed, 116 insertions(+), 116 deletions(-) diff --git a/galgebra/ga.py b/galgebra/ga.py index 991523ed..3a96d3fa 100644 --- a/galgebra/ga.py +++ b/galgebra/ga.py @@ -351,12 +351,12 @@ def com(A, B): return half * (A * B - B * A) @staticmethod - def build(*kargs, **kwargs): + def build(*args, **kwargs): """ Static method to instantiate geometric algebra and return geometric algebra, basis vectors, and grad operator as a tuple. """ - GA = Ga(*kargs, **kwargs) + GA = Ga(*args, **kwargs) basis = list(GA.mv()) return tuple([GA] + basis) @@ -369,7 +369,7 @@ def preset(setting, root='e', debug=False): X = symbols(set_lst[0], real=True) g = eval(set_lst[1]) simps = eval(set_lst[2]) - kargs = [root] + args = [root] kwargs = {'g': g, 'coords': X, 'debug': debug, 'I': True, 'gsym': False} if len(set_lst) > 3: @@ -379,7 +379,7 @@ def preset(setting, root='e', debug=False): kwargs[name] = eval(value) Ga.set_simp(*simps) - return Ga(*kargs, **kwargs) + return Ga(*args, **kwargs) def __eq__(self, ga): if self.name == ga.name: @@ -466,7 +466,7 @@ def __init__(self, bases, **kwargs): self.a = [] # List of dummy vectors for Mlt calculations self.agrads = {} # Gradient operator with respect to vector a - self.dslot = -1 # kargs slot for dervative, -1 for coordinates + self.dslot = -1 # args slot for dervative, -1 for coordinates self.XOX = self.mv('XOX','vector') # Versor test vector def make_grad(self, a, cmpflg=False): # make gradient operator with respect to vector a @@ -507,7 +507,7 @@ def X(self): def sdop(self, coefs, pdiffs=None): return mv.Sdop(coefs, pdiffs, ga=self) - def mv(self, root=None, *kargs, **kwargs): + def mv(self, root=None, *args, **kwargs): """ Instanciate and return a multivector for this, 'self', geometric algebra. @@ -522,18 +522,18 @@ def mv(self, root=None, *kargs, **kwargs): kwargs['ga'] = self if not utils.isstr(root): - return mv.Mv(root, *kargs, **kwargs) + return mv.Mv(root, *args, **kwargs) - if ' ' in root and ' ' not in kargs[0]: + if ' ' in root and ' ' not in args[0]: root_lst = root.split(' ') mv_lst = [] for root in root_lst: - mv_lst.append(mv.Mv(root, *kargs, **kwargs)) + mv_lst.append(mv.Mv(root, *args, **kwargs)) return tuple(mv_lst) - if ' ' in root and ' ' in kargs[0]: + if ' ' in root and ' ' in args[0]: root_lst = root.split(' ') - mvtype_lst = kargs[0].split(' ') + mvtype_lst = args[0].split(' ') if len(root_lst) != len(mvtype_lst): raise ValueError('In Ga.mv() for multiple multivectors and ' + 'multivector types incompatible args ' + @@ -541,13 +541,13 @@ def mv(self, root=None, *kargs, **kwargs): mv_lst = [] for (root, mv_type) in zip(root_lst, mvtype_lst): - kargs = list(kargs) - kargs[0] = mv_type - kargs = tuple(kargs) - mv_lst.append(mv.Mv(root, *kargs, **kwargs)) + args = list(args) + args[0] = mv_type + args = tuple(args) + mv_lst.append(mv.Mv(root, *args, **kwargs)) return tuple(mv_lst) - return mv.Mv(root, *kargs, **kwargs) + return mv.Mv(root, *args, **kwargs) def mvr(self,norm=True): r""" @@ -602,15 +602,15 @@ def grads(self): self.rgrad = mv.Dop(r_basis, pdx, ga=self, cmpflg=True) return self.grad, self.rgrad - def dop(self, *kargs, **kwargs): + def dop(self, *args, **kwargs): """ Instanciate and return a multivector differential operator for this, 'self', geometric algebra. """ kwargs['ga'] = self - return mv.Dop(*kargs, **kwargs) + return mv.Dop(*args, **kwargs) - def lt(self, *kargs, **kwargs): + def lt(self, *args, **kwargs): """ Instanciate and return a linear transformation for this, 'self', geometric algebra. @@ -620,15 +620,15 @@ def lt(self, *kargs, **kwargs): (self.lt_coords, self.lt_x) = lt.Lt.setup(ga=self) kwargs['ga'] = self - return lt.Lt(*kargs, **kwargs) + return lt.Lt(*args, **kwargs) - def sm(self, *kargs, **kwargs): + def sm(self, *args, **kwargs): """ Instanciate and return a submanifold for this geometric algebra. See :class:`Sm` for instantiation inputs. """ kwargs['ga'] = self - SM = Sm(*kargs, **kwargs) + SM = Sm(*args, **kwargs) return SM def parametric(self, coords): @@ -1717,8 +1717,8 @@ def blade_derivation(self, blade, ib): self.dbases[key] = db return db - def pdop(self,*kargs): - return mv.Pdop(kargs,ga=self) + def pdop(self,*args): + return mv.Pdop(args,ga=self) def pDiff(self, A, coord): """ @@ -1891,8 +1891,8 @@ def ReciprocalFrame(self, basis, mode='norm'): return tuple(rbasis) - def Mlt(self,*kargs,**kwargs): - return lt.Mlt(kargs[0], self, *kargs[1:], **kwargs) + def Mlt(self,*args,**kwargs): + return lt.Mlt(args[0], self, *args[1:], **kwargs) class Sm(Ga): """ @@ -1905,22 +1905,22 @@ class Sm(Ga): Parameters ---------- u : - (``kargs[0]``) The coordinate map defining the submanifold + (``args[0]``) The coordinate map defining the submanifold which is a list of functions of coordinates of the base manifold in terms of the coordinates of the submanifold. for example if the manifold is a unit sphere then - ``u = [sin(u)*cos(v),sin(u)*sin(v),cos(u)]``. - Alternatively (``kargs[0]``) is a parametric vector function + Alternatively (``args[0]``) is a parametric vector function of the basis vectors of the base manifold. The coefficients of the bases are functions of the coordinates - (``kargs[1]``). In this case we would call the submanifold + (``args[1]``). In this case we would call the submanifold a "vector" manifold and additional characteristics of the manifold can be calculated since we have given an explicit embedding of the manifold in the base manifold. coords : - (``kargs[1]``) The coordinate list for the submanifold, for + (``args[1]``) The coordinate list for the submanifold, for example ``[u, v]``. Notes @@ -1942,7 +1942,7 @@ class Sm(Ga): 'norm': (False, 'Normalize basis if True'), 'ga': (None, 'Base Geometric Algebra')} - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): #print '!!!Enter Sm!!!' @@ -1951,8 +1951,8 @@ def __init__(self, *kargs, **kwargs): Ga.restore = True kwargs = metric.test_init_slots(Sm.init_slots, **kwargs) - u = kargs[0] # Coordinate map or vector embedding to define submanifold - coords = kargs[1] # List of cordinates + u = args[0] # Coordinate map or vector embedding to define submanifold + coords = args[1] # List of cordinates ga = kwargs['ga'] # base geometric algebra if ga is None: raise ValueError('Base geometric algebra must be specified for submanifold.') diff --git a/galgebra/lt.py b/galgebra/lt.py index 48cf8898..2b5cc618 100644 --- a/galgebra/lt.py +++ b/galgebra/lt.py @@ -130,7 +130,7 @@ def format(mat_fmt=False): Lt.mat_fmt = mat_fmt return - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): """ Except for the spinor representation the linear transformation is stored as a dictionary with basis vector keys and vector @@ -157,7 +157,7 @@ def __init__(self, *kargs, **kwargs): kwargs = metric.test_init_slots(Lt.init_slots, **kwargs) - mat_rep = kargs[0] + mat_rep = args[0] ga = kwargs['ga'] self.fct_flg = kwargs['f'] self.mode = kwargs['mode'] # General g, s, or a transformation @@ -488,7 +488,7 @@ def matrix(self): class Mlt(object): """ A multilinear transformation (mlt) is a multilinear multivector function of - a list of vectors (*kargs) F(v_1,...,v_r) where for any argument slot + a list of vectors (*args) F(v_1,...,v_r) where for any argument slot j we have (a is a scalar and u_j a vector) F(v_1,...,a*v_j,...,v_r) = a*F(v_1,...,v_j,...,v_r) F(v_1,...,v_j+u_j,...,v_r) = F(v_1,...,v_j,...,v_r) + F(v_1,...,u_j,...,v_r). @@ -729,7 +729,7 @@ def __init__(self, f, Ga, args, fct=False): self.fvalue += coef * a_prod else: if isinstance(f, types.FunctionType): # Tensor defined by general multi-linear function - args, _kargs, _kwargs, _defaults = inspect.getargspec(f) + args, _varargs, _kwargs, _defaults = inspect.getargspec(f) self.nargs = len(args) self.f = f Mlt.increment_slots(self.nargs, Ga) @@ -747,14 +747,14 @@ def __str__(self): Printer = printer.GaPrinter return Printer().doprint(self) - def __call__(self, *kargs): - if len(kargs) == 0: + def __call__(self, *args): + if len(args) == 0: return self.fvalue if self.f is not None: - return self.f(*kargs) + return self.f(*args) else: sub_lst = [] - for (x, ai) in zip(kargs, self.Ga.pdiffs): + for (x, ai) in zip(args, self.Ga.pdiffs): for (r_base, aij) in zip(self.Ga.r_basis_mv, ai): sub_lst.append((aij, (r_base | x).scalar())) return self.fvalue.subs(sub_lst,simultaneous=True) diff --git a/galgebra/mv.py b/galgebra/mv.py index 6ca14be9..a51414af 100644 --- a/galgebra/mv.py +++ b/galgebra/mv.py @@ -176,13 +176,13 @@ def characterise_Mv(self): self.char_Mv = True return - def make_grade(self, *kargs, **kwargs): + def make_grade(self, *args, **kwargs): # Called by __init__ to make a pure grade multivector. - grade = kargs[1] + grade = args[1] self.i_grade = grade - if utils.isstr(kargs[0]): - root = kargs[0] + '__' + if utils.isstr(args[0]): + root = args[0] + '__' if isinstance(kwargs['f'], bool) and not kwargs['f']: #Is a constant mulitvector function self.obj = sum([Symbol(root + super_script, real=True) * base for (super_script, base) in zip(self.Ga.blade_super_scripts[grade], self.Ga.blades[grade])]) @@ -195,80 +195,80 @@ def make_grade(self, *kargs, **kwargs): self.obj = sum([Function(root + super_script, real=True)(*kwargs['f']) * base for (super_script, base) in zip(self.Ga.blade_super_scripts[grade], self.Ga.blades[grade])]) else: - if isinstance(kargs[0],(list,tuple)): - if len(kargs[0]) <= len(self.Ga.blades[grade]): + if isinstance(args[0],(list,tuple)): + if len(args[0]) <= len(self.Ga.blades[grade]): self.obj = sum([coef * base - for (coef, base) in zip(kargs[0], self.Ga.blades[grade][:len(kargs[0])])]) + for (coef, base) in zip(args[0], self.Ga.blades[grade][:len(args[0])])]) else: pass else: pass return - def make_scalar(self, *kargs, **kwargs): + def make_scalar(self, *args, **kwargs): # Called by __init__ to make a scalar multivector - if utils.isstr(kargs[0]): + if utils.isstr(args[0]): if 'f' in kwargs and isinstance(kwargs['f'],bool): if kwargs['f']: - self.obj = Function(kargs[0])(*self.Ga.coords) + self.obj = Function(args[0])(*self.Ga.coords) else: - self.obj = Symbol(kargs[0], real=True) + self.obj = Symbol(args[0], real=True) else: if 'f' in kwargs and isinstance(kwargs['f'],tuple): - self.obj = Function(kargs[0])(*kwargs['f']) + self.obj = Function(args[0])(*kwargs['f']) else: - self.obj = kargs[0] + self.obj = args[0] return - def make_vector(self, *kargs, **kwargs): + def make_vector(self, *args, **kwargs): # Called by __init__ to make a vector multivector - self.make_grade(*(kargs[0], 1), **kwargs) + self.make_grade(*(args[0], 1), **kwargs) return - def make_bivector(self, *kargs, **kwargs): + def make_bivector(self, *args, **kwargs): # Called by __init__ to make a bivector multivector - self.make_grade(*(kargs[0], 2), **kwargs) + self.make_grade(*(args[0], 2), **kwargs) return - def make_pseudo_scalar(self, *kargs, **kwargs): + def make_pseudo_scalar(self, *args, **kwargs): # Called by __init__ to make a pseudo scalar multivector - self.make_grade(*(kargs[0], self.Ga.n), **kwargs) + self.make_grade(*(args[0], self.Ga.n), **kwargs) return - def make_multivector(self, *kargs, **kwargs): + def make_multivector(self, *args, **kwargs): # Called by __init__ to make a general (2**n components) multivector - self.make_scalar(kargs[0], **kwargs) + self.make_scalar(args[0], **kwargs) tmp = self.obj for grade in self.Ga.n_range: - self.make_grade(*(kargs[0], grade + 1), **kwargs) + self.make_grade(*(args[0], grade + 1), **kwargs) tmp += self.obj self.obj = tmp return - def make_spinor(self, *kargs, **kwargs): + def make_spinor(self, *args, **kwargs): # Called by __init__ to make a general even (spinor) multivector - self.make_scalar(kargs[0], **kwargs) + self.make_scalar(args[0], **kwargs) tmp = self.obj for grade in self.Ga.n_range: if (grade + 1) % 2 == 0: - self.make_grade(*(kargs[0], grade + 1), **kwargs) + self.make_grade(*(args[0], grade + 1), **kwargs) tmp += self.obj self.obj = tmp return - def make_odd(self, *kargs, **kwargs): + def make_odd(self, *args, **kwargs): # Called by __init__ to make a general odd multivector - self.make_scalar(kargs[0], **kwargs) + self.make_scalar(args[0], **kwargs) tmp = S(0) for grade in self.Ga.n_range: if (grade + 1) % 2 == 1: - self.make_grade(*(kargs[0], grade + 1), **kwargs) + self.make_grade(*(args[0], grade + 1), **kwargs) tmp += self.obj self.obj = tmp return @@ -284,7 +284,7 @@ def make_odd(self, *kargs, **kwargs): 'odd': make_odd, 'grade': make_grade} - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): if 'ga' not in kwargs: raise ValueError("Geometric algebra key inplut 'ga' required") @@ -303,11 +303,11 @@ def __init__(self, *kargs, **kwargs): self.coords = self.Ga.coords self.title = None - if len(kargs) == 0: # default constructor 0 + if len(args) == 0: # default constructor 0 self.obj = S(0) self.i_grade = 0 - elif len(kargs) == 1 and not utils.isstr(kargs[0]): # copy constructor - x = kargs[0] + elif len(args) == 1 and not utils.isstr(args[0]): # copy constructor + x = args[0] if isinstance(x, Mv): self.obj = x.obj self.is_blade_rep = x.is_blade_rep @@ -320,22 +320,22 @@ def __init__(self, *kargs, **kwargs): self.is_blade_rep = True self.characterise_Mv() else: - if not isinstance(kargs[1],int): - if utils.isstr(kargs[1]) and kargs[1] not in Mv.init_dict: - raise ValueError('"' + str(kargs[1]) + '" not an allowed multivector type.') - - if utils.isstr(kargs[1]): - mode = kargs[1] - kargs = [kargs[0]] + list(kargs[2:]) - Mv.init_dict[mode](self, *kargs, **kwargs) - else: # kargs[1] = r (integer) Construct grade r multivector - if kargs[1] == 0: - Mv.init_dict['scalar'](self, *kargs, **kwargs) + if not isinstance(args[1],int): + if utils.isstr(args[1]) and args[1] not in Mv.init_dict: + raise ValueError('"' + str(args[1]) + '" not an allowed multivector type.') + + if utils.isstr(args[1]): + mode = args[1] + args = [args[0]] + list(args[2:]) + Mv.init_dict[mode](self, *args, **kwargs) + else: # args[1] = r (integer) Construct grade r multivector + if args[1] == 0: + Mv.init_dict['scalar'](self, *args, **kwargs) else: - Mv.init_dict['grade'](self, *kargs, **kwargs) + Mv.init_dict['grade'](self, *args, **kwargs) - if utils.isstr(kargs[0]): - self.title = kargs[0] + if utils.isstr(args[0]): + self.title = args[0] self.characterise_Mv() ################# Multivector member functions ##################### @@ -1569,7 +1569,7 @@ def __str__(self): def __repr__(self): return str(self) - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): """ The scalar differential operator structure is of the form (Einstein summation) @@ -1591,19 +1591,19 @@ def __init__(self, *kargs, **kwargs): else: self.Ga = Sdop.ga - if len(kargs[0]) == 0: # identity Dop + if len(args[0]) == 0: # identity Dop self.terms = [(S(1), self.Ga.Pdop_identity)] - elif len(kargs[0]) == 1 and isinstance(kargs[0],Symbol): # Simple Pdop of order 1 - self.terms = [(S(1), self.Ga.pdop(kargs[0]))] + elif len(args[0]) == 1 and isinstance(args[0],Symbol): # Simple Pdop of order 1 + self.terms = [(S(1), self.Ga.pdop(args[0]))] else: - if len(kargs) == 2 and isinstance(kargs[0],list) and isinstance(kargs[1],list): - if len(kargs[0]) != len(kargs[1]): + if len(args) == 2 and isinstance(args[0],list) and isinstance(args[1],list): + if len(args[0]) != len(args[1]): raise ValueError('In Sdop.__init__ coefficent list and Pdop list must be same length.') - self.terms = list(zip(kargs[0],kargs[1])) - elif len(kargs) == 1 and isinstance(kargs[0],list): - self.terms = kargs[0] + self.terms = list(zip(args[0],args[1])) + elif len(args) == 1 and isinstance(args[0],list): + self.terms = args[0] else: - raise ValueError('In Sdop.__init__ length of kargs must be 1 or 2 kargs = '+str(kargs)) + raise ValueError('In Sdop.__init__ length of args must be 1 or 2 args = '+str(args)) def __call__(self, arg): if isinstance(arg, Sdop): @@ -1807,7 +1807,7 @@ def __eq__(self,A): return True return False - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): """ The partial differential operator is a partial derivative with respect to a set of real symbols (variables). The allowed @@ -1832,14 +1832,14 @@ def __init__(self, *kargs, **kwargs): else: self.Ga = Pdop.ga # use geometric algebra of class Pdop - if kargs[0] is None: # Pdop is the identity (1) + if args[0] is None: # Pdop is the identity (1) self.pdiffs = {} - elif isinstance(kargs[0], dict): # Pdop defined by dictionary - self.pdiffs = kargs[0] - elif isinstance(kargs[0],Symbol): # First order derivative with respect to symbol - self.pdiffs = {kargs[0]:1} + elif isinstance(args[0], dict): # Pdop defined by dictionary + self.pdiffs = args[0] + elif isinstance(args[0],Symbol): # First order derivative with respect to symbol + self.pdiffs = {args[0]:1} else: - raise ValueError('In pdop kargs = ', str(kargs)) + raise ValueError('In pdop args = ', str(args)) for x in list(self.pdiffs.keys()): # self.order is total number of differentiations self.order += self.pdiffs[x] @@ -2036,7 +2036,7 @@ def setGa(ga): # set geometric algebra globally for all Dop's def flatten_one_level(lst): return [inner for outer in lst for inner in outer] - def __init__(self, *kargs, **kwargs): + def __init__(self, *args, **kwargs): kwargs = metric.test_init_slots(Dop.init_slots, **kwargs) @@ -2052,20 +2052,20 @@ def __init__(self, *kargs, **kwargs): self.dop_fmt = kwargs['fmt_dop'] # Partial derivative output format (default 1) self.title = None - if len(kargs[0]) == 0: # identity Dop + if len(args[0]) == 0: # identity Dop self.terms = [(S(1),self.Ga.Pdop_identity)] else: - if len(kargs) == 2: - if len(kargs[0]) != len(kargs[1]): + if len(args) == 2: + if len(args[0]) != len(args[1]): raise ValueError('In Dop.__init__ coefficent list and Pdop list must be same length.') - self.terms = list(zip(kargs[0],kargs[1])) - elif len(kargs) == 1: - if isinstance(kargs[0][0][0], Mv): # Mv expansion [(Mv, Pdop)] - self.terms = kargs[0] - elif isinstance(kargs[0][0][0], Sdop): # Sdop expansion [(Sdop, Mv)] + self.terms = list(zip(args[0],args[1])) + elif len(args) == 1: + if isinstance(args[0][0][0], Mv): # Mv expansion [(Mv, Pdop)] + self.terms = args[0] + elif isinstance(args[0][0][0], Sdop): # Sdop expansion [(Sdop, Mv)] coefs = [] pdiffs = [] - for (sdop, mv) in kargs[0]: + for (sdop, mv) in args[0]: for (coef, pdiff) in sdop.terms: if pdiff in pdiffs: index = pdiffs.index(pdiff) @@ -2075,9 +2075,9 @@ def __init__(self, *kargs, **kwargs): coefs.append(coef * mv) self.terms = list(zip(coefs, pdiffs)) else: - raise ValueError('In Dop.__init__ kargs[0] form not allowed. kargs = ' + str(kargs)) + raise ValueError('In Dop.__init__ args[0] form not allowed. args = ' + str(args)) else: - raise ValueError('In Dop.__init__ length of kargs must be 1 or 2.') + raise ValueError('In Dop.__init__ length of args must be 1 or 2.') def simplify(self, modes=simplify): From e43673c13539cec4ac76ce0a71b174ec7afbfa49 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 19 Nov 2019 19:26:01 +0000 Subject: [PATCH 09/10] Remove redundant argument unpacking `f(*(a, b), c)` is just a weird way to spell `f(a, b, c)`. --- galgebra/mv.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/galgebra/mv.py b/galgebra/mv.py index a51414af..63d74704 100644 --- a/galgebra/mv.py +++ b/galgebra/mv.py @@ -224,19 +224,19 @@ def make_scalar(self, *args, **kwargs): def make_vector(self, *args, **kwargs): # Called by __init__ to make a vector multivector - self.make_grade(*(args[0], 1), **kwargs) + self.make_grade(args[0], 1, **kwargs) return def make_bivector(self, *args, **kwargs): # Called by __init__ to make a bivector multivector - self.make_grade(*(args[0], 2), **kwargs) + self.make_grade(args[0], 2, **kwargs) return def make_pseudo_scalar(self, *args, **kwargs): # Called by __init__ to make a pseudo scalar multivector - self.make_grade(*(args[0], self.Ga.n), **kwargs) + self.make_grade(args[0], self.Ga.n, **kwargs) return def make_multivector(self, *args, **kwargs): @@ -245,7 +245,7 @@ def make_multivector(self, *args, **kwargs): self.make_scalar(args[0], **kwargs) tmp = self.obj for grade in self.Ga.n_range: - self.make_grade(*(args[0], grade + 1), **kwargs) + self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp return @@ -257,7 +257,7 @@ def make_spinor(self, *args, **kwargs): tmp = self.obj for grade in self.Ga.n_range: if (grade + 1) % 2 == 0: - self.make_grade(*(args[0], grade + 1), **kwargs) + self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp return @@ -268,7 +268,7 @@ def make_odd(self, *args, **kwargs): tmp = S(0) for grade in self.Ga.n_range: if (grade + 1) % 2 == 1: - self.make_grade(*(args[0], grade + 1), **kwargs) + self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp return From 4918d51bd053bc133dc21aa954d59b980cc67c39 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Wed, 20 Nov 2019 14:40:22 +0000 Subject: [PATCH 10/10] Cleanup `Mv.make_` functions Strips leading blank lines, no-op returns, and indents comments --- galgebra/mv.py | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/galgebra/mv.py b/galgebra/mv.py index 63d74704..2ba51e54 100644 --- a/galgebra/mv.py +++ b/galgebra/mv.py @@ -177,8 +177,7 @@ def characterise_Mv(self): return def make_grade(self, *args, **kwargs): - # Called by __init__ to make a pure grade multivector. - + # Called by __init__ to make a pure grade multivector. grade = args[1] self.i_grade = grade if utils.isstr(args[0]): @@ -203,11 +202,9 @@ def make_grade(self, *args, **kwargs): pass else: pass - return def make_scalar(self, *args, **kwargs): - # Called by __init__ to make a scalar multivector - + # Called by __init__ to make a scalar multivector if utils.isstr(args[0]): if 'f' in kwargs and isinstance(kwargs['f'],bool): if kwargs['f']: @@ -219,40 +216,30 @@ def make_scalar(self, *args, **kwargs): self.obj = Function(args[0])(*kwargs['f']) else: self.obj = args[0] - return def make_vector(self, *args, **kwargs): - # Called by __init__ to make a vector multivector - + # Called by __init__ to make a vector multivector self.make_grade(args[0], 1, **kwargs) - return def make_bivector(self, *args, **kwargs): - # Called by __init__ to make a bivector multivector - + # Called by __init__ to make a bivector multivector self.make_grade(args[0], 2, **kwargs) - return def make_pseudo_scalar(self, *args, **kwargs): - # Called by __init__ to make a pseudo scalar multivector - + # Called by __init__ to make a pseudo scalar multivector self.make_grade(args[0], self.Ga.n, **kwargs) - return def make_multivector(self, *args, **kwargs): - # Called by __init__ to make a general (2**n components) multivector - + # Called by __init__ to make a general (2**n components) multivector self.make_scalar(args[0], **kwargs) tmp = self.obj for grade in self.Ga.n_range: self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp - return def make_spinor(self, *args, **kwargs): - # Called by __init__ to make a general even (spinor) multivector - + # Called by __init__ to make a general even (spinor) multivector self.make_scalar(args[0], **kwargs) tmp = self.obj for grade in self.Ga.n_range: @@ -260,10 +247,9 @@ def make_spinor(self, *args, **kwargs): self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp - return def make_odd(self, *args, **kwargs): - # Called by __init__ to make a general odd multivector + # Called by __init__ to make a general odd multivector self.make_scalar(args[0], **kwargs) tmp = S(0) for grade in self.Ga.n_range: @@ -271,7 +257,6 @@ def make_odd(self, *args, **kwargs): self.make_grade(args[0], grade + 1, **kwargs) tmp += self.obj self.obj = tmp - return init_dict = {'scalar': make_scalar, 'vector': make_vector,