নিউটন ফ্র্যাক্টাল উত্পন্ন করুন


24

কোনও ফাংশনের শিকড় আনুমানিক করতে আপনি নিউটন পদ্ধতিটি জানেন, তাই না? এই কার্যে আমার লক্ষ্য হ'ল আপনাকে এই অ্যালগরিদমের একটি আকর্ষণীয় দিকের সাথে পরিচয় করিয়ে দেওয়া।

নিউটনের অ্যালগরিদম কেবলমাত্র নির্দিষ্ট ক্ষেত্রে রূপান্তর করে তবে বেশিরভাগ জটিল ইনপুট মান। আপনি যদি জটিল প্লেনের মধ্যে সমস্ত ইনপুট মানগুলির জন্য পদ্ধতির রূপান্তরটি চিত্রিত করেন তবে আপনি সাধারণত এটির মতো একটি সুন্দর ফ্র্যাক্টাল পান:

F (x) = x ^ 3-1 এর জন্য নিউটন ফ্র্যাক্টাল উইকিমিডিয়া কমন্স থেকে চিত্র

বিশেষ উল্লেখ

এই কাজের লক্ষ্য হ'ল এ জাতীয় ফ্র্যাক্টাল তৈরি করা। এর অর্থ, আপনি ইনপুট হিসাবে বহুপদী প্রাপ্ত হন এবং আউটপুট হিসাবে আপনার পছন্দের বিন্যাসে চিত্র হিসাবে সম্পর্কিত ফ্র্যাক্টাল প্রিন্ট করতে হবে।

ইনপুট

ইনপুটটি জটিল সংখ্যার একটি সাদা স্থান-বিভাজিত তালিকা। তারা শৈলী নিচে লেখা হয় <Real part><iImaginary part>, এই নম্বরের মতো: 5.32i3.05। আপনি ধরে নিতে পারেন, ইনপুট সংখ্যার 4 দশমিক বেশি জায়গা নেই এবং এটি 1000 এর চেয়ে ছোট। এর মধ্যে প্রথমটি অবশ্যই শূন্য নয়। উদাহরণস্বরূপ, এটি আপনার প্রোগ্রামের একটি ইনপুট হতে পারে:

1 -2i7.5 23.0004i-3.8 আই 12 0 5.1233i0.1

সংখ্যাগুলি বহুবর্ষের গুণফল হিসাবে ব্যাখ্যা করা হয়, সর্বোচ্চ শক্তি দিয়ে শুরু হয়। এই স্পেসিফিকেশন বাকি সর্বত্র, ইনপুট বহুপদী বলা হয় পি । উপরের ইনপুটটি এই বহুপদী সমান:

f (x) = x 5 + (-2 + 7.5 i ) x 4 + (23.0004 - 3.8 i ) x 3 + 12 i x 2 + 5.1233 + 0.1 i

ইনপুটটি আপনার কাছে স্ট্যান্ডিন থেকে, প্রোগ্রামে পাস হওয়া আর্গুমেন্ট থেকে বা আপনার প্রোগ্রামে প্রদর্শিত কোনও প্রম্পট থেকে আসতে পারে। আপনি ধরে নিতে পারেন, ইনপুটটিতে কোনও শীর্ষস্থানীয় বা চলমান সাদা বর্ণের অক্ষর নেই।

অনুবাদ

আপনাকে নিম্নলিখিত উপায়ে ফ্র্যাক্টাল রেন্ডার করতে হবে:

  • পি এর শিকড় হিসাবে যতগুলি রং বেছে নেওয়া যায় বিচরণের জন্য একটি অতিরিক্ত রঙ
  • দৃশ্যমান সমতলটিতে প্রতিটি সংখ্যার জন্য, পদ্ধতিটি রূপান্তর করে কিনা এবং হ্যাঁ কোন মূলকে তা নির্ধারণ করুন। ফলাফল অনুযায়ী পয়েন্টটি রঙ করুন।
  • শাসক বা অন্যান্য অভিনব জিনিস মুদ্রণ করবেন না
  • বিন্দুতে একটি কালো বিন্দু মুদ্রণ করুন, এটি অভিমুখীকরণের জন্য বহুভুজ মূলগুলি। আপনি প্রতিটি মূলের চারপাশে চার পিক্সেল পর্যন্ত মুদ্রণ করতে পারেন।
  • দৃশ্যমান প্লেনটি কোনও উপায়ে বেছে নেওয়ার জন্য কোনও উপায় সন্ধান করুন, যে সমস্ত শিকড় পার্থক্যযুক্ত এবং যদি সম্ভব হয় তবে এটির বিস্তারে ছড়িয়ে পড়ে। যদিও আউটপুট ফ্রেমের একটি নিখুঁত প্লেসমেন্টের প্রয়োজন হয় না, আমি কোনও উত্তর গ্রহণ করতে অস্বীকার করার অধিকার সংরক্ষণ করি যা ফ্রেমটিকে অগ্রহণযোগ্য উপায়ে বেছে নেয়, যেমন। সর্বদা একই স্থানাঙ্কে, সমস্ত শিকড় এক বিন্দুতে থাকে ইত্যাদি always
  • আউটপুট চিত্রের আকার 1024 * 1024 পিক্সেল হওয়া উচিত।
  • রেন্ডারিং সময়টি সর্বোচ্চ 10 মিনিট
  • একক নির্ভুলতা ভাসমান-পয়েন্ট মান ব্যবহার করা যথেষ্ট

আউটপুট

আউটপুটটি আপনার পছন্দের ফাইল ফর্ম্যাটে একটি রাস্টার গ্রাফিক্স চিত্র হওয়া উচিত, যা কোনও ব্র্যান্ড এক্স অপারেটিং সিস্টেমের জন্য স্ট্যান্ডার্ড সফ্টওয়্যার দ্বারা পঠনযোগ্য। আপনি যদি বিরল ফর্ম্যাট ব্যবহার করতে চান তবে এমন কোনও ওয়েবসাইটের লিঙ্ক যুক্ত করার কথা বিবেচনা করুন যেখানে কেউ এর জন্য একজন দর্শক ডাউনলোড করতে পারে।

Stdout ফাইল আউটপুট। যদি আপনার ভাষা স্টাডাউটে কিছু রাখার পক্ষে সমর্থন না করে বা আপনি যদি এই বিকল্পটি কম সুবিধাজনক মনে করেন তবে অন্য কোনও উপায় খুঁজে নিন। যে কোনও উপায়ে, উত্পন্ন চিত্রটি সংরক্ষণ করা অবশ্যই সম্ভব।

বিধিনিষেধ

  • কোনও চিত্র প্রক্রিয়াকরণ গ্রন্থাগার নেই
  • কোন ফ্র্যাক্টাল উত্পন্ন গ্রন্থাগার নেই
  • সংক্ষিপ্ততম কোডটি জয়ী

এক্সটেনশানগুলি

আপনি যদি এই কাজটি পছন্দ করেন তবে আপনি রূপান্তর গতি বা অন্য কোনও মানদণ্ড অনুযায়ী পয়েন্টগুলি রঙ করার চেষ্টা করতে পারেন। আমি কিছু আকর্ষণীয় ফলাফল দেখতে চাই।


6
এটি কোনও কোড গল্ফ হিসাবে উপযুক্ত কিনা তা আমি পুরোপুরি নিশ্চিত নই। আমার দৃষ্টিতে কাজটি খুব জটিল। যদিও আমি ভুল প্রমাণিত হতে পারি।
জয়ে

5
@ জোয়ি: আসলেই। আমি এটি নিজের জন্য একটি কোড-চ্যালেঞ্জ হতে চাই।
জোয়ে অ্যাডামস

2
... বা পিপিএম সেই বিষয়ে।
জোয়

1
@ জোয়াই: আমার উদ্দেশ্যটি বরং একটি কঠিন কাজ তৈরি করা ছিল, কারণ অনেক লোক খুব সহজ কাজকে অপছন্দ করে।
FUZxxl

1
এটি সহজেই পৃথক কার্যক্রমে বিভক্ত হয়ে যায় এবং আপনার ভাষা যদি জটিল ভাসমান পয়েন্ট সংখ্যা স্থানীয়ভাবে সমর্থন করে তবে আপনি একটি বৃহত অংশ সংরক্ষণ করতে পারেন। আমার 1600 টি চর চলমান একটি সম্পূর্ণ-গল্ফযুক্ত সংস্করণ রয়েছে, যার মধ্যে 340 জটিল সংখ্যা শ্রেণি। এটি এখনও শিকড়গুলি সনাক্ত করে এবং রঙগুলি ব্যবহার করে না, তবে আমি অনুমান করি যে এনআর কোডের একটি বাগ এটি track (X-3-1 এর মূল খুঁজে পাওয়া -0.5 + 0.866i থেকে শুরু করে অবশ্যই বিচ্যুত হওয়া উচিত নয়!)
পিটার টেলর

উত্তর:


13

পাইথন, 827 777 অক্ষর

import re,random
N=1024
M=N*N
R=range
P=map(lambda x:eval(re.sub('i','+',x)+'j'if 'i'in x else x),raw_input().split())[::-1]
Q=[i*P[i]for i in R(len(P))][1:]
E=lambda p,x:sum(x**k*p[k]for k in R(len(p)))
def Z(x):
 for j in R(99):
  f=E(P,x);g=E(Q,x)
  if abs(f)<1e-9:return x,1
  if abs(x)>1e5or g==0:break
  x-=f/g
 return x,0
T=[]
a=9e9
b=-a
for i in R(999):
 x,f=Z((random.randrange(-9999,9999)+1j*random.randrange(-9999,9999))/99)
 if f:a=min(a,x.real,x.imag);b=max(b,x.real,x.imag);T+=[x]
s=b-a
a,b=a-s/2,b+s/2
s=b-a
C=[[255]*3]*M
H=lambda x,k:int(x.real*k)+87*int(x.imag*k)&255
for i in R(M):
 x,f=Z(a+i%N*s/N+(a+i/N*s/N)*1j)
 if f:C[i]=H(x,99),H(x,57),H(x,76)
for r in T:C[N*int(N*(r.imag-a)/s)+int(N*(r.real-a)/s)]=0,0,0
print'P3',N,N,255
for c in C:print'%d %d %d'%c

একগুচ্ছ এলোমেলো নমুনার জন্য কনভার্জেন্স পয়েন্টগুলি সন্ধান করে ডিসপ্লে সীমা (এবং শিকড়) সন্ধান করে। এরপরে এটি প্রতিটি সূচনা পয়েন্টের জন্য রূপান্তর পয়েন্টগুলি গণনা করে এবং প্রতিটি কনভার্জেন্স পয়েন্টের জন্য এলোমেলো রঙ পেতে একটি হ্যাশ ফাংশন ব্যবহার করে গ্রাফটি আঁকেন। খুব কাছ থেকে দেখুন এবং আপনি শিকড় চিহ্নিত করা দেখতে পারেন।

এখানে বহুবর্ষের উদাহরণ রয়েছে।

উদাহরণস্বরূপ বহুপদী


ভাল! আমি এই পছন্দ।
FUZxxl

14

জাভা, 1093 1058 1099 1077 অক্ষর

public class F{double r,i,a,b;F(double R,double I){r=R;i=I;}F a(F c){return
new F(r+c.r,i+c.i);}F m(F c){return new F(r*c.r-i*c.i,r*c.i+i*c.r);}F
r(){a=r*r+i*i;return new F(-r/a,i/a);}double l(F c){a=r-c.r;b=i-c.i;return
Math.sqrt(a*a+b*b);}public static void main(String[]a){int
n=a.length,i=0,j,x,K=1024,r[]=new int[n];String o="P3\n"+K+" "+K+"\n255 ",s[];F z=new
F(0,0),P[]=new F[n],R[]=new F[n],c,d,e,p,q;for(;i<n;)P[i]=new
F((s=a[i++].split("i"))[0].isEmpty()?0:Float.parseFloat(s[0]),s.length==1?0:Float.parseFloat(s[1]));double
B=Math.pow(P[n-1].m(P[0].r()).l(z)/2,1./n),b,S;for(i=1;i<n;){b=Math.pow(P[i].m(P[i-1].r()).l(z),1./i++);B=b>B?b:B;}S=6*B/K;for(x=0;x<K*K;){e=d=c=new
F(x%K*S-3*B,x++/K*S-3*B);for(j=51;j-->1;){p=P[0];q=p.m(new
F(n-1,0));for(i=1;i<n;){if(i<n-1)q=q.m(c).a(P[i].m(new
F(n-1-i,0)));p=p.m(c).a(P[i++]);}c=c.a(d=q.r().m(p));if(d.l(z)<S/2)break;}i=j>0?0:n;for(;i<n;i++){if(R[i]==null)R[i]=c;if(R[i].l(c)<S)break;}i=java.awt.Color.HSBtoRGB(i*1f/n,j<1||e.l(c)<S&&r[i]++<1?0:1,j*.02f);for(j=0;j++<3;){o+=(i&255)+" ";i>>=8;}System.out.println(o);o="";}}}

ইনপুট হ'ল কমান্ড-লাইন আর্গুমেন্ট - যেমন চালান java F 1 0 0 -1। আউটপুট পিপিএম ফর্ম্যাট (ASCII পিক্স্যাম্যাপ) এ স্টডআউট করা হবে।

বহুগঠনের জটিল শিকড়গুলির নিখুঁত মানের উপর আবদ্ধ ফুজিওয়ারা ব্যবহার করে স্কেলটি বেছে নেওয়া হয়; আমি তার পরে 1.5 দ্বারা আবদ্ধ গুন। আমি কনভার্জেন্স রেটের মাধ্যমে উজ্জ্বলতা সামঞ্জস্য করি, সুতরাং শিকড়গুলি উজ্জ্বল প্যাচগুলিতে থাকবে। সুতরাং শিকড়গুলির আনুমানিক অবস্থানগুলি চিহ্নিত করার জন্য কালো রঙের পরিবর্তে সাদা ব্যবহার করা যুক্তিসঙ্গত (যা আমাকে "সঠিকভাবে "ও করা যায় না এমন কিছু জন্য আমার জন্য ৪১ টি অক্ষর ব্যয় করে I আমি যদি সমস্ত পয়েন্টকে লেবেল করি যা নিজেরাই 0.5 পিক্সেলের মধ্যে রূপান্তর করে) তারপরে কিছু শিকড় শিরোনামহীনভাবে বেরিয়ে আসে; আমি যদি সমস্ত পয়েন্টগুলি নিজের থেকে 0.6 পিক্সেলের মধ্যে রূপান্তর করি তবে কিছু শিকড় একাধিক পিক্সেলের উপরে লেবেলযুক্ত হয়; সুতরাং প্রতিটি মূলের জন্য আমি প্রথম পয়েন্টটিকে নিজের 1 পিক্সেলের মধ্যে রূপান্তরিত করার জন্য সম্মুখীন করি label )।

বহুবর্ষের উদাহরণের জন্য চিত্র (জিআইএমপির সাথে পিএনজি রূপান্তরিত): X ^ 5 + (- 2 + 7.5i) x ^ 4 + (23.0004-3.8i) x ^ 3 + 12i x ^ 2 + (5.1233 + 0.1i) এর মূল


@FUZxxl, চিত্রটি পুরানো সংস্করণ থেকে এসেছে। আমি পরে রূপান্তর হারের সাথে একটি আপলোড করব। তবে শিকড়গুলি চিহ্নিত করার ক্ষেত্রে সমস্যাটি নির্ধারণ করছে যে কোন পিক্সেলটি চিহ্নিত করতে হবে। এটি ক্লাসিক সমস্যা যে ভাসমান পয়েন্টের সাথে আপনি সঠিক সমতা পরীক্ষা ব্যবহার করতে পারবেন না, তাই আপনাকে একটি অ্যাপসিলনের সাথে তুলনা করতে হবে। ফলস্বরূপ, শিকড়গুলির জন্য আমার "প্রমিত" মান নেই। আমি পিক্সেলকে চিহ্নিত করতে পারি যা এক ধাপে রূপান্তরিত হয় তবে এটি কোনও কিছুই চিহ্নিত করার গ্যারান্টি দেয় না এবং একটি একক মূলের জন্য 4 পিক্সেলের ব্লক চিহ্নিত করতে পারে।
পিটার টেলর

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

@FUZxxl, আপনি আমার বক্তব্য বুঝতে পারেন নি। কোনও মূলের "নিকটতম পিক্সেল" ভালভাবে সংজ্ঞায়িত হয় না। যাইহোক, আমি এমন কিছু হ্যাক করতে পারি যাতে এটি পরীক্ষা করা সমস্ত পরীক্ষার ক্ষেত্রে কাজ করতে পারে এবং আমি এই ধারণাটি পেয়েছি যে এটি আপনাকে খুশি করবে। আমি এটিকে সাদা নয়, কালো নয়, কারণ এটি আরও যুক্তিযুক্ত।
পিটার টেলর

@ পিটার টেইলর: ঠিক আছে।
FUZxxl

6
আমার প্রোফাইল ছবিটি শীঘ্রই পরিবর্তিত হওয়া উচিত x^6-9x^3+8, যত্ন সহকারে শিকড়গুলি বেছে নেওয়ার পরে এবং বহুভুতকে সহজ করার জন্য ওল্ফ্রাম আলফা ব্যবহার করে designed ঠিক আছে, আমি পরে জিএমপিতে আড়ালগুলি ঘুরিয়ে দিয়ে প্রতারণা করেছি।
পিটার টেলর

3

পাইথন, 633 বাইট

import numpy as np
import matplotlib.pyplot as plt
from colorsys import hls_to_rgb
def f(z):
    return (z**4 - 1)
def df(z):
    return (4*z**3) 
def cz(z):
    r = np.abs(z)
    arg = np.angle(z)   
    h = (arg + np.pi)  / (3 * np.pi)
    l = 1.0 - 1.0/(1.0 + r**0.1)
    s = 0.8 
    c = np.vectorize(hls_to_rgb) (h,l,s)
    c = np.array(c)
    c = c.swapaxes(0,2) 
    return c    
x, y = np.ogrid[-1.5:1.5:2001j, -1.5:1.5:2001j]
z = x + 1j*y    
for i in range(10):
    z -= (f(z) / df(z))
zz = z
zz[np.isnan(zz)]=0
zz=cz(zz)
plt.figure()
plt.imshow(zz, interpolation='nearest')
plt.axis('off')
plt.savefig('plots/nf.svg')
plt.close()

স্পিড আপস এবং বিউটিফিকেশন (756 বাইট) পরে

import numpy as np
from numba import jit
import matplotlib.pyplot as plt
from colorsys import hls_to_rgb 

@jit(nopython=True, parallel=True, nogil=True)
def f(z):
    return (z**4 - 1)   

@jit(nopython=True, parallel=True, nogil=True)
def df(z):
    return (4*z**3) 

def cz(z):
    r = np.abs(z)
    arg = np.angle(z)   

    h = (arg + np.pi)  / (3 * np.pi)
    l = 1.0 - 1.0/(1.0 + r**0.1)
    s = 0.8 

    c = np.vectorize(hls_to_rgb) (h,l,s)
    c = np.array(c)
    c = c.swapaxes(0,2) 
    return c    

x, y = np.ogrid[-1.5:1.5:2001j, -1.5:1.5:2001j]
z = x + 1j*y    

for i in range(10):
    z -= (f(z) / df(z))

zz = z
zz[np.isnan(zz)]=0
zz=cz(zz)
plt.figure()
plt.imshow(zz, interpolation='nearest')
plt.axis('off')
plt.savefig('plots/nf.svg')
plt.close()

নীচের প্লটটি লগ (জেড) ফাংশনের নিউটন ফ্র্যাক্টালের জন্য।

লগের জন্য নিউটন ফ্র্যাক্টাল (z)


আপনি সংক্ষিপ্ত (1 চর) নাম ব্যবহার করতে পারেন এবং একাধিক লাইন ব্যবহার করে হোয়াইটস্পেস সরিয়ে ফেলতে পারেন ;। এছাড়াও, সম্ভাব্য সমস্ত স্থান সরিয়ে ফেলুন।
mbomb007

কিছু নিয়মিত গল্ফ এটিকে মাত্র 353 বাইটে হ্রাস করে ! এটি পরীক্ষা করা হয়নি ( matplotlibএখানে নেই), সুতরাং এটি এখনও কাজ করে না তার কোনও গ্যারান্টি নেই।
খুলনায়সথ না'বাড়িয়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.