ϢΩ°ì¼¡ÊýÄø¼°¤Îµá²ò †
LU ʬ²ò †
Áݤ½Ð¤·Ë¡¤òÀþ·ÁÂå¿ô¤Ç¤¤Á¤ó¤Èª¤¨Ä¾¤·¡¢¤«¤Ä¡¢¤Ê¤ë¤Ù¤¯ÊØÍø¤Ê·Á¤Ëľ¤¹¤È¡¢LU ʬ²ò¤È¤¤¤¦¤â¤Î¤Ë¤Ê¤ë¡¥
¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à †
include Math
n = 4
a = [
[ 3.0 , 3.0 , - 5.0 , - 6.0 ] ,
[ 1.0 , 2.0 , - 3.0 , - 1.0 ] ,
[ 2.0 , 3.0 , - 5.0 , - 3.0 ] ,
[ - 1.0 , 0 , 0 , 1.0 ]
]
b = [ 1.0 , 2.0 , 3.0 , 4.0 ]
for k in ( 1. . ( n - 1 ) )
for i in ( k + 1. . n )
a [ i - 1 ] [ k - 1 ] / = a[k-1][k-1]
for j in (k+1..n)
a[i-1][j-1] -= a[i-1][k-1]*a[k-1][j-1]
end
end
end
# We obtain y=L^(-1)b by a forward substitution.
# Its loop is double and it means its computation cost order is n^2.
y = [0.0, 0.0, 0.0, 0.0]
for i in (1..n)
y[i-1] = b[i-1]
if i < n
for j in ((i+1)..n)
b[j-1] -= a[j-1][i-1]*b[i-1]
end
end
end
# Solve the solution x=U^(-1)y by a backward substitution.
# Its computation cost order is also n^2.
x = [0.0, 0.0, 0.0, 0.0]
n.downto(1) { |i|
x[i-1] = y[i-1] / a [ i - 1 ] [ i - 1 ]
if i > 2
( i - 1 ) . downto ( 1 ) { | j |
y [ j - 1 ] -= ( a [ j - 1 ] [ i - 1 ] / a[i-1][i-1])*y[i-1]
}
end
}
# result
p x
# Sample result
# [-4.999999999999999, 8.881784197001252e-16, -1.9999999999999993, -1.0]
ºÇµÞ¹ß²¼Ë¡ †
¹ÔÎó A ¤¬ÀµÄêÃÍÂоΤξì¹ç¡¢Ax = b ¤Î¿¿¤Î²ò x ¤ËÂФ·¤Æ S(a) := (a-x)^t A (a-x) ¤È¤¹¤ë¤È¡¢
¤³¤Î S(a) ¤ÏÈóÉé¤Ç¤¢¤ê¡¢a = x ¤Î»þ¤Î¤ß¥¼¥í¤Ë¤Ê¤ë¡¥
¤³¤ì¤òÍøÍѤ·¤Æ¡¢S(a) ¤¬¾®¤µ¤¯¤Ê¤ë¤è¤¦¤Ë¥Ù¥¯¥È¥ë a ¤òÈ¿Éü²þÎɤ·¤Æ¤¤¤Ã¤Æ¡¢S(a) ¤¬¤Û¤Ü¥¼¥í¤Ë¤Ê¤ì¤Ð¤½¤Î a ¤Ï x ¤Î¶á»÷ÃͤȤǤ¤ë¡¥
¤³¤Î¹Í¤¨Êý¤Ë±è¤Ã¤Æ¡¢S(a) ¤ò¡ÖºÇ¤âÁ᤯¾®¤µ¤¯¤¹¤ëÊý¸þ¡×¤Ë a ¤ò²þÁ±¤·¤Æ¤¤¤¯¼êË¡¤Ç¤¢¤ë¡¥
S(a) ¤ò¤â¤Ã¤È¤âÁ᤯¾®¤µ¤¯¤¹¤ëÊý¸þ¤È¤Ï S(a) ¤Î¸ûÇۤεÕÊý¸þ¤Ç¡¢·×»»¤·¤Æ¤ß¤ë¤È b - Aa ¤Ç¤¢¤ë¡¥
¤Á¤Ê¤ß¤Ë¡¢¤³¤ÎÊý¸þ¤ò¡Ö¤â¤¦¾¯¤·¸¤¯¡×Áª¤ó¤À¤â¤Î¤¬¸å½Ò¤Î CGË¡¤Ç¤¢¤ë¤È¤ß¤Ê¤»¤ë¡¥
¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à †
include Math
Eps = 1.0e-08
A = [
[ 7.0 , 1.0 , 2.0 , 3.0 ] ,
[ 1.0 , 10.0 , 3.0 , 4.0 ] ,
[ 2.0 , 3.0 , 13.0 , 6.0 ] ,
[ 3.0 , 4.0 , 6.0 , 16.0 ]
]
B = [ 1.0 , 2.0 , 3.0 , 4.0 ]
N = A . size
def inner_product ( x , y )
z = 0.0
for i in ( 1. . N )
z += x [ i - 1 ] * y [ i - 1 ]
end
return z
end
def vc_coeff ( c , b )
z = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
z [ i - 1 ] = c * b [ i - 1 ]
end
return z
end
def vc_sum ( a , b )
c = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
c [ i - 1 ] = a [ i - 1 ] + b [ i - 1 ]
end
return c
end
def mtrx_vc_product ( a , b )
c = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
for j in ( 1. . N )
c [ i - 1 ] += a [ i - 1 ] [ j - 1 ] * b [ j - 1 ]
end
end
return c
end
def a_vc ( b )
return mtrx_vc_product ( A , b )
end
def residual ( x )
return vc_sum ( B , vc_coeff ( - 1.0 , a_vc ( x ) ) )
end
def norm ( x )
v = 0.0
for i in ( 1. . N )
v += x [ i - 1 ] ** 2
end
return sqrt ( v )
end
def print_result ( x )
print " x = [ "
for i in ( 1. . N - 1 )
printf ( " %.6f " , x [ i - 1 ] )
print " , "
end
printf ( " %.6f " , x [ N - 1 ] )
print " ], "
print " residual= " , norm ( residual ( x ) ) , " \n "
end
def steepest_descent_iteration ( x )
r = residual ( x )
w = inner_product ( r , r ) / inner_product(r, a_vc(r))
return vc_sum(x, vc_coeff(w,r))
end
##### main program #####
# initial values
x = Array.new(N).collect{ 1.0 }
print_result(x)
# loop to obtain a good x.
loop_times = 0
loop do
if (norm(residual(x)) < Eps) then
break
else
x = steepest_descent_iteration(x)
print_result(x)
loop_times += 1
end
end
# result
print " \n \n You obtain a numerical solution after ",loop_times," loops. \n \n "
print_result(x)
print " \n "
CG Ë¡ †
S(a) ¤òºÇ¤âÁ᤯¾®¤µ¤¯¤¹¤ëÊý¸þ¤Ë²þÁ±¤¹¤ëºÇµÞ¹ß²¼Ë¡¤ÏÍßÄ¥¤ê¤¹¤®¤Ç¤«¤¨¤Ã¤Æ¼ý«¤¬ÃÙ¤¤¤Î¤¬¾ï¤È¸À¤Ã¤ÆÎɤ¤¤Î¤Ç¡¢¿ô³ØŪ¤Ë¤¤Á¤ó¤È¹Í¤¨¤Ê¤ª¤·¤¿¤Î¤¬ CG Ë¡¤Ç¤¢¤ë¡¥
¶ñÂÎŪ¤Ë¤Ï¡¢°ì²óÁ°¤Ë a ¤ò²þÁ±¤·¤Æ¤¤¿¡ÖÊý¸þ¡×¤ËÂФ·¡¢¼¡¤Î²þÁ±Êý¸þ¤ò A-ľ¸ò¤¹¤ë¤è¤¦¤Ë¤·¤¿¤â¤Î¤¬ CG Ë¡¤Ç¤¢¤ë¡¥
ºÇµÞ¹ß²¼Ë¡¤Ï¡¢Àè¤Î²þÁ±Êý¸þ¤ËÂФ·¼¡¤Î²þÁ±Êý¸þ¤¬É¬¤ºÄ¾¸ò¤·¤Æ¤¤¤ë¡¥
Æó¤Ä¤Î¥Ù¥¯¥È¥ë x,y ¤¬ A-ľ¸ò¤Ç¤¢¤ë¤È¤Ï¡¢x^t A y = 0 ¤Ç¤¢¤ë¤³¤È¡¥
¤µ¤Æ¡¢¤³¤Î¤è¤¦¤Ë²þÁ±Êý¸þ¤ò A-ľ¸ò¤Ë¤Ê¤ë¤è¤¦¤Ë¤¹¤ë¤È¡¢¡Ö¸¶ÍýŪ¤Ë¤Ï¡×A ¤Î¼¡¸µ¿ô¤ò n ¤È¤¹¤ë¤È¥Ù¥¯¥È¥ë a ¤ò n ²ó²þÁ±¤¹¤ë¤«¤½¤ì¤Þ¤Ç¤Ë¤«¤Ê¤é¤º a = x ¤È¤Ê¤ë¤È¤¤¤¦ÂçÊÑÎɤ¤À¼Á¤¬¤â¤¿¤é¤µ¤ì¤ë¡¥
¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à †
include Math
Eps = 1.0e-08
A = [
[ 7.0 , 1.0 , 2.0 , 3.0 ] ,
[ 1.0 , 10.0 , 3.0 , 4.0 ] ,
[ 2.0 , 3.0 , 13.0 , 6.0 ] ,
[ 3.0 , 4.0 , 6.0 , 16.0 ]
]
B = [ 1.0 , 2.0 , 3.0 , 4.0 ]
N = A . size
def inner_product ( x , y )
z = 0.0
for i in ( 1. . N )
z += x [ i - 1 ] * y [ i - 1 ]
end
return z
end
def vc_coeff ( c , b )
z = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
z [ i - 1 ] = c * b [ i - 1 ]
end
return z
end
def vc_sum ( a , b )
c = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
c [ i - 1 ] = a [ i - 1 ] + b [ i - 1 ]
end
return c
end
def mtrx_vc_product ( a , b )
c = Array . new ( N ) . collect { 0.0 }
for i in ( 1. . N )
for j in ( 1. . N )
c [ i - 1 ] += a [ i - 1 ] [ j - 1 ] * b [ j - 1 ]
end
end
return c
end
def a_vc ( b )
return mtrx_vc_product ( A , b )
end
def residual ( x )
return vc_sum ( B , vc_coeff ( - 1.0 , a_vc ( x ) ) )
end
def norm ( x )
v = 0.0
for i in ( 1. . N )
v += x [ i - 1 ] ** 2
end
return sqrt ( v )
end
def print_result ( x )
print " x = [ "
for i in ( 1. . N - 1 )
printf ( " %.6f " , x [ i - 1 ] )
print " , "
end
printf ( " %.6f " , x [ N - 1 ] )
print " ], "
print " residual= " , norm ( residual ( x ) ) , " \n "
end
def cg_iteration ( x , r , p , r_R , q )
q_Q = inner_product ( p , q )
w = r_R / q_Q
x_new = vc_sum(x, vc_coeff(w,p))
r_new = vc_sum(r, vc_coeff((-1.0*w),q))
r_R_new = inner_product(r_new, r_new)
beta = r_R_new / r_R
p_new = vc_sum ( r_new , vc_coeff ( beta , p ) )
q_new = a_vc ( p_new )
return [ x_new , r_new , p_new , r_R_new , q_new ]
end
x = Array . new ( N ) . collect { 1.0 }
r = residual ( x )
p = vc_coeff ( 1.0 , r )
r_R = inner_product ( r , r )
q = a_vc ( p )
print_result ( x )
loop_times = 0
loop do
if ( norm ( residual ( x ) ) < Eps ) then
break
else
x , r , p , r_R , q = cg_iteration ( x , r , p , r_R , q )
print_result ( x )
loop_times += 1
end
end
print " \n \n You obtain a numerical solution after " , loop_times , " loops. \n \n "
print_result ( x )
print " \n "