fork download
  1. | f g det2x2 partialDerivative jacobian aN bN newtonMethod x0 y0 h epsilon |
  2.  
  3. " Функции для вычисления определителя матрицы 2х2 и частной производной "
  4. f := [:x :y | x * x + y * y - 4].
  5. g := [:x :y | x - y].
  6. det2x2 := [:a :b :c :d | a * d - b * c].
  7. partialDerivative := [:func :x :y :h :derivativeType |
  8. derivativeType = 'x'
  9. ifTrue: [(func value: x + h value: y) - (func value: x value: y) / h]
  10. ifFalse: [derivativeType = 'y'
  11. ifTrue: [(func value: x value: y + h) - (func value: x value: y) / h]
  12. ifFalse: [Error signal: 'Invalid derivative type']]].
  13. jacobian := [:func1 :func2 :x :y :h |
  14. | dx1 dy1 dx2 dy2 |
  15. dx1 := partialDerivative valueWithArguments: {func1. x. y. h. 'x'}.
  16. dy1 := partialDerivative valueWithArguments: {func1. x. y. h. 'y'}.
  17. dx2 := partialDerivative valueWithArguments: {func2. x. y. h. 'x'}.
  18. dy2 := partialDerivative valueWithArguments: {func2. x. y. h. 'y'}.
  19. ^ det2x2 valueWithArguments: {dx1. dy1. dx2. dy2}.
  20. ].
  21. aN := [:func1 :func2 :x :y :h |
  22. | fx fy dfy1 dfy2 |
  23. fx := func1 value: x value: y.
  24. fy := func2 value: x value: y.
  25. dfy1 := partialDerivative valueWithArguments: {func1. x. y. h. 'y'}.
  26. dfy2 := partialDerivative valueWithArguments: {func2. x. y. h. 'y'}.
  27. ^ det2x2 valueWithArguments: {fx. dfy1. fy. dfy2}.
  28. ].
  29. bN := [:func1 :func2 :x :y :h |
  30. | dfx1 fx dfx2 fy |
  31. dfx1 := partialDerivative valueWithArguments: {func1. x. y. h. 'x'}.
  32. fx := func1 value: x value: y.
  33. dfx2 := partialDerivative valueWithArguments: {func2. x. y. h. 'x'}.
  34. fy := func2 value: x value: y.
  35. ^ det2x2 valueWithArguments: {dfx1. fx. dfx2. fy}.
  36. ].
  37.  
  38. " Функция для вычисления метода Ньютона "
  39. newtonMethod := [:func1 :func2 :x0 :y0 :h :epsilon |
  40. | x y iterations maxIterations result |
  41. x := x0.
  42. y := y0.
  43. iterations := 0.
  44. maxIterations := 1000.
  45. result := nil.
  46.  
  47. [iterations < maxIterations and: [result isNil]] whileTrue: [
  48. | jacobianValue aNValue bNValue newX newY |
  49. jacobianValue := jacobian valueWithArguments: {func1. func2. x. y. h}.
  50. (jacobianValue abs < epsilon)
  51. ifTrue: [
  52. Transcript show: 'Якобиан близок к нулю. Метод может не сойтись.'; cr.
  53. result := nil.
  54. ]
  55. ifFalse: [
  56. aNValue := aN valueWithArguments: {func1. func2. x. y. h}.
  57. bNValue := bN valueWithArguments: {func1. func2. x. y. h}.
  58.  
  59. newX := x - (aNValue / jacobianValue).
  60. newY := y - (bNValue / jacobianValue).
  61.  
  62. ((newX - x) abs <= epsilon and: [(newY - y) abs <= epsilon])
  63. ifTrue: [result := Array with: newX with: newY]
  64. ifFalse: [
  65. x := newX.
  66. y := newY.
  67. iterations := iterations + 1.
  68. ].
  69. ].
  70. ].
  71.  
  72. result isNil ifTrue: [
  73. Transcript show: 'Достигнуто максимальное количество итераций. Метод может не сойтись.'; cr.
  74. ].
  75.  
  76. ^ result
  77. ].
  78.  
  79. " Начальные значения и параметры "
  80. x0 := 1.0.
  81. y0 := 1.0.
  82. h := 1e-6.
  83. epsilon := 1e-10.
  84.  
  85. " Вычисление метода Ньютона "
  86. | result |
  87. result := newtonMethod valueWithArguments: {f. g. x0. y0. h. epsilon}.
  88. result
  89. ifNotNil: [Transcript show: 'x = ', result first printString, ', y = ', result second printString; cr]
  90. ifNil: [Transcript show: 'Метод Ньютона не сошелся'; cr].
  91.  
Success #stdin #stdout 0.01s 10748KB
stdin
Standard input is empty
stdout
Object: -5.00000200017781 error: return from a dead method context
SystemExceptions.BadReturn(Exception)>>signal (ExcHandling.st:254)
SystemExceptions.BadReturn class(Exception class)>>signal (ExcHandling.st:151)
FloatD(Object)>>badReturnError (Object.st:1389)
[] in UndefinedObject>>executeStatements (prog:49)
BlockClosure>>whileTrue: (BlkClosure.st:328)
[] in UndefinedObject>>executeStatements (prog:45)
UndefinedObject>>executeStatements (prog:87)
Метод Ньютона не сошелся