Как вызвать вывод итеративного решения в массив на каждом шаге (используя Python)

#python #arrays #numpy #sequence

#python #массивы #numpy #последовательность

Вопрос:

Ниже приведен код, в котором я решаю задачу путем (1) итеративного решения системы уравнений с использованием метода Ньютона. Результат этой итерации, тройной (z0, z1, z2), используется на втором шаге, шаге (2) для вычисления значений x= (x0,x1, x2). Я должен повторить этот процесс, скажем, для t = (0,1,5). То есть на следующем шаге Ньютон снова решает для z, и это новое значение z используется для повторного получения x. Это означает, что в конце дня мне понадобится массив размером 3 * 6, содержащий значения x .

Проблемы: (1) Мне кажется, что трудно вызвать значения, полученные для z, для использования в функции, которая решает x (2) В функции StepFunction я, кажется, вызываю последовательность «Ньютон» в массив. Я думаю, что это проблема. То, что я на самом деле хочу вызвать, — это решение, полученное Newton (3), И иногда я получаю это ValueError: не удалось передать входной массив из формы (3,5) в форму (3)

Мы будем очень признательны за вашу помощь. Спасибо

 import numpy as np
def Newton_system(F, J, z, zz, x, eps):
    """
    Solve nonlinear system F=0 by Newton's method.
    J is the Jacobian of F. Both F and J must be functions of x.
    At input, z holds the start value. The iteration continues
    until ||F|| < eps.
    """
    #call in the value x from previous iteration
    F_value = F(z,zz,x)
    F_norm = np.linalg.norm(F_value, ord=2)  # l2 norm of vector
    iteration_counter = 0
    while abs(F_norm) > eps and iteration_counter < 100:
        delta = np.linalg.solve(J(z), -F_value)
        z = z   delta
        F_value = F(z,zz,x)
        F_norm = np.linalg.norm(F_value, ord=2)
        iteration_counter  = 1

    # Here, either a solution is found, or too many iterations
    if abs(F_norm) > eps:
        iteration_counter = -1
    return z, iteration_counter
z.shape
  
 def F(z,zz,x):
    k,a,b,c,h = 0.1,0.2,0.2,5.7,6.0` code `
    return np.array([ z[0]-x[0] h/2*(z[1] z[2] k*z[0]-k*zz[0]),
                      z[1]-x[1]-h/2*(z[0] a*z[1]-k*z[1] k*zz[1]),
                      z[2]-x[2]-h/2*(b z[2]*(z[0]-c)-k*z[2] k*zz[2])])
  


def J(z):
    k,a,b,c,h = 0.1,0.2,0.2,5.7,6.0
    return np.array([[1 h*k/2,h/2,h/2],
                     [-h/2,1-(h*a)/2,h*k/2],
                     [-h*z[2]/2,0,1-h/2*(z[0]-c)-k]])



def DelayedRossler(z,zz):     
    a,b,c,k,h = 0.2,0.2,5.7,0.1,6.0
    return np.array([ -z[1] -z[2] -k*z[2]  k*z[0]-k*zz[0] , 
                     z[0]  a*z[1]-k*z[2]  k*z[1]-k*zz[1],
                     b z[2]*(z[0]-c)-k*z[2]  k*z[0]-k*zz[0] ])

def StepFunction(f, zinit, xinit, tinit,tfinal, dt):   
    global z
    t = np.arange(tinit,tfinal, dt)
    nt = t.size
    nx = xinit.size  #number of state variables
    nz = zinit.size  #number of state variables
    
    x = np.zeros((nx,nt)) #initialization with nx rows and nt columns
    z = np.zeros((nz,nt))  #initialization with nz rows and nt columns
    zz = np.zeros((nz,nt))  #initialization with nzz rows and nt columns

    x[:,0] = xinit    
    z[:,0] = zinit
    zz[:,0] = zinit    
    
    for n in range (nt-1): 
        z[:,n] = z
        zz[:,n 1] = z[:,n]
        x[:,n] =x
        z[:,n 1] = Newton_system(F, J, z , zz, x , eps =0.0001)
        s = dt*f(t[n]  dt/2, z[:,n 1],zz[:,n 1]) 
        x[:,n 1] =  x[:,n]   s
    return x, t 
  

#Define Problem
f= lambda t, z: DelayedRossler(z,zz)

#solve the problem
zinit = np.array([0.0,0.0,0.0])
xinit = np.array([0.0,0.0,0.0])
tinit = 0.0
tfinal = 30.0
dt = 6

x, t = StepFunction(f, zinit, xinit, tinit,tfinal, dt)
print(x)
  

Ответ №1:

Вы пытаетесь поместить двумерный массив в одномерный массив.
Попробуйте изменить форму массива, в который вы помещаете значения, в массив 3×5, используя array.reshape(3,5).