Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ввод функции многих переменных 
V
    Опции темы
Shadowlord
Дата 7.6.2009, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



Пишу программу для симпелекс метода минимизации функций многих переменных, вот алгоритм
http://sapr.mgsu.ru/biblio/optimiz/m7.htm
Так вот основная проблема как организовать ввод пользователем этой функции и потом проанализировать ее.  


Это сообщение отредактировал(а) Shadowlord - 7.6.2009, 10:50
PM MAIL   Вверх
xvr
Дата 8.6.2009, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



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

PM MAIL   Вверх
GoldFinch
Дата 8.6.2009, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 6
Всего: 26



если функция линейная - вводи ее коэффициенты

Это сообщение отредактировал(а) GoldFinch - 8.6.2009, 17:39
PM MAIL ICQ   Вверх
Shadowlord
Дата 10.6.2009, 07:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



функция может быть не линейной ,  в этом и есть основная проблема
PM MAIL   Вверх
Shadowlord
Дата 10.6.2009, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



xvr,  можно чуть по подробней про средний метод 
PM MAIL   Вверх
kamre
Дата 10.6.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 24.3.2006

Репутация: 2
Всего: 13



Цитата(xvr @ 8.6.2009,  16:25)
Самый сложный метод - сделать интерпретатор (или JIT) для вычисления функции
Средний по сложности метод - обернуть функцию в специальный врапер, сгенерировать из этого отдельный С файл, откомпилировать его в виде динамической библиотеки, динамически загрузить к себе в программу

Почему интерпретатор (без всяких там JIT) самый сложный? Мне кажется это достаточно стандартная задачка, что-то вроде калькулятора.
А с генерацией файла, компиляцией и динамической загрузкой - это какой-то "извращенный" способ smile Это ж компилятор с собой придется таскать.
PM MAIL   Вверх
xvr
Дата 10.6.2009, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Shadowlord @ 10.6.2009,  08:02)
xvr,  можно чуть по подробней про средний метод

Можно.
Например, пользователь вводит функцию в файле в таком виде:
Код

x,y,z
x*x+3.123*pow(y,3)+z
Первая строка - список переменных, вторая - собственно формула
Система генерит файл следующего содержания (wrap.cpp)
Код

#include <math.h>
extern "C" double user_func(double* _args)
{
 // Эта часть генерится из описания переменных
 double x=_args[0];
 double y=_args[1];
 double z=_args[2];
 // А это собственно вычисление
 return x*x+3.123*pow(y,3)+z;
}
Далее вызывается компилятор, 
  •  VC: cl /LD wrap.cpp 
  •  gcc: g++ -shared wrap.cpp -o wrap.so
  •  mingw: g++ -mdll wrap.cpp -o wrap.dll
Далее в своей программе полученная библиотека загружается и извлекается адрес функции user_func (см LoadLibrary, GetProcAddress для Windows, или dlopen,dlsym для Linux)
Т.к. прототип функции известен и фиксирован, то ее можно вызвать одним и тем же способом, вне зависимости от того, что в нее напишет пользователь

kamre:
Цитата

Почему интерпретатор (без всяких там JIT) самый сложный? Мне кажется это достаточно стандартная задачка, что-то вроде калькулятора.
Если есть готовый и скорость его работы устраивает, то милости просим  smile А вот писать специально для этого свой собственный явно не стоит (если конечно ты не съел собаку на написании компиляторов, и способен написать еще один даже не просыпаясь  smile )
Цитата

А с генерацией файла, компиляцией и динамической загрузкой - это какой-то "извращенный" способ smile
Нормальный способ, некоторые умудряются даже коммерческие продукты так делать  smile 
Цитата

 Это ж компилятор с собой придется таскать.
Да. 
Пример - Xilinx, ISE (среда программирования для их FPGA/CPLD), ихний симулятор (симулирует программы на Verilog & VHDL). Бесплатная и коммерческая версия отличаются только файлом лицензии. Симулятор преобразует исходный код в программу на C++, и компилирует ее вместе со своими библиотеками в exe (gcc входит в состав дистрибутива ISE). Полученный exe запускают под оболочкой симулятора.


PM MAIL   Вверх
Shadowlord
Дата 13.6.2009, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



Вот нашел Парсер математических выражений (http://www.rsdn.ru/article/files/Classes/tparser.xml)
выдает ошибку
Код

Error    6    error C2668: 'exp' : ambiguous call to overloaded function    c:\parser.cpp    329

вот строка на которую ругается
Код

 temp = CreateNode((double)exp(1));

Не могу понять в чем проблема
PM MAIL   Вверх
xvr
Дата 13.6.2009, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Проблема в функции exp из math.h. Видимо где то нашлась еще одна  smile 
Напишите так
Код

 temp = CreateNode((double)exp(1.0));

PM MAIL   Вверх
Shadowlord
Дата 13.6.2009, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



Вот еще вопрос 
я создал массив 
Код

array <double> ^X0;



Запомнил его из грида 
Код

 X0=gcnew array<double>(n);
                 for(int j=0; j<n;j++)
                                
                     X0[j]=Convert::ToSingle(dataGridView1->Rows[0]->Cells[j]->Value);

Хочу запихать его в парсер как  значение переменных а он мне говорит что типы не совпадают 
Код

Error    6    error C2664: 'double TParser::Evaluate(double *)' : cannot convert parameter 1 from 'cli::array<Type> ^' to 'double *'        214

как его привести к double *
PM MAIL   Вверх
xvr
Дата 13.6.2009, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Правильно говорит - массив должен быть обычный (double*), а не array и уж тем более не .net'овский указатель.
Делайте так
Код

double* X0;
 X0=new double[n];
                 for(int j=0; j<n;j++)
                                
                     X0[j]=Convert::ToSingle(dataGridView1->Rows[0]->Cells[j]->Value);
не забудьте позвать в конце delete[] X0;

PM MAIL   Вверх
Shadowlord
Дата 14.6.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 275
Регистрация: 28.11.2006

Репутация: нет
Всего: 5



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

Добавлено через 11 минут и 6 секунд
сделал так вроде каботает
Код

double** X;
X=new double*[n+1]; 
for(int i=0;i<n+1;i++) 
X[i]=new double[i];

PM MAIL   Вверх
xvr
Дата 14.6.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



В строке в new double[] нужно указать размер массива по 2му измерению (пусть будет k), а не i
Код

double** X;
X=new double*[n+1]; 
for(int i=0;i<n+1;i++) 
X[i]=new double[k]; // <<<

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1774 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.