R және C ++-лердегі бірдей есептеулер әртүрлі нәтиже береді?

Менде C ++-ға айналдыратын R коды бар. Ол файлды оқиды, кейіпкерлерді талдайды және тонналар мен тонна құралдарды және стандартты ауытқуларды есептеп, оларды қайтарады, сонымен қатар әр таңбаның қанша санының пайда болғанын санайды.

Енді R нәтижелерінің ондық мәндерінде және C ++-дегі айырмашылықтар аз. Есептеу матрицасында, олар сандар болып саналады, сандар бірдей. Дегенмен, құралдардың матрицасында құндылықтар жүзден астам орынға тең және олардан өзгеше. Стандартты ауытқу матрицасы бойынша мәндер одан да көп - оныншы орынға дейін.

Мұның себебі неде? R мен C ++ сандары ондыққа ие сандармен жұмыс істейтін жолдардағы дәлдік айырмашылығының бір түрі бар деп ойлаймын. Мен білмеймін, компьютерлер басынан бастап өзгермелі нүктелерді көрсетуде ең жақсы емес, бірақ қай өнімді жақсы деп айта аламын?

... Мен тырысып көрген нәрсе - R, C ++ және Windows 7-дегі калькулятордағы sqrt (41111.5/4522) есептеулерін орындау. Олар бірдей нәтиже береді. Неліктен сол кезде дәл сол есептеу есептеу кезінде орындалады, олар айырмашылығы бар ма? Орындалу уақытында C ++ калькулятормен келіседі, ал R - бірден-бір. Сондай-ақ, осы үлкен көлемдегі есептерді орындаған кезде, кейінірек шығарылым алдыңғы шығудан біршама аздап өзгереді. Көптеген есептеулер жасаған кезде ғана Р жарғысы бар ма? Мәміле дегеніміз не?

Міне қаражаттың нәтижесі:

C ++:

38.6068 39.0122 38.633 38.5914 0
38.6159 38.7874 38.5053 38.7195 0
38.5205 38.7352 38.3694 38.5388 0
38.6331 38.7408 38.4588 38.5283 0
38.7503 38.6933 38.4173 38.6808 0
38.7637 38.7978 38.4967 38.603 0
38.7616 38.7384 38.4728 38.6946 0
38.6227 38.7689 38.4016 38.5352 0
38.5993 38.7334 38.3206 38.5514 0
38.6395 38.6598 38.43 38.4887 0
38.6414 38.746 38.4353 38.4908 0
38.4353 38.6767 38.3158 38.4694 0
38.35 38.5801 38.1486 38.3528 0
38.4122 38.6267 38.1731 38.3447 0
38.3751 38.5353 38.1782 38.2229 0
38.3373 38.6117 37.8952 38.2017 4.12443
38.332 38.4991 38.027 38.1984 0
38.2005 38.4417 38.0192 38.0446 4.12443
38.1719 38.4435 37.9727 38.0385 0
38.1346 38.3878 37.8634 37.9746 0
37.8505 38.2289 37.6202 37.6986 0
38.0932 38.142 37.7865 37.815 4.12443
37.9176 38.1381 37.5577 37.7273 0
37.7346 38.0934 37.4874 37.6546 0
37.6961 37.897 37.3342 37.4844 0
37.5534 37.9234 37.3341 37.3369 0
37.4914 37.7409 37.094 37.3211 0
37.2179 37.6653 36.9031 37.2592 0
37.0682 37.5625 36.6972 37.0218 4.12443
36.9713 37.4819 36.5387 36.8767 4.12443
36.8284 37.2411 36.223 36.6869 4.12443
36.7396 36.9682 36.0171 36.4556 4.12443
36.7874 36.9482 36.1641 36.5667 4.12443
36.695 36.9307 36.1856 36.3638 0
36.7224 36.9455 36.2212 36.695 4.12443
36.8983 37.1286 36.2652 36.8055 0
36.7835 36.8905 35.9562 36.4745 0
36.5364 36.9037 36.0927 36.4888 0
36.3959 36.6637 35.7378 36.323 0
35.9372 36.2034 35.452 35.6974 0

R:

            A        C        G        T N
[1,] 38.60573 39.01141 38.63195 38.59036 0
[2,] 38.61464 38.78523 38.50391 38.71826 0
[3,] 38.51908 38.73228 38.36774 38.53731 0
[4,] 38.63182 38.73834 38.45730 38.52657 0
[5,] 38.74903 38.69083 38.41585 38.67933 0
[6,] 38.76250 38.79534 38.49556 38.60156 0
[7,] 38.76039 38.73632 38.47145 38.69319 0
[8,] 38.62123 38.76703 38.40030 38.53354 0
[9,] 38.59810 38.73163 38.31917 38.55015 0
[10,] 38.63819 38.65792 38.42873 38.48740 0
[11,] 38.64002 38.74333 38.43387 38.48920 0
[12,] 38.43359 38.67401 38.31414 38.46783 0
[13,] 38.34827 38.57804 38.14686 38.35125 0
[14,] 38.41038 38.62463 38.17138 38.34302 0
[15,] 38.37329 38.53267 38.17653 38.22097 0
[16,] 38.33555 38.60949 37.89278 38.19956 4
[17,] 38.33024 38.49720 38.02496 38.19627 0
[18,] 38.19842 38.43880 38.01730 38.04205 4
[19,] 38.16998 38.44113 37.97058 38.03598 0
[20,] 38.13242 38.38488 37.86108 37.97245 0
[21,] 37.84771 38.22579 37.61745 37.69546 0
[22,] 38.09113 38.13806 37.78409 37.81250 4
[23,] 37.91487 38.13428 37.55473 37.72422 0
[24,] 37.73137 38.09007 37.48473 37.65181 0
[25,] 37.69295 37.89276 37.33098 37.48131 0
[26,] 37.54974 37.91984 37.33063 37.33263 0
[27,] 37.48773 37.73676 37.09027 37.31701 0
[28,] 37.21365 37.66051 36.89896 37.25519 0
[29,] 37.06418 37.55768 36.69254 37.01714 4
[30,] 36.96674 37.47745 36.53390 36.87150 4
[31,] 36.82324 37.23622 36.21721 36.68085 4
[32,] 36.73433 36.96207 36.01076 36.44930 4
[33,] 36.78201 36.94274 36.15842 36.56135 4
[34,] 36.68991 36.92524 36.17984 36.35769 0
[35,] 36.71720 36.94031 36.21548 36.68985 4
[36,] 36.89332 37.12322 36.25921 36.80057 0
[37,] 36.77870 36.88471 35.94958 36.46900 0
[38,] 36.53080 36.89801 36.08650 36.48348 0
[39,] 36.38996 36.65730 35.73058 36.31767 0
[40,] 35.93152 36.19707 35.44496 35.69141 0
3
str (yourData) және apply (сіздің Даталарыңыз, 2, қорытынды) сөзімен бөлісе аласыз ба? Мен осы мәселеге əсер ететін басқа да мəселелер бар ма екенін білгім келеді. Мұндай келіспеушіліктер, мысалы, тілде емес, іске асырылуда. Екі AFAIK, IEEE-754 стандартына сәйкес (өте) стандарттарға сәйкес келеді. Мәселен, деректерде не болып жатқанын көрейік ...
қосылды автор Iterator, көзі
Сіз, мүмкін, бұл соққы емес, бірақ көп рет адамдар келіспеушіліктер туындайды, өйткені олар INTs жұптасады немесе, кем дегенде, жиі керек.
қосылды автор Iterator, көзі
Әдетте, C ендірулерінде екі түрлі өзгермелі нүкте түрлері бар: float және double , онда double дәлірек болады. Мен R бөлшектері туралы өте аз білемін, бірақ ол бұл түрлердің біреуін (екеуі де) пайдаланады. Егер сіздің C ++ кодыңызда float көп болса, R дәлірек дәлірек болады және оны double арқылы өзгертуге болады. Егер C ++ кодында double қолданылса, бұл кері жағдайда дұрыс.
қосылды автор David Thornley, көзі
Қарапайым есептеу R, C ++ және Калькулятордағы әртүрлі нәтижелерді береді, бірақ үлкен жүгірістің ортасында ғана бар ма? Оның мінез-құлқын қайсысы өзгертеді және қанша?
қосылды автор Beta, көзі
бұл fp spec/C ++ компиляторының нұсқалары туралы және аздаған бастапқы коды туралы мәселе туралы жаңылыстыруға көмектеседі.
қосылды автор Necrolis, көзі
Орташа мәнді қалыптастыру үшін қанша нөмір қосасыз? Сандар қандай көрінеді? Олардың минималды/максималды саны қандай цифрлы сандар? Сіз оларды R-ге қалай жаздыңыз? Олар C ++ сияқты шынымен бірдей ме? Мысалы, оларды C ++ мәтіндік файлына сақтасаңыз, сіз дәлдікті жоғалтасыз.
қосылды автор Tommy, көзі
... жақсы, сіз сол кезде R кезінде қалай жасайсыз? R әр түрлі кодтауды қолдануы мүмкін, ақ кеңістікті басқаша және т.б. өңдеуі мүмкін.
қосылды автор Tommy, көзі
Олар қаншалықты ерекшеленеді? Есептердің нәтижелерін орналастыра аласыз ба?
қосылды автор NickLH, көзі
@Beta Yep, бұл дұрыс. Меніңше, R өзгереді ... Мен кейбір үлгілік шығарылымды орналастырдым
қосылды автор Pojo, көзі
Мен C ++-те тек екі есе үлкейтемін. Мен жүзуді ешқашан пайдаланбаймын. : Р
қосылды автор Pojo, көзі
Мен осы кестелердегі әрбір мәнді қалыптастыру үшін шамамен 6000 нөмірді қосып отырмын. Сандар басынан бастау үшін сандар болып табылмайды ... олар функцияны пайдаланып сандарға түрлендіретін таңбалар болып табылады: return 10 * log (1 + pow (10, ( -64)/10))/log (10); мұндағы , анық, таңба.
қосылды автор Pojo, көзі

3 жауаптар

Сіздер білесіздер, кез-келген нәрсе жалғасуы мүмкін. Осылайша, мен бір экзотикалық ықтимал себебі бола аламын.

One possibility is that R is performing computations in such a way as to minimize floating-point error; you wouldn't necessarily do this in C++ or when computing by hand, unless you knew better. In particular, you should sort your values in increasing order of exponent before you compute an aggregate sum (which should be the first step of any accurate averaging procedure). The reason for this is that floating-point arithmetic is not associative (unless you're using arbitary-precision libraries, which I assume is not the case). Due to rounding, (a + b) + c can equal c if a >> b, c whereas a + (b + c) would give a result larger than a (assuming a, b, c > 0). This is especially possible if R e.g. parallelizes its work, in which case you can reasonably expect to get a slightly different result every time!

Басқа экзотикалық мүмкіндіктері төмендегілерді қамтиды: R және C ++ кодтары мағыналы болса да, біршама нәзік болады (мүмкін, 72-ші элементті өткізіп жібергенде бір қате бар немесе сіз STDEV-ды n-1-ні қолдана отырып есептеп, басқа және т.б.); R пен C ++ арасындағы айырмашылық бар, бұл негізінен осы айырмашылыққа әкеледі (әртүрлі дәлдік - екі есе көп есе, екі есе көп және т.б.), әртүрлі кітапхананы іске асыру және т.б.).

Бұл сіздің мәселеңізге қатысы бар-жоқтығын білмеймін, бірақ егер ештеңе ештеңе оны пайдалы деп таппаса, қайсысы өзгермелі нүкте әрекеттерінің нәтиже бермейтінін түсіну қиын болса.

3
қосылды
R көзінен summary.c: 385, R ұзындығы екі еселенген s = 0, t = 0 (парафрирование); (i = 0; i және if (R_FINITE ((қос) s)) {for (i = 0; i .
қосылды автор Martin Morgan, көзі
@Tommy: сұрыптау кезінде айтарлықтай шығындар болуы мүмкін, менің ойымша, негізгі хабарламасы - R есептеуін басқа тәртіпте жасай алатындығына сенімдімін - бұл жарамды мүмкіндік болып қала береді. Мен айтып өткенімдей, параллелизация осыдан туындауы мүмкін. Сондай-ақ, R векторын қалай таңдағанына байланысты, үстіңгі қабат өте ыңғайлы болуы мүмкін. Мен R-ні біраз күрделі өңдеу логикасын жасау үшін қоймас едім. Сонда да, егер Р осындай нәрсе істеп жатса, онда ол бір жерде құжатталуы керек ...?
қосылды автор Patrick87, көзі
Мен R санатындағы сұрыптау бойынша өзгермелі нүктелік қателерді азайтатынына күмәнданамын. Үлкен векторға sort қоңырау шалу mean қоңырауынан көп көп қабылдайды. Және қазіргі уақытта (R 2.13.2) осы операцияларды параллелизирует.
қосылды автор Tommy, көзі

Мен тексеретін бірнеше нәрсе:

  • It may be a difference between using float and double or even long double. If you're using double it may be that R uses float. Try using float if its easy to switch between the two.
  • Check the floating point precision mode set in your compiler (for example, VC2010) and try different settings.
  • Ensure that all your calculations in C++ properly cast to double/float. For example, this code:

     double Test = 1.0 + 3/2;
    

    results in 2 not 2.5. R may cast such expressions differently leading to the differences seen in your results.

  • Double check that the functions in R and C++ are identical. For example, maybe cos() in R expects degrees while it is radians in C++. If in doubt make a quick test application in both to confirm.
  • If all else fails take one specific calculation and log/output detailed diagnostics for it in both the R and C++ applications. At some point you should begin to see the difference and trace back to where it originates. Try it with a smaller sample and see if you can replicate the behavior with just 6/60 samples instead of 6000.

Мен байқаған бір нәрсе, C ++ нәтижелерінің соңғы бағанында 4,12443, ал Р-ны береді. 4. Егер бұл жай ғана бейнебет мәселесі болса, онда неге бұлай дейді. Мүмкін, R ішіндегі бір нәрсе бүтін санға айналады, бірақ C ++-де емес.

2
қосылды

Жақсы, мен C ++ мәндерін пайдаланамын, негізінен соңғы соңғы бағандағы uesp түсінігімен арқасында, R кейбір аралық қадамда бір бүтін санға ауысып, кейбір дәлдікті жоғалтады. Мен C ++-дегі әрбір қадамда екі есе үлестіремін, сондықтан оған көп сенемін (... түсіндірілген тілдерді бірден бастауға әрдайым әділ сенімсіз болғанымды айтпаймын)

1
қосылды
R аралық кезеңде бүтін санға ауысу шынымен екіталай көрінеді. Мен мұнда не болып жатқанын шынымен білетініне сенімді емеспін ... Егер мен сен болсам, бұл мені алаңдатады. Дегенмен, мәселе комитеттің бұзылуын және қашықтан басқару арқылы жеткілікті болып көрінеді, себебі ол сәттілікке жете алмайды.
қосылды автор Ben Bolker, көзі