This file is indexed.

/usr/lib/python2.7/dist-packages/ffc/uflacs/analysis/indexing.py is in python-ffc 2016.2.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# -*- coding: utf-8 -*-
# Copyright (C) 2011-2016 Martin Sandve Alnæs
#
# This file is part of UFLACS.
#
# UFLACS 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.
#
# UFLACS 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 UFLACS. If not, see <http://www.gnu.org/licenses/>.

"""Algorithms for working with multiindices."""

from ufl import product
from ufl.permutation import compute_indices
from ufl.utils.indexflattening import shape_to_strides, flatten_multiindex
from ufl.classes import ComponentTensor, FixedIndex, Index, Indexed


def map_indexed_arg_components(indexed):
    """Build integer list mapping between flattended components
    of indexed expression and its underlying tensor-valued subexpression."""

    assert isinstance(indexed, Indexed)

    # AKA indexed = tensor[multiindex]
    tensor, multiindex = indexed.ufl_operands

    # AKA e1 = e2[multiindex]
    # (this renaming is historical, but kept for consistency with all the variables *1,*2 below)
    e2 = tensor
    e1 = indexed

    # Get tensor and index shape
    sh1 = e1.ufl_shape
    sh2 = e2.ufl_shape
    fi1 = e1.ufl_free_indices
    fi2 = e2.ufl_free_indices
    fid1 = e1.ufl_index_dimensions
    fid2 = e2.ufl_index_dimensions

    # Compute regular and total shape
    tsh1 = sh1 + fid1
    tsh2 = sh2 + fid2
    # r1 = len(tsh1)
    r2 = len(tsh2)
    # str1 = shape_to_strides(tsh1)
    str2 = shape_to_strides(tsh2)
    assert not sh1
    assert sh2  # Must have shape to be indexed in the first place
    assert product(tsh1) <= product(tsh2)

    # Build map from fi2/fid2 position (-offset nmui) to fi1/fid1 position
    ind2_to_ind1_map = [None] * len(fi2)
    for k, i in enumerate(fi2):
        ind2_to_ind1_map[k] = fi1.index(i)

    # Build map from fi1/fid1 position to mi position
    nmui = len(multiindex)
    multiindex_to_ind1_map = [None] * nmui
    for k, i in enumerate(multiindex):
        if isinstance(i, Index):
            multiindex_to_ind1_map[k] = fi1.index(i.count())

    # Build map from flattened e1 component to flattened e2 component
    perm1 = compute_indices(tsh1)
    ni1 = product(tsh1)

    # Situation: e1 = e2[mi]
    d1 = [None] * ni1
    p2 = [None] * r2
    assert len(sh2) == nmui
    for k, i in enumerate(multiindex):
        if isinstance(i, FixedIndex):
            p2[k] = int(i)
    for c1, p1 in enumerate(perm1):
        for k, i in enumerate(multiindex):
            if isinstance(i, Index):
                p2[k] = p1[multiindex_to_ind1_map[k]]
        for k, i in enumerate(ind2_to_ind1_map):
            p2[nmui + k] = p1[i]
        c2 = flatten_multiindex(p2, str2)
        d1[c1] = c2

    # Consistency checks
    assert all(isinstance(x, int) for x in d1)
    assert len(set(d1)) == len(d1)
    return d1


def map_component_tensor_arg_components(tensor):
    """Build integer list mapping between flattended components
    of tensor and its underlying indexed subexpression."""

    assert isinstance(tensor, ComponentTensor)

    # AKA tensor = as_tensor(indexed, multiindex)
    indexed, multiindex = tensor.ufl_operands

    e1 = indexed
    e2 = tensor  # e2 = as_tensor(e1, multiindex)
    mi = [i for i in multiindex if isinstance(i, Index)]

    # Get tensor and index shapes
    sh1 = e1.ufl_shape  # (sh)ape of e1
    sh2 = e2.ufl_shape  # (sh)ape of e2
    fi1 = e1.ufl_free_indices  # (f)ree (i)ndices of e1
    fi2 = e2.ufl_free_indices  # ...
    fid1 = e1.ufl_index_dimensions  # (f)ree (i)ndex (d)imensions of e1
    fid2 = e2.ufl_index_dimensions  # ...

    # Compute total shape (tsh) of e1 and e2
    tsh1 = sh1 + fid1
    tsh2 = sh2 + fid2
    r1 = len(tsh1)  # 'total rank' or e1
    r2 = len(tsh2)  # ...
    str1 = shape_to_strides(tsh1)
    assert not sh1
    assert sh2
    assert len(mi) == len(multiindex)
    assert product(tsh1) == product(tsh2)
    assert fi1

    assert all(i in fi1 for i in fi2)

    nmui = len(multiindex)
    assert nmui == len(sh2)

    # Build map from fi2/fid2 position (-offset nmui) to fi1/fid1 position
    p2_to_p1_map = [None] * r2
    for k, i in enumerate(fi2):
        p2_to_p1_map[k + nmui] = fi1.index(i)

    # Build map from fi1/fid1 position to mi position
    for k, i in enumerate(mi):
        p2_to_p1_map[k] = fi1.index(mi[k].count())

    # Build map from flattened e1 component to flattened e2 component
    perm2 = compute_indices(tsh2)
    ni2 = product(tsh2)

    # Situation: e2 = as_tensor(e1, mi)
    d2 = [None] * ni2
    p1 = [None] * r1
    for c2, p2 in enumerate(perm2):
        for k2, k1 in enumerate(p2_to_p1_map):
            p1[k1] = p2[k2]
        c1 = flatten_multiindex(p1, str1)
        d2[c2] = c1

    # Consistency checks
    assert all(isinstance(x, int) for x in d2)
    assert len(set(d2)) == len(d2)
    return d2