eqsolver - เครื่องแก้สมการและไลบรารีการเพิ่มประสิทธิภาพสำหรับการเกิดสนิมห้องสมุดสนิมนี้มีวัตถุประสงค์เพื่อแก้สมการเชิงตัวเลขและเพิ่มประสิทธิภาพฟังก์ชั่นวัตถุประสงค์
ห้องสมุดได้ รับการดูแลอย่างอดทน ซึ่งหมายความว่าจะไม่มีการเพิ่มคุณสมบัติอื่น ๆ อย่างไรก็ตามปัญหาเกี่ยวกับ GitHub จะได้รับคำตอบและแก้ไข
การมีส่วนร่วมและข้อเสนอแนะต่อห้องสมุดนี้เป็นมากกว่าการต้อนรับ!
วิธีการต่อไปนี้มีให้ใช้ในไลบรารี คำอธิบายของพวกเขาใช้โดเมนที่เป็นไปได้มากที่สุดและ codomain สำหรับฟังก์ชั่นซึ่งก็คือ RN อย่างไรก็ตามชุดย่อยของ RN (ประพฤติดี) ก็ใช้งานได้เช่นกัน นอกจากนี้วิธีการที่ใช้อินพุตหลายตัวแปรหรือเอาต์พุตใช้อย่างมากใช้ประโยชน์จากไลบรารีพีชคณิตเชิงเส้นสำหรับ Rust Nalgebra
มีสองเวอร์ชันของวิธีนี้หนึ่งต้องการเมทริกซ์จาโคเบียที่จะได้รับและอีกรุ่นหนึ่งประมาณโดยใช้ความแตกต่างที่ จำกัด รุ่นหลังมีเวลากำแพงนานขึ้นเล็กน้อย ทั้งสองวิธีต้องการการเดาเบื้องต้น
สำหรับปัญหาบางอย่างที่ไม่ดีวิธีนี้จะล้มเหลว สำหรับวิธีที่ช้ากว่า แต่มีความแข็งแกร่งมากขึ้นให้ดูวิธี Levenberg-Marquardt ด้านล่าง
มีสองเวอร์ชันของวิธีนี้หนึ่งต้องการเมทริกซ์จาโคเบียที่จะได้รับและอีกรุ่นหนึ่งประมาณโดยใช้ความแตกต่างที่ จำกัด รุ่นหลังมีเวลากำแพงนานขึ้นเล็กน้อย ทั้งสองวิธีต้องการการเดาเบื้องต้น
สำหรับปัญหาบางอย่างที่ไม่ดีวิธีนี้จะล้มเหลว สำหรับวิธีที่ช้ากว่า แต่มีความแข็งแกร่งมากขึ้นให้ดูวิธี Levenberg-Marquardt ด้านล่าง
มีสองเวอร์ชันของวิธีนี้หนึ่งต้องการเมทริกซ์จาโคเบียที่จะได้รับและอีกรุ่นหนึ่งประมาณโดยใช้ความแตกต่างที่ จำกัด รุ่นหลังมีเวลากำแพงนานขึ้นเล็กน้อย ทั้งสองวิธีต้องการการเดาเบื้องต้น
ใช้วิธีนี้หากคุณรู้ขอบเขตของพารามิเตอร์
ใช้วิธีนี้หากคุณไม่ทราบขอบเขตของพารามิเตอร์ แต่รู้ว่าแต่ละพารามิเตอร์มีความไม่แน่นอนเพียงใด
มี struct เดียวสำหรับสมการเชิงอนุพันธ์สามัญ (ODE) ซึ่งสามารถแก้ไขได้ (โดยใช้รูปแบบตัวสร้าง) เพื่อใช้วิธีหนึ่งในขั้นตอนต่อไปนี้:
use eqsolver :: single_variable :: FDNewton ;
let f = | x : f64 | x . exp ( ) - 1. /x ; // e^x = 1/x
let solution = FDNewton :: new ( f ) . solve ( 0.5 ) ; // Starting guess is 0.5 use eqsolver :: multivariable :: MultiVarNewtonFD ;
use nalgebra :: { vector , Vector2 } ;
// Want to solve x^2 - y = 1 and xy = 2
let f = | v : Vector2 < f64 > | vector ! [ v [ 0 ] . powi ( 2 ) - v [ 1 ] - 1. , v [ 0 ] * v [ 1 ] - 2. ] ;
let solution = MultiVarNewtonFD :: new ( f ) . solve ( vector ! [ 1. , 1. ] ) ; // Starting guess is (1, 1) use eqsolver :: ODESolver ;
let f = | t : f64 , y : f64 | t * y ; // y' = f(t, y) = ty
let ( x0 , y0 ) = ( 0. , 0.2 ) ;
let x_end = 2. ;
let step_size = 1e-3 ;
let solution = ODESolver :: new ( f , x0 , y0 , step_size ) . solve ( x_end ) ; use eqsolver :: multivariable :: LevenbergMarquardtFD ;
use nalgebra :: { vector , Vector2 } ;
let c0 = [ 3. , 5. , 3. ] ;
let c1 = [ 1. , 0. , 4. ] ;
let c2 = [ 6. , 2. , 2. ] ;
// Function from R2 to R3
let f = | v : Vector2 < f64 > | {
vector ! (
( v [ 0 ] - c0 [ 0 ] ) . powi ( 2 ) + ( v [ 1 ] - c0 [ 1 ] ) . powi ( 2 ) - c0 [ 2 ] * c0 [ 2 ] ,
( v [ 0 ] - c1 [ 0 ] ) . powi ( 2 ) + ( v [ 1 ] - c1 [ 1 ] ) . powi ( 2 ) - c1 [ 2 ] * c1 [ 2 ] ,
( v [ 0 ] - c2 [ 0 ] ) . powi ( 2 ) + ( v [ 1 ] - c2 [ 1 ] ) . powi ( 2 ) - c2 [ 2 ] * c2 [ 2 ] ,
)
} ;
let solution_lm = LevenbergMarquardtFD :: new ( f )
. solve ( vector ! [ 4.5 , 2.5 ] ) // Guess
. unwrap ( ) ; use eqsolver :: global_optimisers :: { CrossEntropy , ParticleSwarm } ;
use nalgebra :: SVector ;
use std :: f64 :: consts :: PI ;
const SIZE : usize = 10 ;
let rastrigin = | v : SVector < f64 , SIZE > | {
v . fold ( 10. * SIZE as f64 , |acc , x| {
acc + x * x - 10. * f64 :: cos ( 2. * PI * x )
} )
} ;
let bounds = SVector :: repeat ( 10. ) ;
let standard_deviations = SVector :: repeat ( 10. ) ;
let guess = SVector :: repeat ( 5. ) ;
let opt_pso = ParticleSwarm :: new ( rastrigin , -bounds , bounds ) . solve ( guess ) ;
let opt_ce = CrossEntropy :: new ( rastrigin )
. with_std_dev ( standard_deviations )
. solve ( guess ) ;สำหรับตัวอย่างเพิ่มเติมโปรดดูไดเรกทอรีตัวอย่าง