2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5, 6, 7  След.
 
 Re: Программирование для математиков: класс Polynomial
Сообщение15.11.2018, 21:30 
Экс-модератор
Аватара пользователя


23/12/05
10807
VTsalyuk в сообщении #1337243 писал(а):
Случилось страшное! Я имею еще идею разработки класса матриц (в математическом смысле) на таком же примитивном уровне. С демонстрацией простенького примера наследования (строка и столбец как частные случаи матрицы). Это тоже считаете вредным?

разве что для демонстрации...

Если для использования в вычислениях, тогда уж точно путь в Matlab (или что-то подобное, скажем, Python), который создан для работы с матрицами, гораздо более надёжен, универсален, документирован. С/С++ нужен, имхо, для высокопроизводительных вычислений где-нибудь у конечного пользователя. Математику для прототипирования или решения разовых задач выбор С/С++ в качестве языка программирования очень маловероятно будет хорошим решением - потратить месяц на написание программы для вычисления за 10 секунд, вместо написания за день и вычисления за 5 минут - кому нужна такая "экономия"? При этом выгода в скорости появится только если вы хороший специалист и напишете действительно высокоэффективный код. Как пример для студентов - он тоже не лучший в плане простоты и наглядности пример.

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

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение15.11.2018, 22:42 
Заслуженный участник
Аватара пользователя


27/04/09
24110
Уфа
VTsalyuk в сообщении #1337243 писал(а):
С демонстрацией простенького примера наследования (строка и столбец как частные случаи матрицы).
Это не случай, при котором есть смысл использовать наследование.

Кроме того (не помню, говорили тут уже или ещё нет) польза наследования некоторыми преувеличивается. Многие вещи естественнее решаются композицией или ссылками на функции; в языках с интерфейсами реализация интерфейса часто лучше наследования классу, и так далее. Вот инкапсуляция — это всегда дело, я не припомню причин (кроме глубокой оптимизации) ею пренебрегать. Ну и третий столп классического ООП, полиморфизм, в современных языках возможен не только через ООПный dynamic dispatch.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 03:23 
Экс-модератор
Аватара пользователя


23/12/05
10807
Добрался до кода.
Это хороший пример, как писать не стоит. Часть была озвучена выше, возможно, я что-то продублирую, часть, видимо, будет новой добавкой, бОльшая часть, скорее всего, при первом прочтении не будет озвучена вовсе.

1) В коде масса граблей, на которые рано или поздно предстоит наступить, а можно было бы их не раскладывать:
а) наличие неконстантных указателей на неконстантные данные там, где это, очевидно, не нужно, может поломать данные, которые менять вы не планировали;
б) Потенциально бесконечные циклы (типа while(1) - можно же условие выхода записать тут, а не вставлять брейки. Кстати об eps там: а почему это static переменная, а не аргумент ф-ции Cut()? - неужели не может быть, что в одной и той же задаче для одних многочленов eps следует задать одним, а для других - другим? - каждый раз дергать eps - не лучшее решение.
в) шастание указателями по памяти там, где это не дает прироста производительности, и без которого можно обойтись.
г) отсутствие фигурных скобок у однострочных циклов и if-ов - не ошибка, но частый источник, порой сложнозамечаемых багов
д) не ошибочные, но странные мелочи, типа проверки на равенство unsigned int и даблового нуля.
e) ошибки компиляции, которые вы получили при многократном включении заголовочных файлов, - за это линейкой по пальцам надо. Это же стандартные вещи и решать их надо не заметанием под ковер, а цивилизованными методами, типа использования #pragma once или, хуже, но тоже допустимо, оборачивания в #ifndef
2) Эффективность.
a) Вы навязываете использование double, даже если пользователю хватит целых чисел или float. Проблема решается темплейтными классами.
б) Наличие переменных и операций, без которых можно обойтись (например i в циклах, где оно непосредственно в вычислениях не участвует, а только инкрементится)
в) Сравнение плохого кода на С с отвратительным на Maple - не показатель. Используйте готовые функции в Maple, типа taylor(), а не то, что вы себе там придумали. Языки типа Matlab, Maple действительно будут в десятки, а в худшем случае и в десятки тысяч раз медленнее, если вы будете их использовать криво, однако базовые операции реализованы на том же самом С и зашиты в ядро, и тут-то, конечно, тоже переплюнуть их можно по быстродействию, но придется повозиться.
3) Стиль. Его просто нет: с большой буквы, с маленькой, кэмелкейс, снейккейс - все вперемешку. Похожим образом могут называться классы, функции, типы, переменные...
4) Это не С++. Откройте для себя стандартные контейнеры типа std::vector и операции с ним, такие как std::transform(), std::for_each() и др. и замените бОльшую часть циклов однострочными гораздо более безопасными командами. Забудьте про alloc() - free() (да и new - delete вам в этом классе не нужны). Отговорки, что сначала изучим базу для понимания, а потом уже перейдем к С++, не принимаются. Это плохой путь сначала учить плохому и даже опасному (чего стоит только ваш конструктор Polynomial(unsigned n, double * p) вместо, скажем, Polynomial(std::vector<double> const& p), а потом якобы сложному, но более надежному. Вообще говоря, С и С++ - разные языки и, если вы учите С++, то учите С++, а не (плохому) С с жалкими вкраплениями плюсов.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 08:41 
Заслуженный участник
Аватара пользователя


02/08/11
5395
1г - субъективно и спорно.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 12:10 


24/08/18
21
А я с 1г соглашусь. Наблюдение за учащимися показало, что писать
Используется синтаксис C
if()
  {
  };

а потом думать, что туда вписать -- полезная привычка. Но когда код отлажен, я предлагаю при желании убрать операторные скобки.

За #pragma once спасибо. А оно сработает, если использовать уже откомпилированный Polynomial.obj?

По поводу многих других замечаний photon'а писать не буду: скучно. Многие из них вызваны незнакомством в предыдущими обсуждениями на форуме, с текстами документов, с последней версией, с целями этого учебного пособия. Если вы знаете vector, то оно уже давно не для вас.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 13:53 
Заслуженный участник


20/08/14
5502
Россия, Москва
А я с 1г частично не соглашусь: вместо
Используется синтаксис C
if ()
{
  <один_оператор>;
};
почти всегда пишу
Используется синтаксис C
if () <один_оператор>;
if () { <один_оператор>; };
Вот последний вариант лично для меня и наиболее приемлем, но придерживаюсь не всегда, потому и согласен лишь частично.
Пример:
Используется синтаксис C
if (a) b++; else c--;//вполне понятно и обозримо
if (a) { b++; } else { c--; };//хуже из-за визуального загромождения, хотя плюс что видна группировка по блокам
if (a)
{
  b++;
}
else
{
  c--;
};//8 строк вместо одной это ужас-ужас для столь простого кода

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

VTsalyuk в сообщении #1354696 писал(а):
с целями этого учебного пособия. Если вы знаете vector, то оно уже давно не для вас.
Вот тут полностью согласен с photon и остальными: учить стоит сразу правильному и хорошему, а не абы чему - переучивать потом окажется на порядок сложнее. Впрочем об этом уже не однажды сказали и толку похоже нет.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 14:14 
Заслуженный участник
Аватара пользователя


30/01/06
67859
У меня возражения к 1е. Качественные заголовки должны не вызывать ошибок, сколько бы раз их ни вставляли. При этом не #pragma, потому что это не переносимо, а именно #ifndef.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 15:32 
Заслуженный участник
Аватара пользователя


16/07/14
2852
Москва
VTsalyuk в сообщении #1354696 писал(а):
Но когда код отлажен, я предлагаю при желании убрать операторные скобки
Зачем? Байты экономить?
Dmitriy40 в сообщении #1354715 писал(а):
Используется синтаксис C
if (a) b++; else c--;//вполне понятно и обозримо
if (a) { b++; } else { c--; };//хуже из-за визуального загромождения, хотя плюс что видна группировка по блокам
if (a)
{
  b++;
}
else
{
  c--;
};//8 строк вместо одной это ужас-ужас для столь простого кода

Я за вот такое подход:
Используется синтаксис C
if (x) {
  f();
} else if (y) {
  g();
} else {
  h();
}


Несколько операций на одной строке - это ужасно. Вот как в вашем if (a) b++; else c--; хотя бы breakpoint на b++ поставить?

(Оффтоп)

И кстати, если возвращаемое значение не используется - используйте преинкремент вместо постинкремента; компиляторы конечно умные, но для некоторых типов не справятся.

Так 1е ровно про это.
Munin в сообщении #1354718 писал(а):
При этом не #pragma, потому что это не переносимо, а именно #ifndef.
Это спорный вопрос. Я в целом за переносимость, но #pragma once поддерживается настолько широко, что можно принять волевое решение и отказаться от поддержки не поддерживающих ее компиляторов.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 16:08 
Заслуженный участник


06/07/11
5213
кран.набрать.грамота
VTsalyuk в сообщении #1354696 писал(а):
Если вы знаете vector, то оно уже давно не для вас.
А если не знаете - тоже не для вас, потому что надо сначала узнать vector...

(Оффтоп)

mihaild в сообщении #1354736 писал(а):
Вот как в вашем if (a) b++; else c--; хотя бы breakpoint на b++ поставить?
Пошаговый отладчик javascript в Firefox худо-бедно умеет такие строки отрабатывать пошагово, кстати.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение17.11.2018, 23:25 
Заслуженный участник
Аватара пользователя


16/07/14
2852
Москва

(Оффтоп)

rockclimber в сообщении #1354747 писал(а):
Пошаговый отладчик javascript в Firefox худо-бедно умеет такие строки отрабатывать пошагово, кстати.
Отладчик, который не позволяет такое пройти пошагово - плохой отладчик. Вопрос именно в постановке breakpoint (это может быть полезно, если скажем наш код начал падать на b++).

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение18.11.2018, 00:58 
Экс-модератор
Аватара пользователя


23/12/05
10807
Munin в сообщении #1354718 писал(а):
У меня возражения к 1е. Качественные заголовки должны не вызывать ошибок, сколько бы раз их ни вставляли. При этом не #pragma, потому что это не переносимо, а именно #ifndef.

Представьте, что вам предстоит сделать проект, задействующий несолько достаточно сложных алгоритмов. Потом вы напишете как положено, но для начала решили запрототипировать на основе найденных нескольких чужих решений с открытым кодом. И так сложилось, что в каждом из них разработчики написали свой класс, скажем, Matrix, а какие-то из них еще и недальновидно использовали достаточно простые дефайны. В результате в разных подпроектах, разных каталогах, из которых вы как доктор Франкенштейн лепите монстра есть заголовочные файлы с одинаковыми именами и одинаковыми дефайнами. Такое пересечение может привести к проблемам, которых не будет при использовании #pragma once, который поддерживается сейчас всеми популярными компиляторами (во всяком случае, студийный, gcc и clang поддерживают)

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение18.11.2018, 01:24 
Заслуженный участник
Аватара пользователя


30/01/06
67859
photon в сообщении #1354821 писал(а):
В результате в разных подпроектах, разных каталогах, из которых вы как доктор Франкенштейн лепите монстра есть заголовочные файлы с одинаковыми именами и одинаковыми дефайнами.

Вы знаете, ещё в конце 90-х хорошие free open-source проекты так не делали, а использовали стандартный префикс на каждый проект, и стандартный namespace на классы, функции и константы. Дефайны тоже с префиксом. Так что я не знаю, где вам удаётся раздобыть такую первобытную дикость.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение18.11.2018, 01:52 
Заслуженный участник


20/08/14
5502
Россия, Москва
mihaild в сообщении #1354736 писал(а):
Я за вот такое подход:
Когда операции более-менее сложные или вложенные ветвления не слишком простые - именно так и пишу. :-)
mihaild в сообщении #1354736 писал(а):
Вот как в вашем if (a) b++; else c--; хотя бы breakpoint на b++ поставить?
Да, это один из недостатков. Хотя лично мне несложно для отладки нажать ентер перед b++ и поставить breakpoint, а после убрать обратно и сделать снова компактно, не так уж часто это [мне] надо.
Зато есть и плюс иногда: однострочные циклы проходятся одним нажатием, если он точно работает правильно (типа инициализации массивов), то это удобно.
Думаю это уже дело вкуса, мне удобнее более компактный вид, когда обозрим без постоянных листаний туда-сюда максимально большой кусок кода (без фанатизма, в кашу не превращать). Но для отладки да, бывает размазываю его тонким слоем. :-)

(Оффтоп)

mihaild в сообщении #1354736 писал(а):
используйте преинкремент вместо постинкремента
Я помню об этой тонкости, но не все языки поддерживают преинкремент (пример - PARI/GP не поддерживает) и думать кто да и кто нет - лишний напряг, проще ставить одинаково, а где важно быстродействие до таких мелочей - там по любому детально смотреть и думать, а то и на асме переписать (вот люблю я его как явление). Я и скобки расставляю с большим запасом не надеясь на приоритет операций компилятора - символов больше, выглядит хуже, но сильно надёжнее и не надо помнить в тонкостях политику каждого компилятора (разных языков).

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение18.11.2018, 02:09 
Экс-модератор
Аватара пользователя


23/12/05
10807
Munin в сообщении #1354822 писал(а):
Вы знаете, ещё в конце 90-х хорошие free open-source проекты так не делали

Хорошие - конечно, не делали. Но плохой код может выложить автор статьи по какому-то предложенному им алгоритму - он, может быть, скажем, хороший математик, но посредственный программист, написал для себя и по доброте душевной выложил для всех, а вы вдруг решите у себя его опробовать для того, чтобы вообще понять, нужно вам это или нет. Ситуация, чтобы в одном проекте таких "поделок" встретилось несколько, редкая, но не невозможная.

 Профиль  
                  
 
 Re: Программирование для математиков: класс Polynomial
Сообщение18.11.2018, 12:39 
Заслуженный участник
Аватара пользователя


30/01/06
67859
photon в сообщении #1354829 писал(а):
Но плохой код может выложить автор статьи по какому-то предложенному им алгоритму

Такой код обычно не настолько большой, чтобы в нём нельзя было сделать find and replace. А если слишком большой, я бы всё равно поопасался пришивать его к своему без перелопачивания и переделок - хотя бы из-за обработки ошибок.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 96 ]  На страницу Пред.  1, 2, 3, 4, 5, 6, 7  След.

Модераторы: Karan, PAV, Toucan, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group