Springen naar inhoud

Kwantumenergieen berekenen


  • Log in om te kunnen reageren

#1

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 06 juli 2011 - 17:37

Hallo allemaal,

Ik zit met een klein probleempje. Ik heb de volgende vraag:

-----------------------------------------

A particle confined in a three-dimensional, rectangular box may occupy only certain energy levels according to quantum mechanics. In a simple model (eg. ignoring spin or magnetic moment of the particle), these energy levels are characterised by three (positive integer) quantum numbers.

For this problem, it is assumed that the dimensions of the box are in the proportion 1:2:3, so that the energy of a given quantum state (l,m,n) is proportional to:

f(l,m,n) = (l^2) + (m^2)/4 + (n^2)/9
(the constant of proportionality is dependent on the mass of the particle and various physical constants).

The lowest possible energy corresponds to (l,m,n) = (1,1,1), which is called the ground state.

Subsequent states are ordered by energy level, which as noted above corresponds to the value of the function f(l,m,n). Note that the phenomenon called "degeneracy" does occur - two states can have the same energy (eg. f(1,4,1)=f(2,2,1)).

For this , you must recover the f(l,m,n) value for the millionth state in this ordered list (starting with the ground state).

Since it is only the f-value that is required, the order of specific states within a degenerate set does not affect the result. The answer should be rounded to three decimal places.

As an example, if the state found was (2,2,3), the answer would be 6.000. This is actually the 25th state, and (1,2,6) and (1,4,3) have the same energy.

------------------------------------------

Het verhaal is erg duidelijk en ik ben dus ook opzoek naar de miljoenste staat van een quantumdeeltje. Ik heb hier een programma voor geschreven die alle energieen in een bestand schrijft (van 1,1,1 tot 200,200,200 dus 8 miljoen energieen). Vervolgens sorteer ik de lijst met het commando sort in linux en ga ik op zoek naar de miljoenste regel. Wat eruitkomt klopt echter niet en ik heb geen idee hoe dat kan. Moet ik soms l, m en n hoger laten lopen, en zo ja, hoe hoog? In feite kunnen ze tot oneindig lopen, maar ik zoek alleen de eerste miljoen energieniveaus.

Als iemand mij even zou kunnen helpen, heel graag ;)

alvast bedankt!

Dit forum kan gratis blijven vanwege banners als deze. Door te registeren zal de onderstaande banner overigens verdwijnen.

#2

JorisL

    JorisL


  • >250 berichten
  • 555 berichten
  • Ervaren gebruiker

Geplaatst op 06 juli 2011 - 18:26

Ik zou een 3D-array bouwen.

Zijn er geen verbanden tussen l, n en m? dus bijvoorbeeld LaTeX ?

Anders gewoon manueel tellen. Dus eerst l=1 -> zoeken tot waar m gaat -> aantal n-waarden bepalen voor iedere m.
Dan zijn er n*(m+1) elementen voor die l waarde.
Doe dit in een geneste while lus(1 om l-waarden te doorlopen en 1 om m-waarden te doorlopen) die telkens het aantal optelt.

Ik heb zitten zoeken naar andere methodes maar zonder taal is dat erg moeilijk ;)
Had iets gevonden in z-shell maar ben het kwijt

Veranderd door JorisL, 06 juli 2011 - 18:26


#3

Jan van de Velde

    Jan van de Velde


  • >5k berichten
  • 44865 berichten
  • Moderator

Geplaatst op 06 juli 2011 - 21:14

..//..
the millionth state in this ordered list (starting with the ground state).

wat wordt verstaan onder "ordered list" ? geordend per energieniveau?

als dat zo is kom je er niet met te gaan tot 200,200,200 , want 1,1,300 heeft een lagere energie dan 200,1,1.
ALS WIJ JE GEHOLPEN HEBBEN....
help ons dan eiwitten vouwen, en help mee ziekten als kanker en zo te bestrijden in de vrije tijd van je chip...
http://www.wetenscha...showtopic=59270

#4

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 06 juli 2011 - 21:53

wat wordt verstaan onder "ordered list" ? geordend per energieniveau?

als dat zo is kom je er niet met te gaan tot 200,200,200 , want 1,1,300 heeft een lagere energie dan 200,1,1.


een ordered list is dan de georderde lijst per energieniveau, beginnend met de energie van 1,1,1. Er kunnen dan ook 2 states met dezelfde energie zijn.

Je tweede zin is precies mijn probleem: ik weet niet tot welke waardes ik door moet gaan. Als ik l,m,n tot 300 laat lopen, krijg ik 300^3 mogelijkheden om te verwerken.

JorisNL, er zijn geen verbanden tussen l,m en n helaas voor zover ik weet ;) .

#5

Jan van de Velde

    Jan van de Velde


  • >5k berichten
  • 44865 berichten
  • Moderator

Geplaatst op 07 juli 2011 - 00:01

Hier moet iets elegants wiskundigs op te vinden zijn. Reken niet op mij, want wiskunde is zeker niet mijn sterke punt.

We kunnen je "state" ook schrijven als LaTeX

zoals (1,4,n) gelijk is aan (2,2,n) zal ook (1,m,9) gelijk zijn aan (3,m,3).

misschien geeft dit een duwtje in een goede denkrichting?
ALS WIJ JE GEHOLPEN HEBBEN....
help ons dan eiwitten vouwen, en help mee ziekten als kanker en zo te bestrijden in de vrije tijd van je chip...
http://www.wetenscha...showtopic=59270

#6

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 07 juli 2011 - 11:27

Hier moet iets elegants wiskundigs op te vinden zijn. Reken niet op mij, want wiskunde is zeker niet mijn sterke punt.

We kunnen je "state" ook schrijven als LaTeX



zoals (1,4,n) gelijk is aan (2,2,n) zal ook (1,m,9) gelijk zijn aan (3,m,3).

misschien geeft dit een duwtje in een goede denkrichting?


Hmm dat had ik nog niet gezien en ik heb me even afgevraagd wat je er mee kunt. Ik zoek dus de miljoen kleinste energieniveaus en daar zullen ongetwijfeld een aantal "dubbele" tussenzitten maar verder denk ik dat ik er niet zoveel mee kan.

Ik vraag me dan af hoe je dat wiskundig zou kunnen doen?

Maar bedankt voor je hulp!

#7

In physics I trust

    In physics I trust


  • >5k berichten
  • 7384 berichten
  • Moderator

Geplaatst op 07 juli 2011 - 21:43

public class Energy 
{
	
	
	private static int EnergyLevel(int l, int m, int n)
	{
		int energy=(int) (Math.pow(l, 2)+(1/4)*Math.pow(m, 2)+(1/9)*Math.pow(n, 2));
		return energy;
		
	}
	
	static int[] energieniveaus= new int[1000000];
	static int l=1;
	static int m=1;
	static int n=1;
	
	static int teller=0;
	
	public static void main(String args0[])
	{
		
		energieniveaus[teller]=EnergyLevel(l,m,n);
		
		teller++;
		while(teller<1000000)
		{
					int a=EnergyLevel(l+1,m,n);
					int b=EnergyLevel(l,m+1,n);
					int c=EnergyLevel(l,m,n+1);
					
					if (a<b && a<c)
					{
						l++;
						energieniveaus[teller]=a;
					} 
					else if(b<a && b<c)
					{
						m++;
						energieniveaus[teller]=b;	
					} 
					else 
					{
						n++;
						energieniveaus[teller]=c;	
						
					}
					teller++;
		}
		
		
		
	}
	

}

Zoiets?
"C++ : Where friends have access to your private members." — Gavin Russell Baker.

#8

ZVdP

    ZVdP


  • >1k berichten
  • 2097 berichten
  • VIP

Geplaatst op 07 juli 2011 - 21:51

Dat zal niet werken, aangezien je geen mechanisme hebt om de kwantumgetallen te laten dalen. Stel dat je tot (1,1,6) bent geraakt, maar dat het volgende niveau gelijk is aan (2,1,1)...
"Why must you speak when you have nothing to say?" -Hornblower
Conserve energy: Commute with a Hamiltonian

#9

In physics I trust

    In physics I trust


  • >5k berichten
  • 7384 berichten
  • Moderator

Geplaatst op 07 juli 2011 - 21:54

Je hebt gelijk, ik ben wat kort door de bocht gegaan.
"C++ : Where friends have access to your private members." — Gavin Russell Baker.

#10

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 08 juli 2011 - 10:58

public class Energy 
{
	
	
	private static int EnergyLevel(int l, int m, int n)
	{
		int energy=(int) (Math.pow(l, 2)+(1/4)*Math.pow(m, 2)+(1/9)*Math.pow(n, 2));
		return energy;
		
	}
	
	static int[] energieniveaus= new int[1000000];
	static int l=1;
	static int m=1;
	static int n=1;
	
	static int teller=0;
	
	public static void main(String args0[])
	{
		
		energieniveaus[teller]=EnergyLevel(l,m,n);
		
		teller++;
		while(teller<1000000)
		{
					int a=EnergyLevel(l+1,m,n);
					int b=EnergyLevel(l,m+1,n);
					int c=EnergyLevel(l,m,n+1);
					
					if (a<b && a<c)
					{
						l++;
						energieniveaus[teller]=a;
					} 
					else if(b<a && b<c)
					{
						m++;
						energieniveaus[teller]=b;	
					} 
					else 
					{
						n++;
						energieniveaus[teller]=c;	
						
					}
					teller++;
		}
		
		
		
	}
	

}

Zoiets?


Bedankt voor je hulp, je hebt me wel in de juiste richting gestuurd.

Wat misschien zou werken, is om een programma te schrijven die alle energieniveaus afgaat. Wat ik hiermee bedoel is het volgende: je begin op 1,1,1 en zet het energieniveau weg in een variabele bijv. E. Vervolgens laat je de teller oplopen, net zolang totdat hij een energieniveau vindt dat gelijk of groter is dan E. Omdat er ook dubbele tussenzitten, schrijf ik alle dubbele energieniveaus weg in een array en kijk of ze er nog niet inzitten. Als hij er niet inzit wordt hij in de array gezet. Zit hij er wel in, gaan we gewoon verder met tellen. Vervolgens zou ik een teller kunnen maken die oploopt met ieder energieniveau wat hij vindt (zowel dubbele als niet-dubbele) en die kan ik laten stoppen bij 1000000. Vervolgens is het een kwestie van E uitlezen wat het miljoenste niveau dan is ;)

Zou dit werken?

#11

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 08 juli 2011 - 13:40

Dit zou ik doen:
In Haskell:
import Data.List as List
import Data.Map as Map
import Data.Ratio

solution = f $ head $ drop 99999 $ concat (ordered startMap)

-- energy function
f (a,b,c) = (a*a)%1 + (b*b)%4 + (c*c)%9

-- starting point
startMap = Map.fromList [(f (1,1,1), [(1,1,1)])]


generateNext (a,b,c) = [(a+1,b,c), (a,b+1,c), (a,b,c+1)]

ordered m = uniqueConfList : (ordered (unionWith (++) nm pm))
	where
		((energy, confList), nm) = Map.deleteFindMin m
		uniqueConfList = nub confList
		newConfs = nub (concatMap generateNext uniqueConfList)
		pm = unionsWith (++) (List.map (\k -> Map.singleton (f k) [k]) newConfs)
Ik houd een map bij waarin de key gelijk is aan het energieniveau en de value een lijst is van alle toestanden die hierbij horen. Ik zoek dan de kleinste key (= laagste energieniveau in de map). Voor elke toestand in de bijbehorende lijst bereken ik de 3 volgende toestanden (a+1, b+1 of c+1). Bij elk van deze nieuwe toestanden bereken ik de energie en ik voeg deze toestanden dan met die energie toe aan de map. Ik haal dan de laagste energie uit de map weg, en begin daarna opnieuw.
Ik krijg op deze manier een lijst van toestanden geordend naar energieniveau. Ik bekijk van deze lijst het 1000000ste element en ik heb het antwoord. Het antwoord dat ik krijg is 1034 (interpreted, ~9 s).

#12

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 08 juli 2011 - 16:58

Dit zou ik doen:
In Haskell:

import Data.List as List
import Data.Map as Map
import Data.Ratio

solution = f $ head $ drop 99999 $ concat (ordered startMap)

-- energy function
f (a,b,c) = (a*a)%1 + (b*b)%4 + (c*c)%9

-- starting point
startMap = Map.fromList [(f (1,1,1), [(1,1,1)])]


generateNext (a,b,c) = [(a+1,b,c), (a,b+1,c), (a,b,c+1)]

ordered m = uniqueConfList : (ordered (unionWith (++) nm pm))
	where
		((energy, confList), nm) = Map.deleteFindMin m
		uniqueConfList = nub confList
		newConfs = nub (concatMap generateNext uniqueConfList)
		pm = unionsWith (++) (List.map (\k -> Map.singleton (f k) [k]) newConfs)
Ik houd een map bij waarin de key gelijk is aan het energieniveau en de value een lijst is van alle toestanden die hierbij horen. Ik zoek dan de kleinste key (= laagste energieniveau in de map). Voor elke toestand in de bijbehorende lijst bereken ik de 3 volgende toestanden (a+1, b+1 of c+1). Bij elk van deze nieuwe toestanden bereken ik de energie en ik voeg deze toestanden dan met die energie toe aan de map. Ik haal dan de laagste energie uit de map weg, en begin daarna opnieuw.
Ik krijg op deze manier een lijst van toestanden geordend naar energieniveau. Ik bekijk van deze lijst het 1000000ste element en ik heb het antwoord. Het antwoord dat ik krijg is 1034 (interpreted, ~9 s).


Je krijgt dus als antwoord 1034? Kun je het op 3 decimalen afronden svp (stond ook in de opdracht)?

Ik zal eens naar de code kijken (ben zelf niet bekend met Haskell helaas). Heel erg bedankt voor je hulp!! ;)

#13

physicalattraction

    physicalattraction


  • >1k berichten
  • 3103 berichten
  • Moderator

Geplaatst op 08 juli 2011 - 19:29

Ik houd een map bij waarin de key gelijk is aan het energieniveau en de value een lijst is van alle toestanden die hierbij horen. Ik zoek dan de kleinste key (= laagste energieniveau in de map). Voor elke toestand in de bijbehorende lijst bereken ik de 3 volgende toestanden (a+1, b+1 of c+1). Bij elk van deze nieuwe toestanden bereken ik de energie en ik voeg deze toestanden dan met die energie toe aan de map. Ik haal dan de laagste energie uit de map weg, en begin daarna opnieuw.
Ik krijg op deze manier een lijst van toestanden geordend naar energieniveau. Ik bekijk van deze lijst het 1000000ste element en ik heb het antwoord. Het antwoord dat ik krijg is 1034 (interpreted, ~9 s).

Ik begrijp je niet helemaal. Hoe kun je voorkomen dat je zo geen dubbele toestanden toevoegt? Stel ik heb de toestanden [2,3,4] en [3,2,4] al. Eerst heeft [2,3,4] de laagste energie, dan voeg ik o.a. [3,3,4] toe. Vervolgens heeft [3,2,4] de laagste energie, en ik voeg wederom [3,3,4] toe. Heb je expliciet ingebouwd dat dit voorkomen wordt?

#14

EvilBro

    EvilBro


  • >5k berichten
  • 6703 berichten
  • VIP

Geplaatst op 09 juli 2011 - 01:29

Hoe kun je voorkomen dat je zo geen dubbele toestanden toevoegt? Stel ik heb de toestanden [2,3,4] en [3,2,4] al. Eerst heeft [2,3,4] de laagste energie, dan voeg ik o.a. [3,3,4] toe. Vervolgens heeft [3,2,4] de laagste energie, en ik voeg wederom [3,3,4] toe. Heb je expliciet ingebouwd dat dit voorkomen wordt?

nub confList
confList bevat dubbele toestanden. 'nub' verwijdert alle dubbele exemplaren uit een lijst zodat er slechts 1 kopie van elke toestand overblijft.

#15

devos50

    devos50


  • 0 - 25 berichten
  • 24 berichten
  • Gebruiker

Geplaatst op 10 juli 2011 - 15:17

Ok, ik heb je code even bekeken en ik ben zover dat ik nu 1034 op mijn scherm krijg als solution (zonder enige kennis van Haskell ;) ). Ik ben nu nog even opzoek hoe ik 1034 op 3 decimalen kan laten afronden (of is het precies 1034?). Ik heb me wel een beetje verdiept in de basis van Haskell zoals lists en functions.

Ik heb nog even een vraagje over de code. Je gebruikt op een gegeven moment om de energieniveau te berekenen het % teken. Is dit niet het modulo-teken wat de resultante van een deling geeft? Ik heb % vervangen door de div function en toen kwam er 1012 uit. Enig idee hoe dat kan? Ik ben namelijk wel bekend met C(++) en java.





0 gebruiker(s) lezen dit onderwerp

0 leden, 0 bezoekers, 0 anonieme gebruikers

Ook adverteren op onze website? Lees hier meer!

Gesponsorde vacatures

Vacatures