2016-06-23 3 views
1

Ich habe eine große Menge von Daten, die in Bezug auf Intensität und Wellenlänge, die ich mit Planks Law passen soll, um den Schätzwert für Temperatur zu bestimmen.Normalisieren von Werten in einer curve_fit von Plancks Law aus Datensatz * Edit *

Der Datensatz wird als Textdatei importiert

import numpy as np 
import scipy as sp 
from scipy.optimize import curve_fit 

with open('Good_SolarRun2.txt') as g: 
    data = g.read() 
data = data.split('\n') 
Wavle2 = [float(row.split()[0]) for row in data] # Wavelength (nm) 
Int2 = [float(row.split()[1]) for row in data] # Intensity (counts) 

So definiere ich jetzt das passende Modell für Planks Recht (In Bezug auf die Wellenlänge) https://en.wikipedia.org/wiki/Planck%27s_law

--- Wie Benutzer Evert empfehlen , Setze ich die Konstanten auf 1, da die Optimierung für kleine Zahlen auf einem Computer schwierig ist.

from scipy.constants import h,k,c 

def Plancks_Law(lamb, T): 
    return 1/np.power(lamb,5.0) * 1/(np.exp(1/(lamb*T)) - 1) 

So jetzt, ich gehe über die Einrichtung der curve_fit-Konfiguration mit meinem Datensatz.

x = Wavle2 

# This has the same shape as Wavle2, but these values are scaled by me. 
# Also the same shape as Int2 
y = np.array(Intscale2P) 

p0_R = (500.) 
optR, pcovR = curve_fit(Plancks_Law, x, y, p0_R) 
T_R = optR 
T_Rp = pcovR 
yM = Plancks_Law(x, T_R) 

print T_R gibt den Wert von 542.04628177

Welche einige unbekannte Einheiten ist. Ich bin jetzt ratlos, wie man alles in richtige Einheiten umwandelt. Vor allem die Werte im Exponenten zu den richtigen Einheiten.

Wie kann man das korrigieren?

+2

'a' und' b' könnten für eine anständige Passform zu klein sein. Versuchen Sie, diese auch aus Ihrer Fit-Funktion herauszufiltern oder sie mit 1 gleichzusetzen und nach der Anpassung zu renormieren. Eine Anpassung funktioniert im Allgemeinen am besten, wenn sowohl x, y als auch Fit-y in der Reihenfolge 1 liegen; Andernfalls können Probleme mit der Maschinenpräzision auftreten. – Evert

+0

@Evert, lassen Sie mich sehen, ob ich meine Magie arbeiten kann. – DarthLazar

+0

@Evert Guter Vorschlag, jetzt ist der schwierige Teil nur alles zu konvertieren. Du warst doch Hilfe. Sie können eine Antwort senden und ich werde es hochladen, wenn Sie möchten. – DarthLazar

Antwort

3

Sie haben hier ein etwas heikles Problem: abhängig von Ihren x-Werten (Wellenlängen) kann der Exponent 1/(lamb*T) oft zu groß sein, um ausgewertet zu werden, und Sie werden einen Überlauf bekommen. (Oder zu klein, und es wird immer zu Null

Es könnte gut sein, um zu versuchen, und teilen Sie Ihre Planck-Funktion in drei Teile:.

  • ein Teil, wo lamb * T groß ist, sagen> 100. Sie Rayleigh-Jeans-Näherung kann dann verwendet werden.
  • ein Teil, wo lamb * T klein ist, sagen < 1e-4. Sie dann die Annäherung Wien nutzen können.
  • für den Zwischenteil, verwenden Sie die Funktion selbst.

Das sollte Überläufe verhindern.


gute Passform Ergebnisse zu erhalten, ist es wünschenswert, Parameter und Daten nicht Ergebnisse in den Grenzen der Maschine laufen zu lassen, entweder zu groß oder zu klein. Da die Anpassung oft zu Zwischenergebnissen führt, die weit außerhalb des Eingabebereichs (Parameter oder Daten) liegen, sind Sie sicher, dass alles von der Ordnungseinheit ist (dies ist einfach das Ergebnis von "(hu)man(s) being the measure of all things", und Computer werden von und für Menschen hergestellt).

Beginnend mit der Original-Planck-Funktion:

alpha = 2*h*c*c 
beta = h*c/k 
return alpha/np.power(lamb,5.0) * 1/(np.exp(beta/(lamb*T)) - 1) 

Beachten Sie, dass Alpha nur eine Normalisierung ist. Lassen Sie es hier draußen und wenden Sie es am Ende auf Ihre Fit Ergebnisse an. Während der Anpassung haben Sie dort keinen großen oder kleinen Alpha-Wert, nur 1. Dieser ist einfach.

Für Beta, Sie können dies nicht wirklich tun: Sie können es nicht außerhalb der Exponential-Modus, und wenden Sie es nach der Tat.Dafür ist die dreiteilige Funktion gedacht, um Probleme dort zu umgehen.

Sie können aber auch Ihre x-Werte normalisieren (und möglicherweise sollten). Nehmen wir an, Ihre Eingabe ist in der Reihenfolge 1e-9, also Nanometer in Metern ausgedrückt. Machen Sie Nanometer zu Ihrer Einheit und multiplizieren Sie alle Werte mit 1e9. Jetzt sind die x-Eingabewerte von der Ordnungseinheit.

Das bedeutet natürlich, dass sich Ihr Alpha ändert; es gibt einen lambd**-5 Faktor dort, wenn also lambd um 1e9 steigt, dann ändern sich hier Dinge durch 1/1e-(9*5) = 1e45. Faktor 1e45 in Alpha.

Für Beta gibt es etwas ähnliches: Sie multiplizieren beta mit 1e9.

Schließlich könnten Sie auch versuchen, "T" zu "normalisieren". 5000 ist nicht so weit von der Ordnungseinheit entfernt, aber Sie könnten es in Int 5 umwandeln und den Faktor 1000 in beta setzen.
Setzen Sie auch alpha und betaaußerhalb die Funktion: Sie sind im Wesentlichen Konstanten und müssen nicht jedes Mal ausgewertet werden, wenn die Funktion aufgerufen wird. Das macht die Anpassung schneller.

Hinweis: Wenn Sie Alpha aus der Funktion entfernen und erst nach der Anpassung verwenden, vergessen Sie nicht, auch die Approximationen von Wien und Rayleigh-Jeans zu entfernen. Wie unten angegeben: Test (z. B. manuell vergleichen Sie die Ergebnisse um die Region, wo Sie von einer Formulierung zur anderen gehen, und sehen, dass es übereinstimmt. Oder einfach die Kurve über einen breiten Bereich auf einem logarithmischen Plot zeichnen)!


Haftungsausschluss: Ich habe dies nicht getestet und möglicherweise Zeichen falsch verstanden. Dreifach überprüfen, dass Sie 1e45 und nicht 1e-45, und dito für 1e9 oder 1e-9 benötigen. Einfache Überprüfung: Geben Sie einige anständige Zahlen mit der Wellenlänge in Metern ein, sehen Sie, welchen Fluss Sie erhalten, geben Sie dann die Wellenlänge in Nanometer mit den zusätzlichen Faktoren ein und sehen Sie, ob Sie den gleichen Fluss erhalten.

Auch: schnappen Sie sich ein Stück Papier und arbeiten Sie die Änderungen Schritt für Schritt aus. Tun Sie das hier, und Sie können dieselbe Methode auch für andere Funktionen und Anpassungsprobleme anwenden.

Verwandte Themen