forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   2D-программирование (http://forum.boolean.name/forumdisplay.php?f=13)
-   -   Переполнение (http://forum.boolean.name/showthread.php?t=551)

impersonalis 13.01.2006 02:29

Есть небольшая либа для решения матричной системы.
Всё работает нормально, пока при попытке инвертировать матрицу порядка 7 на 7, ф-ция аварийно не завершает работу, т.к. получает детерминант=NaN (хотя он чуть превышает 10^6).
Само собой разумеется, в остальных случаях всй считается.
Код:

Const TMatrixMaxIndex2D=99
Type TMatrix
        Field Buffer$[TMatrixMaxIndex2D]
        Field StringSize
        Field CSize
End Type

Function TMatrix_Create.TMatrix(size,size2=-1)
        M.TMatrix=New TMatrix
        M\StringSize=size
        M\CSize=size2
        If M\CSize=-1 M\CSize=size
        Return M
End Function

Function TMatrix_IN(M.TMatrix,SNumber,CNumber,Z$)
        Local Index2d=(SNumber-1)*M\StringSize+(CNumber-1)
        M\Buffer[Index2d]=Z$
End Function

Function TMatrix_OUT$(M.TMatrix,SNumber,CNumber)
        Local Index2d=(SNumber-1)*M\StringSize+(CNumber-1)
        Return M\Buffer[Index2d]
End Function

Function TMatrix_Delete(M.TMatrix)
        Delete M
End Function

Function TMatrix_Determinant#(M.TMatrix)
       
        SS=M\StringSize
        CS=M\CSize
        If SS=1 And CS=1
 *Return Float(M\buffer[0])
        EndIf
        Local DET#=0
        For i=1 To SS
 *MINOR.TMATRIX=TMatrix_minor(M,1,i)
 *DET=DET+(-1)^(i+1)*TMatrix_Determinant(MINOR)*Float(TMatrix_OUT(M,1,i))
 *TMatrix_Delete(MINOR)
        Next
        Return Float(DET)
End Function

Function TMatrix_minor.TMatrix(M.TMatrix,NS,NC)
        minSS=M\StringSize-1
        minCS=M\CSize-1
        Minor.TMatrix=TMATRIX_Create(minSS,minCS)
        Local Smin=1
        For S=1 To M\CSize
 *Local Cmin=1
 *For C=1 To M\StringSize
 *        If C=NC
 * *Cmin=Cmin-1
 *        Else
 * *TMatrix_IN(Minor,Smin,Cmin,TMatrix_OUT(M,S,C))
 *        EndIf
 *        Cmin=Cmin+1
 *Next
 *If S=NS
 *        Smin=Smin-1
 *EndIf
 *Smin=Smin+1
        Next
        Return Minor
End Function

вот - выдрал необходимые куски кода.
Собсна вопрос - можно как-нить уменьшить кол-во рекурсий, не сильно загромождая код?

jimon 13.01.2006 21:49

лутче скажи что собствено код делает... ну я в математике матриц не очень... всештаки только 9 класс :)

impersonalis 14.01.2006 22:01

проблема отпала

impersonalis 17.01.2006 15:43

Проблему с нехваткой места в 4-байтовых переменных сначала хотел решить эмуляцией длинных чисел на основе массива коээфициентов. Но код получился слишком громоздкий (мне была необходима поддержка положительных/отрицательных дробных чисел.
Поэтому на данный момент пишу систему округлений вычислений, т.к. точность некритична а вот скокрость работы на эмуляции упадёт больше чем на округениях с вынесением степени десятки.

pax 14.03.2006 14:27

Инвертированную матрицу можно найти намного быстрее используя дополнительную единичную путем преобразования обеих матриц методом Жордано-Гаусса (точнее методом пямоугольника, а еще точнее смесью)

pax 14.03.2006 14:59

Вложений: 2
И вообще лучше и быстрее всего решать системы лин. уравнений методом Жордано-Гаусса... никаких переполнений переменных не будет...
Код:

'Процедура преобразования матрицы методом Жордана-Гаусса
Public Sub MAT(A() As Double, I1 As Integer)
 * If A(I1, I1) = 0 Then *'Проверка на "0" по главной диагонали
 * *If I1 = N Then R = True: Exit Sub
 * * For i = I1 + 1 To N
 * * *If A(i, I1) <> 0 Then
 * * * For j = 0 To N + 1
 * * * *b = A(I1, j): A(I1, j) = A(i, j): A(i, j) = b
 * * * Next j
 * * * If A(I1, I1) <> 0 Then Exit For
 * * *End If
 * * Next i
 * * *If A(I1, I1) = 0 Then R = 1: Exit Sub
 * * *If N < NNN Then
 * * * Form2.Text1 = Form2.Text1 + "МЕНЯЕМ СТРОКИ МЕСТАМИ" + vbCrLf: VIVOD A()
 * * *End If
 * End If
 * * *For j = N + 1 To I1 Step -1 'Получение единицы по главной диагонали
 * * * *A(I1, j) = A(I1, j) / A(I1, I1)
 * * *Next j
 * * For i = 0 To N
 * * *If i <> I1 Then
 * * * For j = N + 1 To I1 Step -1
 * * * *A(i, j) = A(i, j) - A(I1, j) * A(i, I1)
 * * * Next j
 * * *End If
 * * Next i
End Sub

Преобразований таких N, т.е. число переменных (цикл for I1=0 to N-1, где I1 - номер итерации матрица A() - имеет размер [N,N+1])

А вот исходник моей проги (релизовать нахождение обратной матрицы методом дополнительной единичной я наверное неуспел... или исходник потерял хз)

VB рулез, С++ отстой :lol: :lol: :lol:

impersonalis 14.03.2006 20:27

1)"И вообще лучше и быстрее всего решать системы лин. уравнений методом Жордано-Гаусса... никаких переполнений переменных не будет..." - это типа, того , вводная, млин!
2)"Инвертированную матрицу можно найти намного быстрее используя дополнительную единичную путем преобразования обеих матриц методом Жордано-Гаусса (точнее методом пямоугольника, а еще точнее смесью)" - неизящно + потеря точности
3)"VB рулез, С++ отстой" - а на это я и обидеться могу. Тем блее не понял : причём здесь С++? На С++ это всё реализовано очень даже.

pax 16.03.2006 16:36

Цитата:

2)"Инвертированную матрицу можно найти намного быстрее используя дополнительную единичную путем преобразования обеих матриц методом Жордано-Гаусса (точнее методом пямоугольника, а еще точнее смесью)" - неизящно + потеря точности
какие тут могут быть разговоры о точности с 4-х байтовыми переменными? зато никакого переполнения, да и при расчете определителей высших порядков у тебя всегда будет необходимость понизить степень, что ведет к понижению точности, или сделать что-то извращенное а не изящное, а этим способом можно алгоритм на одном экране уписать...

Цитата:

3)"VB рулез, С++ отстой" - а на это я и обидеться могу. Тем блее не понял : причём здесь С++? На С++ это всё реализовано очень даже.
извини, но я просто для себя решил недавно, что VB намного круче C++... просто дело в том, что я в будующем не собираюсь в одиночку изобретать супер программы, а для обычных прог VB просто идеальный язык (это мое мнение... можешь меня забросать булыжниками :P ), к томуже он круче C# по производительности, и не уступает по возможностям... если я и буду использовать C++ то только для математических рассчетов...

impersonalis 16.03.2006 17:25

Я в будующем не собираюсь писать обычные программы (их и так навалом),а вот для супер-прог - С++ самое оно (это мое мнение... можешь меня забросать булыжниками =/ ), к тому же он круче VB по производительности и возможностям... если я буду использовать VB - то даже не знаю на кой фиг (вариант : готовые компонеты/библиотеки ?) ....


Часовой пояс GMT +4, время: 19:59.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot