นี่คือคำตอบยาว ดังนั้นขอมอบเวอร์ชั่นสั้นของที่นี่
- ไม่มีวิธีแก้พีชคณิตที่ดีสำหรับปัญหาการค้นหารูทนี้ดังนั้นเราจึงต้องการอัลกอริธึมเชิงตัวเลข
- functionมีคุณสมบัติที่ดีมากมาย เราสามารถควบคุมสิ่งเหล่านี้เพื่อสร้างวิธีเฉพาะของนิวตันสำหรับปัญหานี้โดยมีการบรรจบกันแบบ monotonicต่อรากแต่ละอันdf(λ)
- แม้กระทั่ง
R
รหัสที่ไม่มีสมองความพยายามใด ๆ ในการปรับให้เหมาะสมสามารถคำนวณกริดขนาด 100 ด้วยในไม่กี่วินาที รหัสที่เขียนอย่างระมัดระวังจะลดขนาดลงอย่างน้อย 2-3 คำสั่งp=100000C
มีสองรูปแบบที่ระบุด้านล่างเพื่อรับประกันการบรรจบกันของเสียงโมโน หนึ่งใช้ขอบเขตที่แสดงด้านล่างซึ่งดูเหมือนจะช่วยประหยัดขั้นตอนที่นิวตันหรือสองครั้ง
ตัวอย่าง :และกริดสม่ำเสมอสำหรับองศาอิสระขนาด 100 ค่าลักษณะเฉพาะมีการกระจายพาเรโตจึงเบ้สูง ด้านล่างนี้เป็นตารางจำนวนขั้นตอนของนิวตันเพื่อค้นหาแต่ละรูตp=100000
# Table of Newton iterations per root.
# Without using lower-bound check.
1 3 4 5 6
1 28 65 5 1
# Table with lower-bound check.
1 2 3
1 14 85
จะไม่มีการแก้ปัญหาการปิดแบบฟอร์มสำหรับการนี้โดยทั่วไป แต่มีเป็นจำนวนมากปัจจุบันโครงสร้างซึ่งสามารถนำมาใช้ในการผลิตโซลูชั่นที่มีประสิทธิภาพและปลอดภัยโดยใช้วิธีการหารากมาตรฐาน
ก่อนที่จะขุดลึกลงไปในสิ่งต่าง ๆ มากเกินไปให้รวบรวมคุณสมบัติและผลที่ตามมาของฟังก์ชั่น
df(λ)=∑i=1pd2id2i+λ.
อสังหาริมทรัพย์ 0 :เป็นฟังก์ชั่นที่มีเหตุผลของ\(นี่คือที่เห็นได้ชัดจากคำนิยาม.)
ผล 0 : ไม่มีการแก้ปัญหาเกี่ยวกับพีชคณิตทั่วไปจะมีอยู่สำหรับการหาราก0 นี่เป็นเพราะมีปัญหาการค้นหารูทพหุนามเทียบเท่าของระดับและดังนั้นหากไม่เล็กมาก (เช่นน้อยกว่าห้า) จะไม่มีวิธีแก้ปัญหาทั่วไป ดังนั้นเราจะต้องใช้วิธีการเชิงตัวเลข λdfλ
df(λ)−y=0พีpp
ทรัพย์สิน 1 : ฟังก์ชั่นนูนและลดลงใน0 (รับอนุพันธ์)
ผลที่ตามมา 1 (a) : อัลกอริทึมการค้นหารากของนิวตันจะทำงานได้ดีมากในสถานการณ์นี้ Letเป็นองศาที่ต้องการของเสรีภาพและรากที่สอดคล้องกันคือlambda_0) โดยเฉพาะอย่างยิ่งถ้าเราเริ่มต้นด้วยการใด ๆค่าเริ่มต้น (ดังนั้น ) แล้วลำดับของนิวตันขั้นตอนซ้ำจะมาบรรจบกันmonotonicallyไป ทางออกที่ไม่ซ้ำ λ ≥ 0dfλ≥0
λ 0 y = d f ( λ 0 )yλ0y=df(λ0)λ1<λ0df(λ1)>yλ1,λ2,…λ0\
ผล 1 (ข) : นอกจากนี้ถ้าเราจะเริ่มต้นด้วยแล้วครั้งแรกขั้นตอนที่จะให้ผลผลิตมาจากไหนมัน monotonically จะเพิ่มขึ้นเป็นวิธีการแก้ปัญหาโดยผลก่อนหน้านี้ (ดูข้อแม้ ด้านล่าง) ความจริงสุดท้ายนี้ตามมาเพราะถ้าเราเริ่มทางด้านขวาของรูตอนุพันธ์ก็คือ "เกินไป" ที่ตื้นเนื่องจากความนูนของดังนั้นขั้นตอนแรกของนิวตันจะพาเราไปทางซ้ายของรูต NBเนื่องจากไม่ได้เป็นแบบทั่วไปสำหรับการลบλ1>λ0λ2≤λ0dfdfλนี่เป็นเหตุผลที่ดีที่จะเริ่มจากด้านซ้ายของรูตที่ต้องการ มิฉะนั้นเราจะต้องตรวจสอบว่าขั้นตอนของนิวตันยังไม่ได้ส่งผลให้ค่าลบสำหรับรากโดยประมาณซึ่งอาจวางเราที่ไหนสักแห่งในส่วนของ nonconvex \
ผลที่ตามมา 1 (c) : เมื่อเราเจอรูทของและจากนั้นค้นหารูทจากโดยใช้เพื่อให้เป็นการเดาเริ่มต้นของเรา ด้านซ้ายของรูตที่สอง ดังนั้นการบรรจบกันของเรารับประกันว่าจะเป็นแบบโมโนโทนิกจากที่นั่นdf
y1y2<y1λ1df(λ1)=y1
คุณสมบัติ 2 : มีขอบเขตที่สมเหตุสมผลเพื่อให้จุดเริ่มต้น "ปลอดภัย" การใช้ข้อโต้แย้งนูนและความไม่เท่าเทียมของเซ่นเรามีขอบเขต
ผลที่ตามมา 2 : สิ่งนี้บอกเราว่ารูททำให้พอใจเชื่อฟัง
ดังนั้นขึ้นไปอย่างต่อเนื่องร่วมกันเราได้แซนวิชรากในระหว่างวิธีการประสานและการคำนวณของ 2λ 0 d f ( λ 0 ) = y 1
p1+λp∑d−2i≤df(λ)≤p∑id2i∑id2i+pλ.
λ0df(λ0)=y11p∑id−2i(p−yy)≤λ0≤(1p∑id2i)(p−yy).(⋆)
d2i
นี้อนุมานว่าสำหรับทุกฉันถ้ากรณีนี้ไม่ได้แล้วที่ถูกผูกไว้เดียวกันถือโดยพิจารณาเพียงบวกและแทนที่จากจำนวนบวกd_iหมายเหตุ : ตั้งแต่สมมติว่า , จากนั้น , ดังนั้นขอบเขตจึงไม่จำเป็นเสมอ (เช่น, ขอบล่างจะไม่เป็นค่าลบเสมอ)di>0idipdidf(0)=pdi>0y∈(0,p]
นี่คือพล็อตเป็นตัวอย่างที่ "ปกติ" ของกับ400 เราวางตารางขนาด 10 สำหรับองศาอิสระ นี่คือเส้นแนวนอนในเนื้อเรื่อง เส้นสีเขียวแนวตั้งตรงกับขอบเขตล่างในดาว)df(λ)p=400(⋆)
อัลกอริทึมและตัวอย่างรหัส R
อัลกอริทึมที่มีประสิทธิภาพมากได้รับตารางขององศาที่ต้องการของเสรีภาพในคือการจัดเรียงไว้ในลำดับที่ลดลงแล้วตามลำดับพบว่ารากของแต่ละคนโดยใช้รากก่อนหน้านี้เป็นจุดเริ่มต้นสำหรับต่อไปนี้ หนึ่งเราสามารถปรับแต่งเพิ่มเติมได้โดยตรวจสอบว่าแต่ละรูทนั้นมีค่ามากกว่าขอบเขตล่างสำหรับรูตถัดไปหรือไม่และถ้าไม่เราสามารถเริ่มต้นการทำซ้ำครั้งถัดไปที่ขอบเขตล่างแทนy1,…yn(0,p]
นี่คือตัวอย่างโค้ดบางส่วนR
โดยไม่พยายามปรับให้เหมาะสม ดังที่เห็นด้านล่างมันยังค่อนข้างเร็วแม้ว่าจะR
เป็น - เพื่อวางอย่างสุภาพ - ช้าอย่างน่ากลัวและแย่มากที่ลูป
# Newton's step for finding solutions to regularization dof.
dof <- function(lambda, d) { sum(1/(1+lambda / (d[d>0])^2)) }
dof.prime <- function(lambda, d) { -sum(1/(d[d>0]+lambda / d[d>0])^2) }
newton.step <- function(lambda, y, d)
{ lambda - (dof(lambda,d)-y)/dof.prime(lambda,d) }
# Full Newton step; Finds the root of y = dof(lambda, d).
newton <- function(y, d, lambda = NA, tol=1e-10, smart.start=T)
{
if( is.na(lambda) || smart.start )
lambda <- max(ifelse(is.na(lambda),0,lambda), (sum(d>0)/y-1)/mean(1/(d[d>0])^2))
iter <- 0
yn <- Inf
while( abs(y-yn) > tol )
{
lambda <- max(0, newton.step(lambda, y, d)) # max = pedantically safe
yn <- dof(lambda,d)
iter = iter + 1
}
return(list(lambda=lambda, dof=y, iter=iter, err=abs(y-yn)))
}
ด้านล่างนี้เป็นอัลกอริธึมสุดท้ายที่สมบูรณ์ซึ่งใช้กริดของจุดและเวกเตอร์ของ ( ไม่ใช่ !)di d2i
newton.grid <- function(ygrid, d, lambda=NA, tol=1e-10, smart.start=TRUE)
{
p <- sum(d>0)
if( any(d < 0) || all(d==0) || any(ygrid > p)
|| any(ygrid <= 0) || (!is.na(lambda) && lambda < 0) )
stop("Don't try to fool me. That's not nice. Give me valid inputs, please.")
ygrid <- sort(ygrid, decreasing=TRUE)
out <- data.frame()
lambda <- NA
for(y in ygrid)
{
out <- rbind(out, newton(y,d,lambda, smart.start=smart.start))
lambda <- out$lambda[nrow(out)]
}
out
}
ฟังก์ชั่นการโทรตัวอย่าง
set.seed(17)
p <- 100000
d <- sqrt(sort(exp(rexp(p, 10)),decr=T))
ygrid <- p*(1:100)/100
# Should take ten seconds or so.
out <- newton.grid(ygrid,d)