Arcsinc approximatif

9

L'objectif est simple: produire une solution réelle non nulle xdans l'équation sin(x) = -mx, en fonction de l'entrée m, dans le moins d'octets.

Caractéristiques:

  • Votre réponse doit être correcte à 3 chiffres significatifs.
  • Vous pouvez sortir n'importe quelle solution réelle autre que la solution triviale x=0. Vous pouvez supposer qu'il mexiste au moins une solution. Vous pouvez également supposer m!=0.

Une solution python évidemment sous-optimale utilisant la descente de gradient :

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

Cas de test

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
theideasmith
la source
1
La meilleure approche consiste à imprimer une valeur fixe, mais vous devez spécifier le nombre de décimales nécessaires. Je suggère d'inclure un paramètre d'entrée, comme apour résoudre sin(x)=-ax. Veuillez ne pas dire "vous devez réellement le calculer", car les exigences comme celles-ci sont trop vagues pour fonctionner.
xnor
C'est aussi x=0une solution triviale. Vous devez spécifier la solution que vous souhaitez.
xnor
Vous avez besoin de quelques limites sur m pour garantir une solution non nulle.
xnor
m=0a des solutions ( x=kπpour entier k). Les valeurs mqui n'ont pas de vraies solutions non triviales sont celles qui sont trop éloignées 0.
Peter Taylor
1
Vous recherchez uniquement des solutions à valeur réelle ou des solutions à valeur complexe sont-elles également autorisées?
miles

Réponses:

1

isé : 32 28 octets

En utilisant l'itération de Newton à partir de π:

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

L'argument est passé $1, qui peut être extrait d'un fichier, comme ceci:

ised --l inputfile.txt 'code'

Version un peu moins stable mais plus courte:

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

Parfois, il lance des avertissements de limite d'itération, mais la précision semble correcte compte tenu des conditions.

Version Unicode (même bytecount):

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

Partir de 4 coupe un autre octet et semble converger vers les mêmes valeurs

{λ{x-tanx}/{1+$1/cosx}}∙4
orion
la source
8

Haskell, 34 octets

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

Compte xde 0 à 0,001 jusqu'à sin(x)< -m*x.

Exemples de sortie

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
la source
Et alors m=-0.1?
Peter Taylor
@PeterTaylor Notez bien si c'est nécessaire, mais ça donne 2.853, ce qui semble correct.
2016
Bien sûr, ce sont deux fonctions étranges, donc s'il y a une solution, il y a une solution positive. Doh.
Peter Taylor
Pourquoi répondriez-vous à un défi dont vous savez qu'il n'est pas clair?
Mego
2

Mathematica, 28 octets

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

Recherche une racine numérique à partir de la supposition initiale x=1. Cas de test:

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

la source
1

C, 99 octets

#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;}

non golfé:

#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
la source
1

MATL , 17 octets

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

Cela utilise la recherche linéaire sur l'axe réel positif, donc c'est lent. Tous les cas de test se terminent en 1 minute dans le compilateur en ligne.

Essayez-le en ligne!

Explication

`         % 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
la source
1

C ++ 11, 92 91 octets

-1 octet pour l'utilisation #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
la source
0

Python 2, 81 78 octets

Itération de point fixe

Comme lambda récursif

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

En boucle (81 octets):

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
la source
0

Mathematica, 52 octets

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

Fonction anonyme. Prend un nombre en entrée et renvoie une liste de nombres en sortie. Utilise juste NSolvepour résoudre l'équation approximative.

LegionMammal978
la source
Si vous remplacez Sin@x==-x#par, Sinc@x==-#vous pouvez supprimer~DeleteCases~0.
0

Axiome, 364 octets

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)

résultats

(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
la source
0

Haskell, 50 octets

Je viens d'apprendre la méthode de newton dans ma classe calc, alors voici comment haskellutiliser la méthode de newton.

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

theideasmith
la source