10 votes

Utiliser les échelles pour remapper un nombre

J'ai un domaine de nombres, par exemple domain = [100, 200] et un nombre de bandes dans lesquelles diviser l'intervalle, par exemple bands = 5 . Je sais que chaque bande correspond à une valeur :

band #1 --> v = 0.2
band #2 --> v = 0.4
band #3 --> v = 0.6
band #4 --> v = 0.8
band #5 --> v = 1.0

Ces valeurs sont fixes (codées en dur) : si les bandes deviennent bands = 6 c'est le développeur qui choisit la valeur de band #6 .

Je souhaite diviser le domaine en bandes dont la taille varie en fonction de l'échelle utilisée. Par exemple, je pourrais vouloir utiliser l'échelle linéaire, l'échelle logarithmique ou l'échelle pow.

Je veux ensuite une fonction qui, en entrée, prend un nombre x domain et doit renvoyer la valeur v associé à la bande à laquelle appartient le numéro d'entrée.

Voici une question similaire mais je veux maintenant utiliser des échelles différentes (par exemple, je peux utiliser d3 scales ) mais je ne sais pas comment

Voici un morceau de code :

function getLinearScaledValue(x, min, max, bands) {
  const range = max - min
  if (x === max) {
    return 1
  } else {
    return Math.floor(1 + ((x - min) / range) * bands) / bands
  }
}

donde min y max sont les valeurs minimale et maximale du domaine.

Je pense que les exemples de sleepwalking étaient bons, alors je les ai mis ici :

si bandes = 5 :

band #1 --> v = 0.2
band #2 --> v = 0.4
band #3 --> v = 0.6
band #4 --> v = 0.8
band #5 --> v = 1.0

(1) si l'échelle est linéaire et le domaine = [0, 100] --> les bandes sont :

band #1 --> v = 0.2 --> [0, 20]
band #2 --> v = 0.4 --> [21, 40]
band #3 --> v = 0.6 --> [41, 60]
band #4 --> v = 0.8 --> [61, 80]
band #5 --> v = 1.0 --> [81, 100]

par exemple :

if x = 0  --> v = 0.2
if x = 10 --> v = 0.2
if x = 21 --> v = 0.4
if x = 98 --> v = 1.0

(2) si l'échelle est linéaire et le domaine = [100, 200] --> les bandes sont :

band #1 --> v = 0.2 --> [100, 120]
band #2 --> v = 0.4 --> [121, 140]
band #3 --> v = 0.6 --> [141, 160]
band #4 --> v = 0.8 --> [161, 180]
band #5 --> v = 1.0 --> [181, 200]

par exemple :

if x = 100 --> v = 0.2
if x = 110 --> v = 0.2
if x = 121 --> v = 0.4
if x = 198 --> v = 1.0

(3) si l'échelle est logarithmique et le domaine = [0, 100] --> les bandes sont :

band #1 --> v = 0.2 --> [?, ?]
band #2 --> v = 0.4 --> [?, ?]
band #3 --> v = 0.6 --> [?, ?]
band #4 --> v = 0.8 --> [?, ?]
band #5 --> v = 1.0 --> [?, ?]

par exemple :

if x = 0  --> v = ?
if x = 10 --> v = ?
if x = 21 --> v = ?
if x = 98 --> v = ?

0voto

Lajos Arpad Points 5986

Tout d'abord, vous avez besoin de conventions. Il faut se poser les bonnes questions.

Que signifie le terme "logarithmique" ? La fonction logarithme a deux entrées, une base et une valeur. La sortie est la puissance à laquelle vous augmentez la base pour obtenir le nombre. Supposons que la base soit 2 et que le domaine soit 0-200. Dans ce cas, vous calculez log(2, 200) qui est approximativement 7.64 . Cela signifie que nous avons les limites, [1, 2, 4, 8, 16, 32, 64, 128] . Si nous excluons 1 (c'est-à-dire 2 0 ), nous avons donc 6 frontières, ce qui signifie que nous avons 7 régions.

Que se passe-t-il si le domaine est compris entre 200 et 400 ? Dans ce cas, vous n'auriez que deux régions, ce qui n'a pas de sens. Contrairement à l'échelle linéaire, l'échelle logarithmique donne des résultats différents pour des domaines différents, même si leur taille est identique.

Je pense qu'il est logique de considérer les domaines comme vectoriels, c'est-à-dire qu'il est indifférent que le domaine soit compris entre 0 et 200 ou entre 200 et 400. Les seules contraintes sont que le domaine soit positif et qu'il ait une longueur de 200. Ainsi, le domaine 200-400 serait divisé de la même manière que le domaine 0-200, la seule différence étant les valeurs. Pour la division elle-même, nous utilisons les indices.

Si nous acceptons cette convention, le problème est grandement simplifié. Le domaine 200-400 a une longueur de 201. Ainsi, au lieu de [1, 2, 4, 8, 16, 32, 64, 128] nous avons [201, 202, 204, 208, 216, 232, 264, 328] .

L'échelle logarithmique ressemble maintenant à l'échelle linéaire. Le nombre de bords de l'échelle linéaire est égal à la base du logarithme. Ainsi, dans le cas d'une échelle logarithmique, nous aurions ceci :

function getBaseLog(x, y) {
  return Math.log(y) / Math.log(x);
}

function getLogarithmicScaledValue(x, min, max, base) {
    return parseInt(getBaseLog(base, x - min));
}

Voir le conversion de la base logarithmique .

Un cas d'utilisation évident de l'échelle logarithmique est qu'elle fonctionne bien avec les structures de données de type "tas".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X