# Source code for sympy.galgebra.stringarrays

# sympy/galgebra/stringarrays.py

"""
stringarrays.py are a group of helper functions to convert string
input to vector and multivector class function to arrays of SymPy
symbols.
"""

import operator

from functools import reduce
from itertools import combinations

from sympy import S, Symbol, Function

[docs]def str_array(base, n=None):
"""
Generate one dimensional (list of strings) or two dimensional (list
of list of strings) string array.

For one dimensional arrays: -

base is string of variable names separated by blanks such as
base = 'a b c' which produces the string list ['a','b','c'] or
it is a string with no blanks than in conjunction with the
integer n generates -

str_array('v',n=-3) = ['v_1','v_2','v_3']
str_array('v',n=3) = ['v__1','v__2','v__3'].

In the case of LaTeX printing the '_' would give a subscript and
the '__' a super script.

For two dimensional arrays: -

base is string where elements are separated by spaces and rows by
commas so that -

str_array('a b,c d') = [['a','b'],['c','d']]

"""
if n is None:
if ',' in base:
base_array = []
base_split = base.split(',')
for base_arg in base_split:
base_array.append(list(filter(lambda x: x != '', base_arg.split(' '))))
return base_array
else:
return base.split(' ')
result = []
if isinstance(n, str):
if n[0] == '-':
for index in n[1:].split(' '):
result.append(base + '_' + index)
if n[0] == '+':
for index in n[1:].split(' '):
result.append(base + '__' + index)
if n > 0:
for i in range(1, n + 1):
result.append(base + '__' + str(i))
if n < 0:
for i in range(1, -n + 1):
result.append(base + '_' + str(i))
return result

[docs]def symbol_array(base, n=None):
"""
Generates a string arrary with str_array and replaces each string in
array with Symbol of same name.
"""
symbol_str_lst = str_array(base, n)
result = []
for symbol_str in symbol_str_lst:
result.append(S(symbol_str))
return tuple(result)

[docs]def fct_sym_array(str_lst, coords=None):
"""
Construct list of symbols or functions with names in 'str_lst'.  If
'coords' are given (tuple of symbols) function list constructed,
otherwise a symbol list is constructed.
"""
if coords is None:
fs_lst = []
for sym_str in str_lst:
fs_lst.append(Symbol(sym_str))
else:
fs_lst = []
for fct_str in str_lst:
fs_lst.append(Function(fct_str)(*coords))
return fs_lst

[docs]def str_combinations(base, lst, rank=1, mode='_'):
"""
Construct a list of strings of the form 'base+mode+indexes' where the
indexes are formed by converting 'lst' to a list of strings and then
forming the 'indexes' by concatenating combinations of elements from
'lst' taken 'rank' at a time.
"""
str_lst = list(map(lambda x: base + mode + x, map(lambda x: reduce(operator.add, x),
combinations(map(lambda x: str(x), lst), rank))))
return str_lst