न्यूटन भग्न उत्पन्न करें


24

आप सभी न्यूटन विधि को किसी फ़ंक्शन की जड़ों के बारे में जानते हैं, है ना? इस कार्य में मेरा लक्ष्य आपको इस एल्गोरिथम के एक दिलचस्प पहलू से परिचित कराना है।

न्यूटन का एल्गोरिथ्म केवल कुछ विशेष, लेकिन सभी जटिल इनपुट मूल्यों के लिए ही परिवर्तित होता है। यदि आप जटिल विमान पर सभी इनपुट मूल्यों के लिए विधि के अभिसरण का चित्र बनाते हैं, तो आपको आमतौर पर इस तरह एक सुंदर फ्रैक्टल मिलता है:

F (x) = x ^ 3-1 के लिए न्यूटन भग्न विकिमीडिया कॉमन्स से छवि

विशेष विवरण

इस कार्य का लक्ष्य ऐसे भग्न पैदा करना है। इसका मतलब है, कि आपको इनपुट के रूप में एक बहुपद मिलता है और आउटपुट के रूप में अपनी पसंद के प्रारूप में एक छवि के रूप में संबंधित भग्न को प्रिंट करना पड़ता है।

इनपुट

इनपुट जटिल संख्याओं की एक व्हाट्सएप-अलग-अलग सूची है। वे शैली में नीचे लिखा जाता है <Real part><iImaginary part>, तो यह संख्या की तरह: 5.32i3.05। आप मान सकते हैं, कि इनपुट संख्या में 4 से अधिक दशमलव स्थान नहीं हैं और 1000 से छोटे हैं। उनमें से पहला शून्य नहीं होना चाहिए। उदाहरण के लिए, यह आपके प्रोग्राम का इनपुट हो सकता है:

1 -2i.5.5 23.0004i-3.8 i12 0 5.1233i0.1

संख्याओं को एक बहुपद के गुणांक के रूप में व्याख्या की जाती है, जिसकी शुरुआत उच्चतम शक्ति से होती है। इस विनिर्देश के बाकी हिस्सों में, इनपुट बहुपद को P कहा जाता है । उपरोक्त इनपुट इस बहुपद के बराबर है:

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

इनपुट आपके पास या तो स्टडिन से आ सकता है, एक तर्क से प्रोग्राम में पारित हो सकता है या आपके प्रोग्राम में प्रदर्शित एक प्रॉम्प्ट से हो सकता है। आप मान सकते हैं, कि इनपुट में कोई भी प्रमुख या अनुगामी व्हाट्सएप वर्ण नहीं है।

प्रतिपादन

आपको निम्नलिखित तरीके से भग्न को प्रस्तुत करना होगा:

  • पी प्लस की जड़ों के रूप में कई रंगों का चयन करें। विचलन के लिए एक अतिरिक्त रंग
  • दृश्यमान विमान में प्रत्येक संख्या के लिए, यह निर्धारित करें कि क्या विधि अभिसरण करती है और यदि किस रूट के लिए हाँ। परिणाम के अनुसार बिंदु को रंग दें।
  • शासक या अन्य फैंसी चीजें न छापें
  • बिंदुओं पर एक काला बिंदु प्रिंट करें, जो कि अभिविन्यास के लिए बहुपद हैं। आप प्रत्येक रूट के चारों ओर चार पिक्सेल तक प्रिंट कर सकते हैं।
  • एक तरह से दिखाई देने वाले विमान को चुनने का एक तरीका खोजें, ताकि सभी जड़ें अलग-अलग हो जाएं और यदि संभव हो तो व्यापक रूप से फैल जाए। हालाँकि आउटपुट फ्रेम का एक सही स्थान की आवश्यकता नहीं है, मैं एक जवाब स्वीकार करने से इनकार करने का अधिकार सुरक्षित रखता हूं जो अस्वीकार्य तरीके से फ्रेम चुनता है, जैसे। हमेशा एक ही निर्देशांक पर, सभी जड़ें एक बिंदु में होती हैं, आदि।
  • आउटपुट छवि का आकार 1024 * 1024 पिक्सेल होना चाहिए।
  • रेंडरिंग का समय अधिकतम 10 मिनट है
  • एकल सटीक फ्लोटिंग-पॉइंट वैल्यू का उपयोग करना पर्याप्त है

उत्पादन

आउटपुट को आपकी पसंद के फ़ाइल प्रारूप में एक रेखापुंज ग्राफिक्स छवि होना चाहिए, जो ब्रांड एक्स ऑपरेटिंग सिस्टम के लिए मानक सॉफ़्टवेयर द्वारा पठनीय है। यदि आप एक दुर्लभ प्रारूप का उपयोग करना चाहते हैं, तो एक वेबसाइट पर एक लिंक जोड़ने पर विचार करें जहां कोई इसके लिए एक दर्शक डाउनलोड कर सकता है।

फ़ाइल को स्टडआउट में आउटपुट करें। यदि आपकी भाषा स्टडआउट में कुछ डालने का समर्थन नहीं करती है या यदि आपको यह विकल्प कम सुविधाजनक लगता है, तो दूसरा तरीका खोजें। किसी भी तरह से, उत्पन्न छवि को बचाने के लिए संभव होना चाहिए।

प्रतिबंध

  • कोई इमेज प्रोसेसिंग लाइब्रेरी नहीं
  • कोई फ्रैक्टल जनरेटिंग लाइब्रेरी नहीं
  • सबसे छोटा कोड जीतता है

एक्सटेंशन

यदि आप इस कार्य को पसंद करते हैं, तो आप अभिसरण की गति या कुछ अन्य मानदंडों के अनुसार अंकों को रंगने की कोशिश कर सकते हैं। मैं कुछ दिलचस्प परिणाम देखना चाहूंगा।


6
मुझे पूरी तरह से यकीन नहीं है कि यह कोड गोल्फ के रूप में उपयुक्त है या नहीं। मेरी नजर में यह काम बहुत जटिल है। मैं गलत साबित हो सकता हूं, हालांकि।
जॉय

5
@ जोए: वास्तव में। मैं चाहूंगा कि यह एक कोड-चैलेंज हो
जॉय एडम्स

2
... या उस मामले के लिए पीपीएम।
जोय

1
@ जॉय: मेरा इरादा एक कठिन काम बनाना था, क्योंकि बहुत से लोग बहुत आसान काम पसंद करते हैं।
FUZxxl

1
यह आसानी से अलग-अलग कार्यों में टूट जाता है, और यदि आपकी भाषा मूल रूप से जटिल फ़्लोटिंग पॉइंट नंबरों का समर्थन करती है तो आप एक बड़ा हिस्सा बचा सकते हैं। मेरे पास 1600-चार्ट पर चलने वाला एक पूरी तरह से गोल्फ नहीं है, जिसमें से 340 जटिल संख्या वर्ग हैं। यह अभी तक जड़ों की पहचान नहीं करता है और रंगों का उपयोग नहीं करता है, लेकिन मैं नीचे ट्रैक करने की कोशिश कर रहा हूं कि मैं क्या मानता हूं एनआर कोड में एक बग है। (एक्स की एक जड़ को खोजने ^ ^ 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

यादृच्छिक नमूनों के एक समूह के लिए अभिसरण बिंदुओं को खोजकर (और जड़ें) ढूँढता है। यह तब प्रत्येक प्रारंभिक बिंदु के लिए अभिसरण बिंदुओं की गणना करके और प्रत्येक अभिसरण बिंदु के लिए यादृच्छिक रंग प्राप्त करने के लिए हैश फ़ंक्शन का उपयोग करके ग्राफ खींचता है। बहुत बारीकी से देखें और आप चिह्नित जड़ों को देख सकते हैं।

यहाँ उदाहरण बहुपद के लिए परिणाम है।

उदाहरण के लिए परिणाम बहुपद


अच्छा! यह मुझे पंसद है।
फूजएक्सएक्सएल

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 से गुणा करता हूं। मैं अभिसरण दर से चमक को समायोजित करता हूं, इसलिए जड़ें सबसे उज्ज्वल पैच में होंगी। इसलिए जड़ों के अनुमानित स्थानों को चिह्नित करने के लिए काले रंग के बजाय सफेद रंग का उपयोग करना तर्कसंगत है (जो मुझे कुछ के लिए 41 वर्णों की लागत है जो कि "सही ढंग से" भी नहीं किया जा सकता है। यदि मैं सभी बिंदुओं को लेबल करता हूं जो स्वयं के 0.5 पिक्सल के भीतर परिवर्तित हो जाता है। तब कुछ जड़ें बिना लेबल के निकलती हैं; यदि मैं उन सभी बिंदुओं पर लेबल लगाता हूं जो स्वयं के 0.6 पिक्सेल में परिवर्तित हो जाते हैं, तो कुछ जड़ें एक से अधिक पिक्सेल से लेबल की जाती हैं, इसलिए प्रत्येक रूट के लिए मैं स्वयं के 1 पिक्सेल के भीतर अभिसरण करने के लिए पहले बिंदु का लेबल लगाता हूं। )।

उदाहरण बहुपद के लिए छवि (GIMP के साथ png में परिवर्तित): X ^ 5 + (- 2 + 7.5i) x ^ 4 + (23.0004-3.8i) x ^ 3 + 12i x ^ 2 + (5.1233 + 0.1i) की जड़ें


@FUZxxl, छवि पुराने संस्करण से है। मैं बाद में अभिसरण की दर के साथ एक अपलोड करूँगा। लेकिन जड़ों को चिह्नित करने में समस्या यह निर्धारित करती है कि किस पिक्सेल को चिह्नित करना है। यह क्लासिक समस्या है कि फ्लोटिंग पॉइंट के साथ आप सटीक समानता परीक्षणों का उपयोग नहीं कर सकते हैं, इसलिए आपको एप्सिलॉन से तुलना करनी होगी। नतीजतन, मेरे पास जड़ों के लिए "विहित" मूल्य नहीं है। मैं उन पिक्सल को चिह्नित कर सकता हूं जो एक चरण में परिवर्तित होते हैं, लेकिन यह किसी भी चीज़ को चिह्नित करने की गारंटी नहीं देता है, और एक रूट के लिए 4 पिक्सेल के ब्लॉक को चिह्नित कर सकता है।
पीटर टेलर

@Peter टेलर: जैसा कि आप देख रहे हैं, कीथ रान्डेल ने भी उस समस्या का हल ढूंढ लिया। मैंने एक अतिरिक्त कठिनाई के रूप में इस आवश्यकता को जोड़ा। ऐसा करने के लिए एक दृष्टिकोण यह होगा कि प्रत्येक रूट के लिए निकटतम पिक्सेल की गणना की जाए और फिर प्रत्येक पिक्सेल को उसके बराबर होने के लिए जांचा जाए।
फ्यूजएक्सएक्सएल

@FUZxxl, आपको मेरी बात समझ में नहीं आई। एक रूट का "निकटतम पिक्सेल" अच्छी तरह से परिभाषित नहीं है। हालाँकि, मैं कुछ ऐसा हैक कर सकता हूं जिसमें आप इसे फेंकने वाले सभी परीक्षण मामलों के लिए काम कर सकते हैं, और मुझे यह आभास मिलता है कि यह आपको खुश कर देगा। मैं इसे सफेद रंग देने जा रहा हूं, काला नहीं, क्योंकि यह अधिक तार्किक है।
पीटर टेलर

@ अभिनेता टेलर: ठीक है।
फ़ूजएक्सल

6
मेरी प्रोफ़ाइल तस्वीर जल्द ही बदलनी चाहिए x^6-9x^3+8, सावधानीपूर्वक जड़ों को चुनकर और फिर बहुपद को सरल बनाने के लिए वोल्फ्राम अल्फा का उपयोग करके। ठीक है, मैं GIMP में बाद में hues की अदला-बदली करके धोखा खा गया।
पीटर टेलर

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यहां नहीं ), इसलिए कोई गारंटी नहीं कि यह अभी भी काम करता है।
खुल्द्रसेठ ना'बरिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.