Przybliżony łuk

9

Cel jest prosty: wyprowadzić niezerowe rzeczywiste rozwiązanie xrównania sin(x) = -mx, biorąc pod uwagę dane wejściowe m, w jak najmniejszej liczbie bajtów.

Dane techniczne:

  • Twoja odpowiedź musi być poprawna na 3 znaczące liczby.
  • Możesz wypisać dowolne prawdziwe rozwiązanie inne niż rozwiązanie trywialne x=0. Możesz założyć m, że istnieje co najmniej jedno rozwiązanie. Możesz również założyć m!=0.

Oczywiście nieoptymalne rozwiązanie python wykorzystujące pochylenie gradientu :

from math import *
from random import *
a=x=0.001
m = 5.
def dE(x):return 2*(sin(x)+m*x+1)*(cos(x)+m)
for i in xrange(1000): x-=dE(x)*a
print x

Przypadki testowe

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
theideasmith
źródło
1
Najlepszym podejściem jest tutaj wydrukowanie stałej wartości, chociaż należy określić, ile wymaganych miejsc dziesiętnych. Sugeruję włączenie parametru wejściowego, na przykład arozwiązania sin(x)=-ax. Nie mów „musisz to wyliczyć”, ponieważ takie wymagania są zbyt niejasne, aby działały.
xnor
Również x=0to rozwiązanie trywialne. Powinieneś określić, które rozwiązanie chcesz.
xnor
Potrzebujesz granic na m, aby zagwarantować niezerowe rozwiązanie.
xnor
m=0ma rozwiązania ( x=kπdla liczb całkowitych k). Wartości, mktóre nie mają nietrywialnych rzeczywistych rozwiązań, to te, które są zbyt dalekie 0.
Peter Taylor
1
Szukasz tylko rozwiązań o wartości rzeczywistej, czy też dozwolone są rozwiązania o złożonej wartości?
mil

Odpowiedzi:

1

Ised : 32 28 bajtów

Korzystanie z iteracji Newtona od π:

{:x-{sinx+$1*x}/{cosx+$1}:}:::pi

Argument jest przekazywany $1, który można pobrać z pliku, jak poniżej:

ised --l inputfile.txt 'code'

Trochę mniej stabilna, ale krótsza wersja:

{:{x-tanx}/{1+$1/cosx}:}:::pi

Czasami generuje ostrzeżenia o limicie iteracji, ale dokładność wydaje się dobra, biorąc pod uwagę warunki.

Wersja Unicode (ta sama liczba bajtów):

{λ{x-tanx}/{1+$1/cosx}}∙π

Począwszy od 4 przecina kolejny bajt i wydaje się, że zbiega się do tych samych wartości

{λ{x-tanx}/{1+$1/cosx}}∙4
orion
źródło
8

Haskell, 34 bajty

f m=until(\x->sin x< -m*x)(+1e-3)0

Zlicza xod 0 o 0,001 dosin(x)< -m*x .

Przykłady Ouput

f -0.2 ->   2.595999999999825
f -0.1 ->   2.852999999999797
f  0.0 ->   3.141999999999765
f  0.1 ->   3.4999999999997256
f  0.2 ->   4.1049999999997056
xnor
źródło
Co m=-0.1?
Peter Taylor
@PeterTaylor Uwaga, czy jest to wymagane, ale daje 2.853, co wygląda dobrze.
xnor
Oczywiście są to dziwne funkcje, więc jeśli istnieje rozwiązanie, istnieje rozwiązanie pozytywne. Doh
Peter Taylor
Dlaczego miałbyś odpowiedzieć na wyzwanie, o którym wiesz, że jest niejasne?
Mego
2

Mathematica, 28 bajtów

x/.FindRoot[Sinc@x+#,{x,1}]&

Wyszukuje pierwiastek liczbowy z początkowego odgadnięcia x=1. Przypadki testowe:

% /@ {-0.25, -0.1, 0.2}
(* {2.47458, 2.85234, 4.10462} *)

źródło
1

C, 99 bajtów

#include<math.h>
float f(float m){float x=1,y;do{x=(y=sin(x)+m*x)+x;}while(fabs(y)>1e-4);return x;}

bez golfa:

#include<math.h>
float f(float m){
 float x=1,y;
 do{x=(y=sin(x)+m*x)+x;}while(fabs(y)>1e-4);
 return x;
}
Karl Napf
źródło
1

MATL , 17 bajtów

`@2e3/tY,wG_*>}4M

Wykorzystuje to wyszukiwanie liniowe na dodatniej osi rzeczywistej, więc jest wolne. Wszystkie przypadki testowe kończą się w kompilatorze online w ciągu 1 minuty.

Wypróbuj online!

Wyjaśnienie

`         % Do...while
  @       %   Push iteration index, starting at 1
  2e3/    %   Divide by 2000
  t       %   Duplicate
  Y,      %   Sine
  w       %   Swap
  G_*     %   Multiply by minus the input
  >       %   Does the sine exceed that? If so, next iteration
}         % Finally (execute after last iteration, before exiting loop)
   4M     %   Push input of sine function again
          % Implicit end
          % Implicit display
Luis Mendo
źródło
1

C ++ 11, 92 91 bajtów

-1 bajt do użycia #import

#import<cmath>
using F=float;F f(F m,F x=1){F y=sin(x)+m*x;return fabs(y)>1e-4?f(m,x+y):x;}
Karl Napf
źródło
0

Python 2, 81 78 bajtów

Iteracja punktu stałego

Jako rekurencyjna lambda

from math import*
f=lambda m,x=1:abs(sin(x)+m*x)>1e-4and f(m,sin(x)+m*x+x)or x

Jako pętla (81 bajtów):

from math import*
m=input()
x=1
while abs(sin(x)+m*x)>1e-4:x=sin(x)+m*x+x
print x
Karl Napf
źródło
0

Mathematica, 52 bajty

NSolve[Sin@x==-x#,x,Reals][[;;,1,2]]~DeleteCases~0.&

Funkcja anonimowa. Pobiera liczbę jako dane wejściowe i zwraca listę liczb jako dane wyjściowe. Służy tylko NSolvedo rozwiązania przybliżonego równania.

LegionMammal978
źródło
Jeśli zastąpi Sin@x==-x#się Sinc@x==-#można pozbyć się~DeleteCases~0.
0

Aksjomat, 364 bajty

bisezione(f,a,b)==(fa:=f(a);fb:=f(b);a>b or fa*fb>0=>"fail";e:=1/(10**(digits()-3));x1:=a;v:=x2:=b;i:=1;y:=f(v);if(abs(y)>e)then repeat(t:=(x2-x1)/2.0;v:=x1+t;y:=f(v);i:=i+1;if i>999 or t<=e or abs(y)<e then break;if fb*y<0 then(x1:=v;fa:=y)else if fa*y<0 then(x2:=v;fb:=y)else break);i>999 or abs(y)>e=>"fail";v)
macro g(m) == bisezione(x+->(sin(x)+m*x), 0.1, 4.3)

Ungolf

bisezione(f,a,b)==
    fa:=f(a);fb:=f(b)
    a>b or fa*fb>0=>"fail"
    e:=1/(10**(digits()-3))
    x1:=a;v:=x2:=b;i:=1;y:=f(v)
    if(abs(y)>e) then
      repeat
        t:=(x2-x1)/2.0;v:=x1+t;y:=f(v);i:=i+1
        if i>999 or t<=e or abs(y)<e then break
        if      fb*y<0 then(x1:=v;fa:=y)
        else if fa*y<0 then(x2:=v;fb:=y)
        else break
    i>999 or abs(y)>e=>"fail"
    v

macro g(m) == bisezione(x+->(sin(x)+m*x), 0.1, 4.3)

wyniki

(3) -> g(0.2)
   AXIOM will attempt to step through and interpret the code.
   (3)  4.1046198505 579058527
                                                              Type: Float
(4) -> g(-0.1)
   (4)  2.8523418944 500916556
                                                              Type: Float
(5) -> g(-0.25)
   (5)  2.4745767873 698290098
                                                              Type: Float
RosLuP
źródło
0

Haskell, 50 bajtów

Właśnie dowiedziałem się o metodzie Newtona w mojej klasie calc, więc tutaj haskelljest metoda Newtona.

f m=foldl(\x _->x-(sin x+m*x)/(cos x+m))0[1..10]

theideasmith
źródło