q2K BHP
Black History Portal
THE BHP WIRE —
HIDDEN TRUTHS
What's New!
THE JOURNEY THROUGH TIME

Explore Black History

Explore the people, places, events, achievements, struggles and stories that shaped our journey.

✊🏾

Civil Rights

Movements, leaders, victories and the continuing fight for equality.

⚙️

Black Inventors

Innovation, patents, science, technology and world-changing contributions.

🏆

Sports

Pioneers, champions, Negro Leagues, records, activism and excellence.

♟️

People

Meet the people whose lives, choices and achievements shaped the journey.

📍

Places

Black towns, communities, institutions and places where history happened.

📜

Events

Moments that changed communities, movements, institutions and the nation.

Enter a person, place, event, or topic.
MY'STORY

The MOVE Fire

This is a personal recollection on the Move fire on May 13, 1985 Philadelphia police fired thousands of rounds at the MOVE house, city officials approved dropping an explosive device on the roof, the resulting fire was allowed to burn, 11 people—including five children—died, and 61 homes were destroyed. Philadelphia City Council later called it a “brutal attack carried out by the City of Philadelphia on its own citizens” and acknowledged that no individual faced criminal consequences for the bombing. One timeline correction worth preserving for the BHP record: the major previous MOVE-police confrontation was August 8, 1978, about seven years before the bombing, not a year or two earlier. Officer James Ramp was killed, other police and firefighters were wounded, nine MOVE members were later convicted, and television cameras recorded police beating Delbert Africa during his arrest. The 1985 MOVE Commission later specifically criticized city planners for failing to adequately use lessons from that 1978 confrontation. And that actually strengthens the point you’re making: 1985 did not happen without precedent or institutional memory. There had already been a deadly confrontation with MOVE, years of conflict, negotiations and police involvement before Osage Avenue.

MORE →
BLACK FACTS
The Truths They Never Taught You...

Wilmington 1898 — An American Coup

Wilmington, North Carolina once had a thriving Black middle class and an elected interracial government. In 1898 white supremacists used violence to overthrow that government, kill Black residents and drive many others from the city.

MORE →
BHP gathered finds from its connected research sources. Showing the 4 strongest Black History matches.
← BACK TO RESULTS
Wikipedia

Suffix array

Suffix array
TypeArray
Invented byManber & Myers (1990)
Time complexity
in big O notation
Average Worst case
Space
Construction

In computer science, a suffix array is a sorted array of all suffixes of a string. It is a data structure used in, among others, full-text indices, data-compression algorithms, and the field of bibliometrics.

Suffix arrays were introduced by Manber & Myers (1990) as a simple, space efficient alternative to suffix trees. They had independently been discovered by Gaston Gonnet in 1987 under the name PAT array (Gonnet, Baeza-Yates & Snider 1992).

Li, Li & Huo (2016) gave the first in-place time suffix array construction algorithm that is optimal both in time and space, where in-place means that the algorithm only needs additional space beyond the input string and the output suffix array.

Enhanced suffix arrays (ESAs) are suffix arrays with additional tables that reproduce the full functionality of suffix trees preserving the same time and memory complexity.[1] A sorted array of only some (rather than all) suffixes of a string is called a sparse suffix array.[2]

Definition

[edit]

Let be an -string and let denote the substring of ranging from to inclusive.

The suffix array of is now defined to be an array of integers providing the starting positions of suffixes of in lexicographical order. This means, an entry contains the starting position of the -th smallest suffix in and thus for all : .

Each suffix of shows up in exactly once. Suffixes are simple strings. These strings are sorted (as in a paper dictionary), before their starting positions (integer indices) are saved in .

Example

[edit]

Consider the text =banana$ to be indexed:

i 1 2 3 4 5 6 7
b a n a n a $

The text ends with the special sentinel letter $ that is unique and lexicographically smaller than any other character. The text has the following suffixes:

Suffix i
banana$ 1
anana$ 2
nana$ 3
ana$ 4
na$ 5
a$ 6
$ 7

These suffixes can be sorted in ascending order:

Suffix i
$ 7
a$ 6
ana$ 4
anana$ 2
banana$ 1
na$ 5
nana$ 3

The suffix array contains the starting positions of these sorted suffixes:

i = 1 2 3 4 5 6 7
= 7 6 4 2 1 5 3

The suffix array with the suffixes written out vertically underneath for clarity:

i = 1 2 3 4 5 6 7
= 7 6 4 2 1 5 3
1 $ a a a b n n
2 $ n n a a a
3 a a n $ n
4 $ n a a
5 a n $
6 $ a
7 $

So for example, contains the value 4, and therefore refers to the suffix starting at position 4 within , which is the suffix ana$.

Correspondence to suffix trees

[edit]

Suffix arrays are closely related to suffix trees:

  • Suffix arrays can be constructed by performing a depth-first traversal of a suffix tree. The suffix array corresponds to the leaf-labels given in the order in which these are visited during the traversal, if edges are visited in the lexicographical order of their first character.
  • A suffix tree can be constructed in linear time by using a combination of suffix array and LCP array. For a description of the algorithm, see the corresponding section in the LCP array article.

It has been shown that every suffix tree algorithm can be systematically replaced with an algorithm that uses a suffix array enhanced with additional information (such as the LCP array) and solves the same problem in the same time complexity.[1] Advantages of suffix arrays over suffix trees include improved space requirements, simpler linear time construction algorithms (e.g., compared to Ukkonen's algorithm) and improved cache locality.[3]

Space efficiency

[edit]

Suffix arrays were introduced by Manber & Myers (1990) in order to improve over the space requirements of suffix trees: Suffix arrays store integers. Assuming an integer requires bytes, a suffix array requires bytes in total. This is significantly less than the bytes which are required by a careful suffix tree implementation.[4]

However, in certain applications, the space requirements of suffix arrays may still be prohibitive. Analyzed in bits, a suffix array requires space, whereas the original text over an alphabet of size only requires bits. For a human genome with and the suffix array would therefore occupy about 16 times more memory than the genome itself.

Such discrepancies motivated a trend towards compressed suffix arrays and BWT-based compressed full-text indices such as the FM-index. These data structures require only space within the size of the text or even less.

Construction algorithms

[edit]

A suffix tree can be built in and can be converted into a suffix array by traversing the tree depth-first also in , so there exist algorithms that can build a suffix array in .

A naive approach to construct a suffix array is to use a comparison-based sorting algorithm. These algorithms require suffix comparisons, but a suffix comparison runs in time, so the overall runtime of this approach is .

More advanced algorithms take advantage of the fact that the suffixes to be sorted are not arbitrary strings but related to each other. These algorithms strive to achieve the following goals:[5]

  • minimal asymptotic complexity
  • lightweight in space, meaning little or no working memory beside the text and the suffix array itself is needed
  • fast in practice

One of the first algorithms to achieve all goals is the SA-IS algorithm of Nong, Zhang & Chan (2009). The algorithm is also rather simple (< 100 LOC) and can be enhanced to simultaneously construct the LCP array.[6] The SA-IS algorithm is one of the fastest known suffix array construction algorithms. A careful implementation by Yuta Mori[7] outperforms most other linear or super-linear construction approaches.

Beside time and space requirements, suffix array construction algorithms are also differentiated by their supported alphabet: constant alphabets where the alphabet size is bound by a constant, integer alphabets where characters are integers in a range depending on and general alphabets where only character comparisons are allowed.[8]

Most suffix array construction algorithms are based on one of the following approaches:[5]

  • Prefix doubling algorithms are based on a strategy of Karp, Miller & Rosenberg (1972). The idea is to find prefixes that honor the lexicographic ordering of suffixes. The assessed prefix length doubles in each iteration of the algorithm until a prefix is unique and provides the rank of the associated suffix.
  • Recursive algorithms follow the approach of the suffix tree construction algorithm by Farach (1997) to recursively sort a subset of suffixes. This subset is then used to infer a suffix array of the remaining suffixes. Both of these suffix arrays are then merged to compute the final suffix array.
  • Induced copying algorithms are similar to recursive algorithms in the sense that they use an already sorted subset to induce a fast sort of the remaining suffixes. The difference is that these algorithms favor iteration over recursion to sort the selected suffix subset. A survey of this diverse group of algorithms has been put together by Puglisi, Smyth & Turpin (2007).

A well-known recursive algorithm for integer alphabets is the DC3 / skew algorithm of Kärkkäinen & Sanders (2003). It runs in linear time and has successfully been used as the basis for parallel[9] and external memory[10] suffix array construction algorithms.

Recent work by Salson et al. (2010) proposes an algorithm for updating the suffix array of a text that has been edited instead of rebuilding a new suffix array from scratch. Even if the theoretical worst-case time complexity is , it appears to perform well in practice: experimental results from the authors showed that their implementation of dynamic suffix arrays is generally more efficient than rebuilding when considering the insertion of a reasonable number of letters in the original text.

In practical open source work, a commonly used routine for suffix array construction was qsufsort, based on the 1999 Larsson-Sadakane algorithm.[11] This routine has been superseded by Yuta Mori's DivSufSort, "the fastest known suffix sorting algorithm in main memory" as of 2017. It too can be modified to compute an LCP array. It uses a induced copying combined with Itoh-Tanaka.[12] In 2021 a faster implementation of the algorithm was presented by Ilya Grebnov [13] which in average showed 65% performance improvement over DivSufSort implementation on the Silesia corpus.[14]

Generalized suffix array

[edit]

The concept of a suffix array can be extended to more than one string. This is called a generalized suffix array (or GSA), a suffix array that contains all suffixes for a set of strings (for example, and is lexicographically sorted with all suffixes of each string.[15]

Applications

[edit]

The suffix array of a string can be used as an index to quickly locate every occurrence of a substring pattern within the string . Finding every occurrence of the pattern is equivalent to finding every suffix that begins with the substring. Thanks to the lexicographical ordering, these suffixes will be grouped together in the suffix array and can be found efficiently with two binary searches. The first search locates the starting position of the interval, and the second one determines the end position:[citation needed]

n = len(S)

def search(P: str) -> tuple[int, int]:
    """
    Return indices (s, r) such that the interval A[s:r] (excluding the end
    index) represents all suffixes of S that start with the pattern P.
    """
    # Find starting position of interval
    l = 0  # in Python, arrays are indexed starting at 0
    r = n
    while l < r:
        mid = (l + r) // 2  # division rounding down to nearest integer
        # suffixAt(A[i]) is the ith smallest suffix
        if P > suffixAt(A[mid]):
            l = mid + 1
        else:
            r = mid
    s = l
    
    # Find ending position of interval
    r = n
    while l < r:
        mid = (l + r) // 2
        if suffixAt(A[mid]).startswith(P):
            l = mid + 1
        else:
            r = mid
    return (s, r)

Finding the substring pattern of length in the string of length takes time, given that a single suffix comparison needs to compare characters. Manber & Myers (1990) describe how this bound can be improved to time using LCP information. The idea is that a pattern comparison does not need to re-compare certain characters, when it is already known that these are part of the longest common prefix of the pattern and the current search interval. Abouelhoda, Kurtz & Ohlebusch (2004) improve the bound even further and achieve a search time of for constant alphabet size, as known from suffix trees.

Suffix sorting algorithms can be used to compute the Burrows–Wheeler transform (BWT). The BWT requires sorting of all cyclic permutations of a string. If this string ends in a special end-of-string character that is lexicographically smaller than all other character (i.e., $), then the order of the sorted rotated BWT matrix corresponds to the order of suffixes in a suffix array. The BWT can therefore be computed in linear time by first constructing a suffix array of the text and then deducing the BWT string: .

Suffix arrays can also be used to look up substrings in example-based machine translation, demanding much less storage than a full phrase table as used in Statistical machine translation.

Many additional applications of the suffix array require the LCP array. Some of these are detailed in the application section of the latter.

Enhanced suffix arrays

[edit]

Suffix trees are powerful data structures that have wide application in areas of pattern and string matching, indexing and textual statistics. However, it occupies a significant amount of space and thus has a drawback in many real-time applications that require processing a considerably large amount of data like genome analysis. To overcome this drawback, the Enhanced Suffix Array was developed. It is a data structure consisting of a suffix array and an additional table called the child table that contains the information about the parent-child relationship between the nodes in the suffix tree. The node branching data structure for this tree is a linked list. Enhanced suffix arrays are superior to suffix trees in terms of both space efficiency and time complexity and are easy to implement. Moreover, they can be applied to any algorithm that uses a suffix tree by using an abstract concept called LCP-interval trees. The time complexity for searching a pattern of length in an enhanced suffix array is .

The enhanced suffix array is composed of two arrays:

  1. pos array pos[1,...n]: It represents a sorted list of all S suffixes. Only the initial positions of the suffixes are stored in the array to reduce the space complexity since the suffixes are too large.
  2. lcp array lcp[1,...n]: It is an array of n integers that maintains the lengths of the longest common prefix of two consecutive suffixes stored in the pos array.

Constructing the lcp-interval

[edit]

For a suffix array of S, the lcp-interval associated with the corresponding node of suffix tree of S can be defined as:

Interval [i,..j], 0 ≤ i ≤ j ≤ n is an lcp-interval of lcp-value, if

  1. lcptab[i] < l,
  2. lcptab[k] ≥ l for all i + 1 ≤ k ≤ j,
  3. lcptab[k] = l for some i + 1 ≤ k ≤ j if i ≠ j and l = n − i + 1 if i = j,
  4. lcptab[j + 1] < l.

The length of the longest common prefix of pos[i − 1] and pos[i] is stored in lcp[i],where 2 ≤ i ≤ n. The lcp-interval portrays the same parent-child relationship as that among the associated nodes in the suffix tree of S.This shows that if the corresponding node of [i..j] is a child of the corresponding node of [k..l], a lcp-interval [i..j] is a child interval of another lcp-interval [k..l]. If [k..l] is a child interval of [i..j], a lcp-interval [i..j] is the parent interval of a lcp-interval [k..l].

Constructing a child table

[edit]

The child table cldtab is composed of three n arrays, up, down and nextlIndex. The information about the edges of the corresponding suffix tree is stored and maintained by the up and down arrays. The nextlIndex array stores the links in the linked list used for node branching the suffix tree.

The up, down and nextlIndex array are defined as follows:

  1. The element up[i] records the starting index of the longest lcp-second interval’s child interval, which ends at index i-1.
  2. The initial index of the second child interval of the longest lcp-interval, starting at index i is stored in the element down[i].
  3. If and only if the interval is neither the first child nor the final child of its parent, the element nextlIndex[i] contains the first index of the next sibling interval of the longest lcp-interval, starting at index i.

By performing a bottom-up traversal of the lcp-interval of the tree, the child table can be constructed in linear time. The up/down values and the nextlIndex values can be computed separately by using two distinct algorithms.

[edit]

The suffix links for an enhanced suffix array can be computed by generating the suffix link interval [1,..,r] for each [i,..j] interval during the preprocessing. The left and right elements l and r of the interval are maintained in the first index of [i,..,j]. The table for this interval ranges from 0 to n. The suffix link table is constructed by the left-to-right breadth-first traversal of the lcp-interval tree. Every time an l-interval is computed, it is added to the list of l-intervals, which is referred to as the l-list. When the lcp-value > 0, for every l-interval[i,..,j] in the list, link[i] is calculated. The interval [l,..,r] is computed by a binary search in(l-1)-list, where l is the largest left boundary amongst all the l-1 intervals. The suffix link interval of [i,..j] is represented by this interval[l,..,r]. The values l and r are ultimately stored in the first index of [i,..,j].

Notes

[edit]
  1. ^ a b Abouelhoda, Kurtz & Ohlebusch 2004.
  2. ^ I, Kärkkäinen & Kempa 2014.
  3. ^ Abouelhoda, Kurtz & Ohlebusch 2002.
  4. ^ Kurtz 1999.
  5. ^ a b Puglisi, Smyth & Turpin 2007.
  6. ^ Fischer 2011.
  7. ^ Mori, Yuta. "sais". Archived from the original on 9 Mar 2023. Retrieved 31 Aug 2023.
  8. ^ Burkhardt & Kärkkäinen 2003.
  9. ^ Kulla & Sanders 2007.
  10. ^ Dementiev et al. 2008.
  11. ^ Larsson, N. Jesper; Sadakane, Kunihiko (22 November 2007). "Faster suffix sorting". Theoretical Computer Science. 387 (3): 258–272. doi:10.1016/j.tcs.2007.07.017. ISSN 0304-3975.
  12. ^ Fischer, Johannes; Kurpicz, Florian (5 October 2017). "Dismantling DivSufSort". Proceedings of the Prague Stringology Conference 2017. arXiv:1710.01896.
  13. ^ "New saca and bwt library (libsais)". encode.su. Retrieved 2021-10-03.
  14. ^ Grebnov, Ilya (2021-09-22), libsais, retrieved 2021-10-02
  15. ^ Shi 1996.

References

[edit]
[edit]

Source: Wikipedia. Article content is retrieved live through the MediaWiki API.

No preview image
Wikipedia

Suffix array

In computer science, a suffix array is a sorted array of all suffixes of a string. It is a data structure used in, among others, full-text indices, data-compression algorithms, and the field of bibliometrics. Suffix arrays were introduced by Manber & Myers (1990) as a simple, space efficient alternative to suffix trees. They had independently been discovered by Gaston Gonnet in 1987 under the name PAT array (Gonnet, Baeza-Yates & Snider 1992). Li, Li & Huo (2016) gave the first in-place O ( n ) {\displaystyle {\mathcal {O}}(n)} time suffix array construction algorithm that is optimal both in time and space, where in-place means that the algorithm only needs O ( 1 ) {\displaystyle {\mathcal {O}}(1)} additional space beyond the input string and the output suffix array. Enhanced suffix arrays (ESAs) are suffix arrays with additional tables that reproduce the full functionality of suffix trees preserving the same time and memory complexity. A sorted array of only some (rather than all) suffixes of a string is called a sparse suffix array.

MORE →
No preview image
Wikipedia

Compressed suffix array

In computer science, a compressed suffix array is a compressed data structure for pattern matching. Compressed suffix arrays are a general class of data structure that improve on the suffix array. These data structures enable quick search for an arbitrary string with a comparatively small index. Given a text T of n characters from an alphabet Σ, a compressed suffix array supports searching for arbitrary patterns in T. For an input pattern P of m characters, the search time is typically O(m) or O(m + log(n)). The space used is typically O ( n H k ( T ) ) + o ( n ) {\displaystyle O(nH_{k}(T))+o(n)} , where H k ( T ) {\displaystyle H_{k}(T)} is the k-th order empirical entropy of the text T. The time and space to construct a compressed suffix array are normally ⁠ O ( n ) {\displaystyle O(n)} ⁠. The original presentation of a compressed suffix array solved a long-standing open problem by showing that fast pattern matching was possible using only a linear-space data structure, namely, one proportional to the size of the text T, which takes O ( n log ⁡ | Σ | ) {\displaystyle O(n\,{\log |\Sigma |})} bits. The conventional suffix array and suffix tree use Ω ( n log ⁡ n ) {\displaystyle \Omega (n\,{\log n})} bits, which is substantially larger. The basis for the data structure is a recursive decomposition using the "neighbor function," which allows a suffix array to be represented by one of half its length. The construction is repeated multiple times until the resulting suffix array uses a linear number of bits. Following work showed that the actual storage space was related to the 0 t h {\displaystyle 0^{th}} -order entropy and that the index supports self-indexing. The space bound was further improved achieving the ultimate goal of higher-order entropy; the compression is obtained by partitioning the neighbor function by high-order contexts, and compressing each partition with a wavelet tree. The space usage is extremely competitive in practice with other state-of-the-art compressors, and it also supports fast in-situ pattern matching. The memory accesses made by compressed suffix arrays and other compressed data structures for pattern matching are typically not localized, and thus these data structures have been notoriously hard to design efficiently for use in external memory. Recent progress using geometric duality takes advantage of the block access provided by disks to speed up the I/O time significantly In addition, potentially practical search performance for a compressed suffix array in external-memory has been demonstrated.

MORE →
No preview image
Wikipedia

Generalized suffix array

In computer science, a generalized suffix array (GSA) is a suffix array containing all suffixes for a set of strings. Given the set of strings S = S 1 , S 2 , S 3 , . . . , S k {\displaystyle S=S_{1},S_{2},S_{3},...,S_{k}} of total length n {\displaystyle n} , it is a lexicographically sorted array of all suffixes of each string in S {\displaystyle S} . It is primarily used in bioinformatics and string processing.

MORE →
No preview image
Wikipedia

Suffix (disambiguation)

A suffix is part of a word; an affix that follows the morphemes to which it can attach. Possessive suffix, a suffix used in word formation for creation of various possessive forms Suffix may also refer to: Suffix (name), the style at the end of a person's name which gives additional identifying information about the person Suffix (computer science), the last part of a string of characters Suffix notation, a notation for manipulating vector quantities, also known as index notation Suffix array, an array of integers giving the starting positions of suffixes of a string in lexicographical order Suffix tree, a data structure that presents the suffixes of a given string in a way that allows for a particularly fast implementation of many important string operations

MORE →
TOPIC OF THE DAY

Greenwood / Black Wall Street

Before the 1921 destruction of Tulsa’s Greenwood District, Black residents had created a remarkable center of business and community life. The district included stores, professional offices, entertainment venues and homes owned by Black citizens. Understanding Greenwood means learning what was built—not only what was burned.

MORE →
TRIVIA QUESTION OF THE DAY

Which heavyweight champion was known as the “Brown Bomber”?

Joe Louis.