如何接受一组数字,如{301,102,99,202,198,103}并扔掉~100?

可能重复:
从潜在谐波确定基频的算法

如果您正在考虑投票以结束此问题,请先抓住您的马并查看评论。

我回过头来计算一组谐波的基频,其中一些谐波丢失了。

我正在做的是查看相邻谐波之间的间隙。 我会得到一组数字,例如:

pH(1): (1,2) -> 107.410568 pH(2): (2,3) -> 111.918732 pH(3): (3,4) -> 219.100800 pH(4): (4,5) -> 106.097473 pH(5): (5,6) -> 113.122009 pH(6): (6,7) -> 112.224731 pH(7): (7,8) -> 124.215942 

从这里我需要计算一个基础。 在这种情况下,~110。

有一个额外的问题,有时一个特定的谐波会出来,例如:

 pH(1): (1,2) -> 107.376312 pH(2): (2,3) -> 135.100433 pH(3): (3,4) -> 86.590515 pH(4): (4,5) -> 111.350891 pH(5): (5,6) -> 110.659119 pH(6): (6,7) -> 111.361755 pH(7): (7,8) -> 108.807129 

在这里,显然谐波数3比2更接近4但是135 + 86 = 221 = 2×110.5

有谁能建议算法?

这是一个更完整的数据转储:

 Analysing Frame: 4! (Peak[0].power=496.263458, .freq=209.053009 (Peak[1].power=60.337341, .freq=306.794373 (Peak[2].power=46.169617, .freq=457.628998 (Peak[3].power=10.675227, .freq=576.183167 (Peak[4].power=8.550637, .freq=752.681885 (Peak[5].power=3.088022, .freq=840.088318 (Peak[6].power=4.913011, .freq=1044.712402 (Peak[7].power=1.566417, .freq=1201.859741 (Peak[8].power=1.343318, .freq=1350.521240 (Peak[9].power=7.540891, .freq=1600.914307 Harmonic PeakPair: (0,1)=2/3, error:0.01474 => f0 @ 103.395645 Harmonic PeakPair: (0,2)=1/2, error:0.04318 => f0 @ 218.933746 Harmonic PeakPair: (0,3)=1/3, error:0.02949 => f0 @ 200.557037 Harmonic PeakPair: (0,4)=1/4, error:0.02774 => f0 @ 198.611740 Harmonic PeakPair: (0,5)=1/4, error:0.00115 => f0 @ 209.537537 Harmonic PeakPair: (0,6)=1/4, error:0.04989 => f0 @ 235.115555 Harmonic PeakPair: (0,7)=1/5, error:0.02606 => f0 @ 224.712479 Harmonic PeakPair: (0,8)=1/5, error:0.04521 => f0 @ 239.578629 Harmonic PeakPair: (0,9)=1/6, error:0.03608 => f0 @ 237.936035 Harmonic PeakPair: (0,10)=1/7, error:0.03643 => f0 @ 244.831329 pH(1): (1,2) -> 150.834625 pH(2): (2,3) -> 118.554169 pH(3): (3,4) -> 176.498718 pH(4): (4,5) -> 87.406433 pH(5): (5,6) -> 204.624084 pH(6): (6,7) -> 157.147339 pH(7): (7,8) -> 148.661499 pH(8): (8,9) -> 250.393066 pH(9): (9,10) -> 363.353149 ~ Analysing Frame: 5! (Peak[0].power=323.802490, .freq=107.108635 (Peak[1].power=156.096497, .freq=212.943176 (Peak[2].power=65.058685, .freq=327.891602 (Peak[3].power=55.066936, .freq=443.307678 (Peak[4].power=11.969029, .freq=662.717896 (Peak[5].power=12.774710, .freq=771.691284 (Peak[6].power=3.965956, .freq=991.746338 (Peak[7].power=1.290497, .freq=1218.169434 (Peak[8].power=1.384800, .freq=1428.509766 (Peak[9].power=6.819193, .freq=1651.377319 Harmonic PeakPair: (0,1)=1/2, error:0.00299 => f0 @ 106.790115 Harmonic PeakPair: (0,2)=1/3, error:0.00667 => f0 @ 108.202919 Harmonic PeakPair: (0,3)=1/4, error:0.00839 => f0 @ 108.967773 Harmonic PeakPair: (0,4)=1/5, error:0.03838 => f0 @ 119.826111 Harmonic PeakPair: (0,5)=1/6, error:0.02787 => f0 @ 117.861923 Harmonic PeakPair: (0,6)=1/7, error:0.03486 => f0 @ 124.393341 pH(1): (1,2) -> 114.948425 pH(2): (2,3) -> 115.416077 pH(3): (3,4) -> 219.410217 pH(4): (4,5) -> 108.973389 pH(5): (5,6) -> 220.055054 (gdb) continue ~ Analysing Frame: 6! (Peak[0].power=351.608368, .freq=106.752106 (Peak[1].power=115.021736, .freq=226.598923 (Peak[2].power=71.564438, .freq=332.445831 (Peak[3].power=45.963409, .freq=441.119476 (Peak[4].power=10.906013, .freq=660.755127 (Peak[5].power=7.464951, .freq=768.980408 (Peak[6].power=6.169244, .freq=881.256714 (Peak[7].power=3.427589, .freq=987.147461 (Peak[8].power=1.140599, .freq=1214.196167 (Peak[9].power=1.282757, .freq=1426.420532 Harmonic PeakPair: (0,1)=1/2, error:0.02889 => f0 @ 110.025787 Harmonic PeakPair: (0,2)=1/3, error:0.01222 => f0 @ 108.783691 Harmonic PeakPair: (0,3)=1/4, error:0.00800 => f0 @ 108.515991 Harmonic PeakPair: (0,4)=1/5, error:0.03844 => f0 @ 119.451569 Harmonic PeakPair: (0,5)=1/6, error:0.02784 => f0 @ 117.457756 Harmonic PeakPair: (0,6)=1/6, error:0.04553 => f0 @ 126.814110 Harmonic PeakPair: (0,7)=1/7, error:0.03472 => f0 @ 123.886589 pH(1): (1,2) -> 105.846909 pH(2): (2,3) -> 108.673645 pH(3): (3,4) -> 219.635651 pH(4): (4,5) -> 108.225281 pH(5): (5,6) -> 112.276306 pH(6): (6,7) -> 105.890747 (gdb) continue ~ Analysing Frame: 7! (Peak[0].power=441.757996, .freq=109.572845 (Peak[1].power=75.059662, .freq=333.819489 (Peak[2].power=44.463955, .freq=439.749634 (Peak[3].power=10.445498, .freq=658.419373 (Peak[4].power=7.832435, .freq=773.341919 (Peak[5].power=6.903655, .freq=876.133972 (Peak[6].power=3.478840, .freq=988.908691 (Peak[7].power=0.862488, .freq=1213.805176 (Peak[8].power=0.325413, .freq=1321.078613 (Peak[9].power=1.074599, .freq=1428.187744 Harmonic PeakPair: (0,1)=1/3, error:0.00509 => f0 @ 110.423004 Harmonic PeakPair: (0,2)=1/4, error:0.00083 => f0 @ 109.755127 Harmonic PeakPair: (0,3)=1/5, error:0.03358 => f0 @ 120.628357 Harmonic PeakPair: (0,4)=1/6, error:0.02498 => f0 @ 119.231583 Harmonic PeakPair: (0,5)=1/6, error:0.04160 => f0 @ 127.797585 Harmonic PeakPair: (0,6)=1/7, error:0.03206 => f0 @ 125.422760 pH(1): (1,2) -> 105.930145 pH(2): (2,3) -> 218.669739 pH(3): (3,4) -> 114.922546 pH(4): (4,5) -> 102.792053 pH(5): (5,6) -> 112.774719 (gdb) continue ~ Analysing Frame: 8! (Peak[0].power=329.370514, .freq=107.008003 (Peak[1].power=121.794647, .freq=216.109497 (Peak[2].power=95.227448, .freq=330.530731 (Peak[3].power=51.529533, .freq=441.920685 (Peak[4].power=10.398799, .freq=660.634460 (Peak[5].power=8.171947, .freq=771.948364 (Peak[6].power=7.004751, .freq=883.576904 (Peak[7].power=3.711878, .freq=991.915100 (Peak[8].power=1.043736, .freq=1212.797363 (Peak[9].power=0.866450, .freq=1425.700073 Harmonic PeakPair: (0,1)=1/2, error:0.00484 => f0 @ 107.531372 Harmonic PeakPair: (0,2)=1/3, error:0.00959 => f0 @ 108.592453 Harmonic PeakPair: (0,3)=1/4, error:0.00786 => f0 @ 108.744087 Harmonic PeakPair: (0,4)=1/5, error:0.03802 => f0 @ 119.567444 Harmonic PeakPair: (0,5)=1/6, error:0.02805 => f0 @ 117.833038 Harmonic PeakPair: (0,6)=1/6, error:0.04556 => f0 @ 127.135406 Harmonic PeakPair: (0,7)=1/7, error:0.03498 => f0 @ 124.355087 pH(1): (1,2) -> 114.421234 pH(2): (2,3) -> 111.389954 pH(3): (3,4) -> 218.713776 pH(4): (4,5) -> 111.313904 pH(5): (5,6) -> 111.628540 pH(6): (6,7) -> 108.338196 (gdb) continue ~ Analysing Frame: 9! (Peak[0].power=323.231262, .freq=110.575546 (Peak[1].power=125.892311, .freq=216.045319 (Peak[2].power=144.429672, .freq=329.892181 (Peak[3].power=11.046881, .freq=658.773499 (Peak[4].power=8.210341, .freq=768.891541 (Peak[5].power=6.895733, .freq=882.592957 (Peak[6].power=4.029165, .freq=993.767395 (Peak[7].power=1.674952, .freq=1237.208374 (Peak[8].power=0.383828, .freq=1425.728271 (Peak[9].power=6.948928, .freq=1652.006470 Harmonic PeakPair: (0,1)=1/2, error:0.01182 => f0 @ 109.299103 Harmonic PeakPair: (0,2)=1/3, error:0.00185 => f0 @ 110.269806 Harmonic PeakPair: (0,3)=1/5, error:0.03215 => f0 @ 121.165123 Harmonic PeakPair: (0,4)=1/6, error:0.02286 => f0 @ 119.362068 Harmonic PeakPair: (0,5)=1/6, error:0.04138 => f0 @ 128.837189 Harmonic PeakPair: (0,6)=1/7, error:0.03159 => f0 @ 126.271156 pH(1): (1,2) -> 113.846863 pH(2): (2,3) -> 328.881317 pH(3): (3,4) -> 110.118042 pH(4): (4,5) -> 113.701416 pH(5): (5,6) -> 111.174438 (gdb) continue ~ Analysing Frame: 10! (Peak[0].power=433.398010, .freq=107.317390 (Peak[1].power=77.993584, .freq=330.160217 (Peak[2].power=44.671906, .freq=437.536530 (Peak[3].power=2.209188, .freq=572.636963 (Peak[4].power=11.950575, .freq=659.227478 (Peak[5].power=8.283246, .freq=770.578369 (Peak[6].power=7.082703, .freq=881.237488 (Peak[7].power=4.196370, .freq=992.599243 (Peak[8].power=0.347792, .freq=1101.406372 (Peak[9].power=0.496907, .freq=1221.087769 Harmonic PeakPair: (0,1)=1/3, error:0.00829 => f0 @ 108.685394 Harmonic PeakPair: (0,2)=1/4, error:0.00472 => f0 @ 108.350761 Harmonic PeakPair: (0,3)=1/5, error:0.01259 => f0 @ 110.922394 Harmonic PeakPair: (0,4)=1/5, error:0.03721 => f0 @ 119.581436 Harmonic PeakPair: (0,5)=1/6, error:0.02740 => f0 @ 117.873566 Harmonic PeakPair: (0,6)=1/6, error:0.04489 => f0 @ 127.095154 Harmonic PeakPair: (0,7)=1/7, error:0.03474 => f0 @ 124.558640 Harmonic PeakPair: (0,8)=1/7, error:0.04542 => f0 @ 132.330582 pH(1): (1,2) -> 107.376312 pH(2): (2,3) -> 135.100433 pH(3): (3,4) -> 86.590515 pH(4): (4,5) -> 111.350891 pH(5): (5,6) -> 110.659119 pH(6): (6,7) -> 111.361755 pH(7): (7,8) -> 108.807129 (gdb) continue ~ Analysing Frame: 11! (Peak[0].power=301.910400, .freq=110.975166 (Peak[1].power=74.653061, .freq=222.941483 (Peak[2].power=96.621552, .freq=330.352051 (Peak[3].power=46.238697, .freq=442.270782 (Peak[4].power=11.802574, .freq=661.371582 (Peak[5].power=8.117818, .freq=767.469055 (Peak[6].power=7.903056, .freq=880.591064 (Peak[7].power=4.756960, .freq=992.815796 (Peak[8].power=0.474961, .freq=1117.031738 (Peak[9].power=0.436229, .freq=1223.791870 Harmonic PeakPair: (0,1)=1/2, error:0.00222 => f0 @ 111.222954 Harmonic PeakPair: (0,2)=1/3, error:0.00260 => f0 @ 110.546257 Harmonic PeakPair: (0,3)=1/4, error:0.00092 => f0 @ 110.771431 Harmonic PeakPair: (0,4)=1/5, error:0.03220 => f0 @ 121.624741 Harmonic PeakPair: (0,5)=1/6, error:0.02207 => f0 @ 119.443336 Harmonic PeakPair: (0,6)=1/6, error:0.04064 => f0 @ 128.870178 Harmonic PeakPair: (0,7)=1/7, error:0.03108 => f0 @ 126.403000 Harmonic PeakPair: (0,8)=1/7, error:0.04351 => f0 @ 135.275558 pH(1): (1,2) -> 107.410568 pH(2): (2,3) -> 111.918732 pH(3): (3,4) -> 219.100800 pH(4): (4,5) -> 106.097473 pH(5): (5,6) -> 113.122009 pH(6): (6,7) -> 112.224731 pH(7): (7,8) -> 124.215942 (gdb) continue ~ Analysing Frame: 12! (Peak[0].power=276.669220, .freq=107.785210 (Peak[1].power=66.769165, .freq=237.818069 (Peak[2].power=138.767258, .freq=330.801727 (Peak[3].power=11.674421, .freq=658.715271 (Peak[4].power=8.167289, .freq=768.212402 (Peak[5].power=7.488355, .freq=882.716919 (Peak[6].power=4.416694, .freq=993.001709 (Peak[7].power=0.375417, .freq=1116.808472 (Peak[8].power=0.594698, .freq=1223.301270 (Peak[9].power=1.041116, .freq=1428.525635 Harmonic PeakPair: (0,1)=1/2, error:0.04677 => f0 @ 113.347122 Harmonic PeakPair: (0,2)=1/3, error:0.00750 => f0 @ 109.026230 Harmonic PeakPair: (0,3)=1/5, error:0.03637 => f0 @ 119.764130 Harmonic PeakPair: (0,4)=1/6, error:0.02636 => f0 @ 117.910309 Harmonic PeakPair: (0,5)=1/6, error:0.04456 => f0 @ 127.452347 Harmonic PeakPair: (0,6)=1/7, error:0.03431 => f0 @ 124.821304 Harmonic PeakPair: (0,7)=1/7, error:0.04635 => f0 @ 133.664642 pH(1): (1,2) -> 92.983658 pH(2): (2,3) -> 327.913544 pH(3): (3,4) -> 109.497131 pH(4): (4,5) -> 114.504517 pH(5): (5,6) -> 110.284790 pH(6): (6,7) -> 123.806763 (gdb) continue ~ Analysing Frame: 13! (Peak[0].power=374.303864, .freq=111.099991 (Peak[1].power=95.248856, .freq=330.270538 (Peak[2].power=44.554127, .freq=439.593628 (Peak[3].power=11.259159, .freq=659.028381 (Peak[4].power=7.960227, .freq=772.035156 (Peak[5].power=6.881539, .freq=880.567810 (Peak[6].power=4.322595, .freq=990.723938 (Peak[7].power=0.696263, .freq=1207.584595 (Peak[8].power=0.975314, .freq=1427.747314 (Peak[9].power=6.522787, .freq=1651.469360 Harmonic PeakPair: (0,1)=1/3, error:0.00306 => f0 @ 110.595085 Harmonic PeakPair: (0,2)=1/4, error:0.00273 => f0 @ 110.499199 Harmonic PeakPair: (0,3)=1/5, error:0.03142 => f0 @ 121.452835 Harmonic PeakPair: (0,4)=1/6, error:0.02276 => f0 @ 119.886261 Harmonic PeakPair: (0,5)=1/6, error:0.04050 => f0 @ 128.930649 Harmonic PeakPair: (0,6)=1/7, error:0.03072 => f0 @ 126.315994 Harmonic PeakPair: (0,7)=1/8, error:0.03300 => f0 @ 131.024033 pH(1): (1,2) -> 109.323090 pH(2): (2,3) -> 219.434753 pH(3): (3,4) -> 113.006775 pH(4): (4,5) -> 108.532654 pH(5): (5,6) -> 110.156128 pH(6): (6,7) -> 216.860657 (gdb) continue ~ Analysing Frame: 14! (Peak[0].power=270.657196, .freq=108.657944 (Peak[1].power=159.946777, .freq=215.400558 (Peak[2].power=70.223312, .freq=330.803284 (Peak[3].power=44.181171, .freq=442.037598 (Peak[4].power=11.405427, .freq=660.210876 (Peak[5].power=7.531929, .freq=768.298645 (Peak[6].power=6.746090, .freq=879.789978 (Peak[7].power=4.604754, .freq=993.830872 (Peak[8].power=1.025858, .freq=1216.780762 (Peak[9].power=1.027342, .freq=1432.005981 Harmonic PeakPair: (0,1)=1/2, error:0.00445 => f0 @ 108.179108 Harmonic PeakPair: (0,2)=1/3, error:0.00487 => f0 @ 109.462852 Harmonic PeakPair: (0,3)=1/4, error:0.00419 => f0 @ 109.583672 Harmonic PeakPair: (0,4)=1/5, error:0.03542 => f0 @ 120.350060 Harmonic PeakPair: (0,5)=1/6, error:0.02524 => f0 @ 118.353859 Harmonic PeakPair: (0,6)=1/6, error:0.04316 => f0 @ 127.644806 Harmonic PeakPair: (0,7)=1/7, error:0.03352 => f0 @ 125.316895 pH(1): (1,2) -> 115.402725 pH(2): (2,3) -> 111.234314 pH(3): (3,4) -> 218.173279 pH(4): (4,5) -> 108.087769 pH(5): (5,6) -> 111.491333 pH(6): (6,7) -> 114.040894 (gdb) continue ~ Analysing Frame: 15! (Peak[0].power=250.447220, .freq=110.362984 (Peak[1].power=158.152161, .freq=215.532776 (Peak[2].power=66.299492, .freq=331.592072 (Peak[3].power=39.972214, .freq=436.681610 (Peak[4].power=11.086418, .freq=658.636780 (Peak[5].power=7.820132, .freq=767.756409 (Peak[6].power=5.995249, .freq=881.713013 (Peak[7].power=3.804143, .freq=994.803406 (Peak[8].power=0.285258, .freq=1088.384888 (Peak[9].power=1.440606, .freq=1220.270020 Harmonic PeakPair: (0,1)=1/2, error:0.01205 => f0 @ 109.064682 Harmonic PeakPair: (0,2)=1/3, error:0.00051 => f0 @ 110.446838 Harmonic PeakPair: (0,3)=1/4, error:0.00273 => f0 @ 109.766693 Harmonic PeakPair: (0,4)=1/5, error:0.03244 => f0 @ 121.045166 Harmonic PeakPair: (0,5)=1/6, error:0.02292 => f0 @ 119.161194 Harmonic PeakPair: (0,6)=1/6, error:0.04150 => f0 @ 128.657578 Harmonic PeakPair: (0,7)=1/7, error:0.03192 => f0 @ 126.238876 Harmonic PeakPair: (0,8)=1/7, error:0.04146 => f0 @ 132.923264 pH(1): (1,2) -> 116.059296 pH(2): (2,3) -> 105.089539 pH(3): (3,4) -> 221.955170 pH(4): (4,5) -> 109.119629 pH(5): (5,6) -> 113.956604 pH(6): (6,7) -> 113.090393 pH(7): (7,8) -> 93.581482 (gdb) continue ~ Analysing Frame: 16! (Peak[0].power=225.168457, .freq=109.963272 (Peak[1].power=148.453613, .freq=212.786423 (Peak[2].power=65.515800, .freq=331.216644 (Peak[3].power=42.287544, .freq=441.486938 (Peak[4].power=11.021669, .freq=659.767517 (Peak[5].power=8.184300, .freq=770.097107 (Peak[6].power=6.571711, .freq=881.203125 (Peak[7].power=3.726031, .freq=987.573914 (Peak[8].power=1.173631, .freq=1215.363892 (Peak[9].power=0.564619, .freq=1320.823242 Harmonic PeakPair: (0,1)=1/2, error:0.01678 => f0 @ 108.178238 Harmonic PeakPair: (0,2)=1/3, error:0.00134 => f0 @ 110.184410 Harmonic PeakPair: (0,3)=1/4, error:0.00093 => f0 @ 110.167503 Harmonic PeakPair: (0,4)=1/5, error:0.03333 => f0 @ 120.958389 Harmonic PeakPair: (0,5)=1/6, error:0.02388 => f0 @ 119.156395 Harmonic PeakPair: (0,6)=1/6, error:0.04188 => f0 @ 128.415222 Harmonic PeakPair: (0,7)=1/7, error:0.03151 => f0 @ 125.522629 pH(1): (1,2) -> 118.430222 pH(2): (2,3) -> 110.270294 pH(3): (3,4) -> 218.280579 pH(4): (4,5) -> 110.329590 pH(5): (5,6) -> 111.106018 pH(6): (6,7) -> 106.370789 

我发现了一个相当简单的解决方案,它的计算能力非常低。

它涉及为每个差距提供接近度分数。

为了计算间隙i的接近度得分,我简单地将1 / {dist(gap_i,gap_j)+1}加到所有j!= i

我坚持+1以避免被零除。 这样,如果两个值几乎相等,则得分为1,随着差距的增加,该分数将变为0

但如果Gap j几乎恰好是间隙i的两倍,那么它也应该被视为非常接近。 所以我首先得到最接近gap_j / gap_i的整数(可能必须交换以使gap_j更大),然后将gap_j除以此整数,然后考虑dist(gap_i,fiddled_gap_j)

如果例如gap_j~ = 2 * gap_i,那么我小心提高Gap_i的分数,而不是gap_j

这非常适合获得一个相当准确的候选人。 一些更多的处理过程应该很容易地改进价值。 第一个我想是根据成功的候选人平均值。 然后可能是第二个创建谐波(f)函数,并使用从先前计算的点开始的某种Newton-Raphson过程来隔离局部最大值。

无论如何,fwiw这里是代码:

  float ascertain_f0(PEAK * peaks, POTENTIAL_HARMONIC * pH, int phCount) { int gaps = phCount; // enumerate GAPS GAP gap [ MAX_POTENTIAL_HARMONICS ]; gap[0].len = peaks[pH[0].peakQ].freq; for (int i=1; i < gaps; i++) { int a = pH[i-1].peakQ, b = pH[i].peakQ; gap[i].len = peaks[b].freq - peaks[a].freq; } for (int i=0; i < gaps; i++) gap[i].score = 0.; // find best scoring gap for (int i=0; i < gaps; i++) for (int j=0; j < gaps; j++) { if (i == j) continue; float a = gap[i].len; float B_ = gap[j].len; if (a > B_) continue; // a < B_ int multiplier = closestInt(B_ / a); float b = B_ / multiplier; float dist = fabs(b - a); float sc = 1. / (dist + 1.); gap[i].score += sc; if (multiplier == 1) gap[j].score += sc; } int best = 0; for (int i=1; i < gaps; i++) if (gap[i].score > gap[best].score) best = i; return gap[best].len; }