Arccsinc aproximado

9

O objetivo é simples: gerar uma solução real diferente de zero xpara a equação sin(x) = -mx, dada a entrada m, no menor número de bytes.

Especificações:

  • Sua resposta deve estar correta para 3 algarismos significativos.
  • Você pode produzir qualquer solução real que não seja a trivial x=0. Você pode assumir mque existe pelo menos uma solução. Você também pode assumir m!=0.

Uma solução python obviamente abaixo do ideal usando descida de gradiente :

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

Casos de teste

-0.25 -> ±2.4746
-0.1  -> ±2.8523 or ±7.0682 or ±8.4232
 0.2  -> ±4.1046 or ±4.9063 
theideasmith
fonte
11
A melhor abordagem aqui é imprimir um valor fixo, mas você deve especificar quantas casas decimais são necessárias. Eu sugiro incluir um parâmetro de entrada, gostaria ade resolver sin(x)=-ax. Por favor, não diga "você precisa calculá-lo", pois requisitos como esse são vagos demais para funcionar.
Xnor
Além disso, x=0é uma solução trivial. Você deve especificar qual solução deseja.
Xnor
Você precisa de alguns limites em m para garantir uma solução diferente de zero.
Xnor
m=0tem soluções ( x=kπpara inteiro k). Os valores dos mquais não têm soluções reais não triviais são aqueles que estão muito longe 0.
Peter Taylor
11
Você está procurando apenas soluções com valores reais ou soluções com valores complexos também são permitidas?
miles

Respostas:

1

ised : 32 28 bytes

Usando a iteração de Newton a partir de π:

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

O argumento é passado $1, que pode ser obtido de um arquivo, assim:

ised --l inputfile.txt 'code'

Versão um pouco menos estável, mas mais curta:

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

Às vezes, lança avisos de limite de iteração, mas a precisão parece boa considerando as condições.

Versão Unicode (o mesmo número anterior):

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

A partir de 4 corta outro byte e parece convergir para os mesmos valores

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

Haskell, 34 bytes

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

Conta xdesde 0 por 0,001 até sin(x)< -m*x.

Exemplos 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
fonte
Que tal m=-0.1?
Peter Taylor
@PeterTaylor Observe se é necessário, mas dá 2.853, o que parece certo.
xnor
Obviamente, ambas são funções ímpares; portanto, se houver uma solução, haverá uma solução positiva. Doh.
27416 Peter
Por que você responderia a um desafio que você sabe que não está claro?
Mego
2

Mathematica, 28 bytes

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

Procura uma raiz numérica a partir da estimativa inicial x=1. Casos de teste:

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

fonte
1

C, 99 bytes

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

ungolfed:

#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
fonte
1

MATL , 17 bytes

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

Isso usa pesquisa linear no eixo real positivo, por isso é lento. Todos os casos de teste terminam em 1 minuto no compilador online.

Experimente online!

Explicação

`         % 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
fonte
1

C ++ 11, 92 91 bytes

-1 byte para usar #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
fonte
0

Python 2, 81 78 bytes

Iteração de Fixpoint

Como lambda recursiva

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

Como loop (81 bytes):

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
fonte
0

Mathematica, 52 bytes

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

Função anônima. Pega um número como entrada e retorna uma lista de números como saída. Apenas usa NSolvepara resolver a equação aproximada.

LegionMammal978
fonte
Se você substituir Sin@x==-x#por Sinc@x==-#você pode acabar com #~DeleteCases~0.
0

Axioma, 364 bytes

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)

resultados

(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
fonte
0

Haskell, 50 bytes

Acabei de aprender sobre o método de newton na minha classe de cálculo, então aqui haskellvamos usar o método de newton.

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

theideasmith
fonte