Page MenuHomec4science

hash_derivative.py
No OneTemporary

File Metadata

Created
Sun, Nov 24, 13:01

hash_derivative.py

# Copyright (C) 2018-2020 by the RROMPy authors
#
# This file is part of RROMPy.
#
# RROMPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RROMPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with RROMPy. If not, see <http://www.gnu.org/licenses/>.
#
from copy import deepcopy as copy
import numpy as np
from rrompy.utilities.base.types import List
from rrompy.utilities.exception_manager import RROMPyException
from .degree import degreeToDOFs
__all__ = ['nextDerivativeIndices', 'hashDerivativeToIdx',
'hashIdxToDerivative']
def nextDerivativeIndices(derIdxs:List[List[int]], dim:int,
count : int = 1) -> List[List[int]]:
out = []
if count <= 0: return out
derIdxs = copy(derIdxs)
sumDer, sumInverse, sumCount = np.unique(
[np.sum(derIdx) for derIdx in derIdxs],
return_inverse = True, return_counts = True)
if len(derIdxs) == 0 or 0 not in sumDer:
out += [[0] * dim]
count -= 1
if count <= 0: return out
derIdxs += [[0] * dim]
shellIncomplete = 1
_, sumInverse = np.unique([np.sum(derIdx) for derIdx in derIdxs],
return_inverse = True)
else:
sumCount = np.cumsum(sumCount)
shellIncomplete = 1
for shellIncomplete in range(1, len(sumDer) + 1):
theoreticalCount = degreeToDOFs([shellIncomplete] * dim, "TOTAL")
if (shellIncomplete not in sumDer
or theoreticalCount > sumCount[shellIncomplete]):
break
if theoreticalCount < sumCount[shellIncomplete]:
raise RROMPyException("Starting index list is redundant.")
shell_previous = [derIdxs[x] for x in
np.nonzero(sumInverse == shellIncomplete - 1)[0]]
while count > 0:
shell_current = [derIdxs[x] for x in
np.nonzero(sumInverse == shellIncomplete)[0]]
for prev in shell_previous:
prevC = copy(prev)
for d in range(dim):
prevC[d] += 1
if prevC not in shell_current:
out += [copy(prevC)]
shell_current += [copy(prevC)]
derIdxs += [copy(prevC)]
count -= 1
if count <= 0: return out
prevC[d] -= 1
shell_previous = copy(shell_current)
_, sumInverse = np.unique([np.sum(derIdx) for derIdx in derIdxs],
return_inverse = True)
shellIncomplete += 1
def hashDerivativeToIdx(derIdx:List[int]) -> int:
dim = len(derIdx)
if dim == 0: return 0
derMag = sum(derIdx)
base = degreeToDOFs([derMag - 1] * dim, "TOTAL")
if derMag == derIdx[0]: return base
return base + hashDerivativeToIdx(derIdx[1:])
def hashIdxToDerivative(n:int, dim:int) -> List[int]:
if n == 0: return [0] * dim
shell = 0
shellOld = -1
shellNew = 1
while shellNew <= n:
shell += 1
shellOld, shellNew = shellNew, degreeToDOFs([shell] * dim, "TOTAL")
rest = hashIdxToDerivative(n - shellOld, dim - 1)
return [shell - sum(rest)] + rest

Event Timeline