1. C++ / Говнокод #6644

    +164

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    template < int Order, typename T >
    struct PrefixSum {
      static inline void update ( T* a ) throw () { *a += *(a-1); PrefixSum < Order-1, T > :: update( a+1 ); }
    };
    
    template < typename T >
    struct PrefixSum < 1,T > {
      static inline void update ( T* a ) throw () { *a += *(a-1); }
    };
    
    template < int P, int N, int Condition = 0 > 
    struct Bpn {
      enum { value = N * ( Bpn < P-1, N-1, (N > P) > :: value - Bpn < P-1, N, (N > P-1) > :: value ) };
    };
    
    template < int P, int N > struct Bpn < P, N, !0 > { enum { value = 0 }; };
    template < int P >        struct Bpn < P, 0,  0 > { enum { value = P ? 0 : 1 }; };
    template < int P >        struct Bpn < P, 1,  0 > { enum { value = P & 1 ? 1 : -1 }; };
    
    template < typename Ta, typename Tb, bool C > struct IfThenElse;
    template < typename Ta, typename Tb > struct IfThenElse < Ta, Tb, true  > { typedef Ta TRes; };
    template < typename Ta, typename Tb > struct IfThenElse < Ta, Tb, false > { typedef Tb TRes; };
    
    template < int K, int I = 1 >
    struct MomentSeries {
      typedef typename IfThenElse < MomentSeries<K,I+1>, MomentSeries<K,K>, (I<K) >::TRes SubT;
      static inline double accumulate ( double const* psum ) throw () {
        return Bpn < K, I > :: value * psum [ I + 1 ] + SubT :: accumulate ( psum );
      }
    };
    
    template < int K >
    struct MomentSeries < K, K > {
      static inline double accumulate ( double const* psum ) throw () {
        return Bpn < K, K > :: value * psum [ K + 1 ];
      }
    };
    
    template < int Order >
    struct MomentLoop {
      static inline void assign ( double *moments, size_t momentStride, double const* psum ) throw() {
        *(moments - momentStride) = MomentSeries < Order-1 > :: accumulate ( psum );
        MomentLoopAssign < Order-1 > :: assign ( moments - momentStride, momentStride, psum ); 
      }
    };
    
    template <>
    struct MomentLoop < 1 > {
      static inline void assign ( double *moments, size_t momentStride, double const* psum ) throw() {
        moments [ 0 ] = MomentSeries < 1, 1 > :: accumulate ( psum );
        *(moments - momentStride) = psum [ 1 ];
      }
    };
    
    /**
     * Function computes a series of geometric moments by prefix summation method:
     * Zhou F., Kornerup P. Computing Moments by Prefix Sums. // VLSI Signal Proc. - 2000. - 25. - P. 5 - 17.
     * @param data is first data elemet address.
     * @param ndataItems is number of data items.
     * @param dataStride is the number of elements between two neighbor data items, 
     *        in case of simple array dataStride is equal to 1.
     * @param moments is address of 0-order moment.
     * @param momentStride is number of elements between two neigbor moment items,
     *        in case of consequtive moments placement, momentStride is equal to 1.
     */
    
    template < int Order, class OutPolicy >
    inline void psmoment ( double const* data, 
                           size_t const  ndataItems,
                           size_t const  dataStride,
                           double*       moments,
                           size_t const  momentStride ) throw() { 
      double psum [ Order+1 ] = { 0 };
      // Initialize prefix sum
      for ( size_t i = ndataItems, j = ndataItems * dataStride; i; ) {
        --i; j -= dataStride; psum [ 0 ] = data [ j ];
        PrefixSum < Order, double > :: update ( psum+1 );
      }
      // convert psum to moment values 
      OutPolicy :: assign ( moments + Order * momentStride, momentStride, psum );
    }

    Вы - тестовая площадка, перед написанием статьи в пфп ;)

    Запостил: ngry, 12 Мая 2011

    Комментарии (35) RSS

    • Идите нахуй, крестобляди! Даже не думайте соваться в ПФП со своим приплюснутым.

      Достоинства ФП - чистота, лаконичность кода, высокий уровень абстракции. А здесь - полный ужоснах!

      Моноиды он соорудил, бля...
      Ответить
      • Болит что-то у тебя, друже. Хочешь, угадаю что?
        Ответить
    • Идите получше поготовьтесь:

      test.cpp: In static member function ‘static void MomentLoop<Order>::assign(double*, size_t, const double*)’:
      test.cpp:155: error: ‘MomentLoopAssign’ was not declared in this scope
      test.cpp:155: error: ‘::assign’ has not been declared

      ПФП не нужна, ФП не нужно, сабжевые темплитоизъёбства не нужны,
      работать это ладом не будет, зато будет со скрипом тормозить не хуже жабы.
      Ответить
      • http://www.oonumerics.org/blitz/whatis.html
        Ответить
        • показать все, что скрытоСервер не найден













          Firefox не может найти сервер www.oonumerics.org.








          * Проверьте, не допущена ли ошибка при наборе адреса, например, ww.example.com вместо www.example.com

          * Если ни одна страница не загружается – проверьте настройки соединения с Интернетом.

          * Если компьютер или сеть защищены брандмауэром или прокси-сервером – убедитесь, что Firefox разрешен выход в Интернет.
          Ответить
    • Error E2184 test.cpp 125: Enum syntax error
      Error E2040 test.cpp 125: Declaration terminated incorrectly
      Error E2190 test.cpp 125: Unexpected }
      Error E2190 test.cpp 126: Unexpected }
      Error E2238 test.cpp 161: Multiple declaration for 'MomentLoop<1>::assign(double *,unsigned int,const double *) throw()'
      Error E2344 test.cpp 153: Earlier declaration of 'MomentLoop<1>::assign(double *,unsigned int,const double *) throw()'
      Warning W8026 test.cpp 165: Functions with exception specifications are not expanded inline
      Warning W8027 test.cpp 187: Functions containing for are not expanded inline
      *** 6 errors in Compile **

      Хотите замечаний - напишите то, что можно скомпилять без ошибок, запустить и получить какой-то результат.
      Ответить
      • line 43:
        - MomentLoopAssign < Order-1 > :: assign ( moments - momentStride, momentStride, psum );
        + MomentLoop < Order-1 > :: assign ( moments - momentStride, momentStride, psum );
        Ответить
    • А за вычитание из указателя нужно делать очень больно: к указателю прибавлять правильно умеют очень немногие.
      Ответить
    • Я вынужден признаться.
      Я не осилил этот код.
      Ответить
    • Зачем это все??? Понятно, что и на С++ так можно, но зачем...
      Ответить
      • Хочется чтобы компилятор за меня посчитал LUT и развернул пару циклов.
        Ещё, это всё весьма древние техники, см. например, http://www10.informatik.uni-erlangen.de/~pflaum/pflaum/ProSeminar/meta-art.html
        Ответить
        • Т.е. априори считаeтся, что реализация этого алгоритма "постаринке" еще страшнее и бесплатным бонусом получаем еще и выигрыш по скорости?
          Ответить
          • Нет, в реализации по-старинке нет ничего страшного. Выигрыш таки получаем, но правило 80-20 работает ;)
            Ответить
        • LUT - можно и заранее подготовить.
          заменили цикл рекурсией - быстрей будет?
          Ответить
          • 1. Да, можно, но он ограничен размером (элементы под диагональю матрицы размером Order х Order, не хочется его готовить каждый раз когда нужен будет другой Order). Хотя тут другая проблема, для Order > 12 начинаются целочисельные переполнения ;)
            2. В сгенерированном коде нет рекурсии (разве что в очень древних компиляторах).
            Ответить
            • 2. Да это я ерунду сказал, там пачки инлайнов будут.
              Ответить
      • Эх, дорогуша, не понимаешь ты плюсоепской души. Сейчас объясню на пальцах: крестоебы всегда стараются выдать рандомную вырвиглазную говноконструкцию за б-женькино творение (а как иначе себе внушить, что ты не жрал говно всю жизнь?). Например, такую тривиальную парашу как рекурсивный макроэкспанд называют "мощнейшими компайл-тайм вычислениями", или жуткую мешанину из ооп-говна за "моделирование предметной области", выдумывают всякие "объектные декомпозиции", думаю, вменяемым людям не надо объяснять почему эта красивая сказочка провалилась и на практике не работает.
        А все это из детства идет: да, тяжелое крестодество с деревянными игрушками и каленым железом выжженные в мозгах мысли -- "кроме крестов языков нет", "ооп -- наше всё", "не спалил хард после очередного сегфолта -- не мужик", "один раз -- не пидорас", в этой плоскости крестофильство пересекается с идеями долбославия: когда протестантизм завещает работать над собой и создавать блага, славя величие Господа, православие требует от последователя искупления греха, посредством непрерывного страдания, как страдал Иисус неся свой крест. Стрелять себе в ногу и нажираясь потом водкой, позерски ноя о тяжестях нищебродской жизни -- что может быть лучше для православного плюсоеба?
        Ответить
        • Издайте мемуары, милейший, мы почитаем. Хорошо у вас получается, да пока мало ;)
          Ответить
        • IT-евангелистов знаю, а тут прям IT-Антихрист :) Супротив креста (или даже двух:) святого народ подстрекает!
          Ответить
        • Лиспофаг с ЧСВ?
          Ответить
          • За что всегда презирали императивные отбросы так это за их адовую ментальную ограниченность, если хотите, зашоренность. Но вдруг в их лексиконе возникло новое (для них) слово - Лисп.
            Легко объяснить сей факт: просто кто-то рядом с их курятником вскользь упомянул про какие-то DSL, Code-as-Data на Лиспе. Вот так петушки стали подозревать, что существует что-то помимо плюсов и говняшной. Это если не считать тех слухов про соседний вольер и макак обучаемых жаве и сисярпу.
            Бедные, бедные недолюдишки, наверно им тяжело обитать на самой нижней ступени эволюции, не понимать и малой толики процессов, происходящих вокруг них и уж тем более зверски беспощадных мат. теорий, которых, надо заметить, в хвост и гриву имеют эти ироды - функциональные боги.
            Ответить
        • Это что-то на уровне Минаева, и даже выше.
          Ответить
    • вот эта поебота(строка нумер 13) не будет компилится в мсвц8
      enum { value = N * ( Bpn < P-1, N-1, (N > P) > :: value - Bpn < P-1, N, (N > P-1) > :: value ) }

      вот так будет компилится, но работь ессно не будет, впрочем ладно, не важно, похуй
      enum { value = N * ( Bpn < P-1, N-1, (N >= P) > :: value - Bpn < P-1, N, (N >= P-1) > :: value ) };
      Ответить
    • зачем это и для чего?
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий