stride-align 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/NOTICE +255 -0
  4. data/README.md +107 -0
  5. data/data/bmpm_data/gen_approx_any.txt +131 -0
  6. data/data/bmpm_data/gen_approx_arabic.txt +26 -0
  7. data/data/bmpm_data/gen_approx_common.txt +233 -0
  8. data/data/bmpm_data/gen_approx_cyrillic.txt +18 -0
  9. data/data/bmpm_data/gen_approx_czech.txt +18 -0
  10. data/data/bmpm_data/gen_approx_dutch.txt +18 -0
  11. data/data/bmpm_data/gen_approx_english.txt +47 -0
  12. data/data/bmpm_data/gen_approx_french.txt +25 -0
  13. data/data/bmpm_data/gen_approx_german.txt +73 -0
  14. data/data/bmpm_data/gen_approx_greek.txt +18 -0
  15. data/data/bmpm_data/gen_approx_greeklatin.txt +20 -0
  16. data/data/bmpm_data/gen_approx_hebrew.txt +18 -0
  17. data/data/bmpm_data/gen_approx_hungarian.txt +18 -0
  18. data/data/bmpm_data/gen_approx_italian.txt +18 -0
  19. data/data/bmpm_data/gen_approx_polish.txt +84 -0
  20. data/data/bmpm_data/gen_approx_portuguese.txt +18 -0
  21. data/data/bmpm_data/gen_approx_romanian.txt +18 -0
  22. data/data/bmpm_data/gen_approx_russian.txt +48 -0
  23. data/data/bmpm_data/gen_approx_spanish.txt +21 -0
  24. data/data/bmpm_data/gen_approx_turkish.txt +18 -0
  25. data/data/bmpm_data/gen_exact_any.txt +40 -0
  26. data/data/bmpm_data/gen_exact_approx_common.txt +79 -0
  27. data/data/bmpm_data/gen_exact_arabic.txt +18 -0
  28. data/data/bmpm_data/gen_exact_common.txt +32 -0
  29. data/data/bmpm_data/gen_exact_cyrillic.txt +18 -0
  30. data/data/bmpm_data/gen_exact_czech.txt +18 -0
  31. data/data/bmpm_data/gen_exact_dutch.txt +18 -0
  32. data/data/bmpm_data/gen_exact_english.txt +18 -0
  33. data/data/bmpm_data/gen_exact_french.txt +18 -0
  34. data/data/bmpm_data/gen_exact_german.txt +18 -0
  35. data/data/bmpm_data/gen_exact_greek.txt +18 -0
  36. data/data/bmpm_data/gen_exact_greeklatin.txt +18 -0
  37. data/data/bmpm_data/gen_exact_hebrew.txt +18 -0
  38. data/data/bmpm_data/gen_exact_hungarian.txt +18 -0
  39. data/data/bmpm_data/gen_exact_italian.txt +18 -0
  40. data/data/bmpm_data/gen_exact_polish.txt +23 -0
  41. data/data/bmpm_data/gen_exact_portuguese.txt +18 -0
  42. data/data/bmpm_data/gen_exact_romanian.txt +18 -0
  43. data/data/bmpm_data/gen_exact_russian.txt +19 -0
  44. data/data/bmpm_data/gen_exact_spanish.txt +19 -0
  45. data/data/bmpm_data/gen_exact_turkish.txt +18 -0
  46. data/data/bmpm_data/gen_hebrew_common.txt +113 -0
  47. data/data/bmpm_data/gen_lang.txt +295 -0
  48. data/data/bmpm_data/gen_languages.txt +36 -0
  49. data/data/bmpm_data/gen_rules_any.txt +367 -0
  50. data/data/bmpm_data/gen_rules_arabic.txt +76 -0
  51. data/data/bmpm_data/gen_rules_cyrillic.txt +99 -0
  52. data/data/bmpm_data/gen_rules_czech.txt +67 -0
  53. data/data/bmpm_data/gen_rules_dutch.txt +78 -0
  54. data/data/bmpm_data/gen_rules_english.txt +113 -0
  55. data/data/bmpm_data/gen_rules_french.txt +114 -0
  56. data/data/bmpm_data/gen_rules_german.txt +129 -0
  57. data/data/bmpm_data/gen_rules_greek.txt +97 -0
  58. data/data/bmpm_data/gen_rules_greeklatin.txt +118 -0
  59. data/data/bmpm_data/gen_rules_hebrew.txt +62 -0
  60. data/data/bmpm_data/gen_rules_hungarian.txt +83 -0
  61. data/data/bmpm_data/gen_rules_italian.txt +77 -0
  62. data/data/bmpm_data/gen_rules_polish.txt +185 -0
  63. data/data/bmpm_data/gen_rules_portuguese.txt +105 -0
  64. data/data/bmpm_data/gen_rules_romanian.txt +64 -0
  65. data/data/bmpm_data/gen_rules_russian.txt +142 -0
  66. data/data/bmpm_data/gen_rules_spanish.txt +85 -0
  67. data/data/bmpm_data/gen_rules_turkish.txt +50 -0
  68. data/data/keyboard_data/qwerty.npy +0 -0
  69. data/data/matrix_data/BLOSUM100 +31 -0
  70. data/data/matrix_data/BLOSUM30 +31 -0
  71. data/data/matrix_data/BLOSUM35 +31 -0
  72. data/data/matrix_data/BLOSUM40 +31 -0
  73. data/data/matrix_data/BLOSUM45 +25 -0
  74. data/data/matrix_data/BLOSUM50 +25 -0
  75. data/data/matrix_data/BLOSUM55 +31 -0
  76. data/data/matrix_data/BLOSUM60 +31 -0
  77. data/data/matrix_data/BLOSUM62 +25 -0
  78. data/data/matrix_data/BLOSUM65 +31 -0
  79. data/data/matrix_data/BLOSUM70 +31 -0
  80. data/data/matrix_data/BLOSUM75 +31 -0
  81. data/data/matrix_data/BLOSUM80 +25 -0
  82. data/data/matrix_data/BLOSUM85 +31 -0
  83. data/data/matrix_data/BLOSUM90 +25 -0
  84. data/data/matrix_data/NUC.4.4 +25 -0
  85. data/data/matrix_data/PAM10 +34 -0
  86. data/data/matrix_data/PAM100 +34 -0
  87. data/data/matrix_data/PAM110 +34 -0
  88. data/data/matrix_data/PAM120 +34 -0
  89. data/data/matrix_data/PAM130 +34 -0
  90. data/data/matrix_data/PAM140 +34 -0
  91. data/data/matrix_data/PAM150 +34 -0
  92. data/data/matrix_data/PAM160 +34 -0
  93. data/data/matrix_data/PAM170 +34 -0
  94. data/data/matrix_data/PAM180 +34 -0
  95. data/data/matrix_data/PAM190 +34 -0
  96. data/data/matrix_data/PAM20 +34 -0
  97. data/data/matrix_data/PAM200 +34 -0
  98. data/data/matrix_data/PAM210 +34 -0
  99. data/data/matrix_data/PAM220 +34 -0
  100. data/data/matrix_data/PAM230 +34 -0
  101. data/data/matrix_data/PAM240 +34 -0
  102. data/data/matrix_data/PAM250 +25 -0
  103. data/data/matrix_data/PAM260 +34 -0
  104. data/data/matrix_data/PAM270 +34 -0
  105. data/data/matrix_data/PAM280 +34 -0
  106. data/data/matrix_data/PAM290 +34 -0
  107. data/data/matrix_data/PAM30 +25 -0
  108. data/data/matrix_data/PAM300 +34 -0
  109. data/data/matrix_data/PAM310 +34 -0
  110. data/data/matrix_data/PAM320 +34 -0
  111. data/data/matrix_data/PAM330 +34 -0
  112. data/data/matrix_data/PAM340 +34 -0
  113. data/data/matrix_data/PAM350 +34 -0
  114. data/data/matrix_data/PAM360 +34 -0
  115. data/data/matrix_data/PAM370 +34 -0
  116. data/data/matrix_data/PAM380 +34 -0
  117. data/data/matrix_data/PAM390 +34 -0
  118. data/data/matrix_data/PAM40 +34 -0
  119. data/data/matrix_data/PAM400 +34 -0
  120. data/data/matrix_data/PAM410 +34 -0
  121. data/data/matrix_data/PAM420 +34 -0
  122. data/data/matrix_data/PAM430 +34 -0
  123. data/data/matrix_data/PAM440 +34 -0
  124. data/data/matrix_data/PAM450 +34 -0
  125. data/data/matrix_data/PAM460 +34 -0
  126. data/data/matrix_data/PAM470 +34 -0
  127. data/data/matrix_data/PAM480 +34 -0
  128. data/data/matrix_data/PAM490 +34 -0
  129. data/data/matrix_data/PAM50 +34 -0
  130. data/data/matrix_data/PAM500 +34 -0
  131. data/data/matrix_data/PAM60 +34 -0
  132. data/data/matrix_data/PAM70 +25 -0
  133. data/data/matrix_data/PAM80 +34 -0
  134. data/data/matrix_data/PAM90 +34 -0
  135. data/ext/stride_align/backend_avx2.cpp +2 -0
  136. data/ext/stride_align/backend_avx512bwvl.cpp +2 -0
  137. data/ext/stride_align/backend_generic.cpp +3 -0
  138. data/ext/stride_align/backend_impl.hpp +983 -0
  139. data/ext/stride_align/backend_lasx.cpp +2 -0
  140. data/ext/stride_align/backend_lsx.cpp +2 -0
  141. data/ext/stride_align/backend_neon.cpp +2 -0
  142. data/ext/stride_align/backend_rvv.cpp +2 -0
  143. data/ext/stride_align/backend_sse41.cpp +2 -0
  144. data/ext/stride_align/backend_sve.cpp +2 -0
  145. data/ext/stride_align/backend_sve2.cpp +2 -0
  146. data/ext/stride_align/backend_vsx.cpp +2 -0
  147. data/ext/stride_align/beider_morse_impl.cpp +5 -0
  148. data/ext/stride_align/cpu_detect.cpp +172 -0
  149. data/ext/stride_align/cpu_detect.hpp +6 -0
  150. data/ext/stride_align/extconf.rb +114 -0
  151. data/ext/stride_align/target_profile.hpp +82 -0
  152. data/ext/stride_align/vendor/beider_morse_impl.cpp +1467 -0
  153. data/ext/stride_align/vendor/stride_align/alignment.hpp +199 -0
  154. data/ext/stride_align/vendor/stride_align/batch.hpp +812 -0
  155. data/ext/stride_align/vendor/stride_align/beider_morse.hpp +121 -0
  156. data/ext/stride_align/vendor/stride_align/caverphone.hpp +222 -0
  157. data/ext/stride_align/vendor/stride_align/cologne_phonetic.hpp +202 -0
  158. data/ext/stride_align/vendor/stride_align/core.hpp +731 -0
  159. data/ext/stride_align/vendor/stride_align/daitch_mokotoff.hpp +631 -0
  160. data/ext/stride_align/vendor/stride_align/double_metaphone.hpp +796 -0
  161. data/ext/stride_align/vendor/stride_align/dtw.hpp +300 -0
  162. data/ext/stride_align/vendor/stride_align/encoded.hpp +235 -0
  163. data/ext/stride_align/vendor/stride_align/hamming.hpp +55 -0
  164. data/ext/stride_align/vendor/stride_align/indel.hpp +1200 -0
  165. data/ext/stride_align/vendor/stride_align/jaro.hpp +517 -0
  166. data/ext/stride_align/vendor/stride_align/lcs.hpp +159 -0
  167. data/ext/stride_align/vendor/stride_align/levenshtein.hpp +1247 -0
  168. data/ext/stride_align/vendor/stride_align/levenshtein_prepared.hpp +193 -0
  169. data/ext/stride_align/vendor/stride_align/match_rating.hpp +168 -0
  170. data/ext/stride_align/vendor/stride_align/metaphone.hpp +291 -0
  171. data/ext/stride_align/vendor/stride_align/ngram.hpp +176 -0
  172. data/ext/stride_align/vendor/stride_align/nysiis.hpp +199 -0
  173. data/ext/stride_align/vendor/stride_align/pairwise_alignment.hpp +465 -0
  174. data/ext/stride_align/vendor/stride_align/partial_ratio.hpp +486 -0
  175. data/ext/stride_align/vendor/stride_align/ratcliff_obershelp.hpp +101 -0
  176. data/ext/stride_align/vendor/stride_align/soundex.hpp +108 -0
  177. data/ext/stride_align/vendor/stride_align/token_ratios.hpp +445 -0
  178. data/ext/stride_align/vendor/stride_align/types.hpp +16 -0
  179. data/ext/stride_align/vendor/stride_align/utf8.hpp +512 -0
  180. data/ext/stride_align/vendor/stride_align/wratio.hpp +363 -0
  181. data/lib/stride_align/algorithms.rb +296 -0
  182. data/lib/stride_align/alignment_path.rb +217 -0
  183. data/lib/stride_align/backend.rb +47 -0
  184. data/lib/stride_align/batch.rb +705 -0
  185. data/lib/stride_align/core.rb +180 -0
  186. data/lib/stride_align/keyboard.rb +200 -0
  187. data/lib/stride_align/matrices.rb +403 -0
  188. data/lib/stride_align/version.rb +5 -0
  189. data/lib/stride_align.rb +87 -0
  190. metadata +231 -0
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StrideAlign
4
+ class AlignmentPath
5
+ ATTRIBUTES = %i[
6
+ score query_start query_end target_start target_end operations cigar
7
+ matches mismatches insertions deletions aligned_length
8
+ ].freeze
9
+
10
+ attr_reader(*ATTRIBUTES)
11
+
12
+ def initialize(score: 0, query_start: 0, query_end: 0,
13
+ target_start: 0, target_end: 0,
14
+ operations: "", cigar: "", matches: 0,
15
+ mismatches: 0, insertions: 0, deletions: 0,
16
+ aligned_length: nil)
17
+ @score = score
18
+ @query_start = query_start
19
+ @query_end = query_end
20
+ @target_start = target_start
21
+ @target_end = target_end
22
+ @operations = operations
23
+ @cigar = cigar
24
+ @matches = matches
25
+ @mismatches = mismatches
26
+ @insertions = insertions
27
+ @deletions = deletions
28
+ @aligned_length = aligned_length.nil? ? operations.length : aligned_length
29
+ end
30
+
31
+ def to_h
32
+ ATTRIBUTES.each_with_object({}) { |name, output| output[name] = public_send(name) }
33
+ end
34
+
35
+ def inspect
36
+ "#<#{self.class} score=#{score} query=[#{query_start},#{query_end}) " \
37
+ "target=[#{target_start},#{target_end}) cigar=#{cigar.inspect}>"
38
+ end
39
+ end
40
+
41
+ class AlignmentResult < AlignmentPath
42
+ attr_reader :aligned_query, :aligned_target
43
+
44
+ def initialize(aligned_query: "", aligned_target: "", **attributes)
45
+ super(**attributes)
46
+ @aligned_query = aligned_query
47
+ @aligned_target = aligned_target
48
+ end
49
+
50
+ def aligned
51
+ { query: aligned_query, target: aligned_target }
52
+ end
53
+
54
+ def to_h
55
+ super.merge(aligned: aligned)
56
+ end
57
+
58
+ def to_path
59
+ attributes = AlignmentPath::ATTRIBUTES.each_with_object({}) do |name, output|
60
+ output[name] = public_send(name)
61
+ end
62
+ AlignmentPath.new(**attributes)
63
+ end
64
+ end
65
+
66
+ class Scores
67
+ attr_reader :query, :variant
68
+
69
+ def initialize(query, variant: :smith_waterman, match_score: 2,
70
+ mismatch_score: -1, gap_score: -1,
71
+ gap_open_score: nil, gap_extend_score: nil, width: nil)
72
+ @query = StrideAlign.__send__(:scalar_query, query)
73
+ @variant = variant.to_sym
74
+ @variant = :smith_waterman_farrar if @variant == :farrar
75
+ @compare_method = case @variant
76
+ when :smith_waterman then :smith_waterman_scores
77
+ when :needleman_wunsch then :needleman_wunsch_scores
78
+ when :smith_waterman_farrar then :smith_waterman_farrar_scores
79
+ else
80
+ raise ArgumentError, "unknown score variant: #{variant}"
81
+ end
82
+ @options = {
83
+ match_score: match_score, mismatch_score: mismatch_score,
84
+ gap_score: gap_score, gap_open_score: gap_open_score,
85
+ gap_extend_score: gap_extend_score, width: width
86
+ }
87
+ end
88
+
89
+ def compare(targets)
90
+ StrideAlign.public_send(@compare_method, @query, targets, **@options)
91
+ end
92
+ end
93
+
94
+ class << self
95
+ def smith_waterman_path(query, target, match_score: 2,
96
+ mismatch_score: -1, gap_score: -1,
97
+ gap_open_score: nil, gap_extend_score: nil,
98
+ width: nil, matrix: nil)
99
+ alignment_path(
100
+ query, target, true,
101
+ match_score: match_score, mismatch_score: mismatch_score,
102
+ gap_score: gap_score, gap_open_score: gap_open_score,
103
+ gap_extend_score: gap_extend_score, width: width, matrix: matrix
104
+ )
105
+ end
106
+
107
+ def smith_waterman_path_info(*args, **kwargs)
108
+ smith_waterman_path(*args, **kwargs).to_path
109
+ end
110
+
111
+ def needleman_wunsch_path(query, target, match_score: 2,
112
+ mismatch_score: -1, gap_score: -1,
113
+ gap_open_score: nil, gap_extend_score: nil,
114
+ width: nil, matrix: nil)
115
+ alignment_path(
116
+ query, target, false,
117
+ match_score: match_score, mismatch_score: mismatch_score,
118
+ gap_score: gap_score, gap_open_score: gap_open_score,
119
+ gap_extend_score: gap_extend_score, width: width, matrix: matrix
120
+ )
121
+ end
122
+
123
+ def needleman_wunsch_path_info(*args, **kwargs)
124
+ needleman_wunsch_path(*args, **kwargs).to_path
125
+ end
126
+
127
+ def smith_waterman_cigar(*args, **kwargs)
128
+ smith_waterman_path_info(*args, **kwargs).cigar
129
+ end
130
+ alias smith_waterman_trace_cigar smith_waterman_cigar
131
+ alias smith_waterman_trade_cigar smith_waterman_cigar
132
+
133
+ def needleman_wunsch_cigar(*args, **kwargs)
134
+ needleman_wunsch_path_info(*args, **kwargs).cigar
135
+ end
136
+ alias needleman_wunsch_trace_cigar needleman_wunsch_cigar
137
+ alias needleman_wunsch_trade_cigar needleman_wunsch_cigar
138
+
139
+ private
140
+
141
+ def validate_width(width)
142
+ return if width.nil? || [0, 8, 16, 32, 64].include?(width)
143
+
144
+ raise ArgumentError, "width must be nil, 0, 8, 16, 32, or 64"
145
+ end
146
+
147
+ def resolve_gaps(gap_score, gap_open_score, gap_extend_score)
148
+ open_score = gap_open_score.nil? ? gap_score : gap_open_score
149
+ extend_score = gap_extend_score.nil? ? open_score : gap_extend_score
150
+ [open_score, extend_score]
151
+ end
152
+
153
+ def materialize_path(path, query, target)
154
+ query_points = query.each_char.to_a
155
+ target_points = target.each_char.to_a
156
+ query_index = path.query_start
157
+ target_index = path.target_start
158
+ aligned_query = []
159
+ aligned_target = []
160
+ path.operations.each_char do |operation|
161
+ if operation == "=" || operation == "X"
162
+ aligned_query << query_points[query_index]
163
+ aligned_target << target_points[target_index]
164
+ query_index += 1
165
+ target_index += 1
166
+ elsif operation == "D"
167
+ aligned_query << query_points[query_index]
168
+ aligned_target << "-"
169
+ query_index += 1
170
+ else
171
+ aligned_query << "-"
172
+ aligned_target << target_points[target_index]
173
+ target_index += 1
174
+ end
175
+ end
176
+ AlignmentResult.new(
177
+ **path.to_h,
178
+ aligned_query: aligned_query.join,
179
+ aligned_target: aligned_target.join
180
+ )
181
+ end
182
+
183
+ def alignment_path(query, target, local, match_score:, mismatch_score:,
184
+ gap_score:, gap_open_score:, gap_extend_score:,
185
+ width:, matrix:)
186
+ validate_width(width)
187
+ query = scalar_query(query)
188
+ target = scalar_query(target)
189
+ open_score, extend_score = resolve_gaps(
190
+ gap_score, gap_open_score, gap_extend_score
191
+ )
192
+ if matrix
193
+ if match_score != 2 || mismatch_score != -1 || !width.nil?
194
+ raise ArgumentError,
195
+ "match_score, mismatch_score, and width cannot be used with matrix"
196
+ end
197
+ path = matrix_alignment(
198
+ query, target, matrix, local,
199
+ gap_score: gap_score, gap_open_score: gap_open_score,
200
+ gap_extend_score: gap_extend_score, traceback: true
201
+ )
202
+ return materialize_path(path, query, target)
203
+ end
204
+
205
+ attributes = __primary_backend.alignment_path(
206
+ query, target, local, match_score, mismatch_score,
207
+ open_score, extend_score
208
+ )
209
+ aligned = attributes.delete(:aligned)
210
+ AlignmentResult.new(
211
+ **attributes,
212
+ aligned_query: aligned.fetch(:query),
213
+ aligned_target: aligned.fetch(:target)
214
+ )
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StrideAlign
4
+ module BackendKind
5
+ GENERIC = "generic"
6
+ SWAR = "swar"
7
+ X86_SSE41 = "sse41"
8
+ X86_AVX2 = "avx2"
9
+ X86_AVX512BWVL = "avx512bwvl"
10
+ X86_AVX10_256 = "avx10_256"
11
+ X86_AVX10_512 = "avx10_512"
12
+ LINUX_AARCH64_NEON = "neon"
13
+ LINUX_AARCH64_SVE = "sve"
14
+ LINUX_AARCH64_SVE2 = "sve2"
15
+ MACOS_ARM64_NEON = "neon"
16
+ LINUX_LOONGARCH64_LSX = "lsx"
17
+ LINUX_LOONGARCH64_LASX = "lasx"
18
+ LINUX_POWERPC64_VSX = "vsx"
19
+ LINUX_RISCV64_RVV = "rvv"
20
+ end
21
+
22
+ BackendRecord = Struct.new(:kind, :name, :compiled, :available, keyword_init: true)
23
+
24
+ class << self
25
+ def stride_backend
26
+ @backend_name
27
+ end
28
+
29
+ def stride_available_backends
30
+ __available_backend_names.dup
31
+ end
32
+
33
+ def available_backends
34
+ stride_available_backends.map do |name|
35
+ BackendRecord.new(kind: name, name: name, compiled: true, available: true)
36
+ end
37
+ end
38
+
39
+ def backend_is_available(kind)
40
+ __available_backend_names.include?(kind.to_s)
41
+ end
42
+
43
+ def detect_best_backend
44
+ stride_backend
45
+ end
46
+ end
47
+ end