Pull to refresh
2
0
Send message
Эх. Если бы вы этот текст сказали с самого начала, беседа пошла совсем по иному пути. У меня не складывается впечатления, что вы хотите узнать что-то новое. Вы достаточно агрессивно отстаиваете точку зрения что предлагаемое и так работает. Вы и так уверены в том, что оно работает, зачем защищиться? А вот если бы вы хотели узнать новое, то просто переспросили бы пару раз вместо нападения.
разумеется я с этим согласен. А остальные мои аргументы вам не важны?
И это нормально, разделить две независимые сущности: функцию и ее производную. Ведь фактически вы строите два параллельных (но связанных) итерационных процесса. Если вам в будущем захочется рассмотреть третью сущность, вам так и так менять код.

Вы явно не хотите услышать простого: перегрузить арифметическую операцию — хорошее решение только тогда, когда у вас первая производная. Когда нужно вычислить сразу вторую — становится сложнее. Вам код переписывать нужно тогда, когда подход с символьным пакетом сработает без изменений.

И мы с размаху вляпываемся во все прелести Not Invented Here, когда нужно проверять, одинаково ли мы с разработчиками понимаем задачу, а кроме того, надеяться, что библиотека будет поддерживаться на тех платформах, на которых мы планируем поддерживать нашу программу…


Я вам предлагаю не готовый код, а подход. И вам решать, пойти по этому маршруту или нет. В обоих случаях есть свои минусы и плюсы. Вы явно от меня ждете готовых ответов там, где я предлагаю задуматься.

Насчет NIH, извините, это аргумент не к месту. Математика — она на всех одна. И тот же GiNaC будет вычислять так, как того математика требует. Проблемы будут с поддержкой JIT генерации байт-кода — тут да, это еще область исследований, готового подхода нет. Хотя вот Numba для Python'а уже показывает результаты, сравнимые с кодом на numpy (то есть на фортране, быстрее уже вряд ли выйдет), но это пример немного не отсюда.
В разы проще и быстрее в поддержке:
— нет класса Derivable
— нет рефакторинга, когда нужно добавить поддержку, например, второй производной.
— композиция функций и другие естественные конструкции инкапсулированы в строке, которую обрабатывает внешняя специализированная библиотека. Оно не размазано по коду в форме
Derivable xd = Derivable::IndependendVariable(x);
Derivable xsq = xd*xd;
Derivable res = cos(xsq);

трех последовательных присваиваний, за порядком которых приходится следить и сверяться с формулой на бумаге. Цитируемый код заменяется одной строкой в духе
interpreter.evaluate("cos(x^2)", "x = 1");

— в итоге дает меньше шансов выстрелить себе в ногу
— и вообще, всякое явное представление концепции лучше, чем более низкоуровневое описание ее следствий (формула целиком против алгоритма, который ее вычисляет)
— работает, наверное, со сравнимой скоростью внутри горячего цикла, медленнее на старте (накладные расходы на символьные манипуляции) — это зависит от библиотеки, которую вы возьмете. Со сравнимой скоростью должен работать JIT подход, чисто символьное вычисление, конечно, будет медленным.
— работает одинаково хорошо для простых примеров, так и для сложных. Вторая производная, производная спец. функций, попытка аналитически решить уравнение до решения численно — это возможно, и инкапсулировано в специализированном пакете, который для того и писан. Посмотрите на возможности GiNaC — вы вряд ли хотите переписывать его функционал.

Если вы сомневаетесь в точности численного ответа, то у вас к вариантам сменить численный метод прибавляется еще вариант попробовать решить точно, символьно. Этот ответ лежит на поверхности. И я его тут даже указывал, в других комментариях.

Вот это сравнение увидеть и хотелось бы, а не то, что вы написали.


Вообще-то в этом треде я отвечал юзеру Mrrl, который хотел именно численного метода для производной. Он хотел именно этого — я показал, что численно сойтись к производной возможно.
У меня выше со скобками неверно, правильно читать так:

BytecodeObject symbolic_iteration = interpreter.generate_bytecode(interpreter.evaluate("diff( (k*dx-f*f)*dx, x )") );
Извините, а вы зачем эту беседу ведете? Чего добиваетесь? Не хотите послушать рассказ о том, что бывает иначе чем вы привыкли — ну и не слушайте. Зачем мое время тратите?

Если всмотритесь в код вот в этом каменте (см ниже, habrahabr.ru/company/intel/blog/170729/#comment_5937833), увидите что композицию функций и правда можно не реализовывать руками, а дать специальной библиотеке символьных вычислений сделать свое дело. Причем сделать его гарантированно правильно, для любых выражений. В том числе тех, которые вам прямо сейчас не нужны, а через день потребуют рефакторинга вашего писаного самостоятельно кода — когда окажется, что вам и вторая производная нужна, и спец. функции бы неплохо добавить, и не ОДУ, а уравнения в частных производных и т.п.
Мне кажется, вы столкнулись с непривычным вам решением и совершенно не прилагаете усилий понять что вам предлагают. Сходили бы по ссылкам-то, для начала, почитали что там пишут. Ну и про JIT тоже почитали бы.

Грубо говоря, я предлагаю сделать следующее:

<code>
  BytecodeObject symbolic_iteration = interpreter.generate_bytecode(interpreter.evaluate("diff(k*dx-f*f)*dx,x)") );
  double f=a;
  double df = 0;
  int N=1000000;
  double dx=1.0/N;
  for(int k=0;k<N;k++)
  {
     f+=(k*dx-f*f)*dx;
    df += symbolic_iteration(k,dx,f);
  }
</code>


Тут я псевдокод написал, но должно быть понятно, о чем я:
— перед генерацией байт-кода происходит автоматическое вычисление производной от символьного выражения, эквивалентного одному шагу численного алгоритма,
— для один раз созданного выражения генерация байт-кода происходит автоматически,
— внутри горячего цикла происходит выполнение бинарного кода, вычисляющего один шаг численного алгоритма, сходящегося к производной решения ОДУ.

При этом interpreter у вас уже есть и поддерживается другой командой разработчиков. Никакого «однажды при любом изменении кода программы» у вас нет — однажды добавили сторонюю библиотеку в проект и поехали.
посмотрите пожалуйста мой камент выше habrahabr.ru/company/intel/blog/170729/#comment_5937583

Мне кажется, вы под символьными вычислениями сейчас поняли безкомпромисное решение «все целиком считать символьно, а когда данные распухнут, вот посчитаем в точке». Нет, я лишь предлагаю построить аналог вашего класса, который производную той же одной итерации посчитает однажды, но символьно. И по результату построит быстрый байт-код. Вы получите те же два параллельных численных процесса, каждый сходящийся к своему ответу, но символьные манипуляции вы получите гарантированно правильно.
Вы видимо себе представляете процесс символьного вычисления производной единственно возможным способом как построение скобочной структуры символьных итераций первых производных, которые затем символьно упрощаются (получаем многочлен), и уже потом вычисляется значение многочлена в точке. В такой схеме, разумеется, выражение распухнет.

Если уж предлагать все варианты, которые предлагает символьный счет, то их я вижу как минимум два:
— построение точного решения, то есть не численно. Для данного случайного диффура есть точное решение. В точке его вычислить — легко. При известных оговорках, в определенных случаях это может быть быстрее численного счета. Но я его ввиду не имел, а имел следующий:
— однажды совершить символьную манипуляцию, эквивалентную вашей итерации, перегнать результат в байт-код и на каждом шаге цикла быстро вычислять. Получится тот же численный процесс, сходящийся к производной решения ОДУ. Только в этом случае вы будете использовать инструментарий, который вам точно не позволит выстрелить в ногу.

А о том, как растут символьные данные я в курсе, у меня были символьные вычисления с полтерабайта данных для переопределенных систем.
Это забавно. Я вам говорю, что в предлагаемом решении приходится композицию функций реализовывать руками и это минус, а вы в ответ уверяете, что все замечательно работает. Да работать может даже если на ассемблере будете писать, но дык мой комментарий же не об этом.
эммм, чего? Пакеты символьных вычислений будут экспоненциально быстро накапливать данные, если эти данные сохранять и не перезаписывать. В каждой уважающей себя системе компьютерной алгебры есть средство «забывания» ненужных переменных. Ну или можно просто присваивать новые значения на место старых.

По ссылкам будет скорее всего не то, чего вы ожидаете, но все же:
code.google.com/p/numexpr/
beltoforion.de/muparsersse/math_expression_compiler_en.html
muparser.beltoforion.de/mup_features.html#idDef2
www.codeproject.com/Articles/45797/Fast-Polymorphic-Math-Parser
Это из первых хитов поиска на «fast math formula evaluation JIT», хотя в сторону muparsersse я в какой-то момент смотрел.

Если интересны более продвинутые C++ движки символьных вычислений, но без JIT и фокуса на «много раз вычислить», то можно посмотреть на
www.ginac.de/
и
Ev3:
www.lix.polytechnique.fr/~liberti/Ev3.pdf
www.lix.polytechnique.fr/~liberti/Ev3-1.0.tar.gz

А кроме того, можно же ж и комбинировать: сначала символьно поманипулировать внутри ginac/Ev3, потом отдать быстровычислятелю в заданных точках.
Спасибо, теперь понятнее. Помогло то, что вы сначала явно определяете xsq, а потом вручную вычисляете косинус от xsq.

Главная претензия у меня следующая: код топикстартера синтаксически поддерживает аддитивность и правило Лейбница (произведение производных), но нет синтаксической поддержки для композиции функций. Вы в своем примере композицию реализовывали руками. Как вы понимаете, это открывает широкое поле для всевозможных багов, особенно когда формулы становятся хоть сколько-нибудь сложными.

На всякий случай уточню — у меня есть некий опыт работы с системами компьютерной алгебры (CAS), включая такие экзотические как FORM. В большинстве CAS проблем из предыдущего абзаца нет в принципе, но в FORM все специфично. У него синтаксической поддержки для взятия производных нет, но возможно написать цикл подстановок, эквивалентный символьному дифференцированию. Фактически, приходится вручную прописывать аддитивность производной, правило Лейбница и производную композиции. В общем, это поучительный был опыт. А тут топикстартер наступает на грабли и главное не пытается вслух и громко сказать о глючевых ограничениях его дизайна.

Возвращаясь к миру быстрых вычислений (CAS в общем случае медленные), я встречал код для символьных манипуляций, специально заточенный под задачу «один раз символьно проманипулировать, потом очень много раз быстро вычислять». По сравнению с символьным движком предлагаемый стиль программирования выглядит ну… велосипедом с квадратными колесами. По крайней мере до того, как сформулированы критерии дизайна, из-за которых готовые решения не годятся. Да и начиналась статья в духе «поставили задачу, решил и вдруг потом открыл для себя новый мир аналогичных решений».
Конечно, если учесть правило дифференцирования сложной функции, будет работать. А теперь посмотрите в код топикстартера.
Собственно, в посте теория с практикой небрежно друг с другом связаны, в следующем смысле: если было достаточно решить конкретное уравнение (в котором композиции нет), то вопросов нет. Хотя получается, что вся ответственность за вывод формул на бумажке и все возможные при этом глюки переносятся на программиста.
Если я правильно понял, этот метод не заработает даже для композиции элементарных функций (например, sin(x^2)). В смысле, возможно работать будет, но выдавать будет лажу. Это если не пытаться рассматривать интегралы от элементарных функций и, как частный случай, спец. функции. Вы бы хоть от математической постановки задачи стартовали, а то фиг знает какие у вас тут грабли спрятаны.

И неясно, зачем было изобретать велосипед, если есть пакеты для символьных манипуляций, к тому же с трансляцией в байт-код (аналог JIT). Отказ от рефакторинга может быть слабым аргументом против принциальных ограничений выбранного подхода, но задачу, опять же, вы не сформулировали.
Я не слышал ни разу что использование числа переносов в качестве метрики кем-то используется вообще


Возможно, вы имели ввиду верстку только таблиц, но в ТеХе именно число переносов (взвешенное, суммированное со штрафами за другие типографические события) является метрикой, которую оптимизируют во время верстки текста. Не возьмусь утверждать, что в ТеХе таблицы расчитываются ровно так же (давно не заглядывал в TeXbook).
Сейчас прочитать статью по вашей ссылке не успел, только общую идею с первой страницы. Думаю, это частичные решения, потому что кроме расположения ячеек нужно еще учитывать «плохость» (термин не мой, а Кнута) текста внутри ячеек. Плохость в ТеХе определяется как функция отклонений межсловных интервалов от нормальных (эти значения берут из данных кернинга шрифта), штрафов за переносы и ряд характерных типографических событий типа «нельзя однобуквенный заглавный предлог оставлять в конце строки». Без оптимизации набора внутри ячеек получается то, что вы видите в поликлиниках на стенах, то есть — никуда не годится.
А вы не смотрели алгоритмы верстки таблиц в LaTeX'е, в качестве образца? Там наверняка есть много поучительного, и идеи для верстки в ТеХе исходно стоят на хорошем алгоритмическом/математическом фундаменте.
Похоже на то. Вот тут tabletrepublic.com/forum/android-mini-pc/2537-mini-pc-benchmark-comparison-8-print.html дают таблицу wifi драйверов и наименований TV stick'ов. На том славном форуме на slatedroid еще не видел, чтоб кто-нибудь обсуждал драйвера от Mediatek (как раз случай UG007), но может это потому, что оно из коробки работает :) Пока PicUntu точно поддерживает встроенный wifi на RTL8188EUS и BCM40181.

Кроме поддержки встроенного wifi еще присмотритесь к отзывам, точно ли будут полные 1.6Ghz и синезуб. Некоторые железки (например моя) пока под этим линуксом умеют разбегаться только до 1.2Ghz. Синезуб только на некоторых моделях, он кажется не на SoC живет.
интересно, почему так дешево. В любом случае, это перепродажа, тут гарантией точно не пахнет.

С другой стороны, тут железка на cortex A5 (против A9 у UG007), разгоняется максимум до 1.2 Ghz (против 1.6Ghz у UG007) и памяти 786MB (вместо 1GB). Если нужна производительность и память, ваш планшет и UG007 две несравнимых железяки. Разница в производительности между Cortex A5 и A9 значительная.
кто такой air play не знаю, а xbmc для MK808 уже есть.

Information

Rating
Does not participate
Location
Великобритания
Works in
Date of birth
Registered
Activity