Trigonometric,Wood,Extended Powell singular

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
方向是牛顿方向 G k d k = − g k G_kd_{k}=-g_k Gkdk=gk

稳定牛顿法

步长为1




import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F

def Newton(f,g,h,X,N):
    eps = 1e-8
    for i in range(N):
        X_old = X
        d,lu = torch.solve(-g(X_old).t(),h(X_old))
        X = X_old + d.t()
        if i%5 == 0:
            print('the iteration:%d,grad_2:%.3e'%(i,(g(X)**2).sum()))
        tmp = abs(f(X_old) - f(X))
        if max(tmp) < eps:
            break
    print('the end iteration:%d,grad_2:%.3e'%(i + 1,(g(X)**2).sum()))
    return X

#Wood函数
def FF(X):
    out = 100*(X[:,1] - X[:,0])**2 + (1 - X[:,0])**2 + 90*(X[:,3] - X[:,2])**2 +     (1 - X[:,2])**2 + 10*(X[:,1] + X[:,3] - 2)**2 + ((X[:,1] - X[:,3])**2)/10
    return out
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    vec[:,0] = -400*X[:,0]*(X[:,1] - X[:,0]**2) - 2*(1 - X[:,0])
    vec[:,1] = 200*(X[:,1] - X[:,0]**2) + 20*(X[:,1] + X[:,3]- 2) + (X[:,1] - X[:,3])/5
    vec[:,2] = -360*X[:,2]*(X[:,3] - X[:,2]**2) - 2*(1 - X[:,2])
    vec[:,3] = 180*(X[:,3] - X[:,2]**2) + 20*(X[:,1] + X[:,3] - 2) - (X[:,1] - X[:,3])/5
    return vec
def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    mat[0,0] = -400*(X[:,1] - X[:,0]**2) + 800*X[:,0]**2 + 2
    mat[0,1] = -400*X[:,0];mat[0,2] = 0;mat[0,3] = 0
    #----------------
    mat[1,0] = -400*X[:,0]
    mat[1,1] = 220.5
    mat[1,2] = 0;mat[1,3] = 19.5
    #-----------------
    mat[2,0] = 0;mat[2,1] = 0
    mat[2,2] = 720*X[:,2]**2 - 360*(X[:,3] - X[:,2]**2) + 2
    mat[2,3] = -360*X[:,2]
    #---------------------
    mat[3,0] = 0
    mat[3,1] = 19.5
    mat[3,2] = -360*X[:,2]
    mat[3,3] = 200.5
    return mat
X = torch.tensor([[-3.0,-1,-3,-1]])

N = 200
x_new = Newton(FF,GG,HH,X,N)
print(x_new)
print(FF(x_new))    

#!/usr/bin/env python
# coding: utf-8

# In[2]:


import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F
import random


# In[3]:


def Newton(f,g,h,X,N):
    eps = 1e-8
    for i in range(N):
        X_old = X
        d,lu = torch.solve(-g(X_old).t(),h(X_old))
        X = X_old + d.t()
        if i%5 == 0:
            print('the iteration:%d,grad_2:%.3e'%(i,(g(X)**2).sum()))
        tmp = abs(f(X_old) - f(X))
        if max(tmp) < eps:
            break
    print('the end iteration:%d,grad_2:%.3e'%(i + 1,(g(X)**2).sum()))
    return X


# In[6]:


#Trigonometric 函数
def F(X,i):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp -= torch.cos(X[:,j])
    temp += n + (i + 1)*(1 - torch.cos(X[:,i])) - torch.sin(X[:,i])
    return temp
def FF(X):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp += F(X,j)**2
    return temp
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        vec[:,i] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*F(X,i) + 2*torch.sin(X[:,i])*temp
    return vec


def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        for j in range(n):
            if i == j:
                mat[i,j] = 2*((i + 1)*torch.cos(X[:,i]) + torch.sin(X[:,i]))*F(X,i) +                 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*((i + 2)*torch.sin(X[:,i]) - torch.cos(X[:,i])) +                2*torch.cos(X[:,i])*temp + 2*torch.sin(X[:,i])*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))
            else:
                mat[i,j] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*torch.sin(X[:,j]) +                  2*torch.sin(X[:,i])*((j + 1)*torch.sin(X[:,j]) - torch.cos(X[:,j]))
    return mat
n = 20;X = torch.ones(1,n)/n
alpham = 1.0
rho = 0.4
t = 1
N = 800
x_new = Newton(FF,GG,HH,X,N)
print(x_new)
print(FF(x_new))    





#!/usr/bin/env python
# coding: utf-8

# In[4]:


import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F


# In[5]:


def Newton(f,g,h,X,N):
    eps = 1e-8
    for i in range(N):
        X_old = X
        d,lu = torch.solve(-g(X_old).t(),h(X_old))
        X = X_old + d.t()
        if i%5 == 0:
            print('the iteration:%d,grad_2:%.3e'%(i,(g(X)**2).sum()))
        tmp = abs(f(X_old) - f(X))
        if max(tmp) < eps:
            break
    print('the end iteration:%d,grad_2:%.3e'%(i + 1,(g(X)**2).sum()))
    return X



#eps函数
# Extended Powell singular function
def F(X,rank,i):
    if i == 0:
        return X[:,4*rank] + 10*X[:,4*rank + 1]
    if i == 1:
        return (X[:,4*rank + 2] - X[:,4*rank + 3])*5**(0.5)
    if i == 2:
        return (X[:,4*rank + 1] - 2*X[:,4*rank + 2])**2
    if i == 3:
        return (10**(0.5))*(X[:,4*i] - X[:,4*i + 3])**2
def FF(X):#i >= 0
    n = X.shape[1];rank = int(n/4)
    temp = 0
    for i in range(rank):
        temp += (X[:,4*i] + 10*X[:,4*i + 1])**2
        temp += 5*(X[:,4*i + 2] - X[:,4*i + 3])**2
        temp += (X[:,4*i + 1] - 2*X[:,4*i + 2])**4
        temp += 10*(X[:,4*i] - X[:,4*i + 3])**4
    return temp
def GG(X):
    n = X.shape[1];rank = int(n/4)
    vec = torch.zeros_like(X)
    for i in range(rank):
        vec[:,4*i] = 2*(X[:,4*i] + 10*X[:,4*i + 1]) + 40*(X[:,4*i] - X[:,4*i + 3])**3
        vec[:,4*i + 1] = 20*(X[:,4*i] + 10*X[:,4*i + 1]) + 4*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 2] = 10*(X[:,4*i + 2] - X[:,4*i + 3]) - 8*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 3] = -10*(X[:,4*i + 2] - X[:,4*i + 3]) - 40*(X[:,4*i] - X[:,4*i + 3])**3
    return vec

def HH(X):
    n = X.shape[1];rank = int(n/4)
    mat = torch.zeros(n,n)
    for j in range(rank):
        mat[4*j,4*j] = 2 + 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j,4*j + 1] = 20 
        mat[4*j,4*j + 2] = 0
        mat[4*j,4*j + 3] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        #------------------
        mat[4*j + 1,4*j] = 20
        mat[4*j + 1,4*j + 1] = 200 + 12*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 2] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 3] = 0
        #-------------------
        mat[4*j + 2,4*j] = 0
        mat[4*j + 2,4*j + 1] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 2] = 10 + 48*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 3] = -10
        #----------------
        mat[4*j + 3,4*j] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j + 3,4*j + 1] = 0
        mat[4*j + 3,4*j + 2] = -10
        mat[4*j + 3,4*j + 3] = 10 + 120*(X[:,4*j] - X[:,4*j + 3])**2
    return mat
n = 20
X = torch.zeros(1,n)
for i in range(int(n/4)):
    X[:,4*i] = 3.0
    X[:,4*i + 1] = -1
    X[:,4*i + 3] = 1
N = 200
x_new = Newton(FF,GG,HH,X,N)
print(x_new)
print(FF(x_new))    








GLL+牛顿方向



import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F

#eps函数
# Extended Powell singular function
def F(X,rank,i):
    if i == 0:
        return X[:,4*rank] + 10*X[:,4*rank + 1]
    if i == 1:
        return (X[:,4*rank + 2] - X[:,4*rank + 3])*5**(0.5)
    if i == 2:
        return (X[:,4*rank + 1] - 2*X[:,4*rank + 2])**2
    if i == 3:
        return (10**(0.5))*(X[:,4*i] - X[:,4*i + 3])**2
def FF(X):#i >= 0
    n = X.shape[1];rank = int(n/4)
    temp = 0
    for i in range(rank):
        temp += (X[:,4*i] + 10*X[:,4*i + 1])**2
        temp += 5*(X[:,4*i + 2] - X[:,4*i + 3])**2
        temp += (X[:,4*i + 1] - 2*X[:,4*i + 2])**4
        temp += 10*(X[:,4*i] - X[:,4*i + 3])**4
    return temp
def GG(X):
    n = X.shape[1];rank = int(n/4)
    vec = torch.zeros_like(X)
    for i in range(rank):
        vec[:,4*i] = 2*(X[:,4*i] + 10*X[:,4*i + 1]) + 40*(X[:,4*i] - X[:,4*i + 3])**3
        vec[:,4*i + 1] = 20*(X[:,4*i] + 10*X[:,4*i + 1]) + 4*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 2] = 10*(X[:,4*i + 2] - X[:,4*i + 3]) - 8*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 3] = -10*(X[:,4*i + 2] - X[:,4*i + 3]) - 40*(X[:,4*i] - X[:,4*i + 3])**3
    return vec

def HH(X):
    n = X.shape[1];rank = int(n/4)
    mat = torch.zeros(n,n)
    for j in range(rank):
        mat[4*j,4*j] = 2 + 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j,4*j + 1] = 20 
        mat[4*j,4*j + 2] = 0
        mat[4*j,4*j + 3] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        #------------------
        mat[4*j + 1,4*j] = 20
        mat[4*j + 1,4*j + 1] = 200 + 12*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 2] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 3] = 0
        #-------------------
        mat[4*j + 2,4*j] = 0
        mat[4*j + 2,4*j + 1] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 2] = 10 + 48*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 3] = -10
        #----------------
        mat[4*j + 3,4*j] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j + 3,4*j + 1] = 0
        mat[4*j + 3,4*j + 2] = -10
        mat[4*j + 3,4*j + 3] = 10 + 120*(X[:,4*j] - X[:,4*j + 3])**2
    return mat

def gll(f,df,d,x,rho,lis,M = 4):
    if (df(x)**2).sum() > 1e2:
        al_old = 16.0
    else:
        al_old = 1.0
    for i in range(10):
        mi = min(i + 1,M)
        al_new = al_old*0.5**i
        #print(max(lis[-mi:]))
        if f(x + al_new*d.t()) <= max(lis[-mi:]) + rho*al_new*df(x)@d:
            break
    return al_new

def gllsolve(f,df,h,x,rho,M,N):
    lis = []
    eps = 1e-8
    for i in range(N):
        x_old = x
        lis.append(f(x_old))
        d,lu = torch.solve(-df(x_old).t(),h(x_old))
        al_new = gll(f,df,d,x_old,rho,lis,M)
        
        x = x_old + al_new*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3e'%(i,(df(x)**2).sum()))
        tmp = abs(f(x_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3e,tmp = %.3e'%(i + 1,(df(x)**2).sum(),tmp))
    return x

n = 20
X = torch.zeros(1,n)
for i in range(int(n/4)):
    X[:,4*i] = 3.0
    X[:,4*i + 1] = -1
    X[:,4*i + 3] = 1
N = 200
rho = 0.4
M = 4

x = gllsolve(FF,GG,HH,X,rho,M,N)
print(FF(x))

import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F

#Trigonometric 函数
def F(X,i):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp -= torch.cos(X[:,j])
    temp += n + (i + 1)*(1 - torch.cos(X[:,i])) - torch.sin(X[:,i])
    return temp
def FF(X):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp += F(X,j)**2
    return temp
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        vec[:,i] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*F(X,i) + 2*torch.sin(X[:,i])*temp
    return vec


def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        for j in range(n):
            if i == j:
                mat[i,j] = 2*((i + 1)*torch.cos(X[:,i]) + torch.sin(X[:,i]))*F(X,i) +                 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*((i + 2)*torch.sin(X[:,i]) - torch.cos(X[:,i])) +                2*torch.cos(X[:,i])*temp + 2*torch.sin(X[:,i])*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))
            else:
                mat[i,j] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*torch.sin(X[:,j]) +                  2*torch.sin(X[:,i])*((j + 1)*torch.sin(X[:,j]) - torch.cos(X[:,j]))
    return mat
def gll(f,df,d,x,rho,lis,M = 4):
    if (df(x)**2).sum() > 1e2:
        al_old = 16.0
    else:
        al_old = 1.0
    for i in range(10):
        mi = min(i + 1,M)
        al_new = al_old*0.5**i
        #print(max(lis[-mi:]))
        if f(x + al_new*d.t()) <= max(lis[-mi:]) + rho*al_new*df(x)@d:
            break
    return al_new

def gllsolve(f,df,h,x,rho,M,N):
    lis = []
    eps = 1e-8
    for i in range(N):
        x_old = x
        lis.append(f(x_old))
        d,lu = torch.solve(-df(x_old).t(),h(x_old))
        al_new = gll(f,df,d,x_old,rho,lis,M)
        
        x = x_old + al_new*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3e'%(i,(df(x)**2).sum()))
        tmp = abs(f(x_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3e,tmp = %.3e'%(i + 1,(df(x)**2).sum(),tmp))
    return x

n = 20;X = torch.ones(1,n)/n
rho = 0.4
M = 4
N = 100

x = gllsolve(FF,GG,HH,X,rho,M,N)
print(FF(x))


import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F
#Wood函数
def FF(X):
    out = 100*(X[:,1] - X[:,0])**2 + (1 - X[:,0])**2 + 90*(X[:,3] - X[:,2])**2 + \
    (1 - X[:,2])**2 + 10*(X[:,1] + X[:,3] - 2)**2 + ((X[:,1] - X[:,3])**2)/10
    return out
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    vec[:,0] = -400*X[:,0]*(X[:,1] - X[:,0]**2) - 2*(1 - X[:,0])
    vec[:,1] = 200*(X[:,1] - X[:,0]**2) + 20*(X[:,1] + X[:,3]- 2) + (X[:,1] - X[:,3])/5
    vec[:,2] = -360*X[:,2]*(X[:,3] - X[:,2]**2) - 2*(1 - X[:,2])
    vec[:,3] = 180*(X[:,3] - X[:,2]**2) + 20*(X[:,1] + X[:,3] - 2) - (X[:,1] - X[:,3])/5
    return vec
def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    mat[0,0] = -400*(X[:,1] - X[:,0]**2) + 800*X[:,0]**2 + 2
    mat[0,1] = -400*X[:,0];mat[0,2] = 0;mat[0,3] = 0
    #----------------
    mat[1,0] = -400*X[:,0]
    mat[1,1] = 220.5
    mat[1,2] = 0;mat[1,3] = 19.5
    #-----------------
    mat[2,0] = 0;mat[2,1] = 0
    mat[2,2] = 720*X[:,2]**2 - 360*(X[:,3] - X[:,2]**2) + 2
    mat[2,3] = -360*X[:,2]
    #---------------------
    mat[3,0] = 0
    mat[3,1] = 19.5
    mat[3,2] = -360*X[:,2]
    mat[3,3] = 200.5
    return mat
def gll(f,df,d,x,rho,lis,M = 4):
    if (df(x)**2).sum() > 1e2:
        al_old = 16.0
    else:
        al_old = 1.0
    for i in range(10):
        mi = min(i + 1,M)
        al_new = al_old*0.5**i
        #print(max(lis[-mi:]))
        if f(x + al_new*d.t()) <= max(lis[-mi:]) + rho*al_new*df(x)@d:
            break
    return al_new

def gllsolve(f,df,h,x,rho,M,N):
    lis = []
    eps = 1e-8
    for i in range(N):
        x_old = x
        lis.append(f(x_old))
        d,lu = torch.solve(-df(x_old).t(),h(x_old))
        al_new = gll(f,df,d,x_old,rho,lis,M)
        
        x = x_old + al_new*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3e'%(i,(df(x)**2).sum()))
        tmp = abs(f(x_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3e,tmp = %.3e'%(i + 1,(df(x)**2).sum(),tmp))
    return x

X = torch.tensor([[-3.0,-1,-3,-1]])
d,lu = torch.solve(-GG(X).t(),HH(X))
rho = 0.4
M = 4
N = 300

x = gllsolve(FF,GG,HH,X,rho,M,N)
print(FF(x))

gold+牛顿方向

# -*- coding: utf-8 -*-
"""
Created on Sun Nov 22 23:08:02 2020

@author: 2001213226
"""

import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F


def goldsteinsearch(f,df,d,x,alpham,rho,t):#利用goldstein原则求解步长

    flag = 0
    a = 0

    b = alpham

    fk = f(x)

    gk = df(x)

 

    phi0 = fk

    dphi0 = gk@d.t()#梯度和方向的内积

    # print(dphi0)

    #alpha=b*random.uniform(0,1)
    alpha = 1e-1
 

    for i in range(10):#类似于二分的过程,最多进行10次

        newfk = f(x + alpha * d)

        phi = newfk

        if (phi - phi0 )<= (rho * alpha * dphi0):

            if (phi - phi0) >= ((1 - rho) * alpha * dphi0):
                break#如果满足goldstein的两个准则,直接跳出循环
            else:

                a = alpha

                b = b

                if (b < alpham):

                    alpha = (a + b) / 2

                else:

                    alpha = t * alpha
        else:

            a = a

            b = alpha

            alpha = (a + b) / 2

    return alpha
def Goldsolve(x,f,df,h,alpham,rho,t,N):
    eps = 1e-8
    for i in range(N):
        X_old = x
        
        d,lu = torch.solve(-df(X_old).t(),h(X_old))
        x = X_old + goldsteinsearch(f,df,d.t(),x,alpham,rho,t)*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3f'%(i,(df(x)**2).sum()))
        tmp = abs(f(X_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3f,tmp = %.3f'%(i + 1,(df(x)**2).sum(),tmp))
    return x
#Wood函数
def FF(X):
    out = 100*(X[:,1] - X[:,0])**2 + (1 - X[:,0])**2 + 90*(X[:,3] - X[:,2])**2 + \
    (1 - X[:,2])**2 + 10*(X[:,1] + X[:,3] - 2)**2 + ((X[:,1] - X[:,3])**2)/10
    return out
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    vec[:,0] = -400*X[:,0]*(X[:,1] - X[:,0]**2) - 2*(1 - X[:,0])
    vec[:,1] = 200*(X[:,1] - X[:,0]**2) + 20*(X[:,1] + X[:,3]- 2) + (X[:,1] - X[:,3])/5
    vec[:,2] = -360*X[:,2]*(X[:,3] - X[:,2]**2) - 2*(1 - X[:,2])
    vec[:,3] = 180*(X[:,3] - X[:,2]**2) + 20*(X[:,1] + X[:,3] - 2) - (X[:,1] - X[:,3])/5
    return vec
def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    mat[0,0] = -400*(X[:,1] - X[:,0]**2) + 800*X[:,0]**2 + 2
    mat[0,1] = -400*X[:,0];mat[0,2] = 0;mat[0,3] = 0
    #----------------
    mat[1,0] = -400*X[:,0]
    mat[1,1] = 220.5
    mat[1,2] = 0;mat[1,3] = 19.5
    #-----------------
    mat[2,0] = 0;mat[2,1] = 0
    mat[2,2] = 720*X[:,2]**2 - 360*(X[:,3] - X[:,2]**2) + 2
    mat[2,3] = -360*X[:,2]
    #---------------------
    mat[3,0] = 0
    mat[3,1] = 19.5
    mat[3,2] = -360*X[:,2]
    mat[3,3] = 200.5
    return mat

X = torch.tensor([[-3.0,-1,-3,-1]])

alpham = 1.0
rho = 0.4
t = 1
N =100
x_new = Goldsolve(X,FF,GG,HH,alpham,rho,t,N)
print(FF(x_new))

import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F



def goldsteinsearch(f,df,d,x,alpham,rho,t):#利用goldstein原则求解步长

    flag = 0
    a = 0

    b = alpham

    fk = f(x)

    gk = df(x)

 

    phi0 = fk

    dphi0 = gk@d.t()#梯度和方向的内积

    # print(dphi0)

    #alpha=b*random.uniform(0,1)
    alpha = 1e-1
 

    for i in range(10):#类似于二分的过程,最多进行10次

        newfk = f(x + alpha * d)

        phi = newfk

        if (phi - phi0 )<= (rho * alpha * dphi0):

            if (phi - phi0) >= ((1 - rho) * alpha * dphi0):
                break#如果满足goldstein的两个准则,直接跳出循环
            else:

                a = alpha

                b = b

                if (b < alpham):

                    alpha = (a + b) / 2

                else:

                    alpha = t * alpha
        else:

            a = a

            b = alpha

            alpha = (a + b) / 2

    return alpha
def Goldsolve(x,f,df,h,alpham,rho,t,N):
    eps = 1e-8
    for i in range(N):
        X_old = x
        
        d,lu = torch.solve(-df(X_old).t(),h(X_old))
        x = X_old + goldsteinsearch(f,df,d.t(),x,alpham,rho,t)*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3f'%(i,(df(x)**2).sum()))
        tmp = abs(f(X_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3f,tmp = %.3f'%(i + 1,(df(x)**2).sum(),tmp))
    return x

#Trigonometric 函数
def F(X,i):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp -= torch.cos(X[:,j])
    temp += n + (i + 1)*(1 - torch.cos(X[:,i])) - torch.sin(X[:,i])
    return temp
def FF(X):
    n = X.shape[1]
    temp = 0
    for j in range(n):
        temp += F(X,j)**2
    return temp
def GG(X):
    n = X.shape[1]
    vec = torch.zeros_like(X)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        vec[:,i] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*F(X,i) + 2*torch.sin(X[:,i])*temp
    return vec

def HH(X):
    n = X.shape[1]
    mat = torch.zeros(n,n)
    temp = 0
    for j in range(n):
        temp += F(X,j)
    for i in range(n):
        for j in range(n):
            if i == j:
                mat[i,j] = 2*((i + 1)*torch.cos(X[:,i]) + torch.sin(X[:,i]))*F(X,i) + \
                2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*((i + 2)*torch.sin(X[:,i]) - torch.cos(X[:,i])) +\
                2*torch.cos(X[:,i])*temp + 2*torch.sin(X[:,i])*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))
            else:
                mat[i,j] = 2*((i + 1)*torch.sin(X[:,i]) - torch.cos(X[:,i]))*torch.sin(X[:,j]) + \
                 2*torch.sin(X[:,i])*((j + 1)*torch.sin(X[:,j]) - torch.cos(X[:,j]))
    return mat

n = 20;X = torch.ones(1,n)/n
alpham = 1.0
rho = 0.4
t = 1
N = 200
x_new = Goldsolve(X,FF,GG,HH,alpham,rho,t,N)
print(FF(x_new))
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 22 23:06:47 2020

@author: 2001213226
"""

import numpy as np
import matplotlib.pyplot as plt
import torch
import time
import torch.nn as nn
import torch.nn.functional as F

def goldsteinsearch(f,df,d,x,alpham,rho,t):#利用goldstein原则求解步长

    flag = 0
    a = 0

    b = alpham

    fk = f(x)

    gk = df(x)

 

    phi0 = fk

    dphi0 = gk@d.t()#梯度和方向的内积

    # print(dphi0)

    #alpha=b*random.uniform(0,1)
    alpha = 1e-1
 

    for i in range(10):#类似于二分的过程,最多进行10次

        newfk = f(x + alpha * d)

        phi = newfk

        if (phi - phi0 )<= (rho * alpha * dphi0):

            if (phi - phi0) >= ((1 - rho) * alpha * dphi0):
                break#如果满足goldstein的两个准则,直接跳出循环
            else:

                a = alpha

                b = b

                if (b < alpham):

                    alpha = (a + b) / 2

                else:

                    alpha = t * alpha
        else:

            a = a

            b = alpha

            alpha = (a + b) / 2

    return alpha
def Goldsolve(x,f,df,h,alpham,rho,t,N):
    eps = 1e-8
    for i in range(N):
        X_old = x
        
        d,lu = torch.solve(-df(X_old).t(),h(X_old))
        x = X_old + goldsteinsearch(f,df,d.t(),x,alpham,rho,t)*d.t()
        if i%20 == 0:
            print('the iteration is %d,the grad_2 is %.3f'%(i,(df(x)**2).sum()))
        tmp = abs(f(X_old) - f(x))
        if max(tmp) < eps:
            break
    print('the end iteration is %d,the grad_2 is %.3f,tmp = %.3f'%(i + 1,(df(x)**2).sum(),tmp))
    return x
#eps函数
# Extended Powell singular function
def F(X,rank,i):
    if i == 0:
        return X[:,4*rank] + 10*X[:,4*rank + 1]
    if i == 1:
        return (X[:,4*rank + 2] - X[:,4*rank + 3])*5**(0.5)
    if i == 2:
        return (X[:,4*rank + 1] - 2*X[:,4*rank + 2])**2
    if i == 3:
        return (10**(0.5))*(X[:,4*i] - X[:,4*i + 3])**2
def FF(X):#i >= 0
    n = X.shape[1];rank = int(n/4)
    temp = 0
    for i in range(rank):
        temp += (X[:,4*i] + 10*X[:,4*i + 1])**2
        temp += 5*(X[:,4*i + 2] - X[:,4*i + 3])**2
        temp += (X[:,4*i + 1] - 2*X[:,4*i + 2])**4
        temp += 10*(X[:,4*i] - X[:,4*i + 3])**4
    return temp
def GG(X):
    n = X.shape[1];rank = int(n/4)
    vec = torch.zeros_like(X)
    for i in range(rank):
        vec[:,4*i] = 2*(X[:,4*i] + 10*X[:,4*i + 1]) + 40*(X[:,4*i] - X[:,4*i + 3])**3
        vec[:,4*i + 1] = 20*(X[:,4*i] + 10*X[:,4*i + 1]) + 4*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 2] = 10*(X[:,4*i + 2] - X[:,4*i + 3]) - 8*(X[:,4*i + 1] - 2*X[:,4*i + 2])**3
        vec[:,4*i + 3] = -10*(X[:,4*i + 2] - X[:,4*i + 3]) - 40*(X[:,4*i] - X[:,4*i + 3])**3
    return vec

def HH(X):
    n = X.shape[1];rank = int(n/4)
    mat = torch.zeros(n,n)
    for j in range(rank):
        mat[4*j,4*j] = 2 + 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j,4*j + 1] = 20 
        mat[4*j,4*j + 2] = 0
        mat[4*j,4*j + 3] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        #------------------
        mat[4*j + 1,4*j] = 20
        mat[4*j + 1,4*j + 1] = 200 + 12*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 2] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 1,4*j + 3] = 0
        #-------------------
        mat[4*j + 2,4*j] = 0
        mat[4*j + 2,4*j + 1] = -24*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 2] = 10 + 48*(X[:,4*j + 1] - 2*X[:,4*j + 2])**2
        mat[4*j + 2,4*j + 3] = -10
        #----------------
        mat[4*j + 3,4*j] = - 120*(X[:,4*j] - X[:,4*j + 3])**2
        mat[4*j + 3,4*j + 1] = 0
        mat[4*j + 3,4*j + 2] = -10
        mat[4*j + 3,4*j + 3] = 10 + 120*(X[:,4*j] - X[:,4*j + 3])**2
    return mat
n = 20
X = torch.zeros(1,n)
for i in range(int(n/4)):
    X[:,4*i] = 3.0
    X[:,4*i + 1] = -1
    X[:,4*i + 3] = 1
alpham = 1.0
rho = 0.4
t = 1
N = 800
x_new = Goldsolve(X,FF,GG,HH,alpham,rho,t,N)
print(FF(x_new))

运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/forrestguang/article/details/110314419