PHP를 사용하여 √2
개요
구\sqrt{2}의 문제는 수치 계산에서FuzzBuzz와 비슷한 기초 문제이며, 방법은 수치 구해 f(x)=x^2-2=0이다.
이 해법은 이분법과 뉴턴법으로 유명하다.
나는 PHP를 거의 써 본 적이 없지만, 나는 이것을 연습 문제로 삼아 시험해 보고 싶다.
디자인 같은 거.
방정식을 푸는 것은 해법에 달려 있지 않을 것이다.따라서 해법 알고리즘의 실현을 인터페이스로 분리한다.
또한 예에서 f(x)=x^2-2=0이지만 PHP는 λ식을 사용할 수 있기 때문에 f(x) 자체를 매개 변수로 설정하여 통용성을 높인다.
해법에 관하여
오차가 예측 오차시간보다 많으면 이를 해결 방법의 하나로 삼는다.(이 때문에 진짜\sqrt{2}가 아니라 일정한 오차가 있다)
소개한 두 가지 방법은 간단하게 다음과 같다. 이분법은 해결 방안만 있으면 안정적으로 해결 방안을 찾을 수 있다.다른 한편, 뉴턴법은 수렴이 비교적 빠른 동시에 이해에서 멀리 떨어진 함수 시스템이 복잡할 때 때때로 방향을 향해 진동하지 않는다.
이분법
이른바 협공이란 중간에 풀린 두 개의 점이 f(x0)φ0이고 f(x1)′0의 원리를 사용하며 중점은 x이다{center]=0.5(x0+x1), f(x{center})의 기호를 통해 범위를 좁히는 방법입니다.
뉴턴법
미분을 사용하는 방법의 초기 값을 일회식 근사로 다음 해를 구하고 이 차(+함수의 값)에서 수렴하여 해를 구하는지 판단한다.
이루어지다
Solver
Solver를 방정식을 풀기 위한 도구의 인터페이스로 사용하고 매개변수는 첫 번째 매개변수를 풀 방정식을 함수 대상으로 하며 두 번째 매개변수의 초기 값으로 설정합니다.
또한 절단 오차를 솔버에 상수로 유지합니다.
이분법(By Selection)과 뉴턴법(Newton) 등급을 실현하는 것으로
내부 설치는 다음과 같습니다.
Solver.php
<?php
interface Solver{
const threshold=1.0e-8;
public function solve($func, $x);
}
class BySelection implements Solver{
public function solve($func, $x){
$x1=0.5*$x;
$x2=1.5*$x;
$y =$func($x);
$y1=$func($x1);
$y2=$func($x2);
$count=0;
if( $y1*$y2>0 ) throw new Exception('二分法、初期値エラー');
while( true ){
$count++;
if( $y*$y1>0 ){
$x1=$x;
$y1=$y;
}
else{
$x2=$x;
$y2=$y;
}
$x=0.5*($x1+$x2);
$y=$func($x);
if( abs($y1)<Solver::threshold && abs($y2)<Solver::threshold && abs($x1-$x2)<Solver::threshold ) return $x;
if( $count==1000 ) throw new Exception('二分法で収束しませんでした');
}
}
}
class Newton implements Solver{
public function solve($func, $x){
$count=0;
while( true ){
$count++;
$y=$func($x);
$dy=($func($x+Solver::threshold)-$func($x-Solver::threshold))/(2.0*Solver::threshold);
if( abs($y)<Solver::threshold && abs($y/$dy)<Solver::threshold ) return $x;
$x=$x-$y/$dy;
if( $count==1000 ) throw new Exception('ニュートン法で収束しませんでした');
}
}
}
?>
나는 이분법이 알고리즘으로 매우 간단하기 때문에 읽을 수 있다고 생각한다.뉴턴 방법에서 미분은 선형과 비슷하게 쓰이지만 수치 미분를 사용한다.
main 함수
실제 사용은 다음과 같다.
내부 알고리즘은 BySelection이나 뉴튼을 통해
$solver
의 실체를 바꿀 수 있지만 결과는 바뀌지 않는다.main.php
<?php
require_once('Solver.php');
// $func=function($x){ return cos($x); };
$func=function($x){ return x*x-2; };
// $sovler=new BySelection();
$solver=new Newton();
var_dump(2.0*$solver->solve($func, 2.0));
?>
미비
대체로 이런 구상은 가능하지만 일반적인 함수 시스템이라면 초기값 등에 따라 해결 방안을 구할 수 없을 때도 있다.(이분법의 초기값의 거친 처리 등 가장 예)
수치 계산에서 수렴조건(threshold)과 교체 횟수 등은 어느 정도 알고리즘과 해결해야 할 문제에 의존하기 때문에 흑체화는 적합하지 않다고 생각한다.
후기와 감상
필자는 PHP를 거의 사용한 적이 없다. 수치로 단일하게 이동할 수 있는 견본을 계산해 봤다. 비록 PHP가 이 용도에 적합하다고 생각하지는 않지만 인터페이스와 λ식을 사용하면 상당히 큰 대응을 할 수 있다고 생각한다.
또한 PHP의 상수 사용 방법과 예외 처리의 건너뛰기 방법(이 단계)을 알게 되었다.
참고 문헌
Reference
이 문제에 관하여(PHP를 사용하여 √2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/takeyasu/articles/315ef328a5f9ff409671텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)