Où ira le chat? (mécanique orbitale)

16

Un chat presque sans masse est tombé dans l'espace (ne vous inquiétez pas, avec une combinaison spatiale et tout) au point (x, y, z)avec la vitesse (vx, vy, vz). Il y a une planète fixe, infiniment dense (avec un volume de 0) au point (0, 0, 0)et elle attire des objets à distance ravec accélération 1/r^2. Selon la gravité newtonienne, où va l'objet après le temps t?

Presque sans masse dans ce cas signifie que vous produisez la valeur de lim (mass --> 0) <position of cat>. La masse est affectée par la gravité de la planète, mais la planète n'est pas affectée par la gravité du chat. En d'autres termes, le corps central est fixe.

C'est quelque peu similaire à Code Golf: quel est le sort du vaisseau spatial? [version à virgule flottante] , mais c'est différent car il s'agit de mesurer la précision.

Vous pouvez implémenter une solution basée sur une simulation, qui doit s'exécuter en moins de 3 secondes, OU vous pouvez implémenter un programme qui donne une valeur exacte (doit également s'exécuter en moins de 3 secondes). Voir les détails de notation ci-dessous. Si vous implémentez une simulation, il n'est pas nécessaire qu'elle soit exacte, mais votre score sera inférieur en raison de l'inexactitude.

Entrée : x y z vx vy vz tpas nécessairement des nombres entiers représentant x, y, z les coordonnées, la vitesse en x, y, et z et de temps respectivement. Il est garanti que la vitesse du chat est strictement inférieure à la vitesse d'échappement à cette altitude. L'entrée peut être prise de n'importe où, y compris les paramètres d'une fonction. Le programme doit s'exécuter en moins de trois secondes sur mon ordinateur portable t < 2^30, ce qui signifie que si vous exécutez une simulation, vous devez ajuster votre pas de temps en conséquence. Si vous prévoyez d'atteindre la limite de 3 secondes pour chaque test, assurez-vous qu'il existe un paramètre réglable qui peut le rendre plus précis / moins précis pour les gains de vitesse, afin que je puisse le faire fonctionner en trois secondes sur mon ordinateur.

Sortie : x y zla position après le temps t.

Étant donné que le problème des deux corps peut être résolu parfaitement, il est en théorie possible d'obtenir une réponse parfaite et correcte.

Scoring : Pour tout cas de test, l'erreur est définie comme étant la distance entre votre sortie et la "vraie" sortie. La véritable sortie est définie comme étant celle générée par l'extrait de scénario de test. Si l'erreur est inférieure à 10^(-8), l'erreur est arrondie à zéro. Votre score est l'erreur moyenne sur 100 (ou plus) cas de test aléatoires. Si vous écrivez une réponse parfaitement précise, vous devriez obtenir un score de 0; le score le plus bas l'emporte et les égalités seront rompues par la longueur du code.

Cas de test :

1 0 0 0 -1 0 1000000000 --> 0.83789 -0.54584 0

Dans ce cas, l'orbite est parfaitement circulaire avec une période 2 * pi, donc après avoir encerclé 159154943 fois, le chat se retrouve à environ (0,83789, -0,54584). Ce n'est pas un cas de test sur lequel votre code sera testé; cependant, si vous soumettez une réponse parfaitement exacte, vous pouvez la tester.

L'extrait ci-dessous génère des cas de test supplémentaires aléatoires et sera utilisé pour juger les soumissions; faites-moi savoir s'il y a un bug avec ceci:

soktinpk
la source
Le temps est-il tdonné en secondes? Si oui, la vitesse serait-elle donnée en unités par seconde, ou quelque chose de plus petit?
R. Kap
@R. Kap Ça n'a pas d'importance. test donnée en unité de temps, quelle qu'elle soit, et la vitesse utilisera la même unité. Que ce soit en secondes ou en heures, la réponse sera la même.
soktinpk
nearly massless catEh bien, quelle serait la masse exacte du chat? Faut-il simplement utiliser 0comme valeur la masse de ce chat?
R. Kap
@R. Kap Oui. Mais il est toujours affecté par la gravité (généralement, Newton ne considérait pas les objets sans masse comme affectés par la gravité). Nous devons donc considérer qu'il a une masse arbitrairement petite, et votre réponse est en fait la position lorsque la masse du chat va à zéro. Le point principal est que la planète elle-même n'est pas du tout affectée par le chat.
soktinpk
2
@soktinpk, il pourrait être plus facile de dire explicitement que le corps central est fixe.
Maltysen le

Réponses:

6

Python 3.5 + NumPy, exact, 186 octets

from math import*
def o(r,v,t):
 d=(r@r)**.5;W=2/d-v@v;U=W**1.5;b=[0,t*U+9]
 while 1:
  a=sum(b)/2;x=1-cos(a);y=sin(a)/U;k=r@v*x/W+d*y*W
  if a in b:return k*v-r*x/W/d+r
  b[k+a/U-y>t]=a

Il s'agit d'une solution exacte, utilisant une formule que j'ai conçue sur la base de Jesper Göranssonhis, «Symmetries of the Kepler problem», 2015 . Il utilise une recherche binaire pour résoudre l'équation transcendantale Ax + B cos x + C sin x = D, qui n'a pas de solution de forme fermée.

La fonction s'attend à ce que la position et la vitesse soient transmises sous forme de tableaux NumPy:

>>> from numpy import array
>>> o(array([1,0,0]),array([0,-1,0]),1000000000)
array([ 0.83788718, -0.54584345,  0.        ])
>>> o(array([-1.1740058273269156,8.413493259550673,0.41996042044140003]),array([0.150014367067652,-0.09438816345868332,0.37294941703455975]),7999.348650387233)
array([-4.45269544,  6.93224929, -9.27292488])
Anders Kaseorg
la source
Que fait- @il?
R. Kap
1
C'est un nouvel opérateur en Python 3.5 que NumPy surcharge numpy.dot(multiplication produit / matrice). Voir PEP 465.
Anders Kaseorg
C'est génial qu'il soit joué au golf, mais c'est un défi de code, pourriez-vous le rendre un peu plus clair, j'ai fait un peu de travail en Python et je peux calculer l'anomalie, le thêta, l'excentricité, la période, etc., mais je suis coincé à déterminer le signe de thêta et déterminer la rotation du plan de référence xy vers l'espace 3d. Pourtant, c'est vraiment génial
miles
@miles Étant donné que les liens sont rompus par la longueur du code, il est logique que cela soit joué au golf.
Mego
C'est vrai, car je travaillais également sur une solution exacte, car le générateur de cas de test ne crée que des orbites elliptiques
miles
2

Javascript

C'est juste pour lancer la balle, car personne ne semble poster de réponses. Voici un moyen très naïf et simple qui peut être beaucoup amélioré:

function simulate(x, y, z, vx, vy, vz, t) {
  var loops = 1884955; // tune this parameter
  var timestep = t / loops;
  for (var i = 0; i < t; i += timestep) {
    var distanceSq = x*x + y*y + z*z; // distance squared from origin
    var distance = Math.sqrt(distanceSq);
    var forceMag = 1/distanceSq; // get the force of gravity
    var forceX = -x / distance * forceMag;
    var forceY = -y / distance * forceMag;
    var forceZ = -z / distance * forceMag;
    vx += forceX * timestep;
    vy += forceY * timestep;
    vz += forceZ * timestep;
    x += vx * timestep;
    y += vy * timestep;
    z += vz * timestep;
  }
  return [x, y, z];
}

Essai:

simulate(1, 0, 0, 0, -1, 0, Math.PI*2) --> [0.9999999999889703, -0.0000033332840909716455, 0]

Hé, c'est plutôt bien. Il a une erreur d'environ 3,333 * 10 ^ (- 6) ce qui n'est pas suffisant pour qu'il soit arrondi ... c'est proche.

Juste pour le fun:

console.log(simulate(1, 0, 0, 0, -1, 0, 1000000000))
--> [-530516643639.4616, -1000000000.0066016, 0]

Tant pis; ce n'est donc pas le meilleur.

Et sur un cas de test aléatoire du générateur:

simulate(-1.1740058273269156,8.413493259550673,0.41996042044140003,0.150014367067652,-0.09438816345868332,0.37294941703455975,7999.348650387233)
-->    [-4.528366392498373, 6.780385554803544, -9.547824236472668]
Actual:[-4.452695438880813, 6.932249293597744, -9.272924876103785]

Avec une erreur d'environ 0,32305 seulement!

Cela peut être beaucoup amélioré en utilisant quelque chose comme l'intégration de Verlet ou un algorithme sophistiqué. En fait, ces algorithmes peuvent même obtenir des scores parfaits, bien qu'ils soient des simulations.

soktinpk
la source