2017-09-13 2 views
2

Je suis (en quelque sorte) familier avec les techniques de lissage/interpolation dans Gnuplot. Il me semble que ces interpolations ne fonctionnent que pour tracer les valeurs interpolées. Cependant, j'ai besoin des valeurs interpolées pour d'autres calculs.Comment interpoler des données avec Gnuplot pour d'autres calculs

Un exemple simple peut illustrer ceci: Disons que nous vendons un article spécifique sur quatre jours et ont le nombre de ventes enregistrées dans input_numbers.dat:

# days | number_of_sold_items 
1 4 
2 70 
3 80 
4 1 

Maintenant, je veux tracer mon revenu pour chaque journée. Mais la relation entre le prix par article et le nombre d'articles vendus ne sont pas d'une simple relation linéaire, mais compliquent quelque chose qui est connu que quelques exemples - stockés dans input_price.dat:

# number_of_sold_items | price_per_item 
1  5.00 
3  4.10 
10  3.80 
100 3.00 

Comment puis-je faire quelque chose comme ce (pseudo-code):

make INTERPOLATED_PRICE(x) using "input_price.dat" 
plot "input_numbers.dat" using 1:($2*INTERPOLATED_PRICE($2)) 

Je peux le faire en ajustant mais ce n'est pas ce que je veux. La relation des données est trop compliquée.

P.S .: Je sais que le prix par article par rapport au nombre d'articles dans un tel exemple ressemble plus à une fonction de type pas et pas lisse. Ceci est juste un exemple pour une interpolation en général.

Répondre

1

Il est difficile de prouver la non-existence de quelque chose, mais je suis assez confiant que cela ne peut être fait avec Gnuplot seul, comme:

  • Je suis dans l'illusion d'être suffisamment familier avec Gnuplot que je Je le saurais s'il existait.

  • Je ne trouve rien à propos d'une telle fonctionnalité.

  • Il serait complètement contraire au paradigme de Gnuplot d'être un outil à usage unique pour le traçage (l'ajustement est déjà limite) et de ne pas traiter le traitement des données.

0

interpolation linéaire n'est pas disponible, mais que diriez-vous:

set xr [0:10] 
set sample 21 

$dat << EOD 
0 1 
2 2 
4 4 
6 5 
8 4 
10 3 
EOD 
set table $interp 
plot $dat us 1:2 with table smooth cspline 
unset table 
plot $dat w lp, $interp w lp 
0

Gnuplot peut faire quelque chose comme ceci:

text = "%f*x + %f" 

a = 2 
b = 10 

eval("f(x) = ".sprintf(text,a,b)) 

set grid x y 
plot f(x) 

ce qui signifie essentiellement que les fonctions complexes peuvent être définies dynamiquement: La commande sprintf convertit le texte "% f * x +% f" en "2.0 * x + 10", l'opérateur de point . concatène les chaînes "f (x) =" et "2.0 * x + 10", et leLa commandedéfinit la fonction f(x) = 2.0*x + 10.Le résultat peut être tracée et donne le schéma prévu:

linear diagram

Ce comportement peut être utilisé pour créer une fonction d'interpolation par morceaux comme suit:

ip_file = "input_price.dat" 
stats ip_file nooutput 

n = STATS_records - 1 
xmin = STATS_min_x 
xmax = STATS_max_x 

ip_f = sprintf("x < %f ? NaN : ", xmin) 

f(x) = a*x + b # Make a linear interpolation from point to point. 

do for [i=0:n-1] { 

    set xrange [xmin:xmax] 
    stats ip_file every ::i::(i+1) nooutput 

    xmintemp = STATS_min_x 
    xmaxtemp = STATS_max_x 

    set xrange [xmintemp:xmaxtemp] 

    a = 1 
    b = 1 
    fit f(x) ip_file every ::i::(i+1) via a, b 

    ip_f = ip_f.sprintf("x < %f ? %f * x + %f : ", xmaxtemp, a, b) 

} 

ip_f = ip_f."NaN" 

print ip_f # The analytical form of the interpolation function. 

eval("ip(x) = ".ip_f) 

set samples 1000 

#set xrange [xmin:xmax] 
#plot ip(x) # Plot the interpolation function. 

unset xrange 
plot "input_numbers.dat" using 1:($2*ip($2)) w lp 

La every en combinaison avec stats et fit limites la plage à deux points de données successifs, voir help stats et help every. L'opérateur ternaire ?: définit la fonction d'interpolation section par section, voir help ternary.

C'est la forme analytique résultant de la fonction d'interpolation (après une mise en forme):

x < 1.000000 ? NaN 
    : x < 3.000000 ? -0.450000 * x + 5.450000 
    : x < 10.000000 ? -0.042857 * x + 4.228571 
    : x < 100.000000 ? -0.008889 * x + 3.888889 
    : NaN 

Ceci est la fonction d'interpolation résultante (tracée par plot ip(x)):

interpolation function

C'est le tracé résultant utilisant la fonction d'interpolation dans un autre calcul (plot "input_numbers.dat" using 1:($2*ip($2))):

use interpolation function

Je ne connais pas les limites sur le nombre d'opérateurs ternaires vous pouvez imbriquer et sur combien de temps une chaîne ou une définition de fonction peut être, ...

testé avec Gnuplot 5.0 sur Debian Jessie.