<commit_before># -*- coding: utf-8 -*-
"""
Created on Tue Sep 03 17:44:46 2013

@author: <NAME> (original Code)
@author: <NAME> (enhancements)
"""

from sympy import Function, diff
from sympy.matrices import zeros
from itertools import combinations
import numpy as np
import sympy as sp
import itertools as it

#from ipHelp import IPS

## Vorzeichen einer Permutation
# original-Algorithmus -> liefert manchmal 0 bei längeren Permutationen
# -> durch vorherige Anwendung von 'range_indices' behoben

# TODO: evtl darauf zurückgreifen:
# from sympy.functions.special.tensor_functions import eval_levicivita
# das hat aber auch Probleme mit nicht-Konsekutiven Indizes
def sign_perm(perm):
    perm = range_indices(perm)
    Np = len(np.array(perm))
    sgn = 1
    for n in range(Np - 1):
        for m in range(n + 1,Np):
            sgn *= 1. * (perm[m]  - perm[n]) / (m - n)
    sgn = int(sgn)
#    if not sgn in (-1, 1):
#        IPS()
    assert sgn in (-1, 1), "error %s" %perm

    return sgn


def range_indices(seq):
    """
    returns a tuple which represents the same permutation
    but with indices from range(N)
    (5, 2, 10, 1) -> (2, 1, 3, 0)
    """
    assert len(set(seq)) == len(seq)

    #assert False
    # range_indices((0, 1, 3, 8, 2, 4))

    new_elements = range(len(seq))

    res = [None]* len(seq)

    seq = list(seq)
    seq_work = list(seq)

    for i in range(len(seq)):
        m1 = min(seq_work)
        m2 = min(new_elements)

        i = seq.index(m1)
        res[i] = m2

        seq_work.remove(m1)
        new_elements.remove(m2)

#    tuples = list(enumerate(seq))
#    tuples.sort(key = lambda x: x[1])
#    res = zip(*tuples)[0]
    assert not None in res
    return res


def perm_parity(seq):
    '''\
    Given a permutation of the digits 0..N in order as a list,
    returns its parity (or sign): +1 for even parity; -1 for odd.
    '''
    # adapted from http://code.activestate.com/
    # recipes/578227-generate-the-parity-or-sign-of-a-permutation/
    # by <NAME>
    lst = range_indices(seq) # normalize the sequence to the first N integers
    parity = 1
    index_list = range(len(lst))
    for i in range(0,len(lst)-1):
        if lst[i] != i:
            # there must be a smaller number in the remaining list
            # -> perform an exchange
#            print i, lst
            mn = np.argmin(lst[i:]) + i
            lst[i],lst[mn] = lst[mn],lst[i]
#            print mn, lst
            parity *= -1
    return parity


class DifferentialForm:
    def __init__(self, n, basis, koeff=None, name=None):
        """
        :n: degree
        :basis: list of basis coordinates (Symbols)

        """
        # Grad der Differentialform
        self.grad = n
        # Basis der Differentialform
        self.basis = basis
        # Dimension der Basis
        self.dim_basis = len(basis)
        # Liste zulässiger Indizes
        if(self.grad == 0):
            self.indizes = [(0,)]
        else:
            # this is a list like [(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)]
            #TODO: this should be renamed to index_tuples
            self.indizes = list(combinations(range(self.dim_basis),self.grad))


        # Anzahl der Koeffizienten der Differentialform
        self.num_koeff = len(self.indizes)
        # Koeffizienten der Differentialform
        if koeff == None:
            self.koeff = zeros(self.num_koeff,1)
        else:
            assert len(koeff) == self.num_koeff
            self.koeff = sp.Matrix(koeff).reshape(self.num_koeff, 1)

        self.name = name # usefull for symb_tools.make_global


    # TODO: the property should be named coeff instead of koeff
    # quick hack combine new name with backward compability
    @property
    def coeff(self):
        return self.koeff


    def __repr__(self):
        return self.ausgabe()

    def __add__(self, a):


        assert self.grad == a.grad
        assert self.basis == a.basis

        new_form = DifferentialForm(self.grad, self.basis)
        new_form.koeff = self.koeff + a.koeff

        return new_form


    def __sub__(self, m):

        return self + (m*(-1))


    def __rmul__(self, f):
        """scalar multiplication from the left (reverse mul)"""
        # use commutativity
        return self*f


    def __mul__(self, f):
        """ scalar multipplication"""
        new_form = DifferentialForm(self.grad, self.basis)

        new_form.koeff = self.koeff*f
        return new_form

    def __eq__(self, other):
        """test for equality"""
        assert isinstance(other, DifferentialForm)
        assert self.basis == other.basis
        if self.grad == other.grad:
            return self.koeff == other.koeff
        else: return False


    def __neg__(self):
        return -1*self

    def __getitem__(self,ind):
        """Koeffizient der Differentialform zuweisen"""
        assert len(ind) == self.grad
        try:
            ind_1d, vz = self.__getindexperm__(ind)
        except ValueError:
            print u'invalid Index'
            return None
        else:
            return vz * self.koeff[ind_1d]

    def __setitem__(self,ind,wert):
        """Koeffizient der Differentialform abrufen"""
        ind = np.atleast_1d(ind)
        assert len(ind) == self.grad<commit_msg>Add: __xor__ Methode (Ermöglicht Notation: dx1^dx2)<commit_after># -*- coding: utf-8 -*-
"""
Created on Tue Sep 03 17:44:46 2013

@author: <NAME> (original Code)
@author: <NAME> (enhancements)
"""

from sympy import Function, diff
from sympy.matrices import zeros
from itertools import combinations
import numpy as np
import sympy as sp
import itertools as it

#from ipHelp import IPS

## Vorzeichen einer Permutation
# original-Algorithmus -> liefert manchmal 0 bei längeren Permutationen
# -> durch vorherige Anwendung von 'range_indices' behoben

# TODO: evtl darauf zurückgreifen:
# from sympy.functions.special.tensor_functions import eval_levicivita
# das hat aber auch Probleme mit nicht-Konsekutiven Indizes
def sign_perm(perm):
    perm = range_indices(perm)
    Np = len(np.array(perm))
    sgn = 1
    for n in range(Np - 1):
        for m in range(n + 1,Np):
            sgn *= 1. * (perm[m]  - perm[n]) / (m - n)
    sgn = int(sgn)
#    if not sgn in (-1, 1):
#        IPS()
    assert sgn in (-1, 1), "error %s" %perm

    return sgn


def range_indices(seq):
    """
    returns a tuple which represents the same permutation
    but with indices from range(N)
    (5, 2, 10, 1) -> (2, 1, 3, 0)
    """
    assert len(set(seq)) == len(seq)

    #assert False
    # range_indices((0, 1, 3, 8, 2, 4))

    new_elements = range(len(seq))

    res = [None]* len(seq)

    seq = list(seq)
    seq_work = list(seq)

    for i in range(len(seq)):
        m1 = min(seq_work)
        m2 = min(new_elements)

        i = seq.index(m1)
        res[i] = m2

        seq_work.remove(m1)
        new_elements.remove(m2)

#    tuples = list(enumerate(seq))
#    tuples.sort(key = lambda x: x[1])
#    res = zip(*tuples)[0]
    assert not None in res
    return res


def perm_parity(seq):
    '''\
    Given a permutation of the digits 0..N in order as a list,
    returns its parity (or sign): +1 for even parity; -1 for odd.
    '''
    # adapted from http://code.activestate.com/
    # recipes/578227-generate-the-parity-or-sign-of-a-permutation/
    # by <NAME>
    lst = range_indices(seq) # normalize the sequence to the first N integers
    parity = 1
    index_list = range(len(lst))
    for i in range(0,len(lst)-1):
        if lst[i] != i:
            # there must be a smaller number in the remaining list
            # -> perform an exchange
#            print i, lst
            mn = np.argmin(lst[i:]) + i
            lst[i],lst[mn] = lst[mn],lst[i]
#            print mn, lst
            parity *= -1
    return parity


class DifferentialForm:
    def __init__(self, n, basis, koeff=None, name=None):
        """
        :n: degree
        :basis: list of basis coordinates (Symbols)

        """
        # Grad der Differentialform
        self.grad = n
        # Basis der Differentialform
        self.basis = basis
        # Dimension der Basis
        self.dim_basis = len(basis)
        # Liste zulässiger Indizes
        if(self.grad == 0):
            self.indizes = [(0,)]
        else:
            # this is a list like [(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)]
            #TODO: this should be renamed to index_tuples
            self.indizes = list(combinations(range(self.dim_basis),self.grad))


        # Anzahl der Koeffizienten der Differentialform
        self.num_koeff = len(self.indizes)
        # Koeffizienten der Differentialform
        if koeff == None:
            self.koeff = zeros(self.num_koeff,1)
        else:
            assert len(koeff) == self.num_koeff
            self.koeff = sp.Matrix(koeff).reshape(self.num_koeff, 1)

        self.name = name # usefull for symb_tools.make_global


    # TODO: the property should be named coeff instead of koeff
    # quick hack combine new name with backward compability
    @property
    def coeff(self):
        return self.koeff


    def __repr__(self):
        return self.ausgabe()

    def __add__(self, a):
        assert self.grad == a.grad
        assert self.basis == a.basis

        new_form = DifferentialForm(self.grad, self.basis)
        new_form.koeff = self.koeff + a.koeff

        return new_form


    def __sub__(self, m):

        return self + (m*(-1))


    def __rmul__(self, f):
        """scalar multiplication from the left (reverse mul)"""
        # use commutativity
        return self*f


    def __mul__(self, f):
        """ scalar multipplication"""
        new_form = DifferentialForm(self.grad, self.basis)

        new_form.koeff = self.koeff*f
        return new_form

    def __xor__(self, f):
        """ overload ^-operator with wedge product """
        return self.wp(f)

    def __eq__(self, other):
        """test for equality"""
        assert isinstance(other, DifferentialForm)
        assert self.basis == other.basis
        if self.grad == other.grad:
            return self.koeff == other.koeff
        else: return False


    def __neg__(self):
        return -1*self

    def __getitem__(self,ind):
        """Koeffizient der Differentialform zuweisen"""
        assert len(ind) == self.grad
        try:
            ind_1d, vz = self.__getindexperm__(ind)
        except ValueError:
            print u'invalid Index'
            return None
        else:
            return vz * self.koeff[ind_1d]

    def __setitem__(self,ind,wert):
        """Koeffizient der Differentialform abrufen"""
        ind = np.atleast_1d(ind)
        assert len(ind) == self.grad
{'fraction_non_alphanumeric': 0.11339820359281437, 'fraction_numerical': 0.014970059880239521, 'mean_word_length': 2.218608852755194, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5139445', 'n_tokens_mistral': 3722, 'n_tokens_neox': 3479, 'n_words': 1006}