Как взять набор чисел типа {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
здесь, очевидно, гармоника номер три гораздо ближе к 4, чем к 2. но 135+86 = 221 = 2x110,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
1 ответ
Я нашел довольно простое решение с очень низкой вычислительной мощностью.
Это включает в себя предоставление оценки близости для каждого разрыва.
чтобы вычислить оценку близости для промежутка 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) и использует какой-то процесс Ньютона-Рафсона, начиная с ранее рассчитанной точки, чтобы изолировать локальный максимум.
в любом случае, вот код:
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;
}