|
Арифметика высокой точности в ALGLIB, как ее использовать? |
|
|
|
Dec 11 2013, 13:01
|
Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 20-05-13
Пользователь №: 76 911

|
Цитата(thermit @ Dec 11 2013, 15:00)  Честно говоря, лень ковыряться с чужими исходниками. Должно быть как-то так: Это Вы мне что, прямо таки код рабочий дали ?  Спасибо большое, буду проверять. Если все OK, то куда donation перевести ? Так как же должно быть в BackwardSubstitution(): if(A[(C-1)*R+C-1]==0.0) x[C-1]=0.0; else x[C-1]=b[C-1]/A[(C-1)*R+C-1]; или if(A[(C-1)*C+C-1]==0.0) x[C-1]=0.0; else x[C-1]=b[C-1]/A[(C-1)*C+C-1]; ?
Сообщение отредактировал MSP430F - Dec 11 2013, 13:27
|
|
|
|
|
Dec 11 2013, 14:20
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата(MSP430F @ Dec 11 2013, 16:01)  Это Вы мне что, прямо таки код рабочий дали ?  Спасибо большое, буду проверять. Если все OK, то куда donation перевести ? Так как же должно быть в BackwardSubstitution(): if(A[(C-1)*R+C-1]==0.0) x[C-1]=0.0; else x[C-1]=b[C-1]/A[(C-1)*R+C-1]; или if(A[(C-1)*C+C-1]==0.0) x[C-1]=0.0; else x[C-1]=b[C-1]/A[(C-1)*C+C-1]; ? Последняя редакция верна. Первый раз скопировал с ошибкой. Цитата _pv: если то же самое в чём радость по сравнению с Гауссом? На плохо обусловленных системах с числом уравнений большим числа неизвестных ошибка гаусса будет на порядок больше. Нужно будет принимать специальные меры. Кроме того, применение ортогонального преобразования гарантирует состоятельность и численную устойчивость алгоритма. Про гаусса такого сказать нельзя. Если число операций не является приоритетом, лучше использовать вращения или отражения. зы старик уилкинсон утверждает, что ему всегда хватало гаусса. Но это было в эпоху медленных компьютеров...
|
|
|
|
Guest_TSerg_*
|
Dec 11 2013, 19:42
|
Guests

|
Цитата(thermit @ Dec 11 2013, 18:20)  старик уилкинсон утверждает, что ему всегда хватало гаусса. Но это было в эпоху медленных компьютеров... Не только. Все чаще дело имеем с разреженными системами, а Гаусс разреженность лучше сохраняет, в отличии от методов отражений и вращений.
|
|
|
|
|
Dec 12 2013, 09:01
|
Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 20-05-13
Пользователь №: 76 911

|
Цитата(thermit @ Dec 11 2013, 18:20)  Я правильно догадался, что в этом месте ошибка: for(j=0;j<21;j++) aa[i][j]=aorig[i][j]=a[j][i]; Должно быть: for(j=0;j<21;j++) aa[i][j]=aorig[i][j]=a[i][j]; Первый индекс - строка, второй - столбец. Это же одинаково для всех массивов ?
|
|
|
|
|
Dec 12 2013, 10:18
|
Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 20-05-13
Пользователь №: 76 911

|
Цитата(thermit @ Dec 12 2013, 13:18)  Ошибки здесь нет. Исходная матрица лежит в памяти постолбцово (1-я строка состоит из единиц). Во всяком случае я так считал. Для работы алгоритмов матрица должна лежать в памяти построчно. for(j=0;j<21;j++) aa[i][j]=aorig[i][j]=a[j][i]; Это и есть такое преобразование (транспонирование). Если считать, что первый индекс - строка, а второй - столбец, то первая строка как раз и не состоит из 1.0, а равна {1.000000, 1.229402, 1.229566, 1.230016, 1.229648, 1.229771, 1.229975, 1.229361, 1.229525, 1.229648, 1.229484, 1.229238, 1.229156, 1.228992, 1.228214, 1.227518, 1.227928, 1.227108, 1.227231, 1.226453, 1.226576}, как она и проинициализирована. Зачем же здесь тогда транспонирование ? Можете проверить: i = 0; for(j=0; j<21; j++) printf("a = %f\n", a[i][j]);
Сообщение отредактировал MSP430F - Dec 12 2013, 10:21
|
|
|
|
|
Dec 12 2013, 10:56
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата MSP430F: Зачем же здесь тогда транспонирование ? Для данных, которые вы прислали погрешность вычислялась (и с вашей совпадала) для матрицы, где строки являются столбцами из вашей таблицы. Поскольку я вставил ее себе в код копипастом, пришлось ввести транспонирование. С индексами все путем: 1-й - номер строки, 2-й - номер столбца. Честно говоря, не понял проблемы. Разместите свои данные построчно да и все дела. Цитата _pv: будет вам счастье и без ALGLIBа. Собственно, то, что алглиб тут лишний, давно понятно.
|
|
|
|
|
Dec 12 2013, 12:03
|
Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 20-05-13
Пользователь №: 76 911

|
Цитата(thermit @ Dec 12 2013, 14:56)  Для данных, которые вы прислали погрешность вычислялась (и с вашей совпадала) для матрицы, где строки являются столбцами из вашей таблицы. Поскольку я вставил ее себе в код копипастом, пришлось ввести транспонирование. С индексами все путем: 1-й - номер строки, 2-й - номер столбца. Честно говоря, не понял проблемы. Разместите свои данные построчно да и все дела. Нет, Вы не правы. В моих данных все на месте - строки это строки, столбцы - столбцы. Первый элемент каждой строки - это 1.0 (так и должно быть). Транспонирование не нужно.
|
|
|
|
|
Dec 12 2013, 12:15
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата MSP430F: Нет, Вы не правы. В моих данных все на месте - строки это строки, столбцы - столбцы. Первый элемент каждой строки - это 1.0 (так и должно быть). Транспонирование не нужно. Это непринципиально. Кстати, что за данные? Откуда?
|
|
|
|
|
Dec 12 2013, 14:42
|
Частый гость
 
Группа: Участник
Сообщений: 85
Регистрация: 20-05-13
Пользователь №: 76 911

|
Цитата(thermit @ Dec 12 2013, 16:15)  Это непринципиально. Кстати, что за данные? Откуда? Проверяю метод ближайших соседей для прогнозирования значения временного ряда хаотического типа. Для примера взял котировки EUR/USD с шагом 1 час. Ваш код хорошо работает. Правда, пришлось немного попотеть, чтобы можно было в качестве аргумента передавать матрицу в виде нормального двумерного массива, так как размерность матрицы может меняться динамически. Ваш код дает ошибку не хуже, чем alglib. При небольшой прямоугольности разница заметна в пользу Вашего кода. Если матрица 21 * 25 или 21 * 31, то разница в ошибке незаметна. Зато код получается небольшой и нет кучи warning-ов при компиляции, как при использовании alglib.
|
|
|
|
|
Dec 12 2013, 14:49
|
Знающий
   
Группа: Участник
Сообщений: 781
Регистрация: 3-08-09
Пользователь №: 51 730

|
Цитата MSP430F: Правда, пришлось немного попотеть, чтобы можно было в качестве аргумента передавать матрицу в виде нормального двумерного массива Зачем передавать в виде двумерного массива? Решателю достаточно передать адрес начала матрицы и ее размерность.
|
|
|
|
|
Dec 12 2013, 15:08
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(thermit @ Dec 12 2013, 18:49)  Зачем передавать в виде двумерного массива? Решателю достаточно передать адрес начала матрицы и ее размерность. У топик-стартера матрица аллокируется не одним блоком памяти, а построчно: Код double **copy_mass = new double *[cnt_str]; // создаем копию матрицы, так как элементы матрицы будут модифицированы for(i = 0; i < cnt_str; i++){ copy_mass[i] = new double [cnt_str + 1]; // N столбцов = N строк + 1 for(j = 0; j < cnt_str + 1; j++) copy_mass[i][j] = mass[i][j]; } Однако это обстоятельство ничуть не мешает ее передавать через указатель double**, а еще лучше, как &double**. Хотя на C++ можно было бы создать для матрицы класс, где кроме указателя double**, хранились бы и обе ее размерности. А конструктор и деструктор память под эту матрицу аллокировали и деаллокировали. В этом случае ссылку (здесь она удобнее указателя) на матрицу можно передавать одним единственным парамером. Кроме того, данный класс можно снабдить фукциями членами класса дял матричного умножения, сложения и т.п.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|