দুটি কণা ইন্টিগ্রাল <ij | কেএল> জন্য দক্ষ সূচক ফাংশন কীভাবে বাস্তবায়ন করবেন?


11

এটি একটি সাধারণ প্রতিসমের গণনার সমস্যা। আমি এখানে পুরো ব্যাকগ্রাউন্ড দিচ্ছি, তবে কোয়ান্টাম রসায়নের কোনও জ্ঞানের প্রয়োজন নেই।

দুই কণা অবিচ্ছেদ্য হল: এবং এর নিম্নলিখিত 4 টি প্রতিসাম্য রয়েছে: আমার একটি ফাংশন রয়েছে যা অবিচ্ছেদ্য গণনা করে এবং সেগুলি নীচে সূচিযুক্ত 1D অ্যারে সংরক্ষণ করে:আমি | = ψ * আমি ( এক্স ) ψ * ( এক্স ' ) ψ ( এক্স ) ψ ( এক্স ' )ij|klআমি | = আমি | = | আমি = | আমি

ij|kl=ψi(x)ψj(x)ψk(x)ψl(x)|xx|d3xd3x
ij|kl=ji|lk=kl|ij=lk|ji
int2
int2(ijkl2intindex2(i, j, k, l))

যেখানে ফাংশনটি ijkl2intindex2উপরের প্রতিসাম্যগুলি বিবেচনায় নিয়ে একটি অনন্য সূচক দেয়। একমাত্র প্রয়োজনীয়তা হ'ল যদি আপনি i, j, k, l এর (প্রতিটি 1 থেকে n) সমস্ত সংমিশ্রণগুলি লুপ করেন তবে এটি int2ধারাবাহিকভাবে অ্যারে পূরণ করবে এবং এটি উপরের সাথে সম্পর্কিত সমস্ত আইজকিএল সংমিশ্রণগুলিতে একই সূচকটি নির্ধারণ করবে 4 প্রতিসাম্য।

ফোর্টরানে আমার বর্তমান প্রয়োগ এখানে । এটা খুব ধীর। কেউ কীভাবে কার্যকরভাবে এটি করতে জানেন? (যে কোনও ভাষায়।)

ইঙ্গিত: অরবিটালগুলি যদি real হয় তবে উপরের প্রতিসাম্যগুলি ছাড়াও, এবং আদান প্রদান করতে পারি সুতরাং আমরা মোট 8 টি প্রতিসাম্য পেতে: এবং তারপরে কেউ এটিকে সূচিকরণের জন্য খুব দ্রুত ফাংশন প্রয়োগ করতে পারে, আমার বাস্তবায়নটি এখানে দেখুন । কক্ষপথ বাস্তব না হলে আমি কেসগুলির জন্য কিছু দক্ষ সূচীকরণ স্কিম সন্ধান করতে চাই।আমি আমি | = আমি | = | আমি = আমি | =ψi(x)ikjl

ij|kl=ji|lk=kj|il=il|kj=
=kl|ij=lk|ji=il|kj=kj|il

নোট: ফাংশন যে আমি আসলে চার নম্বর গ্রহণ বাস্তবায়িত , , , একটি তথাকথিত 'রসায়ন' স্বরলিপি , অর্থাত্ এবং আর্গুমেন্ট আন্তঃপরিবর্তন করা হয়, তবে এটি গুরুত্বপূর্ণ নয়।( আমি |) = আমি k | ijkl(ij|kl)=ik|jljk


d3x

1
d3xdx1dx2dx3x=(x1,x2,x3)d3x

xx=(x1,x2,x3)dx

d3x

উত্তর:


5

[সম্পাদনা করুন: চতুর্থবারের কমনীয়তা, শেষ পর্যন্ত বোধগম্য কিছু]

nn2(n2+3)t(t(n))+t(t(n1))t(a)at(a)=a(a+1)/2

ijtid(i,j)tid(k,l)tid(a,b)a,b

def ascendings(n):
    idx = 0
    for i in range(1,n+1):
        for j in range(1,i+1):
            for k in range(1,i):
                for l in range(1,k+1):
                    idx = idx + 1
                    print(i,j,k,l)
            k=i
            for l in range(1,j+1):
                idx = idx + 1
                print(i,j,k,l)
    return idx

llk

t(t(n1))

def mixcendings(n):
    idx = 0
    for j in range(2,n+1):
        for i in range(1,j):
            for k in range(1,j):
                for l in range(1,k):
                    print(i,j,k,l)
                    idx = idx + 1
            k=j
            for l in range(1,i+1):
                print(i,j,k,l)
                idx = idx + 1
    return idx

এই উভয়ের সংমিশ্রণ সম্পূর্ণ সেট দেয়, সুতরাং উভয় লুপ একসাথে রাখলে আমাদের সূচকের সম্পূর্ণ সেট দেয়।

n

পাইথনে আমরা প্রতিটি ভিন্ন দৃশ্যের জন্য আইডএক্স এবং আই, জে, কে, এল মান প্রদান করতে নীচের পুনরাবৃত্তিকে লিখতে পারি:

def iterate_quad(n):
    idx = 0
    for i in range(1,n+1):
        for j in range(1,i+1):
            for k in range(1,i):
                for l in range(1,k+1):
                    idx = idx + 1
                    yield (idx,i,j,k,l)
                    #print(i,j,k,l)
            k=i
            for l in range(1,j+1):
                idx = idx + 1
                yield (idx,i,j,k,l)

    for i in range(2,n+1):
        for j in range(1,i):
            for k in range(1,i):
                for l in range(1,k):
                    idx = idx + 1
                    yield (idx,i,j,k,l)
            k=i
            for l in range(1,j+1):
                idx = idx + 1
                yield (idx,i,j,k,l)

in3+jn2+kn+l

integer function squareindex(i,j,k,l,n)
    integer,intent(in)::i,j,k,l,n
    squareindex = (((i-1)*n + (j-1))*n + (k-1))*n + l
end function

integer function generate_order_array(n,arr)
    integer,intent(in)::n,arr(*)
    integer::total,idx,i,j,k,l
    total = n**2 * (n**2 + 3)
    reshape(arr,total)
    idx = 0
    do i=1,n
      do j=1,i
        do k=1,i-1
          do l=1,k
            idx = idx+1
            arr(idx) = squareindex(i,j,k,l,n)
          end do
        end do
        k=i
        do l=1,j
          idx = idx+1
          arr(idx) = squareindex(i,j,k,l,n)
        end do
      end do
    end do

    do i=2,n
      do j=1,i-1
        do k=1,i-1
          do l=1,j
            idx = idx+1
            arr(idx) = squareindex(i,j,k,l,n)
          end do
        end do
        k=i
        do l=1,j
          idx = idx+1
          arr(idx) = squareindex(i,j,k,l,n)
        end do
      end do
    end do

    generate_order_array = idx
  end function

এবং তারপরে এভাবে লুপ করুন:

maxidx = generate_order_array(n,arr)
do idx=1,maxidx
  i = idx/(n**3) + 1
  t_idx = idx - (i-1)*n**3
  j = t_idx/(n**2) + 1
  t_idx = t_idx - (j-1)*n**2
  k = t_idx/n + 1
  t_idx = t_idx - (k-1)*n
  l = t_idx

  ! now have i,j,k,l, so do stuff
  ! ...
end do

হাই ফিল, উত্তরের জন্য অনেক ধন্যবাদ! আমি এটি পরীক্ষা করেছি, এবং দুটি সমস্যা আছে। উদাহরণস্বরূপ idx_all (1, 2, 3, 4, 4) == idx_all (1, 2, 4, 3, 4) = 76. তবে <12 | 34> / = <12 | 43>। কক্ষপথ বাস্তব হলেই এটি সমান। সুতরাং আপনার সমাধানটি 8 টি প্রতিসামগ্রীগুলির ক্ষেত্রে বলে মনে হচ্ছে (উপরে একটি সহজ সংস্করণ, ijkl2intindex ()) এর জন্য আমার ফোরট্রান উদাহরণ দেখুন। দ্বিতীয় সমস্যাটি হ'ল সূচকগুলি ধারাবাহিক নয়, আমি এখানে ফলাফলগুলি আটকালাম : gist.github.com/2703756 । উপরে আমার ijkl2intindex2 () রুটিন থেকে সঠিক ফলাফলগুলি এখানে: gist.github.com/2703767
ওনডেজ এর্তটেক

1
@ ওন্ডিজেজারটেক: আপনি কি একটি চিহ্ন যুক্ত করতে চান? আপনি যদি অর্ডারটি পরিবর্তন করেন তবে আইডিস্পায়ারটিতে একটি চিহ্ন উপস্থিত রয়েছে।
ডেথথ্রিথ

ওয়ান্ডেজেরটিক: আমি এখন পার্থক্যটি দেখতে পাচ্ছি। @ ডেথব্রেথ যেমন উল্লেখ করেছেন, আপনি সূচিটি উপেক্ষা করতে পারেন, তবে সামগ্রিক লুপের জন্য এটি পরিষ্কার হবে না। আমি একটি চিন্তা আছে এবং এটি আপডেট করব।
ফিল এইচ

প্রকৃতপক্ষে, সূচকে অবহেলা করা পুরোপুরি কাজ করবে না কারণ আইডিপায়ারটির মানটি ভুল হয়ে যাবে।
ফিল এইচ

<ij|kl>=<ji|kl>=<ij|lk>=<ji|lk>
ijkl[idxpair(indexij,indexkl,,)]signijsignkl

3

প্রতিসামগ্রী ক্ষেত্রে (সমস্ত কোড স্নিপেট অজগরে রয়েছে) একই কী ফেরত দিতে সংশোধিত একটি সাধারণ স্পেস ফিলিং কার্ভটি ব্যবহার করার একটি ধারণা এখানে রয়েছে।

# Simple space-filling curve
def forge_key(i, j, k, l, n): 
  return i + j*n + k*n**2 + l*n**3

# Considers the possible symmetries of a key
def forge_key_symmetry(i, j, k, l, n): 
  return min(forge_key(i, j, k, l, n), 
             forge_key(j, i, l, k, n), 
             forge_key(k, l, i, j, n), 
             forge_key(l, k, j, i, n)) 

মন্তব্য:

  • উদাহরণটি অজগর তবে আপনি যদি এই ফাংশনগুলিকে আপনার ফরটারান কোডের সাথে ইনলাইন করে থাকেন এবং (i, j, k, l) এর জন্য আপনার অভ্যন্তরীণ লুপটি আনরোল করেন তবে আপনার ভাল পারফরম্যান্স পাওয়া উচিত।
  • আপনি ফ্লোটগুলি ব্যবহার করে কীটি গণনা করতে পারেন এবং তারপরে কীটিকে একটি সূচক হিসাবে ব্যবহার করতে পূর্ণসংখ্যায় রূপান্তর করতে পারেন, এটি কম্পাইলারকে ভাসমান পয়েন্ট ইউনিটগুলি ব্যবহার করার অনুমতি দেবে (যেমন AVX উপলব্ধ)।
  • যদি এন 2 এর শক্তি হয় তবে গুণগুলি কেবল বিট শিফট হবে।
  • প্রতিসামগ্রীগুলির জন্য চিকিত্সা মেমরির ক্ষেত্রে দক্ষ নয় (যেমন এটি একটি ধারাবাহিক সূচক তৈরি করে না) এবং মোট সূচক অ্যারের এন্ট্রিগুলির প্রায় 1/4 ব্যবহার করে।

এখানে এন = 2 এর পরীক্ষার উদাহরণ দেওয়া হল:

for i in range(n):
  for j in range(n):
    for k in range(n):
      for l in range(n):
        key = forge_key_symmetry(i, j, k, l, n)
        print i, j, k , l, key

এন = 2 এর আউটপুট:

i j k l key
0 0 0 0 0
0 0 0 1 1
0 0 1 0 1
0 0 1 1 3
0 1 0 0 1
0 1 0 1 5
0 1 1 0 6
0 1 1 1 7
1 0 0 0 1
1 0 0 1 6
1 0 1 0 5
1 0 1 1 7
1 1 0 0 3
1 1 0 1 7
1 1 1 0 7
1 1 1 1 15

যদি আগ্রহের বিষয় থাকে তবে ফরজ_কির বিপরীত ফাংশনটি হ'ল:

# Inverse of forge_key
def split_key(key, n): 
  d = key / n**3
  c = (key - d*n**3) / n**2
  b = (key - c*n**2 - d*n**3) / n 
  a = (key - b*n - c*n**2 - d*n**3)
  return (a, b, c, d)

আপনি কি বোঝাতে চেয়েছিলেন 2 এর একাধিকের পরিবর্তে "যদি এন 2 এর শক্তি হয়"?
অরন আহমদিয়া

হ্যাঁ, ধন্যবাদ অ্যারন আমি রাতের খাবারের আগে এই উত্তরটি লিখেছিলাম এবং হাল্ক লিখছিলেন writing
এফক্রুজ

চতুর! তবে সর্বাধিক সূচক n ^ 4 নয় (বা আপনি যদি 0 থেকে শুরু করেন তবে n ^ 4-1)? সমস্যাটি হ'ল আমি যে ভিত্তির আকারটি করতে সক্ষম হতে চাই তার জন্য এটি মেমরির সাথে খাপ খায় না। পরপর সূচকের সাথে অ্যারের আকার n ^ 2 * (n ^ 2 + 3) / 4. এইচএম, এটি যাইহোক পুরো আকারের প্রায় 1/4। সুতরাং সম্ভবত আমার 4 স্মৃতি মেমরির ফ্যাক্টর সম্পর্কে চিন্তা করা উচিত নয়। তবুও, কেবলমাত্র এই 4 টি প্রতিসাম্য ব্যবহার করে সঠিক ক্রমাগত সূচককে এনকোড করার কিছু উপায় থাকতে হবে (আমার পোস্টে আমার কুশ্রী সমাধানের চেয়ে ভাল, যেখানে আমার ডাবল লুপগুলি করা দরকার)।
ওঁদেজ এর্ত্তেক

হ্যাঁ, এটা ঠিক! আমি সূচকটি কীভাবে মার্জিতভাবে সমাধান করতে হবে তা বাছাই করতে পারি না (বাছাই এবং পুনর্নির্মাণ ছাড়াই) তবে মেমরির ব্যবহারের ক্ষেত্রে শীর্ষস্থানীয় শব্দটি হ'ল (এন ^ 4)। 4 এর ফ্যাক্টরটি বড় এন এর জন্য স্মৃতিতে একটি ছোট পার্থক্য করা উচিত
fcruz

0

এটি কি কেবল প্যাকড সিমেট্রিক ম্যাট্রিক্স ইনডেক্সিং সমস্যার সাধারণীকরণ নয়? সেখানে সমাধানটি অফসেট (i, j) = i * (i + 1) / 2 + j, তাই না? আপনি কি এটিকে দ্বিগুণ করতে পারবেন না এবং দ্বিগুণ-প্রতিসাম্য 4D অ্যারেটি সূচক করতে পারবেন? বাস্তবায়ন শাখা প্রয়োজন অপ্রয়োজনীয় বলে মনে হচ্ছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.