Dr. M. Turhan ÇOBAN EGE ÜNİVERSİTESİ Mühendislik Fakultesi Makine Mühendisliği Bornova, İZMİR JAVA PROGRAMLAMA DİLİ ÖRNEKLERİYLE SAYISAL ÇÖZÜMLEME Dr. M. Turhan ÇOBAN EGE ÜNİVERSİTESİ Mühendislik Fakultesi Makine Mühendisliği Bornova, İZMİR İÇERİK 1. JAVA PROGRAMLAMA DİLİ 1.1 JAVA DİLİNİN TEMELLERİ 1.1.1 JAVA PROGRAMINI YAZMA VE ÇALIŞTIRMA 1.1.2 JAVA PROGRAMLAMA DİLİ TEMEL DEĞİŞKEN TÜRLERİ 1.1.2.1 BOOLEAN DEĞİŞKEN TÜRÜ 1.1.2.2 CHAR (HARF) DEĞİŞKEN TÜRÜ 1.1.2.3 TAM SAYI DEĞİŞKEN TÜRLERİ (BYTE, SHORT,İNT,LONG) 1.1.3 JAVA NESNESİ OLARAK TANIMLANMIŞ TEMEL DEĞİŞKENLER 1.1.3.1 STRİNG NESNE TİPİ DEĞİŞKENİ 1.1.3.2 INTEGER NESNE TİPİ DEĞİŞKENİ 1.1.3.3 DOUBLE NESNE TİPİ DEĞİŞKENİ 1.1.3.4 DİĞER NESNE TEMELLİ DEĞİŞKEN TÜRLERİ 1.1.4 FİNAL TERİMİ VE SABİTLER 1.1.5 ARİTMETİK İŞLEMLER 1.1.6 JAVADA MANTIKSAL İŞLEMLER 1.1.7 JAVA DİLİNDE BİT KOMUTLARI VE İŞLEMLERİ 1.1.8 JAVA DİLİNİN TEMEL KOMUTLARI 1.1.8.1 İF – ELSE İF - ELSE MANTIKSAL KARŞILAŞTIRMA YAPISI 1.1.8.2 WHİLE TEKRARLAMA YAPISI 1.1.8.3 FOR TEKRARLAMA YAPISI 1.1.8.4 SWİTCH - CASE YAPISI 1.1.9 ARİTMETİK İŞLEMLERDE DEĞİŞKEN TÜRÜ DEĞİŞTİRME OPERASYONU 1.1.10 SAYI DEĞİL VE SONSUZ SONUÇLARI (CASTİNG) 1.2 : METODLAR VE OBJECT KULLANIMI 1.2.1 JAVA API KÜTÜPHANESİ 1.2.2 METOTLAR 1.2.3 NESNE (OBJECT) TANIMI VE METOTLARDA KULLANIMI 1.2.4 METOTLARIN KENDİ KENDİNİ ÇAĞIRMASI (RECURSION) 1.2.5 AYNI ADLI METOTLARIN BİR ARADA KULLANILMASI (OVERLOADİNG) 1.2.6 METOT (METHOD) VE SINIF(CLASS) DEĞİŞKENLERİ 1.3 . SINIF (CLASS) VE NESNE KAVRAMI 1.3.0 STANDART KAVRAMLARIN TÜRKÇE KARŞILIKLARI 1.3.1 SINIF YAPISININ GENEL TANIMI 1.3.2 KURUCU ( CONSTRUCTOR ) METOT 1.3.3 DİĞER METOTLAR 1.3.4 THIS DEYİMİNİN KULLANIMI 1.3.5 SINIF DEĞİŞKENLERİNİN DIŞ DÜNYADAN GİZLENMESİ 1.3.6 SINIFLARDA KALITIM (INHERITANCE) 1.3.7 SINIFLARI BAŞKA BIR SINIFTA NESNE OLARAK ÇAĞIRARAK BiR ARAYA GETiRME (COMPOSITION) 1.3.8 KALITIM YOLUYLA ALT SINIFA BAĞLANMIŞ ÜST SINIF REFERANSI ÜZERINDEN ALT SINIFI ÇAĞIRMA 1.3.9 NESNEYi DiNAMiK OLARAK SiLMEK FINALIZE() METOTU 1.4 : BOYUTLU DEĞİŞKENLER VE NESNELER (ARRAYS) 1.4.1 TEK BOYUTLU DEĞiŞKENLER 1.4.2 TEK BOYUTLU NESNE TİPİ DEĞİŞKENLER 1.4.3 ÇOK BOYUTLU DEĞİŞKENLER 1.4.4 BOYUTLU DEĞİŞKENLERİN METOTLARA AKTARIMI 1.4.5 BOYUTLU DEĞİŞKENLERDE BOYUT DEĞİŞTİRME BÖLÜM 1.5 : SINIFLARDA HİYERARSİ, ABSTRACT SINIF VE İNTERFACE 1.5.1 ABSTRACT SINIF 1.5.2 INTERFACE KOMUTU BÖLÜM 1. 6 : GRAFİKLER, FONTLAR VE RENKLER 1.6.1 GRAFİKLERE GİRİŞ 1.6.2 GRAPHICS VE GRAPHICS2D SINIFLARI 1.6.3 RENK KONTROLÜ 1.6.4 YAZI KONTROLU 1.6.5 ÇiZGi ÇiZiMi 1.6.6 DiKDÖRTGEN ÇİZİMİ 1.6.7 ÇİZİLEN ŞEKİLLERİN DEĞİŞTİRİLEREK ÇİZİMİ (TRANSFORM) 1.6.8 OVAL VE AÇILI OVAL ÇİZİMİ 1.6.9 ÇİZİMİN SEÇİLEN BİR RESİMLE DOLDURULMASI 1.6.10 POLYGON ÇİZİMİ 1.6.11 GENELLEŞTİRİLMİŞ EĞRİ ÇİZİMİ 1.6.12 RESİM GÖSTERİMİ 1.6.13 JAVA 2 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT 1.6.14 JAVA 3 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT3D 1.6.15 JAVA 3 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT3D_JM BÖLÜM 1.7: GRAFİK APPLET VE ÇERÇEVE OLUŞTURMA OLUŞTURMA METOTLARI, GRAFİK KULLANICISI ARABİRİM PROGRAMLARI (GUI) , 1.7.1 GRAPHIC KULLANICISI ARABİRİM PROGRAMLARI, GUI, (GRAPHICS USER INTERFACE) 1.7.2 AWT LABEL (ETİKET) SINIFI , JAVAX JLABEL VE ICON SINIFLARI 1.7.3 BUTTON VE JBUTTON (DÜĞME) SINIFLARI 1.7.4 TEXTFIELD (YAZIM ALANI) SINIFI 1.7.5 YAZIM ALANI AWT TEXTAREA VE SWING JTEXTAREA SINIFLARI 1.7.6 AWT CHOICE , SWING JCOMBOBOX SEÇIM SINIFLARI 1.7.7 AWT, CHECKBOX VE CHECKBOXGROUP VE SWING JCHECKBOX VE JRADIOBUTTON SINIFLARI 1.7.8 MOUSE(FARE) KONTROLU 1.7.9 SWING JTABLE SINIFI 1.7.10 AWT, LIST SINIFI VE JAVA SWING JLIST SINIFI , LİSTEDEN SEÇİM 1.7.11 SWING JMENU 1.7.12 SWING JSLIDER SINIFI VE JPANEL TEMEL ÇİZİM ELEMANI (PANELİ) 1.7.13 FLOWLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI 1.7.14 BORDERLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI 1.7.15 GRIDLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI 1.7.16 JTABBEDPANE SINIFI KULLANILARAK FORMATLAMA 1.7.17 JSPLITPANE SINIFI KULLANILARAK GRAFİK ARAYÜZ FORMATLAMA 1.7.18 JSCROLLPANE SINIFI KULLANILARAK GRAFİK ARAYÜZ FORMATLAMA 1.7.19 PANEL VE JPANEL SINIFI 1.7.20 JOPTIONPANE SINIFI 1.7.21 SWING, JCOLORCHOOSER SINIFI 1.7.22 JFILECHOOSER SINIFI 1.7.23 JAVA JAR (JAVA ARCHIVES - JAVA ARŞİVİ) YAPILARININ KULLANIMI BÖLÜM 1.8 JAVA GİRDİ - ÇIKTI PROGRAMLANMASI 1.8.1 JAVANIN I/O (GİRDİ ÇIKTI ) KÜTÜPHANESİNDE YER ALAN SINIFLAR VE İNTERFACE’LER 1.8.2 FİLE (DOSYA) SINIFI 1.8.3 ARDIŞIK (SEQUENTIAL) DOSYA YARATILMASI 1.8.4 JAVA VERİ GİRDİ-ÇIKTI SINIFI TEXT 1.8.5 GRAFİK ORTAMDAN VERİ OKUNMASI 1.8.6 FONKSİYON TANIMINI PROGRAM İÇİNDE GİRDİ OLARAK TANIMLIYARAK KULLANMAK 1.8.5 RASLANTISAL ULAŞIM DOSYASI OKU (RANDOM ACCESS FILE) 1.8..6 DOSYA SIKIŞTIRILMASI (GZIP,GUNZIP,ZIP,UNZIP) BÖLÜM 1.9 GELİŞMİŞ JAVA BİLGİ İŞLEME YAPILARI 1.9.0 GİRİŞ 1.9.1 STRINGTOKENIZER SINIFI 1.9.2 STRİNG BUFFER SINIFI 1.9.3 VECTOR SINIFI 1.9.4 LIST(LİSTE) SINIFI 1.9.5 DİZİ (STACK) SINIFI 1.9.6 SIRA (QUEUE) SINIFI 1.9.7 TREE(AGAÇ) SINIFI 1.9.8 DICTIONARY ve HASHTABLE SINIFLARI 1.9.9 ARRAYS SINIFI VE SIRALAMA BÖLÜM 1.10 ALIŞTIRMA VE PROBLEMLER BÖLÜM 2 DOĞRUSAL DENKLEM SİSTEMLERİ 2.0 DOĞRUSAL DENKLEM SİSTEMLERİ, GENEL 2.1 GAUSS ELEME METODU 2.2 KISMİ PİVOT İŞLEMİ, KISMİ PİVOTLU GAUSS ELEME METODU 2.3 GAUSS-JORDAN METODU 2.4 KISMİ PİVOTLU GAUSS-JORDAN METODU 2.5 LU-ALT-ÜST ÜÇGEN MATRİS- GAUSS (DOLİTTLE) METODU 2.6 CRAUT LU METODU 2.7 JACOBİ, GAUSS-SEİDEL VE RAHATLAMALI İNTERPOLASYON İTERATİF METODLARI 2.8 CHOLESKY SİMETRİK MATRİS LU METODU 2.9 3LÜ VE 5Lİ BANT MATRİS ALGORİTMALARI 2.10 KONJUGE GRADYAN METODU 2.11 PROBLEMLER BÖLÜM 3 VEKTÖR VE MATRİS İŞLEMLERİ 3.1 MATRİS TEMEL İŞLEMLERİ TOPLAMA VE ÇARPMA TANIMLARI 3.2 NORM TANIMI 3.3 BİRİM MATRİS, TRANSPOSE MATRİS VE TERS MATRİS 3.4 PROBLEMLER BÖLÜM 4 LİNEER OLMAYAN DENKLEM VE DENKLEM SİSTEMLERİNİN KÖKLERİ BÖLÜM 4-A BİR BİLİNMEYENLİ SİSTEMLERİN KÖKLERİ 4.1 İKİYE BÖLME YÖNTEMİ (BİSECTİON) 4.2 YER DEĞİŞTİRME YÖNTEMİ (FALSE POSİTİON) 4.3 MÜLLER YÖNTEMİ 4.4 NEWTON-RAPHSON YÖNTEMİ 4.5 KİRİŞ YÖNTEMİ (SECANT) 4.6AİTKEN EXTRAPOLASYON DÜZELTMELİ NEWTON-RAPHSON YÖNTEMİ 4.7 AİTKEN EKSTRAPOLASYON DÜZELTMELİ DİREK YERİNE KOYMA : STEFFENSEN METODU 4.8 İKİNCİ TÜREVLİ NEWTON RAPHSON YÖNTEMİ 4.9 NEWTON-RAPHSON – İKİYE BÖLME METODLARININ BİRLİKTE KULLANILMASI 4.10 BRENT KÖK BULMA YÖNTEMİ 4.11 KÖK SINIRLARININ SAPTANMASI 4.12 RIDDER METODU 4.13 ÜÇÜNCÜ DERECEDEN POLİNOMUN KÖKLERİ 4.14 LEGUERRE METODU İLE POLİNOMLARIN KOMPLEKS KÖKLERİNİ BULMA BÖLÜM 4-B BİRDEN ÇOK BİLİNMEYENLİ SİSTEMLERİN KÖKLERİ ( LİNEER OLMIYAN DENKLEM SİSTEMLERİ ) 4.15 LİNEER OLMAYAN DENKLEM SİSTEMLERİ - NEWTON-RAPHSON YÖNTEMİ 4.16 LİNEER OLMAYAN DENKLEM SİSTEMLERİ – SHERMAN MORRISON FORMÜLLÜ BROYDEN KİRİŞ YÖNTEMİ 4.17 LİNEER OLMAYAN DENKLEM SİSTEMLERİ – SÜREKLİLİK YÖNTEMİ 4.18 LİNEER OLMAYAN DENKLEM SİSTEMLERİ –OPTİMİZASYON YÖNTEMLERİ : NELDER-MEAD AMİP YÖNTEMİ 4.19 LİNEER OLMAYAN DENKLEM SİSTEMLERİ –OPTİMİZASYON YÖNTEMLERİ : GENETİK ALGORİTMA YÖNTEMİ 4.20 LİNEER OLMAYAN DENKLEM SİSTEMLERİ –OPTİMİZASYON YÖNTEMLERİ : EN DİK YAMAÇ METODU 4.21 LİNEER OLMAYAN DENKLEM SİSTEMLERİ –OPTİMİZASYON YÖNTEMLERİ : DAVİDON-FLETCHER-POWELL METODU 4.22 PROBLEMLER BÖLÜM 5 OPTİMİZASYON(MİNİMİZASYON VE MAKSİMİZASYON) BÖLÜM 5-A BİR BİLİNMEYENLİ SİSTEMLERİN GEOMETRİK YÖNTEMLERLE OPTİMİZASYONU 5.0 OPTİMİZASYONUN TANIMLANMASI VE GRAFİK YÖNTEMLE TEK BOYUTLU OPTİMİZASYON 5.1 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-ALTIN ORAN (FİBONACCHİ) ARAMA 5.2 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-İKİNCİ DERECE POLİNOM METODU 5.3 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK- POLİMOM QUADRATURE METODU 5.4 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NEWTON-RAPHSON METODU 5.5 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK BRENT METODU 5.6 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-TÜREVLİ BRENT METODU 5.7 OPTİMİZASYON SINIR TAHMİN DEĞERLERİNİN İYİLEŞTİRİLMESİ BÖLÜM 5-B BİRDEN FAZLA (ÇOK) BİLİNMEYENLİ SİSTEMLERİN GEOMETRİK YÖNTEMLERLE OPTİMİZASYONU 5.8 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NEWTON-RAPHSON METODU 5.9 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NELDER VE MEAD SİMPLEKS METODU 5.10 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-EN DİK YAMAÇ METODU 5.11 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK- DEĞİŞTİRİLMİŞ NEWTON METODU 5.12 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK FLETCHER - REEVES VE POLAK-RIBIERE METODLARI (KONJUGE GRADYEN METODU) 5.13 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK DAVİDON-FLETCHERPOWELL METODU 5.14 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK DİREK HESSİAN DEĞİŞTİRME METODU : BROYDEN-FLETCHER-GOLDBERG-SHANNO (BFGS) 5.15 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK SÜREKLİLİK METODU 5.16 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK SHERMAN MORRISON FORMÜLLÜ BROYDEN KİRİŞ METODU İLE OPTİMİZASYON BÖLÜM 5-C BİRDEN FAZLA(ÇOK) BİLİNMEYENLİ SİSTEMLERİN GLOBAL YÖNTEMLERLE OPTİMİZASYONU 5.17 GLOBAL ÇÖZÜM METODLARI : GENETİK ALGORİTMALAR 5.17.1 GENEL KAVRAMLAR 5.17.2 MÜHENDİSLİK OPTİMİZASYONU 5.17.3 GENE SINIFI, GENOTYPE1 VE GENETIC1 SINIFI KULLANARAK GENETİK ALGORİTMA OLUŞTURMA 5.17.4 GEN SINIFI, GENOTYPE2 VE GENETİC2 SINIFI KULLANARAK GENETİK ALGORİTMA OLUŞTURMA 5.17.5 GENE3 SINIFI, GENOTYPE3 VE GENETIC3 SINIFI KULLANARAK GENETİK ALGORİTMA OLUŞTURMA 5.18 GLOBAL ÇÖZÜM METODLARI : MONTE CARLO METODU 5.19 GLOBAL ÇÖZÜM METODLARI : İTERASYONLU TEPE TIRMANMA 5.20 GLOBAL ÇÖZÜM METODLARI : TAVLAMA SİMULASYONU (SIMULATED ANNEALING) 5.21 SINIRLAMALI LİNEER OLMAYAN OPTİMİZASYON BÖLÜM 5-D KOMBİNATORAL (SAYILARIN DİZİLİŞ SIRASI İLE DEĞİŞEN) OPTİMİZASYON 5.22 GEZGİN SATICI PROBLEMİ 5.22.1 GEZGİN SATICI PROBLEMİ GENETİK ALGORİTMA ÇÖZÜMÜ 5.22.2 5.22.3 GEZGİN SATICI PROBLEMİ MONTE-CARLO ÇÖZÜMÜ GEZGİN SATICI PROBLEMİ KARINCA (GEOMETRİK OLMIYAN) ÇÖZÜMÜ BÖLÜM 5-E LİNEER OPTİMİZASYON 5.23 LİNEER OPTİMİZASYON, SİMPLEKS METODU 5.24 PROBLEMLER 6 EĞRİ UYDURMA 6.1 POLİNOM EN KÜÇÜK KARELER METODU 6.2 ORTOGONAL POLİNOM EN KÜÇÜK KARELER METODU 6.3 GENELLEŞTİRİLMİŞ EN KÜÇÜK KARELER METODU 6.4 GENELLEŞTİRİLMİŞ EN KÜÇÜK KARELER METODU İLE BİRDEN FAZLA DEĞİŞKENLİ FONKSİYONLARIN EĞRİ UYDURMASI 6.5 NEWTON İNTERPOLASYONU 6.6 LAGRANGE İNTERPOLASYONU 6.7 HERMİT İNTERPOLASYONU 6.8 KÜBİK ŞERİT İNTERPOLASYONU 6.9 B-ŞERİT İNTERPOLASYON 6.10 LİNEER OLMAYAN KATSAYILI BİR VE ÇOK BOYUTLU BAĞIMSIZ DEĞİŞKENLİ FONKSİYONLARA EĞRİ UYDURMA 6.11 EĞRİ UYDURMADA İNDİREK (PARAMETRİK) DEĞİŞKEN KULLANIMI 6.12 HAREKETLİ EN KÜÇÜK KARELER METODU 6.13 BENSTEIN POLİNOMLARI VE BEZİER EĞRİLERİ 6.14 PROBLEMLER 7 İNTEGRAL VE TÜREV 7.1 NEWTON-COTES FORMULLERİ : TRAPEZ, BOLE, SİMPSON 1/3 VE 3/8 METODLARI 7.2 RİCHARDSON EXTRAPOLASYONU (ROMBERG İNTEGRASYONU) VE AITKEN EXTRAPOLASYONU 7.3 GAUSS-LEGENDRE, GAUSS-CHEBCHEV, GAUSS-JACOBİ, GAUSS-HERMİT, GAUSSLEQUERRE İNTEGRAL FORMÜLLERİ 7.4 AYARLANABİLİR HATA MİKTARLI İNTEGRASYON FORMÜLLERİ 7.5 CLENSHAW-CURTİS İNTEGRAL FORMÜLÜ 7.6 TEK VE ÇOK BOYUTLU MONTE-CARLO İNTEGRALİ 7.7 ÇOK BOYUTLU İNTEGRALLERİ PARAMETRİK METODLA ÇÖZME 7.8 TÜREV FORMÜLLERİ 7.9 TÜREV İŞLEMİNDE RİCHARDSON EXTRAPOLASYONU 7.10 PROBLEMLER BÖLÜM 8 ÖZDEĞER - SINIR DEĞER PROBLEMLERİ 8.0 GİRİŞ 8.1 EN BÜYÜK SINIR DEĞER (KUVVET METODU) 8.2 EN KÜÇÜK SINIR DEĞER(KUVVET METODU) 8.3 JACOBİ METODU VE HOUSEHOLDER DÖNÜŞÜMÜ 8.4 QL ALGORİTMASI 8.5 QR ALGORİTMASI 8.6 POLİNOMLARIN KÖKLERİ VE REFAKATÇİ MATRİSİ 8.7 PROBLEMLER BÖLÜM 9 DİFERANSİYEL DENKLEM SİSTEMLERİ 9.1 EULER DENKLEMİ 9.2 HEUN DENKLEMİ 9.3 ORTA NOKTA VEYA GELİŞTİRİLMİŞ POLİGON DENKLEMİ 9.4 RUNGE KUTTA DENKLEMLERİ 9.5 ÇOK ADIMLI YÖNTEMLER 9.6 DEĞİŞKEN ADIM BOYUTLU YÖNTEMLER 9.7 BİRDEN FAZLA DEĞİŞKENLİ DENKLEMLER 9.8 DİFERANSİYEL DENKLEMLERDE BAŞLANGIÇ NOKTASI, ATIŞ PROBLEMİ 9.9 PROBLEMLER BÖLÜM 10 İNDEKS BÖLÜM 11 PROGRAM LİSTESİ BÖLÜM 12 REFERANS LİSTESİ ÖNSÖZ Bir mühendis olarak daima bu problemi ne şekilde çözeceğim sorusuyla iç içe yaşamışızdır. Bu gereksinme beni sayısal yöntemlerle yakından uğraşmaya itti. Sayısal yöntemleri daha iyi anladıkça da mühendislik problemlerimi çözme yetim arttı. Sayısal matematik yapısı gereği bilgisayar ortamında işlenerek oluşturulan ve kullanılan metodlardır, bu yüzden temel olarak iyi bir bilgisayar programlama altyapısıyla desteklenmesi gerekir. Bu kitapla bu iki konudaki altyapımı birleştirerek bilimle uğraşan tüm arkadaşlarımıza aktarmaya çalışacağım. Bu kitabı ne şekilde adlandıracağımdan tam olarak emin değilim, Sayısal yöntemlerin bilgisayara uygulanmasını anlatan bir bilgisayar kitabı veya bilgisayar kodlarıyla desteklenmiş bir sayısal çözümleme kitabı diyebiliriz. Bu tür kitaplar Matlab gibi popüler hazır sayısal çözümleme kodlarını kullanarak daha önce de mevcuttu. Ancak Matlab gibi kodlar oldukça pahalı ve ülkemiz ortamında kullanılmaları maddi açıdan her zaman için (en azından resmi yollarla satın alınarak) mümkün olamıyabiliyor. Benim bu kitabı geliştirirken temel amacım hem açık kodlar üzerinden dili geliştirirken hem de sayısal metodların daha iyi anlaşılabilmesini sağlamak, hem de matlab gibi bazı kodların sıfırdan başlamadan kallanıcılarımızın elinde hazır olarak bulunabilmesinin sağlanması. Kitapa bulacağınız programları geliştirmek için Java dilinden yararlandık, bu seçimdeki temel gayemiz Java’nın platform bağımsız bir dil olması ve aynı zamanda internet ortamında direk olarak çalıştırılabilmesidir. Kitapla birlikte sunulan kodlar, 2 ve üç boyutlu grafiklerin çizilebilmesini sağlayacak böylece sayısal çıktıları grafik olarak irdeleyebileceğimiz 2 ve 3 boyutlu grafik kütüphanelerine de sahiptir. 2 boyutlu grafik sistemi benim tarafımdan geliştirildi. 3 boyutlu grafik sistemi için VisAD isimli açık bir kod bulduğumdan sadece kendi fonksiyonlarımın bu ortamda çalışması için ara program hazırlamakla yetindim. Ayrıca giriş ve çıkış proseslerinde yine benim tarafımdan geliştirilmiş Text sınıfı tüm programlarda yoğun olarak kullanılmıştır. Buradaki gayemiz Java giriş çıkış terimlerini çok bilmesek de yeterince basit bir yolla karmaşık giriş çıkış işlemlerini gerçekleştirebilmekti. Sayısal çözümleme kodları, temelde Ege Üniversitesi Mühendislik fakultesi makine mühendisliği bölümünde verdiğim lisans seviyesi Sayısal çözümleme ve yüksek lisans seviyesi optimizasyon dersleri içeriğinde geliştirilmiş, ancak bu derslerde işlemediğimiz ek kodlar ve konularla zenginleştirilmiştir. Buradaki bazı programların kökeni bu derslere göre çok daha gerilere gitmektedir, hatta bir kısmını daha java dili çıkmadan önce c++ dilinde geliştirdiğim programlardan java diline direk olarak tercüme ettim, iki dil yapı olarak aynı dil yapısını kullandığından bu göreceli olarak basit bir işlemdi. Kitap şu şekliyle seviye olarak standart bir lisans seviyesi kursu için kullanılacağı gibi başlangıç yüksek lisans seviyesine de hitap edebilecek seviyededir. Mühendis ve bilimle uğraşan arkadaşlarımız için aynı zamanda bir referans ve gereksimelerini karşılayacak bir kaynak da olabilir. Elbette sayısal matematik gibi kendi başına bir bilim dalı olan bir alanda geliştirilmiş tüm yöntemleri bir kitapta sunmamız olasılı değildir, zaman içinde ihtiyaçlara göre kapsamı ve kavramı geliştirebiliriz. Şu ana kadarki kısım iki yıllık bir çabanın ürünü. Problemlerin bir kısmı Sayısal çözümleme derslerini Makine ve Teksil bölümlerimizde veren Ali Güngör ve Necdet Özbalta’nın imtihan sorularından alınmıştır, teşekkürler arkadaşlar. Birinci bölümde Java Diline belki gereğinden uzun bir giriş yaptık. Amacımız Java dili bilgisi olmıyan arkadaşlarımızın da kodları rahatlıkla kullanabilecek bilgi seviyesine ulaşmasını sağlamak. Günümüzdeki modern sayısal teknik kullanımında dilleri yeterince bilmiyorsak bir kullanıcı olmanın pek ötesine geçemeyiz, ancak bu tür teknolojiler ancak kendi programlarımızı geliştirerek tam anlamıyla etkin bir kullanım sunarlar. Benim kişisel olarak sayısal yöntemlerle ilgili çalışmalarım mühendislik uygulamalarını daha aktif olarak oluşturabilmek amacıyla idi. Bu kitabın bu konuda tüm kullanıcılarına yardımcı olacağına inanıyorum. Bazı örnekler ve problemler mühendislik problemlerinden seçilmiştir, ancak dikkatli okunduğunda formüller ve değerleri verildiğinden bu problemler rahatlıkla saf matematik formüllerine dönüşür, bu yüzden kitap sadece mühendislere değil sayısal metodlar kullanmak isteyen tüm bilim insanlarına hitap etmektedir. Kitaptaki tüm kodlar, kitapla birikte açık olarak sunulacaktır, buradaki gayelerimizden birisi de sayısal çözümlemeler için sizin daha etkin kodlar üretmeniz için bir başlangıç noktası oluşturabilmektir. Oluşturduğunuz kodları bana gönderirseniz, isimlerinizi de tutarak kitabımızın bundan sonraki basımlarına ekleyebiliriz. Saygılarımla, Dr. M. Turhan ÇOBAN İzmir, 15-04-2008 ÖZGEÇMİŞ Mustafa Turhan Çoban, 1957 yılında Bolu, Sebende doğdu. 1978 yılında Ege Üniversitesi Makine Fakultesi’nden makine mühendisi olarak mezun oldu. 1982 yılında Michigan Technological University(A.B:D.), Makina mühendisliği ve mühendislik mekaniği bölümünden makine mühendisliği yüksek lisans derecesi ile mezun oldu. 1986’da Utah üniversitesi(A.B.D.), Mühendislik fakultesi, makine mühendisliği bölümünden makine mühendisliği doktora derecesini aldı. 1995 yılında Victoria Technological University(Avustralya), matematik ve bilgisayar bilimleri bilgisayar mühendisliği yüksek lisans derecesi aldı. Ballarat Üniversity(Avustralya), University of Nebraska, Lincoln(A.B.D.), Victoria Technological University(Avustralya), Dokuz Eylül Üniversitesi, Mühendislik Fakultesi, makine bölümü, Gebze Yüksek Teknoloji Enstitüsü, Bilgisayar Mühendisliği bölümü, Ege Üniversitesi, Mühendislik fakultesi makine müh. Bölümlerinde çalıştı ve çeşitli dersler verdi. Aras kompresörleri; Maden tetkik arama enstitüsü, sondaj dairesi, jeotermal bölümü, Tübitak, Marmara Araştıma merkezi, enerji bölümü, Tübitak Ulusal Metroloji Enstitüsü, Ceramic Fuel Cells Limited(Avustralya), Imperial Chemical Industries(Avustralya) şirketlerinde çalıştı. BÖLÜM 1. JAVA PROGRAMLAMA DİLİ 1.1 JAVA DİLİNİN TEMELLERİ 1.1.1 JAVA PROGRAMINI YAZMA VE ÇALIŞTIRMA Her programda olduğu gibi java programlarında da ilk evre programı yazmaktır. Java programları her editör programıyla yazılabilirler. Örneğin Unix sistemlerinde vi veya emacs,windows 95 ve windows NT de DOS Edit, veya Windows Notedefteri (notepad) veya WordPad programları kullanılabilir. Kişisel olarak benim tercih ettiğim editör serbest olarak dağıtılan Crimson Editör’dür, sizin de bildiğiniz ve kullanmakta rahat olduğunuz herhangi bir editör programı varsa rahatlıkla kullanabilirsiniz. Windows Notedefteri (notepad) editörüyle ilgili karşılaşacabileceğiniz bir programı burada hemen belirtmekte yarar var. Bu program tüm dosyaların arkasını txt eki getirmeye çalışır. Programı direk içinde yazıp çalıştırabilen Microsoft Visual J++, Symantec Visual Café, Jpad, Borland JBuilder gibi Java geliştirme paketleri de mevcuttur. Bu kitapta bu paketler yardımıyla program yapılmasına direk olarak hiç değinilmemiştir. Kişisel olarak bu tür paketler java dilini öğrenme açısından bilhassa yeni programlama öğrenenlere çok fazla yardımı olacağını sanmıyorum, üstelik sadece o paketi kullanmayaı öğreneceğiniz için bir tür bağımlılığa sebep olabilirler. Fakat bu paketler uzman hale geldikten sonra işinizi kolaylaştırmak açısından çok yararlı olabilir. Şüphesiz programı yazmadan önce Java compilerının bir kopyasını edinmeniz de gerekir. Java geliştirme seti (Java Developers kit - JDK) SUN bilgisayar şirketinin http://www.java.sun.com internet adreslerinden bedava çekilebilir. Çekme zahmeti istemiyorsanız SUN bu programları CD formatında da satmaktadır. Sun programın kitaplar ve üçüncü el kaynaklarda verilmesine müsade etmemektedir. Ayrıca derleyici sürekli olarak yenilendiğinden orijinal kaynağından her zaman en yeni versiyonunu elde edebilirsiniz. Java ile yaptığınız lisans anlaşmasına göre program dilini bedava olarak kullanabilirsiniz, ancak satacağınız profesyonel bir program geliştirdiğinizde sun şirketine kazancınız üzerinden belirli bir yüzde ödemeniz gerekecektir. Java programı isim.java seklinde editörle yazılır. Java programınız yazıldıktan sonra ilk step java derleyici (compiler) programıyla isim.class ara bilgisayar kodunu oluşturmaktır. Java programını yazarken dikkat etmeniz gereken diğer bir özellik de javanın nesne sınıfının ismiyle dosyadaki isminin aynı olmasıdır. Bilgisayar konsol ekranında (DOS veya UNIX Console) javac isim.java Komutunu bilgisayara gönderdiğinizde programınızda hata yoksa java derleyicisi isim.class dosyasını yaratır. Eğer programınızda hata varsa hataların listesini verir. Programlamanın dili ingilizce olduğundan bu hata açıklamaları da ingilizcedir. Editör programına geri dönüp hataları düzeltmeniz, programı tekrar kaydetmeniz ve sonra bu komutu tekrar denemeniz gerekecektir. Java programları iki ortam için yaratılabilir. Birincisi Konsol ortamıdır (DOS, Unix console gibi). Konsol ortamını kullanırken java dilinin konsol komutu java kullanılarak isim.class dosyası yerel bilgisayarın makine diline program çalışırken dönüştürülür. Bu temelde bir tercüme (interpretation) işlemidir. Sonuç olarak java dilinde iki kademeli bir proses kullanılır, birinci işlemde java dosyası class dosyasına çevirilir (derlenir), ikinci işlemde ise class dosyası yerel bilgisayarın makine diline dönüştürülür. konsol ortamında çalıştırılan program sonuçları yine konsol ortamında alınacağı gibi pop-up pencere grafik ortamında da alınabilir. İkincisi ise internet browser penceresi (Applet) ortamıdır. Eğer Program konsol ortamında yazılmışsa java isim komutu kullanılarak sonuçlar ekranda veya açılan bir pencerede görülebilir. Eğer Program applet ortamında yazılmışsa java programına ilave olarak html dilinde isim.html dosyası açılır. En basit şekilde html dosyası şu şekilde tanımlanabilir : <html > <applet code="isim.class" width=200 height=50 > </applet > </html> Buradaki width pencerenin enini pixel olarak, height’da yüksekliğini yine pixel(görüntü noktası) olarak vermektedir. daha sonra bu dosya konsoldan appletviewer isim.html komutuyla çalıstırılabilir. Buradaki appletviewer komutu java program paketindeki basitleştirilmiş bir browser programıdır. Bu komut yerine isim.html dosyası herhangi bir browser programına yüklenerek görülebilir. Burada hemen şunu not etmeliyiz: braowser program yazıcıları genelde java versiyonlarını kendi programlarına aktarmakta biraz yavaş kalmaktadırlar bu yüzden en yeni java derleyicisiyle derlediğiniz bir programı browser’inız göstermeyebilir. Buna karşılık java “plug-in” denilen küçük programlar geliştirmiştir. Diğer bir olasılıkta elbette eski java derleyicinizi hemen atmayıp bir süre daha (yeni versiyonu browser programları tarafından tam olarak tanınıncaya kadar) profesyonel applet programları geliştirirken kullanmanızdır. Programcılıkta adeta adet haline gelen ilk uygulama daima o dilde ekrana Hosgeldiniz çiktisi almaktır. Bizde bu kuralın dışına çıkmayalım. Aşağıdaki listede ilk konsol programımız Hosgeldiniz.java görülmektedir. Program 1.1.1-1 Hoşgeldiniz.java konsol programı import java.io.*; //java girdi cikti sinifini cagir class Hosgeldiniz { public static void main(String args[]) { System.out.println("Java Sinifina Hos Geldiniz!"); } } bu programı çalıştırmak için javac Hosgeldiniz.java java Hosgeldiniz komutlarını konsolda vermemiz yeterlidir konsol çıktısı olarak: Java Sinifina Hos Geldiniz! Yazısını alırız. Şimdi bu programdaki satırlara tek göz atalım. import java.io.*; Bu deyim java konsol girdi çıktı kütüphanesindeki metotları programımıza aktarır. //java girdi cikti sinifini cagir // işaretiyle başlayan yazılar bilgisayar tarafından kullanılamaz sadece programı okuyanı bilgilendirmek amacı taşır /* ..... */ işaretleriyle de verilebilir. Örneğin : /* Bu kısımda yazılanlarla bilgisayar ilgilenmez Sadece insanların programı anlaması içindir */ class Hosgeldiniz Class (sınıf) nesne kökenli programlama yapısının temel taşıdır. Her Class'ın kendine özgü bir ismi olması gerekir. Daha önce yazılmış Class'lar import deyimiyle programa çağırılabilirler. Yeniden yazılmaları gerekmez. Class yapısı ve tanımlamaları üzerinde daha sonraki bölümlerde çok daha detaylı bilgi verilecektir. { } başlatma ve bitirme : Sınıf tanımlaması da dahil olmak üzere Tüm Program parçacıkları { işaretiyle başlar ve } işaretiyle son bulur. {} işaretleri arasında yazılan program parçacıklarını normal metin yazılmasındaki paragraf kavramına benzetebiliriz. Ayrıca program koduna baktığımızda "; " işaretine sık sık rastlıyoruz. Bu işaret java komutunun bittiğini belirtir. Cümle yağısında kullanılan nokta "." işareti gibi işlev görür. Java programlarını istersek ";" ve "{}" ayraçlarını kullanarak tek bir satır olarak yazabiliriz. Fakat bu programın bizim tarafımızdan okunurluğunu zorlaştırır. Program kodunu yazarken boşluk ve satır aralıkları bırakarak insanlar tarafından programın okumasını kolaylaştırabiliriz. Modern programcılıktaki en büyük sorunlardan biri bigisayar kodlarının bakım ve onarımı sorunudur. Ticari olarak yazılan her programın belli bir ömrü olduğunu ve daha sonra başka bir programcı tarafından üzerinde tekrar çalışılacağını sürekli olarak hatırlamak zorundayız. public static void main(String args[]) diğer dillerde fonksiyon (function), subroutine, procedure gibi adlarla anılan Program alt parçacığının başlığı. Bu Program parçacıkları javada Metot (Method) adıyla anılır. Metotların girdileri ve çıktıları olabilir. Bu metotun adı main (ana Program) dır. String değişken türü args[] değişkeni girdi olarak girebilir. Bu metotta void çıktı türü kullanılmıştır. Void kelimesi bu metotdan hiçbir çıktı alınmayacağını belirtir. public metota dışarıdan ulaşılabilme izni verir. System.out.println("Java Sinifina Hos Geldiniz!"); Bu satır System.out sınıfından println metotunu çalıştırır. Bu metot method girişinde gönderilen String tipi değişkeni konsol çıktısına aktarır. Fortran dilindeki write(*,*) veya print*, c dilindeki printf, c++ dilindeki cout<< terimlerinin javadaki tam karşılığıdır. "Java Sinifina Hos Geldiniz!" stringi aynen aktarılırken içinde c dilinde kullanılan temel kontrol terimleri yer alabilir ve aynen c dilindeki anlamlarıyla kullanılabilir. Bu kontrol terimlerinden en yaygın olarak kullanılan bazıları: \n alt satıra geç \t bir sonraki tab’a atla \r gir tuşu bas \\ \ işaretini yaz \” “ işaretini yaz şeklinde gösterilebilir. İkinci konsol programımız HosgeldinizSW.java Program 1.1.1-2 de verilmiştir. Bu program SWING kütüphanesinin alt kütüphanesi olan JoptionPane kütüphanesi kullanılarak yaratılmıştır. Çıktı yazısı ekranda grafik pencere olarak belirir ve Java sınıfına Hos geldiniz! mesajını verir. Tüm bu kütüphanelerin detayları ilerideki bölümlerde verilecektir. Şimdilik nasıl kullanıldıklarını öğrenmekle ve programlarımızı örnek programlara benzeterek yazmaya çalışacağız. Uzman programcılar isterlerse ilgili bölümlerden komut detaylarına derhal girebilirler. Program 1.1.1-2 HosgeldinizSW.java programı import javax.swing.JOptionPane; class HosgeldinizSW { public static void main (String args[]) { JOptionPane.showMessageDialog(null,"Java sınıfına hoş geldiniz!", "HosgeldinizSW programı",JOptionPane.INFORMATION_MESSAGE); System.exit(0); } } Bu programı javac HosgeldinizSW.java ve java HosgeldinizSW komutlarını kullanarak çalıştırdığımızda Şekil 1.1.1-1 HosgeldinizSW dosyasının konsol SWING pop-up grafik çıktısı kullanarak görülmesi Bu çıktıyı alabilmek için java SWING kütüphanesi içerisinde yer alan JOptionPane.showMessageDialog(....) metodunu kullandık. Bu metodun görevi System.out.println metoduyla aynıdır. Farkı ise grafik ortamda çıktı vermesidir. Metot içindeki ikinci sırada verilen String tipi sabit, "Java sınıfına hoş geldiniz!" grafik çıktıya aktarılmıştır. Üçüncü sırada verilen string tipi "HosgeldinizSW programi" sabiti de grafik kutusunun adını belirtmiştir. JoptionPane.INFORMATION_MESSAGE komutu ise bilgi (information) mesajı penceresi açılacağını belirtmiştir. (grafikteki i harfi – information – bilgi kelimesinin baş harfidir). Bu alanda kullanabileceğimiz alternatifler şunlardır : JOptionPane.INFORMATION_MESSAGE : bilgi mesajı JOptionPane.ERROR_MESSAGE : hata mesajı JoptionPane.WARNING_MESSAGE : uyarı mesajı JoptionPane.QUESTION_MESSAGE : soru mesajı JoptionPane.PLAIN_MESSAGE : sade (ikonsuz) mesaj System.exit(0); metodu çıktı penceresinde görülen OK düğmesine basıldığında pencerenin kapanmasını sağlar. import javax.swing.JoptionPane; deyimi swing kütüphanesinde yer alan JoptionPane sınıfını çağırır. Programdan da görüleceği gibi sınıfımızın (class) adı HosgeldinizSW dir. Bir önceki programdaki gibi bu programda kullandığımız komutlar public static void main(String args[]) komutuyla tanımlanan ana metodun içinde yazılmıştır. Üçüncü konsol program örneğimizde iki java programını birleştireceğiz İlk programımız BasicWindowAdaptor.java Program 1.1.1-3 de verilmiştir. Program 1.1.1-4 de ise HosgeldinizSWF.java programını kapsamaktadır. BasicWindowMonitor programını bundan sonraki programlarımızda sık sık kullanacağız. Program 1.1.1-3 BasicWindowMonitor.java programı import java.awt.event.*; import java.awt.Window; public class BasicWindowMonitor extends WindowAdapter { public void windowClosing(WindowEvent e) { Window w=e.getWindow(); w.setVisible(false); w.dispose(); System.exit(0); } } Program 1.1.1-4 HosgeldinizSWF.java programı import javax.swing.*; import BasicWindowMonitor; public class HosgeldinizSWF { public static void main(String[] args) { JLabel etiket=new JLabel("Java Programına Hoş geldiniz!"); JFrame cerceve=new JFrame("HosgeldinizSWF"); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(etiket); cerceve.pack(); cerceve.setVisible(true); } } Burada iki ayrı program bulunmaktadır. Bu iki programlık seti çalıştırmak için önce iki programı da derlemek gerekir. javac BasicWindowMonitor.java javac HosgeldinizSWF.java sonra ikinci prgramı java HosgeldinizSWF komutunu kullanarak çalıştırabiliriz. Burada birinci programın görevi hosgeldinizSWF penceresini köşedeki X işaretine basdığımızda pencereyi kapatmaktır. Bu programı bundan sonraki birçok uygulamamızda kullanacağız. Programımız JFrame denilen grafik pencere ortamında yazılmıştır. Çıktı penceresi : Şekil 1.1.1-2 HosgeldinizSWF dosyasının konsol SWING JFrame pop-up grafik çıktısı kullanarak görülmesi Görüldüğü gibi burada yazma işlemini yaptırmak için tek bir komut yerine bir komutlar ve metotlar zinciri kullanıldı. Bu program swing grafik kütüphanesiyle grafik formatında çıktı almanın çok daha standart bir yoludur. Temel olarak SWING grafik penceresine JLabel sınıf tipi etiket eklenerek yazı grafik ekrana aktarılmıştır. Program 1.1.1-5 de yine swing metodu kullanılmıştır. Buradaki küçük farklılık bir önceki HosgeldinizSWF programında kullanılan Jlabel nesnesi üzerinden yazdırma yerine paint metodunun kullanılmış olmasıdır. Burada da BasicWindowMonitor programı kullanılmıştır. fakat bu programı daha önce derlemiş olduğumuzdan tekrar derlememiz gerekmez. Sadece javac Hosgeldiniz1SWF.java komutuyla bu programı derlememiz ve java Hosgeldiniz1SWF komutuyla çalıştırmamız kafidir. Program 1.1.1-5 Hosgeldiniz1SWF.java programı import javax.swing.*; import java.awt.*; import BasicWindowMonitor; public class Hosgeldiniz1SWF extends Jframe { public void paint(Graphics g) { g.drawString("Java sınıfına hoşgeldiniz!",10,40); } public static void main(String[] args) { Hosgeldiniz1SWF cerceve=new Hosgeldiniz1SWF(); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.setSize(160,50); cerceve.setVisible(true); } } Program çıktısı : Şekil 1.1.1-3 Hosgeldiniz1SWF.java dosyasının konsol SWING pop-up grafik çıktısı kullanarak görülmesi Burada yazıyı temel olarak bir grafik metodu olan g.drawString("Java sinifina hosgeldiniz!",10,40); metodunu kullanarak pencere ortamına aktardık. bu metodda kullanılan 10,40 deyimi yazının grafik ortamındaki x ve y koordinatlarını göstermektedir. y koordinatı yukardan aşağı doğru tanımlanmıştır. cerceve.setSize(160,50); deyimi açılan pencerenin boyutunun 160 genişliğinde ve 50 yüksekliğinde olacağını belirtmektedir. cerceve.setVisible(true); terimi ise pencerenin görünmesini (çizilmesini) sağlamaktadır. Buraya kadar kullandığımız programlar konsol programlarıydı. Bu programlarda da gördüğünüz gibi grafik ortamını yoğun olarak kullanabiliyoruz. Yalnız programların çalıştırılması konsoldan verilen java isim komutuyla gerçekleştirilmektedir. Şimdi de applet grafik ortamında çıktı almaya örnek verelim. İlk applet programımız HosgeldinizApplet.java listesi Program 1..1.1.6 da verilmiştir Program 1.1.1-6 HosgeldinizApplet.java programı import java.applet.Applet; import java.awt.*; public class HosgeldinizApplet extends Applet { public void paint(Graphics g) { g.drawString("Java sınıfına hoş geldiniz!",25,35); }} bu programı çalıştırmak için önce HosgeldinizApplet.html HTML dili programını yazmamız gerekir Program 1.1.1-7 HosgeldinizApplet.html HTML kodu <html > <applet code="HosgeldinizApplet.class" width=200 height=50 > </applet > </html> bu html kodunda <applet code="HosgeldinizApplet.class" width=200 height=50 > komutu html'e compile edilmiş olan HosgeldinizApplet.class dosyasının gösterilmesini istemektedir. Şüphesiz aynı komut çok daha kompleks bir html dosyasının içinde de aynı görevi görmek amacıyla kullanılabilirdi. Programı çalıştırmak için javac HosgeldinizApplet.java appletviewer HosgeldinizApplet.html komutlarını konsolda vermemiz yeterlidir. Elbette HosgeldinizApplet.html dosyasının yukarıda belirtildiği gibi hazırlanmış olması da gerekir. Fakat Konsol programlarından farklı olarak sonucu konsol yerine Applette (browser programında) görürüz. Aynı sonucu appletviewer deyimini kullanmadan herhangi bir browser programı çağırarak da elde edebiliriz. Browser programında sonucu görebilmek için önce programı açmamız sonra da HosgeldinizApplet.html dosyasını bularak açmamız gerekir. Çıktı görüntüsü aşağıdaki gibi olacaktır. Şekil 1.1.1-4 HosgeldinizApplet.html dosyasının Mozilla Firefox browser programı kullanarak görülmesi Şekil 1.1.1-5 HosgeldinizApplet.html dosyasının appletviewer programı kullanarak görülmesi Bu programında temel olarak bazı farklılıklar dışında bir önceki programlara benzediğini gözlemleyebiliriz. Bu programın temel farkı internet ortamından herhangi bir bilgisayardan da (gerekli ayarlama ve kopyelemelerden sonra) görülebilir olmasıdır. import java.applet.Applet; import java.awt.*; deyimleri java kütüphanesindeki Applet ve pencere(awt) sınıf grafik programlarını programımıza aktarır. public class HosgeldinizApplet extends Applet deyimi HosgeldinizApplet isimli sınıfı (class) yaratır. Bu sınıf tüm Applet sınıfının bir devamı olarak tanımlanmaktadır (extends Applet) diğer bir deyimle Applet sınıfının bütün metotları extends deyimiyle HosgeldinizApplet sınıfımızın içine kopyalanmıştır. public void paint(Graphics g) deyimi appletin grafik olarak çizilmesini sağlar. Bu Metot Graphics sınıfı g nesnesini girdi olarak kullanır. Metotun çıktısı yoktur. g.drawString("Java sinifina hos geldiniz!",25,35); Bu terim Appletin x = 25, y=35 noktasına Java sinifina hos geldiniz! Yazısını çizer. DrawString Grafik sınıfı g nesnesine ait bir metotdur. Bu programda temel grafik kütüphanesi olarak abstract window toolkit (awt) kullanılmıştır. ayrıca konsol programlarından farklı olarak bu programda main metodunun kullanılmadığına da dikkat ediniz. bir program hem applet hem de konsol olarak da oluşturulabilir, yani hem main metodu olabilir hem de applet (html) ortamında çalışabilir. Aynı appleti oldukça benzer bir şekilde SWING kütüphanesini kullanarak da oluşturabilirdik. Program 1.1.1.8 HosgeldinizSWA.java programı import javax.swing.Japplet; import java.awt.Graphics; public class HosgeldinizSWA extends JApplet { public void paint(Graphics g) { g.drawString("Java sınıfına Hoşgeldiniz",25,25); } } Şekil 1.1.1-6 HosgeldinizSWA.java dosyasının applet SWING pop-up grafik çıktısı kullanarak görülmesi Bu programdaki import javax.swing.Japplet; import java.awt.Graphics; deyimleri java swing kütüphanesindeki JApplet ve pencere(awt) sınıfındaki Graphics alt programlarını (sınıflarını) programımıza aktarır. public class HosgeldinizSWA extends JApplet deyimi HosgeldinizAppletSWA isimli sınıfı (class) yaratır. Bu sınıf swing sınıfındaki JApplet sınıfının bir devamı olarak tanımlanmaktadır (extends JApplet). Diğer bir deyimle JApplet sınıfının bütün metotları extends deyimiyle HosgeldinizAppletSWA sınıfımızın içine kopyalanmıştır. Aynı işi yapmak için bir çok değişik program yazdık. Bazılarımız buna ne gerek vardı, tek bir şekilde bu işi halledemezmi idik diyebilirler. Haklıdırlarda. Fakat modern bilgisayar dillerinde kullanıcıları da göz önüne almak durumundayız. Aynı işi daha renkli ve çeşitli şekillerde yapmamız temel olarak program kullanıcılarına daha çeşitli alternatifler sunabilir. Aynı zamanda diğer programlama alternatiflerine göre daha üstün bir çalışma ortamı yaratabilir. Şimdi de programımıza bir basamak daha ekleyelim ve program kullanıcılara isimlerini sorsun, yani ekrandan bir veri girelim. Bunu yapmak için ilk tanımlayacağımız program konsol ortamında çalışan Hosgeldiniz2.java programı olacaktır. Bu programın çıktısı dos konsol ortamında şekil 1.6 da görülmektedir. Program ekranda isminizi giriniz yazacak, ve ekranda isim girildikten sonra java sınıfına hosgeldiniz! isim çıktısını verecektir. Program 1.1.1-9 Hosgeldiniz2.java programı import java.io.*; class Hosgeldiniz2 { public static void main (String args[]) throws IOException { BufferedReader cin=new BufferedReader(new InputStreamReader(System.in)); System.out.println("isminizi giriniz : "); String isim=new String(cin.readLine()); System.out.println("Java Sinifina Hos Geldiniz! "+isim); cin.close(); } } ============================= C:\co\java\prog>java Hosgeldiniz2 isminizi giriniz : Turhan Java Sinifina Hos Geldiniz! Turhan C:\co\java\prog> ============================= Şekil 1.1.1-6 Hosgeldiniz2.java dosyasının sonuçlarının dos çıktısı kullanarak görülmesi Bu programda okuma işlemini yapmakiçin önce BufferedReader cin=new BufferedReader(new InputStreamReader(System.in)); Deyimini kullanarak bir okuma kanalı açtık, sonra System.out.println("isminizi giriniz : "); String isim=new String(cin.readLine()); Deyimindeki cin.readLine() komutuyla ismi cin kanalından okuyarak isim değişkenine aktardık. Aynı işlemi yapan fakat girdi çıktı sınıf tanımlarında Ek 1 de verilen Text sınıfını kullanan Hosgeldiniz3.java programı şekil 1.10 da verilmiştir. Program 1.1.1-10 Hosgeldiniz3.java programı import java.io.*; import Text; class Hosgeldiniz3 { public static void main (String args[]) throws IOException { Text cin=new Text(); System.out.print("isminizi giriniz : "); String isim=cin.readString(); System.out.println("Java Sinifina Hos Geldiniz! "+isim); } } Hosgeldiniz2.java programının çıktısı da Hosgeldiniz2.java programıyla aynı olacaktır. Şimdi de swing kütüphanesindeki JoptionPane.showInputDialog() kullanarak girdi penceresi açan ve çıktı penceresine JoptionPane.showMessageDialog() kullanarak mesajı yazan Hosgeldiniz1SW.java programını göreceğiz. Program 1.1.1-11 Hosgeldiniz1SW.java programı import javax.swing.JoptionPane; class Hosgeldiniz1SW { public static void main (String args[]) { String isim=JoptionPane.showInputDialog("Lutfen isminizi giriniz :"); JoptionPane.showMessageDialog(null,"Java Sinifina Hos Geldiniz! "+isim, "Hosgeldiniz1SW programi",JOptionPane.INFORMATION_MESSAGE); System.exit(0); } } Bu programı çalıştırmak içinde javac Hosgeldiniz1SW.java komutuyla bu programı derlememiz ve java Hosgeldiniz1SW komutuyla çalıştırmamız gerekecektir. Program girdi ve çıktı pencereleri şekil 1.1.1-7 ve Şekil 1.1.1-8 de verilmiştir. Şekil 1.1.1-7 Hosgeldiniz1SW.java dosyasının pencere popup girdi penceresi Şekil 1.1.1-8 Hosgeldiniz1SW.java dosyasının pencere popup çıktı penceresi Şimdi aynı girdi ve çıktı programlamasını JApplet sınıfını kullanarak yapalım. Input (girdi) için yine JoptionPane sınıfından yararlanacağız. Program 1.1.1-12 Hosgeldiniz1SWA.java programı import javax.swing.*; import java.awt.Graphics; public class Hosgeldiniz1SWA extends JApplet { String isim; public void init() {isim=JoptionPane.showInputDialog("isminizi giriniz : "); } public void paint(Graphics g) {g.drawString("Java sinifina Hosgeldiniz "+isim,25,25); }} Bu programı çalıştırmak için compile prosesinde yine javac Hosgeldiniz1SWA.java komutunu kullanacağız. sonra Hosgeldiniz1SWA.html dosyasını oluşturacağız. Program 1.1.1-13 Hosgeldiniz1SWA.html programı <html> <applet code="Hosgeldiniz1SWA.class" width=300 height=30> </applet> </html> Hosgeldiniz1SWA.html dosyasını herhangi bir browser programında görebileceğimiz gibi javanın kendi basit browser programı appletviewer da da appletviewer Hosgeldiniz1SWA.html deyimiyle gösterebiliriz. Program girdi ve çıktısı : Şekil 1.1.1-9 Hosgeldiniz1SWA.java dosyasının applet popup girdi penceresi Program çıktısı appletviewer browserinda görüleceği şekliyle : Şekil 1.1.1-10 Hosgeldiniz1SWA.java dosyasının applet çıktı penceresi olacaktır. Son olarak girdi ve çıktı işlemlerini aynı pencerede yapıldığı biraz daha kompleks olan Hosgeldiniz5SWA.java programına göz atalım. Program 1.1.1-13 Hosgeldiniz5SWA.java programı import javax.swing.*; // java JApplet sınıfını çağır import java.awt.*; // java pencere kullanma sınıflarını (awt kütüphanesi) çağır import java.awt.event.*; // java pencereyi dinleme sınıflarını (awt kütüphanesi) çağır public class Hosgeldiniz5SWA extends JApplet implements ActionListener { //sınıf değişkenleri JTextArea ciktiAlani; //JTextArea sınıfı çıktı alanı değişkeni JLabel kutubasligi; //JLabel sınıfı değişkeni (nesnesi) kutubasligi JTextField kutugirdisi;//JTextfield sinifi degiskeni (nesnesi) kutugirdisi String isim; public void init() { //girdi çıktı programlarının içine yazılacağı ana pencereyi tanımla Container c=getContentPane(); c.setLayout(new FlowLayout()); isim="Defne Yasemin Çoban"; kutubasligi=new JLabel("isminizi giriniz :"); c.add(kutubasligi);//kutubasligini pencereye yaz kutugirdisi=new JTextField(10); c.add(kutugirdisi);//kutuyu pencereye yerlestir ciktiAlani=new JTextArea(); Color co=c.getBackground(); ciktiAlani.setBackground(co); c.add(ciktiAlani); ciktiAlani.setText("Java sınıfına Hoşgeldiniz ! "+ isim); // kutuya yeni ilave edilecek komutlari bekle // her yeni komutta actionPerformed metodunu calistir. kutugirdisi.addActionListener(this); } // girdi alanindaki olan olaylari dinleme metodu public void actionPerformed(ActionEvent e) { //pencereden ismi oku isim=e.getActionCommand(); ciktiAlani.setText("Java sınıfına hoşgeldiniz ! "+ isim); repaint(); } } bu programı da yine javac Hosgeldiniz5SWA.java deyimiyle compile edip, appletviewer Hosgeldiniz5SWA.html komutuyla çalıştırırız. Hosgeldiniz5SWA.html dosyasının yukarıda anlatıldığı gibi hazırlanması gerekir. Program çıktısı şekil 1.11 de gösterilmiştir. Şekil 1.1.1-11 Hosgeldiniz5SWA.java dosyasının applet girdi- çıktı penceresi Bu programda verilen komut detaylarını şu anda bilmek zorunda değilsiniz. Benzer işlemleri yapmak için aynı formattan yararlanabilirsiniz. İlerki bölümlerde grafik programlarının alt metodları detaylı olarak incelenecektir. 1.1.2 JAVA PROGRAMLAMA DİLİ TEMEL DEĞİŞKEN TÜRLERİ Programlama dillerinde rakamlar bilgisayar belleğinin temel depolama birimlerine yazılırlar. Temel bilgisayar bellek birimi bit olarak adlandırılır. Bir bilgisayar belleğindeki tek bir transistörden oluşmuştur. Bu transistörden akım geçiyorsa tansistörün veya bitin bellek değeri 1 (bir) veya true (doğru) olarak alınır. Eğer akım geçmiyor veya düşük düzeyde bir akım geçiyorsa transistörün bellek değeri 0 (sıfır) veya false(yanlış) olarak alınır. Bilgisayar bit birimleri bir araya gelerek bilgisayar temel değişken türlerini yazabileceğimiz bir sistem oluştururlar. Değişken türü bilgisayar tarafından bilinmelidir, çünkü aynı bit topluluğu bir harfi simgeleyebileceği gibi bir rakamı da simgeleyebilir. Java dilinde Tablo 1.1 de görülen temel değişken türleri mevcuttur. Tablo 1.1.2-1 Java Temel Değişken türleri Değişken Türü Türkçe karşılığı boolean Mantık değişkeni char harf değişkeni byte tam sayı değişkeni short tam sayı değişkeni Bit büyüklüğü 1 16 8 16 Sınır Değerleri true(doğru) , false(yanlış) '\u0000' den '\uFFFF' -128 den 127 e -32768 den 32767 e int long tam sayı değişkeni tam sayı değişkeni 32 64 float Gerçek sayı değişkeni 32 double Gerçek sayı değişkeni 64 -2157483648 den 2147483647 e -9223372036854775808 den 9223372036854775808 e -3.40292347e+38 den 3.40292347e+38 e -1.7976931348623157e+308 den 1.7976931348623157e+308 e Şimdi bu temel değişken türlerinin bazılarını daha detaylı inceleyelim: 1.1.2.1 BOOLEAN DEĞİŞKEN TÜRÜ boolean değişken türü mantık işlemlerinde kullanılır. Sadece true veya false değerleri alır. true doğru false yanlış anlamı taşır. Mantık değişkenlerine doğrudan true veya false değerleri yüklenebileceği gibi diğer değişkenleri mantık işlemlerini kullanarak karşılaştırarakta değerleri programların içinde hesaplanabilir. Aşağıdaki küçük program parçası mantık değişkeni ilk mantık değiskenini tanımlamakta ve doğru değerini bu değişkene yüklemektedir. boolean ilkmantıkdegiskeni; ilkmantikdegiskeni=true; y boolean değişkenine true değerini, z boolean değişkenine false değerini yükleyecektir. 1.1.2.2 CHAR (HARF) DEĞİŞKEN TÜRÜ char değişken türü harflerin tanımlanmasında kullanılır. Harfler java dilinde ISO Unicode kodu ile bilgisayara aktarılır. Unicode 4 hekzagonal (16 tabanlı) sayının bir araya gelmesiyle oluşur. Hekzagonal sayı sisteminin onlu ve ikili sayı sistemiyle eşitliği şöyledir : Tablo 1.1.2-2 Heksagonal(onaltılı), onlu ve ikili sayı sistemleri eşitlikleri Heksagonal 0 1 2 3 4 5 6 7 8 9 A B C D E F Onlu 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 İkili 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 ISO Unicode da tanımlanan '\u0041' kodu 'A' harfi anlamına gelir. Veya '\u03E1' kodu '' harfini tanımlar. ISO Unicode karakter setinin ilk iki rakamı sıfır olduğunda ASCII karakter kodunu tanımlar. Unicode hakkında daha ayrıntılı bilgi için http:\\unicode.org internet adresini ziyaret edebilirsiniz. Aşağıdaki küçük program parçacığı char tipi A1, A2 ve alpha1,alpha2 değişkenlerine A ve harflerini yüklemektedir. char A1,A2; char alpha1,alpha2; A1='\u0041'; A2='A'; alpha1='\u03E1'; alpha2=''; Burada şunu kaydedelim alpha1 değişkenini her ortamda doğru olarak görebiliriz, fakat alpha2 değişkeni bazı ortamlarda doğru olarak görülmeyebilir. 1.1.2.3 TAM SAYI DEĞİŞKEN TÜRLERİ (BYTE, SHORT,İNT,LONG) Tam sayı değişkenler hafızada işgal ettikleri yere göre byte(8 bit), short(16 bit), int(32 bit) ve long(64 bit) adını alırlar. Bir bitlik hafızaya sadece iki rakamın (0 veya 1) yazılabileceği göz önüne alınırsa örneğin sekiz bitlik byte türü tamsayı değişkenine 256 sayı (ikili sayı eşiti 11111111) yazılabileceği ortaya çıkar. Bitlerden biri + veya - işareti için kullanıldığından byte değişkeninin sınır değerleri -128den 127 e kadardır (toplam 256 sayı). Eğer bir tamsayı değişkenin sadece artı değerlerini kullanmak istersek unsigned terimini kullanırız. Örneğin unsigned byte tipi tamsayı değişkenin sınır değerleri 0 dan 256 ya kadardır. Tamsayı değişken türleri içinde en fazla kullanılan int türüdür. Aşağıdaki küçük program parçacığında int türü ilktamsayi değişkenine 32 rakamı yüklenecektir. int ilktamsayi; ilktamsayi=32; bu iki satırlık program parçacığı tek bir satır olarak int ilktamsayi=32; şeklinde de yazılabilirdi. Javadaki tamsayı değişken türleri + ve – değeri alabilen türlerdir. Örneğin byte değişken türü –128 den +127 e kadar toplam 256 sayı kullanabilir. Eğer – bölgeyi kullanmayacaksak tamsayı değişkenlerin kullanım bölgesini unsigned deyimini kullanarak tamamen artı bölgeye çekebiliriz. Örneğin unsigned byte artıbolgetamsayisi; işlemiyle tanımlanan artıbolgetamsayisi değişkeni 0 ile 256 arasında değerler alabilir. 1.1.2.4 GERÇEK SAYI DEĞİŞKEN TÜRLERİ (FLOAT, DOUBLE,LONG DOUBLE) Gerçek sayı sistemleri de 0 ve 1 bitleri kullanılarak oluşturulabilir. Gerçek sayıların tamsayıdan küçük kısımları 2 li tabanda eksi üstler kabul edilerek oluşturulur. Örnek olarak 16 bitlik gerçek bir sayıyı ikili sistemdeki bilgisayar belleğinde şu şekilde gösterebiliriz : Tablo 1.1.2-3 gerçek sayı 22.625e-17 yazılmasında kullanılan onlu ve ikili sayıların bellekte gerçek sayı organizasyonu örneği +/24 23 22 21 20 2-1 2-2 2-3 2-4 +\24 23 22 21 + 16 8 4 2 1 0.5 0.25 0.125 0.0625 16 8 4 2 0 1 0 1 1 0 1 0 1 0 1 1 0 0 0 Yukarıda 16 bitle temsil edilen sayı : +16+4+2+0.5+0.125)*10 -(16+1) = 22.625e-17 rakamıdır. Gerçek sayı değişkende yeterli hassasiyeti sağlayabilmek için genelde 64 bit uzunluğundaki double değişken türü kullanılır. Javadaki Matematik kütüphaneleri de double değişken türü için tanımlanmıştır. Aşağıdaki küçük program parçacığında double türü ilkgercekdegisken değişkenine 22.625e-7 sayısını yüklüyoruz. double ilkgerçekdegisken; ilkgerceldegisken=22.625e-17; eğer 64 bit double sayı hassaslığı yetmezse long double kullanılabilir. Bu değişken türü 128 bit boyutundadır. 1.1.3 JAVA NESNESİ OLARAK TANIMLANMIŞ TEMEL DEĞİŞKENLER 20 1 1 Java nesne temelli bir dildir. Javadaki tüm değişken türlerinin nesne kökenli eşdeğerleri mevcuttur. Bunun yanında temel değişken türleri arasında yer almıyan String gibi sadece nesne kökenli olarak tanımlanmış değişken türleri de mevcuttur. Şimdi bunların bir kısmını biraz daha detaylı inceleyelim. 1.1.3.1 STRİNG NESNE TİPİ DEĞİŞKENİ String değişkeni yazı yazdırma işleri için kullanılır. Nesne türü değişkendir. Java dilinde char temel değişken türü kullanılarak tanımlanmış bir nesne tipi değişkendir. Aşağıdaki küçük program parçacığında bu değişken türünün kullanılmasını görüyoruz. String a="ali"; String c="veli"; String d; d=a+b; // d nin değeri "ali veli" System.out.println(d); // bu satır ali veli çıktısı verir String türü sabitler her zaman " işaretleri arasına yazılırlar ve + işaretiyle bir araya getirilebilirler. String türü değişkenleri tanımlamak için aynı zamanda String a=new String("ali"); String c=new String("veli"); String d=new String(); d=a+b; // d nin değeri "ali veli" System.out.println(d); // bu satır ali veli çıktısı verir Formunu da kullanabiliriz. İkinci verdiğimiz form işlem olarak ilk verilenin tamamen aynıdır. Sadeve burada değerler String değişken tipinin kurucu metodu üzerinden tanımlanmıştır. Kurucu metodların detayları için ilgili bölümü inceleyebilirsiniz. String a=new String("ali"); boolean y=a.equals(“ali”); boolean z=a.equals(“veli”); 1.1.3.2 INTEGER NESNE TİPİ DEĞİŞKENİ Integer nesne tipi değişkeni, String değişkeni gibi Integer i; i=new Integer(3); veya Integer i=new Integer(3); Şeklinde tanımlanabilir. Integer tanımı String değişkeni üzerinden de tanımlanabilir. Örneğin String s=”15”; Integer i=new Integer(s); Tanımı 15 değerini yükler. Integer değerini int değerine (temel değişken) çevirebiliriz. int x; Integer y=new Integer(3); x=Integer.IntegerValue(y); String değerini int değerine direkt olarak çevirmek içinse String s=”15”; int x=Integer.parseInt(s); kullanılır. int tipi (temel) değişkeni String değişkenine değiştirmek için int x=3; String s=Integer.toString(x); kullanılır. 1.1.3.3 DOUBLE NESNE TİPİ DEĞİŞKENİ Double değişkeni kullanım olarak Integer değişkeninden bir farkı yoktur. Aynı tanımlamalar Integer yerine Double kullanılarak yapılabilir. Değişkenler Double x; x=new Double(3.66e5); veya Double x=new Double(3.66e5); Şeklinde tanımlanabilir. Double tanımı String değişkeni üzerinden de tanımlanabilir. Örneğin String s=”15.66e-3”; Double x=new Double(s); Tanımı 15.66*10-3 değerini yükler. Double değerini double değerine (temel değişken) çevirebiliriz. double x; Double y=new Double(15.66e-3); x=Double.doubleValue(y); int x; Double y=new Double(15.66e3); x=Double.intValue(y); String değerini double (temel değişken) değerine direkt olarak çevirmek içinse String s=”15.25”; double x=Double.parseDouble(s); İşlemi kullanılabilir. double tipi (temel) değişkeni String değişkenine değiştirmek için double x=3.75; String s=Double.toString(x); kullanılır. 1.1.3.4 DİĞER NESNE TEMELLİ DEĞİŞKEN TÜRLERİ Object, Long, Float, Boolean, Character, Vector gibi diğer nesne tipi değişken türleri de mevcuttur. Object nesne tipi tüm bu değişken nesne tiplerini içinde barındıran genel bir tiptir. Tüm nesne tipi değişkenlerin bizim için temel avantajı alt metodlarını kullanarak işlemler gerçekleştime olasılıklarıdır. Fakat bu tür değişkenler temel değişken türlerine göre daha çok hafıza yeri işgal ettiklerinden mecbur kalınmadıkça da kullanılmamalıdırlar. Ayrıca Yine nesne tipi BigDecimal ve BigInteger türleri de hassasiyeti kullanıcı tarafından belirlenen nesne tipi değişkenler olarak kullanılabilirler. 1.1.4 FİNAL TERİMİ VE SABİTLER Java dilinde değişken yerine sabit kullanmak istersek tanımın başına final sözcüğünü getiririz. Final olarak tanımlanan sabitlerin bir kere değerleri verildikten sonra değiştirilemez. Örneğin final double pi=3.14159; pi ( sabitini tanımlar. 1.1.5 ARİTMETİK İŞLEMLER Javadaki temel aritmetik işlemler şunlardır : + toplama - çıkarma * çarpma / bölme % tamsayılar için bölmede kalan (modül) Program 1.1.5-1 deki program örneği int tamsayı kullanarak bu aritmetik işlemlerin yapılmasını göstermektedir. Program 1.1.5-1 : Aritmetik.java konsol programı import java.io.*; //java girdi cikti sınıfını çağır class Aritmetik { public static void main(String args[]) { int sayi1,sayi2; int toplama,cikarma,carpma,bolme,kalan; sayi1=2; sayi2=3; toplama = sayi1+sayi2; cikarma = sayi1-sayi2; carpma = sayi1*sayi2; bolme=sayi1/sayi2; kalan=sayi1%sayi2; System.out.println(sayi1 +" + "+ sayi2+" = "+toplama); System.out.println(sayi1 +" - "+ sayi2+" = "+cikarma); System.out.println(sayi1 +" * "+ sayi2+" = "+carpma); System.out.println(sayi1 +" / "+ sayi2+" = "+bolme); System.out.println(sayi1 +" % "+ sayi2+" = "+kalan); } } Aritmetik.java konsol programı çıktısı : 2+3=5 2 - 3 = -1 2*3=6 2/3=0 2%3=2 şeklinde olacaktır. Swing grafik kütüphanesi çıktısı pratiği yapmak amacıyla aynı programı swing JoptionPane çıktısı ile yazarsak : Program 1.1.5-2 : AritmetikSW.java konsol programı import javax.swing.JOptionPane; //java swing cikti sinifini cagir class AritmetikSW { public static void main(String args[]) { String s; int sayi1,sayi2; int toplama,cikarma,carpma,bolme,kalan; sayi1=Integer.parseInt( JOptionPane.showInputDialog("birinci sayıyı giriniz : ")); sayi2=Integer.parseInt( JOptionPane.showInputDialog("ikinci sayıyı giriniz : ")); toplama = sayi1+sayi2; cikarma = sayi1-sayi2; carpma = sayi1*sayi2; bolme = sayi1/sayi2; kalan = sayi1%sayi2; s=""; s=s+sayi1+" + "+sayi2+" = "+toplama+"\n"; s=s+sayi1+" - "+sayi2+" = "+cikarma+"\n"; s=s+sayi1+" * "+sayi2+" = "+carpma +"\n"; s=s+sayi1+" / "+sayi2+" = "+bolme +"\n"; s=s+sayi1+" % "+sayi2+" = "+kalan +"\n"; JOptionPane.showMessageDialog(null,s, "Aritmetik islemleri",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Bu programın çıktısı : Şekil 1.1.5-2 AritmetikSW.java dosyasının JOptionPane çıktı penceresinde görünümü Java ve C dillerinde temel aritmetik işlemlerinin yanı sıra bu işlemlerin kısaltılmış sembolleri de oldukça sık kullanılır. Bu işlemler : ++ bir ilave et -- bir çıkar += sağ taraftaki rakamı ilave et -= sağ taraftaki rakamı çıkar *= sağ taraftaki rakamla çarp /= sağ taraftaki rakama böl %= sağ taraftaki rakama bölüp kalanını al işlemleridir. ++ ve -- işlemleri değişkenden önce veya sonra gelebilir. Bu iki şeklin değişken tek başlarına kullanıldığında bir farklılıkları yoktur, fakat ikinci bir değişkenle birlikte tek bir deyimde kullanıldıklarında ikinci değişkenin değeri değişir. Aşağıdaki iki program parçacığına göz atalım. ++ işlemcisinin değişkenden sonra kullanılması int a=2; int c; c=a++; // a nın değeri 3 c nin değeri 2 ++ işlemcisinin değişkenden önce kullanılması int a=2; int c; c=++a; // a nın değeri 3 c nin değeri 3 a değişkeninin değeri başlangıçta 2 ise görüldüğü gibi hem ++a işleminde hem de a++ işleminde değeri 3 e çıkmaktadır. Ancak c değişkeninin değeri c=a++ işleminde 2 olarak kalırken (önce değeri yükle sonra arttır), c=++a işleminde 3 olmaktadır(önce arttır, sonra değeri yükle). ++ ve -- işlemleri genelde tam sayı değişkenler için kullanılır. Program 1.17 da aritmetik işlemleri gösteren bir program verilmiştir. Bu programın sonuçları da altta verilmektedir. Programı basamak basamak takip ederek sonuçların doğruluğunu elde hesaplayarak kontrol edebilirsiniz. Program 1.1.5-3 : Aritmetik1.java aritmetik işlem örneği import java.io.*; public class Aritmetik1 { public static void main(String[] args) { int sayi1=1; int sayi2=2; sayi1+=sayi2; System.out.println("sayi1+= : "+ sayi1); sayi1-=sayi2; System.out.println("sayi1-= : "+ sayi1); sayi1*=sayi2; System.out.println("sayi1*= : "+ sayi1); sayi1/=sayi2; System.out.println("sayi1/= : "+ sayi1); } } Aritmetik1 sınıfının sonuçları sayi1+= : 3 sayi1-= : 1 sayi1*= : 2 sayi1/= : 1 1.1.6 JAVADA MANTIKSAL İŞLEMLER Javadaki temel değişken türlerine bakarken boolean türü değişkenleri tanımlamıştık. Tam sayı ve gerçek değişkenlerin aritmetik işlemlerde kullanılabildiği gibi boolean değişkenler de mantıksal işlemlerde kullanılabilirler. Mantıksal işlem işlemcileri şunlardır : Tablo 1.1.6-1 Java dilindeki mantıksal işlemler ve anlamları Mantıksal İşlemci && || > < == >= <= ! != Anlamı ve veya büyüktür küçüktür Eşittir büyük ve eşittir küçük ve eşittir Değildir eşit değildir Mantıksal işlemleri pekiştirmek amacıyla Program 1.1.6-1 de bir örnek verilmiştir. Program 1.1.6-1 : Java mantıksal işlemleri örnek problemi booleanvar.java import java.io.*; public class booleanvar { public static void main(String[] args) { boolean b1,b2; b1=true; b2=false; System.out.println("b1 : "+ b1+" b2 : "+b2); System.out.println("b1 && b2 "+ (b1&&b2) ); System.out.println("b1 || b2 "+ (b1||b2) ); int sayi1,sayi2; sayi1=1; sayi2=2; System.out.println("sayi 1 : "+sayi1); System.out.println("sayi 2 : "+sayi2); b1=(sayi1 > sayi2); System.out.println(sayi1+" > "+sayi2+" "+ b1 ); b1=(sayi1 < sayi2); System.out.println(sayi1+" < "+sayi2+" "+ b1 ); b1=(sayi1 == sayi2); System.out.println(sayi1+" == "+sayi2+" "+ b1 ); b1=(sayi1 >= sayi2); System.out.println(sayi1+" >= "+sayi2+" "+ b1 ); b1=(sayi1 <= sayi2); System.out.println(sayi1+" <= "+sayi2+" "+ b1 ); b1=(sayi1 != sayi2); System.out.println(sayi1+" != "+sayi2+" "+ b1 ); } } Aşağıda bu örnek problemin (Program 1.1.6-1) sonucunu verilmektedir. Satır satır proğramı takip ederek sonucuları kontrol ediniz. b1 : true b2 : false b1 && b2 false b1 || b2 true sayi 1 : 1 sayi 2 : 2 1 > 2 false 1 < 2 true 1 == 2 false 1 >= 2 false 1 <= 2 true 1 != 2 true 1.1.7 JAVA DİLİNDE BİT KOMUTLARI VE İŞLEMLERİ Bit işlemi doğrudan doğruya bitler üzerinde yapılan işlemlerdir. Bit işlemleri genellikle veri trasferi (bilgisayardan bilgisayara veya çeşitli kontrol sistemlerinde) işlemlerinde kullanılır. Javadaki bit işlemleri Tablo 1.4 de verilmiştir. Tablo 1.1.7-1 Java dilindeki bit işlemleri ve anlamları Bit İşlemci & | ^ ~ >> << Anlamı AND ve OR veya XOR Ters bit (NOT) Bir bit sağa kay Bir bit sola kay Bit işleminde ne olduğuna bir örnekle bakalım. int x=7; x=x<<1; bit işleminde x değişkeninin bit yapısı sola doğru bir bit kaydırılmıştır. 7 değerinin bit eşdeğeri 00000000000000000000000000000111 şeklindedir. Sola doğru bir bit kaydığımızda 00000000000000000000000000001110 bit yapısı oluşacaktır. Bu yapının int karşılığı 14 dür. int x=7; x=x<<1; x=~x; işlemi 11111111111111111111111111110001 değerini verecektir. Küçük bir programda bit işlemlerinin bazılarını kullanalım. Program 1.1.7-1 : Java bit işlemleri örnek problemi bitislemi.java class bitislemi{ public static void main (String args[]) { int x=7; System.out.println("x = "+x); x= x<<1; System.out.println("x = "+x); x= x<<1; System.out.println("x = "+x); x= x>>2; System.out.println("x = "+x); x= ~x; System.out.println("x = "+x); } } bu programın sonucu x=7 x = 14 x = 28 x=7 x = -8 şeklinde olacaktır. Çıkan sonuçların bit eşdeğerlerini kontrol ediniz. Bit işlemleri aslında bilgisayarın ve digital elektronik devrelerin temel işlemleridir. Bu işlemler assembler dillerinin de temel işlemlerini teşkil ederler. 1.1.8 JAVA DİLİNİN TEMEL KOMUTLARI Bilgisayar dillerinde değişkenlerden ve işlemlerden sonraki en temel yapı temel dil komutlarıdır. Şimdi bu komut yapılarına tek tek göz atalım. 1.1.8.1 İF – ELSE İF - ELSE MANTIKSAL KARŞILAŞTIRMA YAPISI Bu yapı programda karar mekanizmalarını oluşturmak için kullanılır. Temel yapısı : if( boolean değişken yada sabit) { boolean degişken veya sabitin değeri true olduğunda yapılan işlemler} else if( boolean değişken yada sabit) { boolean degişken veya sabitin değeri true olduğunda yapılan işlemler} else { yukardaki boolean değişken vede sabitlerin hiçbiri true değerine eşit değilse yapılacak olan işlemler} else if yapısı probleme göre istenilen sayıda olabilir, if ve else yapısı sadece bir tane olarak kullanılır. if yapısı java ve C dillerinde kısaltılmış bir şekilde de yazılabilir bu form değişken adı = ( boolean değişken yada sabit ? boolean true ise değişken değeri : boolean false ise değişken değeri ); şeklindedir. Küçük bir örnek programla if-elseif-else yapısının çalışmasını inceleyebiliriz. Program 1.1.8.1-1 : if yapısını gösteren ifyapisi.java programı import java.io.*; // giris çikis class ifyapisi { public static void main (String args[]) throws IOException { double not; // Text cin=new Text(); not=cin.readDouble(); if( not ==90) { System.out.println("A"); } else if(not ==75) { System.out.println("B"); } else if(not ==60) { System.out.println("C"); } else if(not ==50) { System.out.println("D"); } else if(not ==40) { System.out.println("E"); } else { System.out.println("F"); } } } İf yapısı programının çıktısı : Ogrencinin notunu giriniz : 53 D Bu programda öğrenci notu ekrandan girdi olarak girilmektedir. Bunu sağlayabilmek için önce Text cin=new Text(); komutunu kullanarak ekrandan girdi girme kanalı olan cin değişkeni tanımlanmakta, sonra bu kanal üzerinden not=cin.readDouble(); deyimiyle ekrandan girilen değer not değişkenine aktarılmaktadır. Okuma işlemi normalde daha detaylı tanımlar gerektirir. Bu tanımlar şimdilik Text sınıfının arkasında verilmiştir. Text sınıfının detaylı Yeri geldiğinde okuma işlemi daha detaylı olarak incelenecektir. not değişkeni bir ekran girdisi olduğundan girilen nota göre bilgisayar A,B,C,D,E veya F notlarından birini verecektir. Bu ilk programımızda if ve else if parantezlerinin içinde direk olarak boolean sabit kullanılmıştır. Parantez içi boolean değişken de olabilir. Aynı program kodunu java swing kütüphanesi JoptionPane alt sınıfını kullanarak yazacak olursak : Program 1.1.8.1-2: if yapısını gösteren ifyapisiSW.java programı import javax.swing.JOptionPane; class ifyapisiSW { public static void main (String args[]) { double not; //JOptionPane her zaman String turu çıktı verir. Bunu Double.parseDouble() //kullanarak double değerine çevirebiliriz. not=Double.parseDouble(JOptionPane.showInputDialog("Ogrencinin notunu giriniz (0-100) : ")); if( not >= 90) { JOptionPane.showMessageDialog(null,"A","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} else if(not >=75) { JOptionPane.showMessageDialog(null,"B","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} else if(not >=60) { JOptionPane.showMessageDialog(null,"C","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} else if(not >=50) { JOptionPane.showMessageDialog(null,"D","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} else if(not >=40) { JOptionPane.showMessageDialog(null,"E","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} else { JOptionPane.showMessageDialog(null,"F","Ogrenci notu",JOptionPane.PLAIN_MESSAGE);} System.exit(0); } } Program çıktısı : Aşağıdaki program parçasında a degiskeninin degeri : true yazısını yazdıracaktır. boolean a=true; if(a) {System.out.println("a degişkeninin değeri : true");} else {System.out.println("a degişkeninin değeri : false");} if - elseif - else yapıları iç içe girmiş yapılar veya basit mantıkların && (ve), || (veya) işlemleriyle bağlanmasıyla daha kompleks mantıksal şartlar oluşturulabilir. İç içe geçmiş if yapısı kullanılarak mantıksal kontrol prosesi alttaki program parçasında açıklanmıştır : İç içe geçmiş if yapısı double x = 7.0; double y = 3.0; if(x > 5) { if(y > 5) { System.out.println("x ve y besten buyuktur.");} elseif(y==5) { System.out.println("x besten buyuktur ve y bese esittir.");} else { System.out.println("x besten buyuktur ve y besten kucuktur.");} } else { if(y > 5) { System.out.println("x besten kucuktur veya esittir ve y 5 den buyuktur.");} elseif(y==5) { System.out.println("x besten kucuktur veya esittir ve y bese esittir.");} else { System.out.println("x besten kucuktur veya esıttır ve y besten kucuktur."); } } Burada ise && terimiyle bağlanmış bir program parçacığı görüyorsunuz. && (ve) deyimiyle bağlanmış if yapısı double x = 7.0; double y = 3.0; if(x 5 && y 5) { System.out.println("x ve y besten buyuktur.");} else if(x>5 && y==5) { System.out.println("x besten buyuktur ve y bese esittir.");} else if(x>5 && y<5) { System.out.println("x besten buyuktur ve y besten kucuktur.");} else if(x<5 && y>5) { System.out.println("x besten kucuktur ve y 5 den buyuktur.");} else if(x < 5 && y==5) { System.out.println("x besten kucuktur ve y bese esittir.");} } } Yukarıdaki program parçacıklarından da görebildiğimiz gibi her türlü kompleks mantığı bilgisayar programlarına aktarmamız mümkündür. If - else if - else yapıları programlamada en çok kullanılan mantık aktarımı yapı taşlarıdır. 1.1.8.2 WHİLE TEKRARLAMA YAPISI While en çok kullanılan tekrarlama yapılarından biridir. ( ) içindeki boolean terim true (doğru) olduğu sürece yeniden işlemi döndürür. Eğer programda boolean işlemini sonuçlandıracak bir ifade yoksa sonsuza dek veya program başka bir yöntemle durdurulana dek devam eder. while( boolean değişken yada sabit) { boolean degişken veya sabitin değeri true olduğunda yapılan işlemler} örneğin : while(true) { System.out.println("Bu yazı surekli olarak tekrar edecektir");} yapısı sonsuz bir döngü oluşturur. Aşağıdaki program yapısı ise sayı 1000 den büyük veya 1000 e eşit olduğunda durur. Program 1.1.8.2-1 while döngüsü örneği whileyapisi.java programı import java.io.*; //java girdi cikti sınıfını cagir class whileyapisi { public static void main(String args[]) { int sayi=2; while(sayi<=1000) { sayi*=2; System.out.println("sayı = "+sayi); } } } While tekrarlama yapısı bazen biraz daha farklı bir yapı içinde verilebilir. Aşağıda gösterilen bu yeni yapı, bir önceki while yapısına göre daha ender kullanılar.do..while yapısının while yapısından temel farkı, döngünün içine en az bir kere girilme zorunluğunun olmasıdır. do { boolean degişken veya sabitin değeri true olduğunda yapılan işlemler. Bu paranteze boolean değerinin ne olduğuna bakılmaksızın en az bir kere girilir } while( boolean değişken yada sabit) Program 1.1.8.2-2 de dowhile döngüsünün kullanıldığı dowhileSW.java programı görülmektedir Aynı programı Swing JoptionPane çıktısı kullanarak yazalım : Program 1.1.8.2-2 : do..while döngüsü örneği dowhileSW.java programı import javax.swing.*; public class dowhileSW { public static void main(String args[]) { int saydirici=1; String s=""; do { s=s+Integer.toString(saydirici)+" "; } while(++saydirici <= 10); JOptionPane.showMessageDialog(null,s,"do-while yapısı",JOptionPane.PLAIN_MESSAGE); } } Program çıktısı : Şekil 1.1.8.2-2 dowhileSW.class dosyasının JoptionPane.showMassageDialog metodu kullanarak görülmesi 1.1.8.3 FOR TEKRARLAMA YAPISI For tekrarlama yapısı genellikle sayıları belli bir düzen içinde arttırmak için kullanılır. Genel yapısı aşağıda gösterilmiştir.programlamadaki sayı saydırmaya dönük uygulamalarda en fazla kullanılan yapıdır. for tekrarlama yapısı for(baslangıç değerleri ; boolean değişken veya sabiti ; tekrarlama değişkeni artışı) { boolean değişken veya sabiti true (doğru) olduğunda yapılan işlemler } Program 1.23 de 1 den yüze kadar sayıların toplamını hesaplayan bir konsol programı verilmiştir. Program 1.1.8.3-1 : birden 100 e kadar sayıların toplamını hesaplayan foryapisi.java konsol programı import java.io.*; class foryapisi { public static void main(String args[]) { int toplam=0; for(int sayi=1;sayi<=100;sayi++) { toplam+=sayi;} System.out.println("1 den 100 e sayilarin toplami : "+toplam); } } foryapisi.java derlendiğinde 1 den 100 e sayilarin toplami : 5050 sonucunu verecektir. Program 1.1.8.3.2 de yine for döngüsünün uygulaması konusunda bir örnek problem verilmiştir. Programı nasıl çalıştığını inceleyiniz. Bu programda yıllık bileşik faizler on yıl için hesaplanmaktadır. İlk iki faiz oranını elde hesaplayınız. Programı çalıştırarak sonuçları kontrol ediniz. Program sonuçları Şekil 1.1.8.3-2 de listelenmiştir. Program 1.1.8.3-2: faizOraniSW.java applet programı import javax.swing.JOptionPane; //JOptionPane sınıfını çağır public class faizOraniSW { public static void main( String args[]) { double ilkYatanPara=100e6;//yuz milyon lira double paraMiktari=ilkYatanPara; double faizOrani=0.85;//yuzde seksenbes int y=40; String s="Yil Para Miktari\n"; for(int yil=1; yil<=10 ; yil++) { paraMiktari*=(1.0+faizOrani); s=s+yil+" "+paraMiktari+"\n"; } // for döngüsünün sonu JOptionPane.showMessageDialog(null,s,"faiz oranı",JOptionPane.PLAIN_MESSAGE); } // main metodunun sonu } // faizOraniSW sinifinin sonu Şekil 1.1.8.3-2 faizOraniSW.java program çıktısının swing JoptionPane. showMessageDialog metodu kullanılarak görüntülenmesi 1.1.8.4 SWİTCH - CASE YAPISI Switch case yapısı çeşitli alternatifler içeren bir tablodan seçme yapma türü işlerde kullanılır. Temel yapı: switch - case yapısı: switch( degişken ismi) { case değişkenin alacağı deger : bu değer oluştuğunda yapılacak işlemler break; // bu deyim döngünün bitmesini sağlar. case değişkenin alacağı başka bir değer : bu değer oluştuğunda yapılacak işlemler break; // bu deyim döngünün bitmesini sağlar. ................ default : eğer yukarıdaki case kutularından hiçbirine girilemediyse yapılacak işlemler break; } şeklindedir. Switch yapısından sonra değişken ismi gelir. Her case deyiminden sonra ise değişkenin alacağı yeni bir değer alternatifi verilir. Eğer switch yapısında verilen alternatif hiçbir case bloğunda tanımlanmamışsa default bloğuna gider ve buradaki işlemler gerçekleştirilir. Case ve default blokları break deyimi ile sona erer. break deyimi herhangi bir döngü yapısından döngü bitmeden çıkma amacıyla da kullanılabilir. break yapısıyla döngünün dışına çıkma amacıyla diğer döngü yapılarında da kullanılabilir(if, for while gibi), fakat bu tür break kullanılarak döngü dışına çıkılması yapısal programlama teknikleri tarafından tavsiye edilmez. Bilgisayar listelerini yapısallıktan uzaklaştırıp, spagetti programlama dediğimiz karmakarışık programlamaya yol açabilir. Döngü yapılarından standart kontrolları yoluyla çıkılması tavsiye edilir. int i=0; while(true) { i++; if(i==3) break; System.out.println("Bu yazı uc kere tekrar edecektir");} Program 1.1.82.4-1 de verilen switchSWA.java programı switch deyiminin nasıl kullanıldığını göstemektedir. Programcılara göre kullanılma sıklığı değişebildiği varsayılsa bile, switch yapısı şu ana kadar bahsedilen yapılar içinde en az kulanılanıdır. Program 1.1.8.4-1 switch - case yapısı örneği switch.java swing applet programı . Bu program öğrenci notlarını appletden girer ve her nottan kaç tane girildiğini listeler. import javax.swing.*; // java swing JApplet sinifini cagir import java.awt.*; // java pencere awt sinifini cagir import java.awt.event.*; // java pencereyi dinleme sinifini cagir public class switch_case { public static void main(String arg[]) { int Asayisi=0,Bsayisi=0,Csayisi=0,Dsayisi=0,Esayisi=0,Fsayisi=0; String not1=""; char not; String cikti=""; boolean b1=true; while(b1) { not1=JOptionPane.showInputDialog("Ogrencinin notunu giriniz (A,B,C,D,E,F çıkış için başka bir karekter basınız : "); not=not1.charAt(0); switch(not) { case 'A': case 'a': ++Asayisi; break; case 'B': case 'b': ++Bsayisi; break; case 'C': case 'c': ++Csayisi; break; case 'D': case 'd': ++Dsayisi; break; case 'E': case 'e': ++Esayisi; break; case 'F': case 'f': ++Fsayisi; break; default: b1=false; break; } // switch deyiminin sonu } //while deyiminin sonu cikti=cikti+"Her harf notun toplami : \n"; cikti=cikti+"A : "+Asayisi+"\n"; cikti=cikti+"B : "+Bsayisi+"\n"; cikti=cikti+"C : "+Csayisi+"\n"; cikti=cikti+"D : "+Dsayisi+"\n"; cikti=cikti+"E : "+Esayisi+"\n"; cikti=cikti+"F : "+Fsayisi+"\n"; JOptionPane.showMessageDialog(null,cikti,"switch-case deyimi",JOptionPane.PLAIN_MESSAGE); } } Şekil 1.1.8.4-1 switch - case yapısı örneği switch program sonuçlari 1.1.9 ARİTMETİK İŞLEMLERDE DEĞİŞKEN TÜRÜ DEĞİŞTİRME (CASTİNG) OPERASYONU C veya C++ dilinde bir değişken türünden değişkeni diğer değişken türünden değişkene direk olarak atama mümkündür. örneğin char a='x'; int b=a; işlemi c++ da geçerli bir işlemdir. Javada ise bu işlem hata verir. fakat aynı islem char a='x'; int b=(int)a; şeklinde gerçekleştirilebilir (int) deyimi orijinal olarak char olarak tanımlanan a değişkeninin değerini int türüne dönüştürmüş sonra da in türünden b değişkenine yüklemiştir. Bu dönüşüm işlemlerini tüm değişken türleri için kullanabiliriz, yalnız burada programcının çok dikkatli olması ve değişken türlerini, ve sınırlarını iyi tanıması gerekmektedir. Değişken türlerini değiştirirken bazı bilgiler kaybolacağı gibi hiç istemediğimiz bir sonuca ulaşma olasılığımız da mevcuttur. 1.1.10 SAYI DEĞİL VE SONSUZ SONUÇLARI Java gerçek sayı değişken türleri sayı değil (NaN) ve artı sonsuz (Pozitif infinity) ve eksi sonsuz(negative infinity) sonuçları verebilirler. sayı değil (NaN) sonucu sıfır bölü sıfır, sıfır çarpı sonsuz gibi işlemlerden çıkar. sonsuz işlemi ise sayi bölü sıfır gibi işlemlerden çıkar. Bu işlemler sadece float ve double değişkenleri için tanımlıdır. Tamsayı değişkenler sıfıra bölünemezler. 1.2 : METODLAR VE OBJECT KULLANIMI 1.2.1 JAVA API KÜTÜPHANESİ Gerçek problemlerin boyutları genelde birinci bölümde gördüğümüz problemlere göre çok daha büyüktür. Bu yüzden genelde programlar küçük parçalara bölünerek daha kolaylıkla anlaşılır şekle getirilmeye çalışılır. Buna böl parçala ve yönet tekniği de diyebiliriz. Bu küçük parçalara javada metot adi verilir. Java programları yeni metotları içeren java sınıflarıyla(class) java sınıf kütüphanelerinde yer alan metotların birleşmesinden oluşur. Java kütüphanesinde matematik işlemlerinden grafik, ses, giriş çıkış işlemleri, yanlış kontrolu gibi birçok konularda yazılmış metotlar mevcuttur. Java metotlar kolleksiyonu Java API Adını alir. Java sınıf kütüphanesi adi da verilir. Şüphesiz bunun dışında java metodlar kolleksiyonlarının olduğu çeşitli diğer kütüphaneler de mevcutur. Java API kütüphanelerinin bazıları şunlardır : java.applet : (java applet paketi) Java applet paketi applet grafik ortamını sağlar (grafik programlarının internet browser programları aracılığıyla görüntülenebilmesinin temellerini oluşturur.). Bu sınıfa paralel olarak Java 1.2 de grafik applet arayüz birimi javax.swing.JApplet geliştirilmiştir. java.awt : (java window araçları paketi) Bu sınıf grafik arayüzleri tanımlamaya yara. Java 1.2 de paralel sınıf javax.swing geliştirilmiştir. java.awt.color: renk tanımlar java.awt.datatransfer: bilgisayarın geçic hafızasıyla java programı arasında bilgi akışını sağlar. java.awt.dnd : ekle ve çalıştır türü programlar arasında geçiş yapabilen paketlerden oluşur. java.awt.event : grafik programlama ortamıyla kullanıcı arasındakiilişkiyi sağlar. Örneğin grafik penceresinde return tuşuna basıldığında veya farenin düğmesine basıldığında ne yapılması gerektiğini belirler. Java.awt ve javax.swing sınıflarının ikisiyle de kullanılır. java.awt.font : yazı fontları ve bu fontların değiştirilmesiyle ilgili programalrı içerir. java.awt.geom : iki boyutlu geometrik şekilleri tanımlar. java.awt.im : java programlarına çince, japonca ve kore dilinde girdi girebilmek için tanımlanmış bir arabirimdir. java.awt.image : java görüntü işleme paketi java.awt.image.renderable : bir program içindeki resimleri depolama ve değiştirme için gerekli olan programları içerir. java.awt.print : java programlarından yazıcılara yazım için bilgi aktaran paketleri içerir. java.beans : java fasulyeleri paketi, bu paketin detayları için ilgili bölümü inceleyiniz. java.beans.beancontext : tekrar kullanılabilen ve otomatik olarak birleştirilebilen program parçacıkları tanımlar. java.io : dosya ve ekrandan girdi ve çıktı yapmak için gerekli program paketleri tanımlanır. java.lang : bu paket birçok temel program içerir Bunlardan biri olan Math paketi aşağıda açıklanacaktır. Lang paketi java programlarınca otomatik olarak kullanılır. İmport deyimiyle iave edilmesi gerekmez. java.lang.ref : bu paket java programıyla garbage collector (çöp toplayıcısı) denilen otomatik kullanılmayan hafıza temizleme programıyla ilişkiyi sağlar. java.lang.reflect : bu paketteki programlar java programının çağrıldığında içinde bulunan değişken ve metotları dinamik olarak tespit etmesinive kullanma izni almasını sağlar. java.math : bu sınıf değişebilir hassasiyette arimetik işlemler yapmak için gereken tanımları ve sınıfları içerir. java.net : ağ işlemlerinde kullanılan çeşitli paketleri tanımlar java.rmi , java.rmi.activation, java.rmi.dgc, java.rmi.registry, java.rmi.server: programların ve metodların uzaktan çalışabilmeleri için gerekli tanımlamaları içerir. java.security, java.security.acl, java.security.cert, java.security.interfaces, java.security.spec : güvenlikle ilgili programlar demetini içerir. java.sql : database programıyla java programlarını bağlantısını sağlar. java.text : sayı karekter ve string tarih gibi işlemlerle ilgili programlar demeti içerir. Örneğin çok dilli programlar yazmayı sağlayan internalisation paketi bu paket içinde yer alır. java.util : bu sınıf tarih ve zamanla ilgili fonksiyonlar, tesadüfi sayı üreticileri, StringTokenizer gibi programları barındırır. java.util.jar bu paket java programlarını paketlemeye yarıyan jar yapılarını tanımlamada gerekli olan programları tanımlar. java.util.zip : bu paket programları sıkıştırmaya yarayan programları tanımlar. Java.accessibility : bu paket özürlülerin kullanabileceği ara üniteler tanımlar. Ekran okuyucular ve ekran büyüteçleri gibi. javax.swing : grafik kullanıcı arabirimi tanımlar. Bu sınıftakitanımlar aracılığıyla ekrandan grafik ortamında veri transferi kolaylıkla yapılabilir. javax.swing.borders : grafik arabirimi sınır yaratımında çeşitli sınır şekilleri yaratmakta kullanılır. Javax.swing.colorchooser : renk seçimi için tanımlanmış grafik kullanıcı arabirimini tanımlar. Java API dosyalarındaki metotlarin sadece isimlerinin listesi yaklaşık 200 sayfa boyutunda bir liste tuttuğundan burada sadece yeri geldiğine programları kullanırken örneklerde gerekli API isimlerini göreceğiz. Şu ana kadar kullandığımız java programlarında java.applet, java.awt, java.io javax.swing, javax.swing.JApplet ve javax.awt.event API paketlerini kullandık. Java.applet paketi appletleri oluşturma, appletlere giriş çıkısları ve dosyaları applet içerisinde çalıştırmayı sağlar. java.awt pencere(window) ortamındaki tüm programlama sınıflarını ve metotlarını içerir. Java swing (javax.swing) paketi yine aynı tür pencere(window) ortamında programlama için gerekli girdi çıktı grafik ortamlarını içerir. awt grafik ortamına göre daha zengin ve gelişmiş bir kolleksiyondur. Bu metotları ilerideki bölümlerde daha detaylı inceleyeceğiz. java.io paketi javaya dışarıdan(dosya,ekran v.b) bilgi giriş çıkışını ayarlar. Java metodlarının tamamının listesini (İngilizce olarak) Java doküman kütüphanesindeki api alt gurubunda bulabilirsiniz. Java döküman kütühanesi http://java.sun.com adresinden çekilebilir. Java dilinde en çok kullanılan API sınıflarından birisi Math sınıfıdır. Bu sınıf(class) java.lang paketinde yer alır. Java.lang paketi java programı açılırken otomatik olarak çağırılır. Bütün diğer paketler import deyimi kullanılarak programa ilave edilirler. Math sınıfında tanımlanan metotların bazıları Şekil 2.1 de listelenmiştir. Tablodaki x veya y değişkenleri double değişken türündendir. Math sınıfında(class) iki tane de sabit tanımlanmıştır. Bu sabitlerden birisi Math.PI 3.14159265358979323846 (pi, ) sayısına eşittir. Diğeri Math.E 2.7182818284590452354 (e) sayısına eşittir. Tablo 2.1 Math sınıfında(class) çalışan metotlardan bazıları Metot Tanım abs(x) x değişekeninin mutlak değeri türkçesi : Mutlak ceil(x) x degişkenini bir üst tamsayıya dönüştürür (türkçesi : tavan) floor(x) x değişkenini bir alt tamsayıya dönüştürür. (türkçesi : taban) cos(x) x in trigonometrik cosünisü (x radyan cinsinden tanımlanmıştır.) sin(x) x in trigonometrik sinüsü (x radyan cinsinden tanımlanmıştır.) tan(x) x in trigonometrik tanjantı (x radyan cinsinden tanımlanmıştır.) acos(x) x in trigonometrik cosünisünün tersi (sonuç radyan cinsindendir) asin(x) x in trigonometrik sinüsü (x radyan cinsinden tanımlanmıştır.) atan(x) x in trigonometrik tanjantı (x radyan cinsinden atan2(x,y) tanımlanmıştır.) x,y noktanın x,ykoordinatlarıdır exp(x) e(2.7182818284590452354) nin x inci kuvveti log(x) e tabanına göre logaritma pow(x,y) x in y inci kuvveti max(x,y) x ve y nin büyük olanı min(x,y) x ve y nin küçük olanı random() Raslantısal sayı (0 ile 1 arasinda) Örnek Math.abs(9.2) = 9.2 Math.abs(-9.2) = 9.2 Math.ceil(9.2) = 10 Math.ceil(-9.8) = -9 Math.floor(9.2) = 9 Math.floor(-9.8) = -10 Math.cos(1.0)=0.54030230568 Math.sin(1.0)=0.8414709840709 Math.tan(1.0)=1.557040724655 Math.acos(0.54030230568)=1.0 Math.asin(0.8414709840709)=1.0 4.0*Math.atan(1.0)=3.14159265359 4.0*Math.atan2(1.0,1.0)=3.14159265359 Math.exp(1.0) =2.718281828459 Math.exp(2.0) =7.389056098931 Math.log(2.718281828459)=1.0 Math.pow(3,2)=9.0 Math.max(2.3,12.7)=12.7 Math.min(2.3,12.7)=2.3 Math.random() = 0 ila bir arasında her sayı çıkabilir Program 1.2.1-1 de Math sınıfındaki metotları kullanan Matematik1 sınıfını görüyoruz. Program 1.2.1-1 Math sınıfında(class) çalışan metotlardan bazılarını gösteren Matematik1.java programı import javax.swing.JOptionPane; // giriş çıkı class matematik1SW { public static void main (String args[]) { double x,y; String s=""; x=Double.parseDouble(JOptionPane.showInputDialog ("Bir gerçek sayı giriniz : ")); y=Double.parseDouble(JOptionPane.showInputDialog ("İkinci bir gerçek sayı giriniz : ")); s +="Statik Matematik kütüphanesi Math de \n"; s+="en cok kullanilan metodlar :\n" ; // Math.abs(3.2)=3.2 Math.abs(-3.2)=3.2 s+="Math.abs("+x+") = "+Math.abs(x)+"\n"; // Math.ceil(9.2)=10 Math.ceil(-9.8)=-9 // Math.ceil(x) x den buyuk en kucuk tam sayya yuvarlar s+="Math.ceil("+x+") = "+Math.ceil(x)+"\n"; // Math.floor(9.2)=9 Math.floor(-9.8)=-10 // Math.floor(x) x den kucuk en buyuk tam sayya yuvarlar s+="Math.floor("+x+") = "+Math.floor(x)+"\n"; // Trigonometrik fonksiyonlar sin(x) cos(x) tan(x) x:radyan // Math.PI pi sayisi s += "Math.PI = "+Math.PI+"\n"; s += "Math.sin("+x+") = "+Math.cos(x)+"\n"; s += "Math.cos("+x+") = "+Math.sin(x)+"\n"; s += "Math.tan("+x+") = "+Math.tan(x)+"\n"; //Trigonometrik fonksiyonlar asin(y) acos(y) atan(y) // asin,acos,atan : radyan s += "Math.asin("+y+") = "+Math.acos(y)+"\n"; s += "Math.acos("+y+") = "+Math.asin(y)+"\n"; s += "Math.atan("+y+") = "+Math.atan(y)+"\n"; // Math.log(x) dogal logaritma (e) tabanna gore // Math.E e sayisi = 2.718281828... s += "Math.E = "+Math.E+"\n"; s += "Math.log("+x+") = "+Math.log(x)+"\n"; // Math.pow(x,y) x in y inci kuvveti s += "Math.pow("+x+","+y+" ) = "+Math.pow(x,y)+"\n"; // Math.exp(x) Math.E=e=2.718281828.. in x inci kuvveti s += "Math.exp("+x+" ) = "+Math.exp(x)+"\n"; // Math.sqrt(x) x in kare koku s += "Math.sqrt("+x+" ) = "+Math.sqrt(x)+"\n"; // Maximum - minimum functions // Math.max(x,y) Math.min(x,y) s += "Math.max("+x+","+y+" ) = "+Math.max(x,y)+"\n"; s += "Math.min("+x+","+y+" ) = "+Math.min(x,y)+"\n"; JOptionPane.showMessageDialog(null,s, "Math kütüphanesi işlemleri",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Şekil 1.2.1-1 matematik1SW.java programının çıktısı 1.2.2 METOTLAR Metotlar java programlarının ana parçalarıdır. Metotlar sınıfların(class) içinde yer alan küçük program parçacıklarıdır. Metotların çoğunda değişken parametreler metotlar ve sınıflar arasında iletişimi sağlarlar. Ayrıca her metotun kendine özgü değişkenleri de vardır. Metot yapısının ana sebebi programları modüler hale getirmektir. Aynı zamanda aynı program parçacığının tekrarlanmasını önlemeyi de sağlar. Her metot çağrıldığı proğram parçacığına belli bir değişkeni aktarabilir. Metotların tanımlarında aktardıkları değişken türü tanımlanır. Eğer metot hiçbir değişken aktarmıyorsa void sözcüğüyle tanımlanır. Metotların genel tanımı aşağıdaki gibidir. Parantez içindeki terimler kullanılmıyabilir. Genel Metot tanımı (public) (static) sınıf değişken türü sınıf ismi( sınıf değişken girdi listesi) { sınıf içinde geçerli degişken tanımları Metotun ana gövdesi return metot çıktı değişkeni } Örnek olarak aşağıdaki metotu verebiliriz : public static double metotornegi(int x,double y) { double z = 3.5; double f ; f = z*x*x+y; return f; } Bu metotdaki x ve y gerçek (double) değişkenleri metotun girdi değişkenleridir. z ve f değişkenleri metotun yerel değişkenleridir ve bu metot dışında tanımları yoktur. Metot f değişkeninin değerini çıktı olarak metotun dışina aktarmaktadır. Eğer yukarıdaki metot aynı sınıfın içindeki başka bir metotda veya main metotunda aşağıdaki gibi bir örnekte kullanılırsa, double z = 2.5; double r ; int i = 3; r = metotornegi(i,z); System.out.println(“r = “+r); r = 34 sonucuna ulaşılır. Şimdi aynı metotun statik metot olarak bir appletin içinde kullanılmasını görelim. Program 1.2.2-1 : metot1.java programında kare statik metotunun kullanılması import java.io.*; public class metod1 { // sayinin karesi static metodu public static double kare(double x) { return x*x; } public static void main(String[] args) throws IOException { double sayi; DataInputStream cin=new DataInputStream(System.in); System.out.println("Bir tam sayi giriniz : "); sayi=Text.readDouble(cin); System.out.println("girilen sayinin karesi : "+kare(sayi)); } } Program 1.2..2-2 : metot2.java programında kare metotunun kullanılması import javax.swing.*; public class metod2 { // sayinin karesi metodu // bu metodda static kelimesi kullanilmiyor public double kare(double x) { return x*x; } public static void main(String[] args) { double sayi; metod2 b=new metod2(); sayi=Double.parseDouble(JOptionPane.showInputDialog("bir tam sayı giriniz:")); String s="kare metodu çıktısı : "; String s1="girilen sayının karesi : "+b.kare(sayi); JOptionPane.showMessageDialog(null,s1,s,JOptionPane.PLAIN_MESSAGE); } } Şekil 1.2.2-1 metot2.java programında kare metotunun kullanılması Şekil 1.2.2-1 de çıktısı verilen public double kare(double x) metotu, public static void main(String[] args) metotundaki String s1="girilen sayının karesi : "+b.kare(sayi); JOptionPane.showMessageDialog(null,s1,s,JOptionPane.PLAIN_MESSAGE); işleminde çağırılmıştır. Bilgisayar kare(sayi) ifadesini gördüğünde metotun içine gider, orada tanımlanan tüm işlemleri yaptıktan sonra return kelimesinin karşısındaki işlemleri çağırıldığı yere geri iletir. Metot1 java programında çağırılan kare(sayi) metotunda sadece sayının kendisiyle çarpımı return kelimesinin karşısına yazıldığından, kare(sayı) ifadesi sayı*sayı ifadesiyle eşdeğerdir. Burada kare metotundandaki değişken adının sayı değil x olarak verildiğini de burada not edelim. Sayı değişkeni metotun girişinde x degişkenine yüklenir. Gerekli işlemler metotda yapıldıktan sonra sadece metotun sonuçları return deyimiyle metodun değişken türü olarak (bu metod için double ) geri döner. 1.2.3 NESNE (OBJECT) TANIMI VE METOTLARDA KULLANIMI Birinci bölümde temel değişken türlerini (double,int,boolean v.b.) nasıl tanımladığımızı görmüştük. Nesne tipi programlamanın en önemli özelliği kendi değişken türlerimizi yaratabilmemizdir. İlerideki bölümlerde kendi değişken türlerimizi sınıf (class) yapısını kullanarak nasıl yaratacağımızı daha detaylı olarak inceleyeceğiz. Bu bölümde nesnelerin program içindeki tanımlanmasına göz atalım. Daha önce tanımladığımız bazı applet programlarında nesne tanımları zaten geçmişti. Örneğin daha önceki programlarımızda bilgi okutmak için kullandığımız Text cin=new Text(); Terimi Text sınıfından(class) cin nesnesini tanımlar. Nesne(object) tanımı yaparken aynı metotlarda olduğu gibi değişken veya nesneleri girdi olarak tanımlamamız mümkündür. Diğer bir örnek olarak yine daha önceki örnek problemlerde kullandığımız Label sınıfından(class) kutubasligi nesnesinin tanımını ve TextField sınıfından(class) kutugirdisi nesnesini gösterebiliriz. Label kutubasligi; //Label sinifi degiskeni (nesnesi) kutubasligi kutubasligi=new Label("Ogrencinin notunu giriniz (A B C.. : "); TextField kutugirdisi;//Textfield sinifi degiskeni (nesnesi) kutugirdisi kutugirdisi=new TextField(5); Bu örneklerde de görüldüğü gibi Nesne tanımı şu şekilde yapılmaktadır: Sınıf (class) isminesne(object) ismi; nesne(object) ismi = new Sınıf (class) ismi(değişken veya nesne girdi listesi) Nesne tanımını daha iyi anlamak için metot2 sınıfını yazdığımız programı biraz değiştirerek metot3 ve metot3a sınıflarını olusturalım ve kare metotumuzu metot3a sınıfına yerlestirelim. Program 1.2.3-1 : metot3a.java programında kare metotunun tanımlanması public class metod3a { // sayının karesi dinamik metodu // bu metodda static sözcugu kullanılmıyor public double kare(double x) { return x*x; }} Program 1.2.3-2 : metot3.java programında kare metotunun kullanılması import javax.swing.*; public class metod3 { public static void main(String[] args) { double sayi; metod3a b=new metod3a(); sayi=Double.parseDouble(JOptionPane.showInputDialog("bir gerçek sayı giriniz:")); String s="kare metodu çıktısı : "; String s1="girilen sayının karesi : "+b.kare(sayi); JOptionPane.showMessageDialog(null,s1,s,JOptionPane.PLAIN_MESSAGE); } } Şekil 1.2.3.1-1 metod3.java programının girdi penceresi Şekil 1.2.3.1-2 metod3.java programının çıktısı metot3.java ve metod3.java programlarında iki tane sınıf(class) yaratılmıştır. İlk sınıf metot3a da kare metotu tanımlanmıştır. İkinci sınıf(class) metot3 de ise metot3a sınıfı b nesnesi tanımlanmış, ve kare metotu b nesnesi üzerinden b.kare(sayi) olarak çağırılmıştır. Bu metot b nesnesi için bilgisayar belleğinde bir yer ayırır. Kare metotunu çağırırken bu yerin adresini kullanır. metot3.java programında kare metotu ayrı bir sınıf(class) ta tanımlandığından yerinin tanımlanması gerekir. Metotlar statik olarak da tanımlanabilirler. Statik olarak tanımlanan metotlar nesne kullanılmadan direk olarak sınıf(class) adları kullanılarak çağırılabilirler. Program 1.2.3.3 : metoto4a.java programında static kare metotunun tanımlanması public class metod4a { // sayının karesi statik metodu // bu metotda static sözcüğü kullanılıyor public static double kare(double x) {return x*x;} } Program 1.2.3.4 : metoto4.java programında static kare metotunun kullanılaması import java.io.*; public class metod4 { public static void main(String[] args) throws IOException { double sayi; BufferedReader cin=new BufferedReader(new InputStreamReader(System.in)); System.out.println("Bir gerçek sayı giriniz : "); sayi=Text.readDouble(cin); System.out.println("girilen sayının karesi : "+metod4a.kare(sayi)); }} Program girdi ve çıktısı : Bir gerçek sayı giriniz :2.25 girilen sayının karesi : 6.25 Görüldüğü gibi metoti4 sınıfında(class) kare metotu metoti4a.kare(sayi) olarak tanımlanmış ve ek bir nesne adresi kullanılmamıştır. static olarak tanımlanan metotların kendi kendine yeterli metotlar olması gerekir. Yani içinde bulunduğu sınıfla veya baska sınıflarla direk olarak veri alışverişi olamaz. Girdileri sadece girdi parantezleri () arasinda verilen değişkenlerdir.dinamik metotlar ise kendi sınıfları ve diğer sınıflarla değişik yollardan bilgi ve değişken aktarımı yapabilirler 1.2.4 METOTLARIN KENDİ KENDİNİ ÇAĞIRMASI (RECURSION) Bazı problemlerin çözümünde bir metotun kendi kendini çağırması yararlı olabilir. Java bir metotun kendi kendini çağırmasına izin verir. Burada dikkatli olunması gereken nokta bu kendi kendine çağırılma döngüsünün sonsuza kadar sürmesinin bir kontrol yapısı kullanılarak engellenmesidir. Kendi kendini çağıran programlarda mutlaka bir döngü çıkış şartı tanımlanmalıdır. Program 1.2.4-1 de faktoriyelSW sınıfı tanımlanmıştır. Program 1.2.4-1 : Metot kullanılmadan (main metotunun içinde) faktoriyel hesaplayan faktoriyeSW.java programı import javax.swing.JOptionPane; class faktoriyelSW { public static void main(String args[]) { int faktoriyel=1; int faktoriyelsayi; faktoriyelsayi=Integer.parseInt(JOptionPane.showInputDialog("Bir tam sayı giriniz : ")); for(int sayi=1;sayi<=faktoriyelsayi;sayi++) { faktoriyel*=sayi;} String s=faktoriyelsayi+" faktoriyel: "+faktoriyel; JOptionPane.showMessageDialog(null,s, "Metod örneği faktoriyelSW.java ", JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Şimdi aynı programın faktoriyel metodu ayrı yazılmış fakat yine for döngüsü kullanan şekline göz atalım. Program 1.2.4-2 : for döngülü faktoriyel metotunu kullarak faktoriyel hesaplayan faktoriyel1SW.java programı (JoptionPane girdi çıktı sistemi kullanarak hesaplıyor) import javax.swing.JOptionPane; class faktoriyel1SW { public static long faktoriyel(int x) { long faktoriyel=1; for(int sayi=1;sayi<=x;sayi++) { faktoriyel*=sayi;} return faktoriyel; } public static void main(String args[]) { int faktoriyelsayi; faktoriyelsayi=Integer.parseInt( JOptionPane.showInputDialog("Bir tam sayı giriniz : ")); String s=faktoriyelsayi+" faktoriyel: "+faktoriyel(faktoriyelsayi); JOptionPane.showMessageDialog(null,s,"Metod örneği faktoriyel1SW.java ",JOptionPane.PLAIN_MESSAGE); System.exit(0); }} Program 1.2.4-3 de faktoriyeli kendi kendini çağıran(recursive) faktoriyel metotunu kullanarak hesaplayalım. Program 1.2.4-3: kendi kendini çağıran (recursive) faktoriyel metotunu kullarak faktoriyel hesaplayan Faktoriyel2SW.java programı (JOPtionPage girdi/çıktı) import javax.swing.JOptionPane; class faktoriyel2SW { public static long faktoriyel(int x) { if( x <= 1 ) return 1; else return x * faktoriyel( x - 1); } public static void main(String args[]) { int faktoriyelsayi; faktoriyelsayi=Integer.parseInt(JOptionPane.showInputDialog("Bir tam sayı giriniz : ")); String s=faktoriyelsayi+" faktoriyel: "+faktoriyel(faktoriyelsayi); JoptionPane.showMessageDialog(null,s, "kendi kendini çağıran (recursive) Metod örneği faktoriyel2SW.java", JoptionPane.PLAIN_MESSAGE); System.exit(0); }} Şekil 1.2.4-1 : kendi kendini çağıran (recursive) faktoriyel metotunu kullarak faktoriyel hesaplayan Faktoriyel2SW.java programının sonuçlarının JOPtionPage çıktısı olarak görülmesi Program 2.1.4-3’ü çalıştırdığımızda faktoriyel hesabı şu şekilde yapılacaktır : 5! = 5 * 4! = 4 * 3! = 3 * 2! = 2 * 1! = 1 faktoriyel metotu 1 e ulastığında tekrar kendisini çağırmıyacağından geriye dogru yaptığı hesapları göndermeye başlıyacaktır. 1 = (2*1!(=1)) = 2 = (3 * 2!(=2)) = 6= (4*3!(=6))=24= (5*4!(24))=120= 5!(=120) sonuç 120 olarak ana programa gönderilecektir. Kendi kendini çağıran metodlar mutlak bir gereksinim olmadıkça tercih edilmez. Bu tür programlamada hem sonsuz döngülerin görülmesi daha güç olabilir, hemde for, while gibi döngüler kullanılarak programlamaya göre programlar daha yavaş çalışır. 1.2.5 AYNI ADLI METOTLARIN BİR ARADA KULLANILMASI (OVERLOADİNG) Java aynı adlı metotların aynı sınıf içerisinda kullanılmasına izin verir. Aynı sınıfta(class) kullanılan metotların girdi değişkenlerinin değişken türlerinin veya değişken sayılarının farklı olması gerekir. Java aynı isimli ve ayni degişken türlü iki metotu birbirinden ayıramaz. Örneğin public double Bmetodu(double Adeğişkeni) Ve public double Bmetodu(double Bdeğişkeni) Veya public int Bmetodu(double Cdeğişkeni) Java tarafindan ayırt edilemez , Fakat public double Cmetodu(double Adeğişkeni) Ve public double Cmetotu(int Bdeğişkeni) veya public double Cmetotu(double Adeğişkeni, double Bdeğişkeni) Java tarafından ayırt edilir ve birlikte aynı sınıfın (class) içinde yer alabilir. Eğer birbirinin tam olarak eşiti metotlar değişik sınıflarda yer alıyorsa bunun herhangi bir sakıncası yoktur. Program 2.11'de ayniisimliikimetot.java programı görülmektedir. Bu programda daha önceki programlarda da kullandığımız kare metotunu int ve double girdi değişkenleriyle iki kere aynı sınıfın içerisinde tanımlayacağız. Program 1.2.5-1 : ayniisimliikimetot.java programı import java.awt.Graphics; import java.applet.Applet; public class ayniisimliikimetot extends Applet { // void tipi paint metotu public void paint( Graphics g) { g.drawString(“ 7 nin karesi = “+kare(7),25,25); g.drawString( 7.5 un karesi = “+kare(7.5),25,40); } // int tipi kare metotu int kare(int x) { return x*x; } // double tipi kare metotu double kare(double x) { return x*x; } } Şekil 1.2.5-1 ayniisimliikimetot.html programıyla ayniisimliikimetot.class ın gösterilmesi Bu programda parantez içerisinde 7 (tamsayı) verildiğinde java tamsayi metotu kare(int x), 7.5(gerçek sayı) verildiğinde gerçeksayi metotu kare(double x) i çağırır. Benzer bir örneği swing applet olarak verelim : Program 1.2.5-2 : H3AL9_2000 programı import java.awt.Container; import javax.swing.*; public class H3AL9_2000 extends JApplet { JTextArea ciktiAlani; public void init() { ciktiAlani=new JTextArea(); Container c=getContentPane(); c.add(ciktiAlani); int x1=7; double x2=7.0; ciktiAlani.setText(" exp ("+x1+") ciktiAlani.append(" exp ("+x2+") x1=5; x2=5.0; ciktiAlani.append(" exp ("+x1+") ciktiAlani.append(" exp ("+x2+") } (int metod girdisi ) = "+exp(x1)+"\n"); (double metod girdisi) = "+exp(x2)+"\n"); (int metod girdisi ) = "+exp(x1)+"\n"); (double metod girdisi) = "+exp(x2)+"\n"); // double girisli exp metodu public double exp(double x) { double faktoriyel=1; double us=1; double exponent=1; for(double i=1;i<=300;i++) { faktoriyel*=i; us*=x; exponent+=us/faktoriyel; } return exponent; } // int girişli exp metodu public double exp(int x) { double exponent=1.0; for(int i=1;i<=x;i++) { exponent*=Math.E; } return exponent; } } Şekil 1.2.5-2 Gerçek ve tamsayı değişkenleri çağıran aynı adlı metodların çağırılması örneği Aynı programı JOptionPane çıktı penceresi kullanarak yazarsak : Program 1.2.5-3 : metodexpornegi programı import javax.swing.*; public class metodexpornegi { public static void main(String arg[]) { int x1=7; double x2=7.0; String s1=" exp ("+x1+") (int metod girdisi ) = "+exp(x1)+"\n"; s1+=" exp ("+x2+") (double metod girdisi) = "+exp(x2)+"\n"; x1=5; x2=5.0; s1+=" exp ("+x1+") (int metod girdisi ) = "+exp(x1)+"\n"; s1+=" exp ("+x2+") (double metod girdisi) = "+exp(x2)+"\n"; String s="exp int ve double metodu çıktısı : "; JOptionPane.showMessageDialog(null,s1,s,JOptionPane.PLAIN_MESSAGE); } // double girisli exp metodu public static double exp(double x) { double faktoriyel=1; double us=1; double exponent=1; for(double i=1;i<=300;i++) { faktoriyel*=i; us*=x; exponent+=us/faktoriyel; } return exponent; } // int girişli exp metodu public static double exp(int x) { double exponent=1.0; for(int i=1;i<=x;i++) { exponent*=Math.E; } return exponent; } } Şekil 1.2.5-3 Gerçek ve tamsayı değişkenleri çağıran aynı adlı metodların çağırılması örneği 1.2.6 METOT (METHOD) VE SINIF(CLASS) DEĞİŞKENLERİ Metotların içinde kullanılan değişkenler sadece metotlara aittir. O metotun dışında tanımları yoktur. Eğer değişkenler metotların dışında sınıf(class) değişkenleri olarak tanımlanırsa metota da aynen aktarılırlar. Sınıf değişkeniyle aynı isimde bir değişken mettotta da tanımlanmışsa bu değişken metotun içinde kullanılan metotun değişkenidir Program 1.2.6-1 : metotvesinifdeg.java programında metot değişkenlerinin sınıfa aktarılması import java.awt.Graphics; import java.applet.Applet; public class metotvesinifdeg extends Applet { //buradaki değişkenler tüm sınıfa aittir double x ; int y ; void metot1( Graphics g) //metota hiç bir değişken girmiyor { x=5.5; y=6; g.drawString("metot1 in ici : x = "+x+" y = "+y,25,40); } public void paint(Graphics g) { x = 2.5; y = 3; g.drawString("metot1 in disi : x = "+x+" y = "+y,25,25); metot1(g); g.drawString("metot1 in disi : x = "+x+" y = "+y,25,55); } } metotvesinifdeg.java programının sonuçları Metot1 in dışı: x=2.5 y=3 Metot1 in içi : x=5.5 y=6 Metot1 in dışı : x=5.5 y=6 Program 1.2.6-2 : metotvesinifdeg1.java programında metot değişkenlerinin sınıfa aktarılması import java.awt.Graphics; import java.applet.Applet; public class metotvesinifdeg1 extends Applet { //buradaki değişkenler tüm sınıfa aittir double x ; int y ; void metot1( Graphics g) //metota hi‡ bir de§iŸken girmiyor { double x; int y; x=5.5; y=6; g.drawString("metot1 in ici : x = "+x+" y = "+y,25,40); } public void paint(Graphics g) { x = 2.5; y = 3; g.drawString("metot1 in disi : x = "+x+" y = "+y,25,25); metot1(g); g.drawString("metot1 in disi : x = "+x+" y = "+y,25,55); }} metotvesinifdeg1.java programının sonuçları Metot1 in disi : x=2.5 y=3 Metot1 in ici : x=5.5 y=6 Metot1 in disi : x=2.5 y=3 Program 1.2.6-1'daki metotvesinifdeg sinıfındaki metot1 metotunun içinde değiştirilen x ve y değişkenleri tüm tüm sınıfa(class) aittir. Bu yüzden paint metotundaki drawString metotu tekrar çağırıldığında x ve y nin değerlerinin değiştiğini görürüz. Program 1.2.6-2 deki metotvesinifdeg1 sınıfındaki metot1 metotunun içinde ise yerel değişkenler x ve y tanımlanmıştır. Bu yüzden metot1 in içindeki x ve y değişkenlerinin değişmesi paint metotundaki drawString metotu tekrar çağırıldığında x ve y nin değerlerinin değişmediği görülür. Nesne tanımı yapıldığında Bilgisayar bu nesne için bir adres yaratır. Yeni adres yarat komutu new komutudur. Pogram 1.2.6-3 : Point1.java programda nokta1 ve nokta2 nesnelerinin yaratılması ve adres paylaşımı. // java kutuphanelerinde tanimli bir sinifin cagirilip // nesne olarak tanimlanmasi ve adres paylasimi import java.io.*; //java girdi cikti sinifini cagir import java.awt.Point; //Point sinifini cagir class Point1 { public static void main(String args[]) { //Point sinifi x,y koordinatli bir nokta tanimlar Point nokta1,nokta2; nokta1=new Point(100,100); nokta2=nokta1; // nokta1 ve nokta2 bilgisayarda ayni // adres kutusunu paylasiyor System.out.println("nokta1 ve nokta2 ayni degerleri tasiyor"); System.out.println("ve aynı bilgisayar adresini paylasiyor"); System.out.println("nokta 1 : "+nokta1.x+" , "+nokta1.y); System.out.println("nokta 2 : "+nokta2.x+" , "+nokta2.y); nokta1.x=200; nokta1.y=200; System.out.println("nokta1 in degeri degistirildi"); System.out.println("nokta 1 : "+nokta1.x+" , "+nokta1.y); System.out.println("nokta 2 : "+nokta2.x+" , "+nokta2.y); // nokta1 ve nokta2 nin degerleri ayni fakat bilgisayarda // degisik adreslerde tanimlanmis nokta1=new Point(100,100); nokta2=new Point(100,100); System.out.println("nokta1 ve nokta2 ayni degerleri tasiyor"); System.out.println("fakat ayni bilgisayar adresini paylasmiyor"); System.out.println("nokta 1 : "+nokta1.x+" , "+nokta1.y); System.out.println("nokta 2 : "+nokta2.x+" , "+nokta2.y); nokta1.x=200; nokta1.y=200; System.out.println("nokta1 in degeri degistirildi"); System.out.println("nokta 1 : "+nokta1.x+" , "+nokta1.y); System.out.println("nokta 2 : "+nokta2.x+" , "+nokta2.y); }} Point1.java da verilen Point nokta1,nokta2; nokta1=new Point(100,100); nokta2=nokta1; tanımında Point sınıfından(class) nokta1 ve nokta2 değişkenleri tanımlanmış, nokta1 değişkeni için yeni(new) adres tanımlanmış, nokta2 değişkenine de aynı adresi (nokta1'in adresini) kullanması soylenmiştir. Bu yüzden programda nokta1 e yeni deger verildiğinde nokta2 nin değeri de aynı değeri alır. daha sonra kullanılan nokta1=new Point(100,100); nokta2=new Point(100,100); deyimi ile ise nokta1 ve nokta2 için iki ayrı adres yaratılmıştır. Bu yüzden nokta1 değiştiğinde nokta2 eski değerinde kalır. Aynı adresin iki değişken tarafından kullanılması ancak gerektiği zaman ve çok dikkat sarfederek yapılmalıdır. Gereksiz yere kullanılmasından kesin olarak kaçınılmalıdır. Program güvenlik ve kontrol problemleri yaratabildiği gibi, istemediğimiz değişken değerlerinin silinmesi sonucunu da verebilir. 1.3 . SINIF (CLASS) VE NESNE KAVRAMI 1.3.0 STANDART KAVRAMLARIN TÜRKÇE KARŞILIKLARI class : sınıf ana nesne kökenli programlama elemanı. object : nesne sınıf (Class) yapıları bilgisayar belleğinde bir işlem için kullanıldığında aldıkları (özel) isim. new : sınıfların kurucu metotunu çağırıp nesne tanımını ve bilgisayar adreslerini oluşturan deyim Method: metot sınıfların içindeki işlevsel program parçacıkları constructor : kurucu metot nesne ilk defa oluşturulurken hangi sınıf değişkenlerinin hangi değerleri alacağını belirleyen metot 1.3.1 SINIF YAPISININ GENEL TANIMI Şu na kadarki bütün programlarımızda sınıf(class) yapısını kullandık. Fakat tam olarak sınıfların ne olduğunu ve neler yapabileceklerini anlatmadık. Sınıf yapısının en onemli ozelliği yeni bir değişken türü tanımlıyor olmasıdır. Şu ana kadar programlarımızı tanımlamak amacıyla çeşitli sınıflar tanımladık. Bu bölümde sınıfların değişken türü olarak tanımlamasını ve kullanmasını göreceğiz. Sınıf (Class) deyince herhangi bir nesnenin genel tanımlanmasını anlıyoruz. Bu sınıflardan değişkenler tanımlandıklarında nesneleri oluştururlar. Örneğin kalem dediğimizde genel bir sınıfı anlatıyoruz. Alinin cebindeki kırmızı kalem ise belirli bir nesnedir. Sınıfın genel tanımı şu şekilde yapılabilir : class sınıfın_ismi { //sınıfa ait değişken listesi değişken_türü değişken_ismi; değişken_türü değişken_ismi; ......... //sınıfa ait metot listesi degişken türü metotadı(metot girdi değişken listesi) { //metotun içindeki hesaplanan işlemler return çıktı_değişkeni; } .............. } Sınıf (class) tanımında metotların (veya değişkenlerin) bulunması şart değildir. Bulundukları takdirde bunlar o sınıfa ait veya sinifin üyesi metotlar olarak düşünülür. İlk sınıf örneği olarak içinde hiçbir metotun yer almadığı bir kutu sınıfı tanımlıyalım. Bir kutuyu üç geometrik boyutu (eni,boyu,yüksekliği) cinsinden tanımlayabiliriz. class Kutu { double en; double boy; double yukseklik; } Üstte bahsettiğimiz gibi sınıf yeni bir değişken türü yaratır. Yukardaki sınıfın yarattığı değişken türünün adı Kutu’dur. Kutu değişkenini başka bir proğramda tanımlarken budeğişken türünden bir nesne yaratılır. Örneğin Kutu kutu1= new Kutu(); kutu1, kutu türünde tanılanmış bir nesnedir. Bu nesnenin kendisinin de en boy ve yükseklik olmak üzere üç alt değişkeni mevcuttur. Eğer bir programda kutu1 değişkeni tanımlanmışsa, bu değişkenin alt degişkenlerine şu şekilde ulaşılabilir : kutu1.en=1.0; Şimdi Kutu sınıfından nesneyi kullanacak ufak bir kututestı sınıfı oluşturalım ve Kutu sınıfını bu sınıfta kullanalım. Program 1.3.1-1 Kutu ve kututesti sınıfları import javax.swing.JOptionPane; // giriş çıkış class Kutu { double en; double boy; double yukseklik; } class kututesti { public static void main(String args[]) { double hacim; String s=""; Kutu kutu1=new Kutu(); kutu1.en=10.0; kutu1.boy=20.0; kutu1.yukseklik=30.0; hacim=kutu1.en*kutu1.boy*kutu1.yukseklik; s=s+"Kutunun hacmi : "+hacim+"\n"; JOptionPane.showMessageDialog(null,s, "sınıf yapısı: kututesti1",JOptionPane.PLAIN_MESSAGE); System.exit(0);} } Bu programın adının kututesti.java olması zorunludur. Çünki ana metot(main) kututesti sınıfında tanımlanmıştır. Fakat programı javac terimiyle bilgisayar diline çevirdiğimizde iki tane sınıf(class) dosyasının oluştuğunu görürüz. Birisi Kutu.class diğeride kututesti.class. Ana program kututesti olduğu için bu programın işletimi java kututesti deyimini kullanarak yapılır. Program işletildiğinde Şekil 1.3.1-1 kututesti.java programının JoptionPage grafik çıktısındaki görünümü Sonucunu verir. kutu1 nesnesi yaratıldığında bilgisayar belleğinde kutu1 için bir adres tanımlanır. New Kutu() deyimi verildiğinde ise bilgisayrın belleginde en,boy ve yükseklik değişkenleri için yer ayrılır ve bu yerlerin adresleriyle kutu1 nesnesinin adresi arasında bağlantı sağlanır. Bunu grafik olarak anlatalım : Tablo 1.3.1-1 Nesne adreslerinin bilgisayar belleğindeki yerleri ve yerleşmesi Deyim Bilgisayar ana nesne belleği Nesne alt hafıza belleği Kutu kutu1; null Mevcut değil kutu1=new Kutu(); Kutu1 kutu1 adresi (örneğin: 23436A3F) en Boy Yükseklik Not: null terimi bilgisayar beleğinin boş olduğunu gösterir. Yukardaki grafikte ilk olarak Kutu kutu1; tanımı yapıldığında bilgisayar belleğinde 1 byte boyutunda bir yer tanımlar. Ve bu yere boş anlamına gelen null degerini yükler. İkinci durumda ise (kutu1=new Kutu() tanımında) kutu1 nesne adresindeki kutuda en,boy,yükseklik değişkenlerinin adresleri kaydedilmiştir. Bu adres aracılığıyla en boy ve yükseklik değişkenlerine benimkutum degişkeni üzerinden ulaşılabilir. Diğer deyimle en,boy,yükseklik kutu1 nesnesinin alt değişkenleridir. 1.3.2 KURUCU ( CONSTRUCTOR ) METOT İkinci bir programda Kutu sınıfı iki nesne tanımlama gereği duyduğumuzu varsayalım. Buna örnek olarak Şekil 3.2.1 de kututesti1.java programı tanımlanmıştır. Program 1.3.2-1 : Kurucu metot örneği, Kutu sınıfı iki nesne tanımlayan kututesti1.java programı import javax.swing.JOptionPane; // giriş çıkış class Kutu { double en; double boy; double yukseklik; } class kututesti1 { public static void main(String args[]) { double hacim; Kutu kutu1=new Kutu(); String s=""; kutu1.en=10.0; kutu1.boy=20.0; kutu1.yukseklik=30.0; hacim=kutu1.en*kutu1.boy*kutu1.yukseklik; s+="Birinci kutunun hacmi : "+hacim+"\n"; Kutu kutu2=new Kutu(); kutu2.en=5.0; kutu2.boy=10.0; kutu2.yukseklik=15.0; hacim=kutu2.en*kutu2.boy*kutu2.yukseklik; s+="İkinci kutunun hacmi : "+hacim+"\n"; JOptionPane.showMessageDialog(null,s, "Kutu testi 1",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Bu programın çıktısı : Şekil 1.3.2-1 kututesti1.java Bu programda Kutu sınıfından kutu1 ve kutu2 değişkenleri tanımlanmıştır. Bu basit programda bile en,boy ve yükseklik değikenlerini iki defa çağırmak program listesinin uzamasına sebep olmuştur. Gerçek uygulamalarda ise çok daha yüksek sayıda değişken içeren sınıflar oluşturulabilir ve bu sınıflarda oluşturulan toplam nesne sayısı da çok fazla olabilir. Bu yüzden nesneyi ilk tanımlarken aynı zamanda değişkenlerinin değerlerini de tanımlayabilirsek, çok daha okunaklı ve kısa bir bilgisayar listesiyle aynı işi yapabiliriz. Bu iş için kurucu (constructor) adı verilen metotlar kullanılır. Kurucu metotları diğer metotlardan biraz farklıdır. Once metot önüne metot değişken türü gelmez ve metot dışına hiçbir değişken göndermezler. İsimleri de herzaman sınıf(class) ismiyle aynı olur. Program 3.1 deki programı kurucu (constructor) metotu kullanarak tekrar yazalım. Program 1.3.2-2 : Kurucu metot örneği, Kutu sınıfı iki nesneyi kurucu(constructor) metotu yardımıyla tanımlayan kututesti2.java programı import javax.swing.JOptionPane; // giriş çıkış class Kutu { double en; double boy; double yukseklik; //kurucu metod kutu Kutu(double e,double b,double y) { en=e; boy=b; yukseklik=y; } } class kututesti2 { public static void main(String args[]) { double hacim; String s=""; Kutu kutu1=new Kutu(10.0,20.0,30.0); hacim=kutu1.en*kutu1.boy*kutu1.yukseklik; s+="kutu1\'in hacmi : "+hacim+"\n"; Kutu kutu2=new Kutu(5.0,10.0,15.0); hacim=kutu2.en*kutu2.boy*kutu2.yukseklik; s+="kutu2\'nin hacmi : "+hacim; JOptionPane.showMessageDialog(null,s, "Kutu testi 2",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Bu program bir öncekinin aynı sonucu verir. Fakat burada bir önceki programda yapılan Kutu kutu1=new Kutu(); Tanımı yerini Kutu kutu1=new Kutu(10.0,20.0,30.0); Tanımına bırakmış ve kututesti2 sınıfı yazılırken en ,boy yükseklik değişkenlerinin yeniden tanımlanması ihtiyacını ortadan kaldırmıştır. 1.3.3 DİĞER METOTLAR Tekrar yukarıda incelediğimiz kutu sınıfını göz önüne alalım. Hacim bir kutunun özellikleri arasında yer alır, ve her zaman kutunun hacminin hesaplanması gerekebilir. Bu yüzden hacim işlemini Kutu sınıfının içinde tanımlamak daha ideal olacaktır. Şekil 3.3.1 deki kutuornegi3.java programında hacim hesaplarını yapan hacim metotu Kutu sınıfının içinde tanımlanmıştır. Program 1.3.3-1 : Kurucu metot örneği, Kutu sınıfı iki nesneyi kurucu(constructor) metotu yardımıyla tanımlayan ve hacmi hacim() metotuyla hesaplayan kututesti3.java programı import javax.swing.JOptionPane; // giriş çıkış class Kutu { double en; double boy; double yukseklik; //kurucu metod kutu Kutu(double e,double b,double y) { en=e; boy=b; yukseklik=y; } //bu metot kutunun hacmini hesaplar double hacim() { return en*boy*yukseklik; } } class kututesti3 { public static void main(String args[]) { double hacim; String s=""; Kutu kutu1=new Kutu(10.0,20.0,30.0); s+="kutu1\'in hacmi : "+kutu1.hacim()+"\n"; Kutu kutu2=new Kutu(5.0,10.0,15.0); s+="kutu2\'nin hacmi : "+kutu2.hacim(); JOptionPane.showMessageDialog(null,s, "Kutu testi 3",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Program çıktısı yine aynı olacaktır. Şekil 1.3.3-1 kututesti3.java çıktısı Bir önceki bölümde metot yazımı konusunda anlattıklarımızın hepsini buraya ilave edebiliriz. 1.3.4 THIS DEYİMİNİN KULLANIMI Bazen bir metotun içinde o metotun ait olduğu sınıftan yaratılacak nesneyi veya o nesnenin bir alt değişkenini tanımlamak gerekir. Nesne daha tanımlanmadığindan direk olarak nesne ismini kullanamayız. Bunun yerina java this deyimini kullanır. This deyimi bilhassa sınıfa ait değişken isimlerinin aynısı metotda kullanılmışsa da işe yarar. Bu durumda tüm sınıfa ait değişkenler this.değişken_ismi komutuyla çağırılabilir. geçen bölümde sınıf ve metota ait değişkenleri izlerken metotvesinifdeg.java ve metotvesinifdeg1.java isimlerinde iki örnek problemi incelemiştik. Şimdi de aynıgruptan metotvesınıfdeg3.java programını inceleyelim. Program 1.3.4-1 : metotvesinifdeg3.java programıyla ve this deyimi yardımıyla metotun içinde yerel ve sınıfa ait değişkenlere ulaşım. import java.awt.Graphics; import java.applet.Applet; public class metotvesinifdeg3 extends Applet { //buradaki degiskenler tüm sınıfa aittir double x ; int y ; void metot1( Graphics g) //metota hiç bir değişken girmiyor { double x; int y; x=5.5; y=6; //tum sinifa at degiskenler this kelimesi ile birlikte kullanilabilirler g.drawString("metot1 in dis degiskenleri this ile ulasim : x = "+this.x+" y = "+this.y,25,25); g.drawString("metot1 in ic degiskenleri : x = "+x+" y = "+y,25,40); } public void paint(Graphics g) { x = 2.5; y = 3; metot1(g); } } Sınıfa ait her değişkeni başına this. getirerek kullanabiliriz. Fakat this kullanımı mutlaka gerekli değilse kullanılmaması tavsiye edilir. Örneğin yukarıdaki kurucu metot kutu //kurucu metot kutu kutu(double en,double boy,double yukseklik) { this.en=en; this.boy=boy; this.yukseklik=yukseklik; } şeklinde this değişkenini kullanarak da yazılabilirdi. Burada girdi değişkeni ile sınıf değişkeninin adı aynı verilmiştir. This sol taraftaki değişkenin sınıf değişkeni olduğunu bilgisayara bildirmektedir. 1.3.5 SINIF DEĞİŞKENLERİNİN DIŞ DÜNYADAN GİZLENMESİ Yukarda incelediğimiz kutu metodu. Program 3.5 de daha detaylı yazılmıştır. Burada en boy ve yükseklik değişkenleri private olarak tanımlanmıştır. Private olarak tanımlanan değişkenlere dışarıdan direk olarak Kutu x=new Kutu(3.0,5.0,7.0); x.en=8.0; gibi direk ulaşım mevcut değildir. Bu değişkenlere ulaşım (değerlerini değiştirme veya çağırma) ancak ulaşım metodları adını verdiğimiz metodlar aracılığıyla yapılabilir. Program 1.3.5-1 : Kurucu metot örneği, Kutu sınıfı iki nesneyi kurucu(constructor) metotu yardımıyla tanımlayan ve hacmi hacim() metotuyla hesaplayan ve diğer metod tanımlarının da bulunduğu kututesti4.java programı. import javax.swing.JOptionPane; // giriş çıkış class Kutu { private double en; private double boy; private double yukseklik; //kurucu metod kutu Kutu(double e,double b,double y) { en=e; boy=b; yukseklik=y; } //sınıf değişkenlerini değiştirme set metodu public void setKutu(double e,double b,double y) { en=e; boy=b; yukseklik=y; } //sınıf değişkenlerine ulaşma (get) metotları public double getEn() {return en;} public double getBoy() {return boy;} public double getTukseklik() {return yukseklik;} //bu metot kutunun hacmini hesaplar (işlem- hesap) metodu public double hacim() { return en*boy*yukseklik; } //string çıktı metodu public String toString() { return("en = "+en+" boy = "+boy+" yükseklik = "+yukseklik+"\n"+ "Hacim = "+hacim()+"\n"); } } class kututesti4 { public static void main(String args[]) { double hacim; String s=""; Kutu kutu1=new Kutu(10.0,20.0,30.0); s+=kutu1.toString(); Kutu kutu2=new Kutu(5.0,10.0,15.0); s+=kutu2.toString(); JOptionPane.showMessageDialog(null,s, "Kutu testi 4",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Bu programın çıktısı : Şekil 1.3.5-1 kututesti4.java İkinci bir örnek olarak dörtişlemhesapmakinasi sınıfına bakalım. Burada da sınıf değişkenleri protected olarak tanımlanmıştır. Aşağıda dort işlem (toplama cıkarma carpma bolme yapan dortislemhesapmakinasi sınıfını görüyorsunuz. Program 1.3.5-2 : dörtislemhesapmakinasi.java programı ve sınıf değişkenlerinin değerlerinin metot kullanılarak değiştirilmesi public class dortislemhesapmakinasi { //sınıf değişkenleri x sonuc hafiza protected double x,sonuc,hafiza; // kurucu metot dortislemhesapmakinesi public dortislemhesapmakinasi(double y) { //constructor sonuc=y; hafiza=0; } // ikinci bir kurucu metot dortislemhesapmakinesi public dortislemhesapmakinasi() { sonuc=0; hafiza=0; } public double topla(double x) { sonuc+=x; return sonuc; } public double cikar(double x) { sonuc-=x; return sonuc; } public double carp(double x) { sonuc*=x; return sonuc; } public double bol(double x) { sonuc/=x; return sonuc; } //bu metotla sonuc değeri değiştirilir public void gir(double x) { sonuc=x; } public double oku() { return sonuc; } public void C() { sonuc=0; } public void M(double x) { //hafızaya al hafiza=x; } public double MR() { //hafızayı çagır return hafiza; } public void MTopla(double x) { hafiza+=x; } public void Mcikar(double x) { hafiza-=x; } public double isaretdegistir() { sonuc=-sonuc; return sonuc; } public String toString() { return ""+sonuc; } public String MtoString() { return ""+hafiza; } } Bu sınıfta (class) sınıf değişkeni sonuc değerlerinin değiştirilmesi için gir metotu yazılmıştır. Bunun sebebi programlarda sınıfa ait değişkenlere dışarıdan direk ulaşımın önlenmesini sağlamaktır. İyi programlama şartlarından birisi sınıfın değişkenlerine sadece o sınıfın metotları üzerinden ulaşmaktır. Herkese serbest ulaşım verilmez. Hatta bunu saglamak için değişkenlerin başına sadece bu sınıfa aittir dışarıdan kullanılamaz anlamındaki private sözcügü getirilebilir. private sözcüğü yerine ancak dışarda bu sınıftan yaratılana yeni sınıflar (akraba sınıflar) kullanabilir, yabancı sınıflar kullanamaz anlamındaki protected sözcüğü de sık olarak kullanılır. Protected sözcügü aynı directorydeki diğer dosyaları da (public) gibi kabula eder, fakat başka direktorylerdeki dosyalar için private olarak davranır. dortislemhesapmakinasi.java programının x, sonuc ve hafıza değişkenleri için protected sözcüğü kullandığımız için dortislemhesapmakinasi h = new dortislemhesapmakinasi(); h.sonuc = 2.0; şeklinde ulaşılamaz. Aynı işlemi yapmak için aşağıdaki üç yoldan birini kullanabiliriz. dortislemhesapmakinasi h = new dortislemhesapmakinasi(); h.gir(2.0); veya dortislemhesapmakinasi h = new dortislemhesapmakinasi(2.0); şeklinde sonuç değişkenine 2.0 değeri atanır. Hafiza değişkeninin değerinin değiştirilmesi için ise : h.M(3.0); metotu çağırılır. Sınıf değişkenlerinin dış dünyadan gizlenmesi niçin gereklidir? Bunun en önemli sebebi program güvenliğinin sağlanmasıdır. Değişkenlere dışarıdan direk müdahale edilebilirse, değerleri de değiştirilebilir. Örneğin değişkeni bir banka hesabı veya şirketin özel hesabı olarak düşünebiliriz. Dış dünyadan gizlenmemiş bir değişkenin değeri değiştirilebilir. Private veya protected değişkenler ise ancak metotlar üzerinden değiştirilebilir, burada yeterli güvenlik önlemlerini almak mümkündür. 1.3.6 SINIFLARDA KALITIM (INHERITANCE) Bir sınıfın kurulmasında o sınıfla direk olarak ilişkisi olan bir sınıftan onun tüm metotları ve değişkenleri kalıtım (inheritance) yoluyla yeni kurulan bir sınıfa aktarılabilir. Kalıtım için sınıf(class) tanımında extends kelimesi kullanılır. Eğer bir sınıftan daha alt sınıflara kalıtım yoluyla aktarma yapılacaksa private değişken türü yerini protected değişken türüne bırakır. Protected private deyiminin aynıdır. Fakat kalıtımla değişkenlerin aktarıldığı alt sınıflara değişkenleri görme izni verir. Private terimi ise kalıtımla aktarılan alt sınıflardan bile o değişkenleri saklar. Program 3.6 da nokta sınıfı tanımlanmıştır. Program 3.7 de ise nokta sınıfından kalıtım yoluyla yaratılan daire sınıfını görüyoruz. Programda da görüleceği gibi daire sınıfının tanımı public class daire extends nokta terimiyle yapılmıştır. Ayrıca daire sınıfının kurucusu yazılırken nokta sınıfının kurucusu direk olarak super(a,b); terimiyle çağırılmıştır. Burada önemli bir noktayı hatırlatalım : "Java dilindeki bir sınıf sadece bir tane başka sınıfın metot ve değişkenlerini kalıtım yoluyla aktarabilir. " Program 1.3.6-1 : nokta.java programı ve nokta sınıfının tanımı. public class nokta { protected double x, y; public nokta(double a, double b) { noktagir(a,b); } public void noktagir(double a, double b) { x=a; y=b; } public double Xoku() { return x; } public double Yoku() { return y; } public String toString() { return "["+x+","+y+"]"; } } Program 1.3.6-2 : daire.java programı ve daire sınıfının tanımı. Daire sınıfı nokta sınıfından Kalıtım (inheritance) yoluyla türetilmiştir. import nokta; public class daire extends nokta { protected double yaricap; public daire() { //daire kalıtım yaptigi nokta sınıfının kurucu metotunu // super deyimi ile cagirabilir. super(0,0); yaricapgir(0); } public daire(double r, double a, double b) { super(a,b); yaricapgir(r); } public void yaricapgir(double r) { if(r = 0.0) yaricap=r; else yaricap=0.0; } public double yaricapoku() { return yaricap; } public double alan() { return 3.14159*yaricap*yaricap; } public String toString() { return "Merkez = "+"["+x+","+y+"]"+ "; Yaricap="+yaricap; } } Kalıtım yoluyla aktarılan metotlar ve değişkenler yeni programda o programın içinde yazılmış gibi aynen kullanılabilir. 1.3.7 SINIFLARI BAŞKA BIR SINIFTA NESNE OLARAK ÇAĞIRARAK BiR ARAYA GETiRME (COMPOSITION) Sınıftaki değişken ve metotları kalıtım yoluyla aktarabildiğimiz gibi, sadece üst sınıfa ait bir nesne (object) tanımını alt sınıfta tanımlıyarak ta yapabiliriz. Buna nesne yoluyla aktarım (ingilizce composition) diyoruz. Program 1.3.7-1 : 1 daire1.java programı ve daire sınıfının tanımı. Nokta sınıfı daire1 sınıfında merkez adlı nesne olarak tanımlanmıstır. import nokta; public class daire1 { protected double yaricap; protected nokta merkez; public daire1() { merkez=new nokta(0,0); yaricapgir(0); } public daire1(double r, double a, double b) { merkez=new nokta(a,b); yaricapgir(r); } public void yaricapgir(double r) { if(r = 0.0) yaricap=r; else yaricap=0.0; } public double yaricapoku() { return yaricap; } public double alan() { return 3.14159*yaricap*yaricap; } public String toString() { return "Merkez = "+"["+merkez.x+","+merkez.y+"]"+ "; Yaricap="+yaricap; } } daire1 programında 1.3.8 KALITIM YOLUYLA ALT SINIFA BAĞLANMIŞ ÜST SINIF REFERANSI ÜZERINDEN ALT SINIFI ÇAĞIRMA Yukarıda nokta ve daire sınıflarını tanımlamıştık. Baska bir sınıftan kalıtım yoluyla türeyen sınıfın(dairenin noktadan kalıtım yoluyla türemesi gibi), üst sınıfın adresi(tanımı) üzerinden programın içinde aktarımı mümkündür. Program 1.3.8-1 : noktatesti.java sınıfında üst sınıf üzerinden adres referansı kullanımı import java.awt.Graphics; import java.applet.Applet; public class noktatesti extends Applet { private nokta noktaref,n; private daire daireref,d; public void init() { n=new nokta(30,50); d=new daire(2.7,120,89); } public void paint(Graphics g) { //once noktamizi ve dairemizi yazdiralım g.drawString("Nokta n : "+n.toString(),25,25); g.drawString("Daire d : "+d.toString(),25,40); //c dairesinin adresini nokta olarak tanımlanan noktaref e aktaralım noktaref=d; g.drawString("Daire(noktaref uzerinden) :"+noktaref.toString(),25,70); //noktaref nesnesini daireref degişkenine(nesnesine) aktaralım daireref=(daire)noktaref; g.drawString("Daire(daireref uzerinden) :"+daireref.toString(),25,85); g.drawString("Dairenin alani(daireref uzerinden) :"+daireref.alan(),25,100); } } Şekil 1.3.8-1 Noktatesti.html Program 1.3.8-1 de görülen noktatesti.java sınıfında, n nokta sınıfı nesnesi, ve noktaref noktasinifi nesnesi, ve d dairesınıfı nesnesi, ve daireref daire sinifi nesnesi tanımlanmiştır. İnit metotunda p ve c nesnelerinin adresleri kurucu metotu new deyimiyle taşıyarak tanımlanmiştir. Dahasonra noktaref=d; deyimiyle aslında daire sınıfından olan d nesnesi nokta sınıfından tanımlanan noktaref nesnesinin adresine yüklenmiştir. Programda da görüldüğü gibi noktaref üzerinden daireyi kullanmak mümkündür çünkü nokta dairenin kalıtım yoluyla üst sınıfıdır. Aynı zamanda cast işlemcisi (daire) terimini kullanarak noktaref’i daireref’e aktarmak da mümkün olmuştur. Bu aktarma nokta dairenin super sınıfı olmasa başarılamazdı. Bazen sadece bu süper sınıf aktarımını saglamak amacıyla sınıf hiyerarşisinin en tepesine aslında belli bir görevi olmayan abstract sınıflar yerleştirilir. Bu sınıfın alt sınıfları olarak tanımlanan tüm sınıflar bu sınıf adresinden yararlanılarak aktarılabilir. Abstract sınıfların tanımında abstract sözcüğü kullanılır. Abstract tür metotların içinde metotların sadece başlıkları verilip tanımları yapılmıyabilir. (metotun ana gövdesi tanımlanmıyabilir). Abstract super sınıfının kullanılmasına şöyle bir örnek verebiliriz : sekil isimli bir abstract sınıfın alt sınıfları olarak daire,üçgen,dikdörtgen ve kare sınıflarını oluşturduğumuzu ve bu sınıfların herbirinin kendi şeklini çizecek ciz metotunu içerdiğini düşünelim. Programı yazarken abstract sınıf sekilde de alan metotu tanımı yaparız. Ve sekil sınıfından bir nesne tanımlarız. Program çalışırken sekil üzerinden istediğimiz alt şeklin çizimi dinamik olarak her biri için ayrı bir adres tanımlamadan mümkün olur. Aynı şekilde bir nümerik analiz programı yazarken, örneğin her değişik fonksiyon için ayrı ayrı integral metotu yazma yerine abstract tür bir fonksiyon için integral programını yazar ve gerçek foksiyonumuzu tanımladığımız sınıfı bu abstract sınıfın alt sınıfı olarak tanımlarız. Bu kavramı daha sonraki bölümlerimizde daha geniş örneklerle açıklamaya çalışacağız. 1.3.9 NESNEYi DiNAMiK OLARAK SiLMEK FINALIZE() METOTU Java dili kullanılmayan nesneleri silmek için arka planda çalışan bir sisteme sahiptir. Bu yüzden C++ gibi dillerde dinamik nesne tanımlarında mutlaka yer alması gereken nesneyi silme metotları javada o kadar gerekli değildir. Fakat eğer kendiniz metlaka bir nesneyi acil olarak silmek isteseniz finalize() isimli bir metotu sınıfınızda tanımlayıp kullanabilirsiniz. Örnek olarak aşağıdaki metotu verebiliriz. protected void finalize() throws Throwable { super.finalize(); } 1.4 : BOYUTLU DEĞİŞKENLER VE NESNELER (ARRAYS) 1.4.1 TEK BOYUTLU DEĞiŞKENLER Boyutlu değişkenler aynı degişken türü veya sınıf türünden birden fazla nesne veya değişkenin tek bir isimle tanımlanmasıdır. Boyutlu değişkenlere referans indeks numarası kullanılarak ulaşılır. Genel olarak bir boyutlu değişkenler Değişken_türü değişken_ismi[]; veya Değişken_türü[] değişken_ismi; Şeklinde tanımlanır. Birinci tanımın kullanılması daha yaygındır. İki tanım arasında bilgisayar açısından bir fark mevcut değildir. Bir örnek verecek olursak int ayın_gunleri[]; veya int[] ayın_gunleri; Bu tanımlar her ne kadar haftanın_gunleri nin boyutlu bir değişken olduğunu belirtiyorsa da kesin boyutunu bildirmemektedir. Boyutlu değişkenin tam boyutunu tanımlamak ve bilgisayar hafızasındaki yerini tam olarak saptamak için Değişken_ismi=new Değişken_türü[değişken_boyutu]; Terimi kullanılır. Bunu bir önceki örneğe uygularsak : Ayın_gunleri=new int[12]; Boyutlu değişkeni bir kere tanımladıktan sonra onun içindeki her alt değere indeksi üzerinden ulaşmak mümkündür. Örnegin: ayın_gunleri[0] = 31; ayın_gunleri[1] = 28; gibi. . İndeks değişkeni herzaman sıfırdan başlar. Küçük bir örnek sınıfta bu kavramı daha açık olarak vermeye çalışalım. Program 1.4.1-1 Boyut.java import java.io.*; class boyut { public static void main(String args[] ) { int ayin_gunleri[]; ayin_gunleri=new int[12]; ayin_gunleri[0]=31; ayin_gunleri[1]=28; ayin_gunleri[2]=31; ayin_gunleri[3]=30; ayin_gunleri[4]=31; ayin_gunleri[5]=30; ayin_gunleri[6]=31; ayin_gunleri[7]=31; ayin_gunleri[8]=30; ayin_gunleri[9]=31; ayin_gunleri[10]=30; ayin_gunleri[11]=31; System.out.println("Nisan ayi "+ayin_gunleri[3]+" gun ceker"); } } Bu programı daha kısa olarak yazmak için Şekil 1.4.1-2 de görülen şekilde bütün değişkenlerin değerlerini aynı anda tanımlıyabiliriz. Program 1.4.1-2 : Boyut1.java import java.io.*; class boyut1 { public static void main(String args[] ) { int ayin_gunleri[]={31,28,31,30,31,30,31,31,30,31,30,31}; System.out.println("Nisan ayi "+ayin_gunleri[3]+" gun ceker"); } } Program 1.4.1-3’de boyut kavramının for döngüsüyle birlikte kullanışını görüyorsunuz. Boyutlu değişkenin toplam boyutuna da sayı.length değişkeniyle ulaşıyoruz. Daha önceki birçokprogramlama dilinde bu mümkün değildir ve boyutlu değişkenin boyutunun bildirilmesi gerekir. Program 4.3 ün çıktısını step step takip ederek ve bir hesap makinası kullanarak hesaplayınız. Program 1.4.1-3 : Aritmetik2.java import java.io.*; //java girdi cikti sinifini cagir class Aritmetik2 { public static void main(String args[]) { int sayi[]={10,5,7,9,11,13,14,18}; int toplam=0; int i; for(i=0;i<sayi.length;i++) { toplam+=sayi[i]; } System.out.println("Ortalama = "+toplam/sayi.length); } } Şimdi de bir applet örneğinde tek boyutlu değişkenleri kullanalım. Daha önce zarApplet.java programını incelemiştik. Şimdi bu programa her bir zar yüzeyinin atılış frekanslarını ekleyelim. Toplam altı yüz olduğundan birden altıya kadar her sayının kaç kere geldiğini saydırmamız gerekir. Bunun için bir boyutlu zarfrekansi değişkenini tanımlayacağız. Program 1.4.1-4 :: zarfrekansıSWF, java swing JFrame programı import javax.swing.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; public class zarfrekansiSWF extends JFrame implements ActionListener { int toplamzaratisi=0; int toplam=0; JTextField ilkzar,ikincizar; JButton salla; //zar atma düğmesi JTextArea cikti; int zar1,zar2; int zarfrekansi[]; public static int zar() { return 1+(int)(Math.random()*6); } public zarfrekansiSWF() { //programi baslat super("Zar frekansı swing JFrame"); zarfrekansi=new int[6]; Container c=getContentPane(); c.setLayout(new FlowLayout()); ilkzar=new JTextField(10); // JTextfield sinifi ilkzar nesnesini yarat c.add(ilkzar); // ilk zar nesnesini pencereye ekle ikincizar=new JTextField(10);// Textfield sinifi ikincizar nesnesini yarat c.add(ikincizar); // ikinci zar nesnesini pencereye ekle salla=new JButton("Zari salla ve at"); c.add(salla); salla.addActionListener(this); cikti=new JTextArea(); cikti.setBackground(c.getBackground()); c.add(cikti); } public void actionPerformed(ActionEvent e) { String s=""; zar1=zar(); zar2=zar(); ilkzar.setText(Integer.toString(zar1)); ikincizar.setText(Integer.toString(zar2)); toplam+=(zar1+zar2); toplamzaratisi++; // not boyutlu degisken indeksi 0 dan basliyor. zarfrekansi[zar1-1]++; zarfrekansi[zar2-1]++; s+="toplam = "+toplam+" Atilan zar sayisi = "+toplamzaratisi+"\n"; for(int i=0;i<6;i++) { s+=zarfrekansi[i]+" kere "+(i+1)+" atildi \n"; } cikti.setText(s); repaint(); } //===================================================== public static void main(String[] args) { zarfrekansiSWF pencere= new zarfrekansiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(450,200); pencere.setVisible(true); } } Şekil 1.4.1-1 ZarfrekansiAppletSWF.java appletinin görünümü 1.4.2 TEK BOYUTLU NESNE TİPİ DEĞİŞKENLER Nesne tipi değişkenler için de aynı normal basit değişkenlerde olduğu gibi boyut tanımı yapılır. Normal boyut tanımı yapıldıktan sonra, boyuttaki her nesne teker teker tanımlanır. Örneğin : kompleks sayi[]=new kompleks[5]; sayi[0]=new kompleks(1,2); sayi[1]=new kompleks(1,-1); sayi[2]=new kompleks(2,0); sayi[3]=new kompleks(1.1,-0.5); sayi[4]=new kompleks(1,1.5); Dogru3 n[]; n=new dogru3[3]; n[0]=new dogru3(1,1,1,2,2,2); n[1]=new dogru3(2,2,2,3,3,3); n[2]=new dogru3(3,3,3,4,4,4); gibi. 1.4.3 ÇOK BOYUTLU DEĞİŞKENLER İki ve daha fazla boyutlu değişkenler de tanımlamak mümkündür. İki boyutlu değişkenler en fazla tablo veya matris gibi satır ve sütun olmak üzere iki boyutta gösterilmesi gereken büyüklükleri oluşturmak için kullanılır.Java iki boyutlu değişkenleri direk olarak açamaz. Tek boyutlu değişkenlerin yine tek boyutlu degişkenini açar. Sonuç olarak iki boyut sağlanmış olur. Örnek verecek olursak int b[][]=new int[3][4]. Genel olarak ilk parantes satır sayısı, ikinci parantez sütun sayısı olarak kabul edilir. Buna göre b değişkenini şöyle düşünebiliriz : b[0][0] B[1][0] B[2][0] b[0][1] b[1][1] b[2][1] b[0][2] b[1][2] b[2][2] b[0][3] b[1][3] b[2][3] Iki boyutlu değişken de bir boyutlu değişkenlerde olduğu gibi degerleri direk olarak yüklüyebiliriz, ve yükleme sırasında boyutları da tayin edebiliriz. Örneğin : int b[][] = {{1,2},{3,4}}; Terimi bize aşağıdaki tabloyu tanımlar: 1 3 2 4 b[0][0] b[1][0] b[0][1] b[1][1] İki boyutlu değişkenlerin kullanılmasını göstermek amacıyla bir örnek problem verelim: Program 1.4.3-1 : İki boyutlu değişkenler örnegi : ikiboyutS.java import javax.swing.*; public class ikiboyutS { public static void main(String[] args) { int a1[][]={{1,2,3},{4,5,6}}; int a2[][]={{1,2},{4}}; String s="iki boyut yazdır çıktısı : "; String s1="a1 =\n"+ikiboyutcikti(a1); s1+="a2 = \n"+ikiboyutcikti(a2); JOptionPane.showMessageDialog(null,s1,s,JOptionPane.PLAIN_MESSAGE); } public static String ikiboyutcikti(int a[][]) { int x=25; String s1=""; for(int i=0;i<a.length;i++) { for(int j=0;j<a[i].length;j++) { s1+=String.valueOf(a[i][j])+" ";} s1+="\n"; } return s1; }} Şekil 1.4.3-1 İki boyutlu değişkenler örneği ikiboyutS.java Boyutlara ulaşmak için yukarıdaki programlardan da görüleceği gibi for döngüsü kullandık. Boyutlu değişkenlere ulaşım. for döngülerinin en çok kullanıldığı yerlerden biridir. Satırların boyutuna a.length, sütunların boyutuna ise a[satır].length terimiyle ulaştık. Bu tanım bize toplam satır ve sütun boyutunu direk tanımlar, ve kullanımda yeterince esneklik sağlar. 1.4.4 BOYUTLU DEĞİŞKENLERİN METOTLARA AKTARIMI Boyutlu değişkenler aynen boyutsuz değişkenler gibi metotlara aktarılırlar. Örneğin eğer int sıcaklık[] = new int[24]; deyimiyle tanımlanan sicaklık; sicakligidegistir(sıcaklik); terimiyle sicakligidegistir metotuna aktarılabilir. Metot tanımlanırken, sıcaklığın boyutlu değişken olduğu tanımlanmalıdır: double void sicakligideğiştir(int sicaklik[]) { .......................... } gibi. Metotların çıktı değişkenleri de çok boyutlu olarak tanımlanabilir ve kullanılabilir. Örneğin : public static double[][] inversematris(double[][] a) gibi. 1.4.5 BOYUTLU DEĞİŞKENLERDE BOYUT DEĞİŞTİRME Boyutlu değişkenlerin boyutları ilk tanımlamalarında belirtildiğinden normal olarak değiştirilemez. Ancak indirek yollarla boyutun değiştirilmesi mümkündür. Bu yol önce yeni boyutta bir boyutlu değişken tanımlamak, sonra boyutlu değişkenin içerisindeki değerleri bu yeni değişkene aktarmak ve sonra orijinal boyutlu değişkenin adresini yeni oluşturulan boyutlu değişken adresiyle değiştirmek şeklinde yapılır. double a[]={3.0,5.0,7.0} double b[]=new double[4]; for(int i=0;i<a.length;i++) {b[i]=a[i];} a=b; program parçacığında a değişkeninin boyutu üçten 4 e değiştirilmiştir. Daha detaylı bir örnekle boyut değiştirmeyi inceleyelim. Program1. 4.5-1 : boyutlu değiştirme örnegi : doubleBoyut.java public class doubleBoyut { //sınıf değişkenleri public double a[]; public int length; public doubleBoyut(double x[] ) { length=x.length; a=new double[length]; for(int i=0;i<length;i++) a[i]=x[i]; } public doubleBoyut(int n) { a=new double[n]; length=a.length; } public void boyutEkle(int n) { if(n>0) { int z=a.length+n; double[] b=new double[z]; for(int i=0;i<a.length;i++) {b[i]=a[i];} a=b; length=a.length; } } public void boyutEkle() { boyutEkle(1); } public void boyutAzalt(int n) { int z=a.length-n; if(z>1) { double[] b=new double[a.length-n]; for(int i=0;i<z;i++) b[i]=a[i]; a=b; } else { double[] b=new double[1]; b[0]=a[0]; a=b; } length=a.length; } public void boyutAzalt() { boyutAzalt(1); } public double getValue(int i) { return a[i];} public double[] getValue() { return a;} public void setValue(double x,int i) { a[i]=x;} public void setValue(double[] x ) { length=x.length; a=new double[length]; for(int i=0;i<length;i++) { a[i]=x[i]; } } public String toString(int i) { return String.valueOf(a[i]); } public String toString() { String s=""; for(int i=0;i<length;i++) { s+=a[i]+" "; } s+="\n"; return s; } } DoubleBoyut sınıfında boyutu değiştirilebilen değişken (nesne) tanımladık. Bu değişkeni boyutDegistir sınıfında test edelim : Program 1.4.5-1 : boyutlu değiştirme testi : doubleBoyut sınıfını kullanan boyutDegistir.java import javax.swing.JOptionPane; public class boyutDegistir { public static void main(String args[]) { double x[]={3.1,5.3,7.0,9.7,11.0,11.5,12.3}; doubleBoyut y=new doubleBoyut(x); String s="Orijinal boyutlu ("+y.length+") double : \n"; s+=y.toString(); y.boyutEkle(3); s+="3 eklenmiş boyutlu ("+y.length+")double : \n"; s+=y.toString(); y.boyutAzalt(5); s+="5 azaltılmış boyutlu ("+y.length+")double : \n"; s+=y.toString(); JOptionPane.showMessageDialog(null,s, "boyutlu değişken boyut değiştirme eksersizi", JOptionPane.PLAIN_MESSAGE); System.exit(0); }} Program çıktısı : Şekil 1.4.5-1 boyut değiştirme örneği boyutu değiştirilebilen doubleBoyut sınıfının boyutDegistir sınıfında JoptionPane çıktısı olarak görünümü BÖLÜM 1.5 : SINIFLARDA HİYERARSİ, ABSTRACT SINIF VE İNTERFACE 1.5.1 ABSTRACT SINIF Üçüncü bölümde sınıfların diğer sınıflardan kalıtım (Inheritance) yoluyla türetilmesini görmüştük. Sınıfları kalıtım yoluyla birbirinden türetirken eğer ortak özellikli sınıflar yaratıyorsak, bütün bu sınıf gurubunun en tepesine abstract bir sınıf koyabiliriz. Abstract sınıf diğer sınıfların kullanılmasında extends yoluyla tepe sınıflık etmek ve bütün alt sınıflara ortak bir adres çıkış noktası sağlamak dışında bir görevi yoktur. Diğer bir deyimle bu sınıflar hiçbir zaman doğrudan kullanılmazlar. Ancak alt sınıflarından birini referans olarak göstermek ve onlara dolaylı yoldan ulaşmak amacıyla kullanılırlar. Kavramı daha iyi verebilmek için bir örnek problem oluşturalım. Daha önce sınıf kavramını açıklarken kullandığımız nokta,daire sınıflarını hatırlıyacaksınız. Şimdi bu sınıfların üzerine sekil isimli bir abstract sınıf ekleyerek tekrar oluşturalım. Program 1.5.1-1 Abstract sınıf sekil (sekilX.java dosyasında yer alıyor) public abstract class sekilX { public double alan(){return 0.0;} public double hacim() {return 0.0;} public abstract String isim(); } Program 1.5.1-2: sekil sınıfından kalıtım yoluyla türetilen noktaX sınıfı public class noktaX extends sekilX { protected double x, y; public noktaX(double a, double b) { x=a; y=b; } public void noktagir(double a, double b) { x=a; y=b; } public double Xoku() { return x;} public double Yoku() { return y;} public String toString() { return "["+x+","+y+"]";} public String isim() {return "nokta";} } Program 1.5.1-3: noktaX sınıfından kalıtım yoluyla türetilen daireX sınıfı public class daireX extends noktaX { protected double yaricap; public daireX() { //daire kalıtım yaptığı nokta sınıfının kurucu metodunu // super deyimi ile cagirabilir. super(0,0); yaricapgir(0); } public daireX(double r, double a, double b) { super(a,b); yaricapgir(r); } public void yaricapgir(double r) { if(r >= 0.0) yaricap=r; else yaricap=0.0; } public double yaricapoku() { return yaricap;} public double alan() { return Math.PI*yaricap*yaricap; } public String toString() { return "Merkez = "+"["+x+","+y+"]"+"; Yaricap="+yaricap;} public String isim() {return "daire";} } Program 1.5.1-4: daireX sınıfından kalıtım yoluyla türetilen silindirX sınıfı public class silindirX extends daireX { protected double yukseklik; public silindirX() { yukseklikoku(0);} public silindirX( double h, double r, int a, int b) { super(r, a, b ); yukseklikoku( h); } public void yukseklikoku (double h ) { if(h>=0) yukseklik=h; else yukseklik=0; } public double yukseklikoku(){return yukseklik;} public double alan() { return 2* super.alan()+ 2*Math.PI*yaricap*yukseklik; } public double hacim(){return super.alan()*yukseklik;} public String toString() {return super.toString()+";yukseklik="+yukseklik;} public String isim(){return "silindir";} } Program 1.5.1-5 : Abstract sınıf ve indirek referanslamayı test eden abstracttesti sınıfı import javax.swing.JOptionPane; public class abstractTesti_2000 { public static void main(String args[]) { noktaX n; daireX d; silindirX s; sekilX a[]; n = new noktaX(7,11); d = new daireX(3.5,22,8); s = new silindirX(10,3.3,10,10); a = new sekilX[3]; a[0]=n; a[1]=d; a[2]=s; String st=""; st+=n.isim()+": "+n.toString()+"\n"; st+=d.isim()+": "+d.toString()+"\n"; st+=s.isim()+": "+s.toString()+"\n"; //indirek cağırma int y=85; for(int i=0;i<a.length;i++) { st+=a[i].isim()+": "+a[i].toString()+"\n"; st+="Alan : "+a[i].alan()+" Hacim : "+a[i].hacim()+"\n"; } JOptionPane.showMessageDialog(null,st,"abstract test programı", JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Şekil 1.5.1-1 Abstract sınıf ve indirek referanslamayı test eden abstractTesti_2000 sınıfının sonuclarının JoptionPane çıktısı olarak görülmesi Örnekten de görüldügü gibi nokta, daire ve silindir abstract sekil sınıfının alt sınıfları olarak oluşturulmuş, ve aynı zamanda bu sınıflara indirek referans olarak kullanılmıştır. Diğer bir deyimle nokta daire ve silindirin adresleri sekil sınıfı nesneye aktarılmış ve bu nesne üzerinden üç sınıfta indirek olarak kullanılmıştır. Bu indirek kullanımın bize temel faydası, Programımıza yeni sınıflar eklediğimizde daha kolay ve az program değiştirerek uyumu sağlayabilme yeteneğidir. Orneğin yukarıdaki program sınıfları gurubuna koni eklemek istersek bütün yapacağımız koni sınıfını tanımladıktan sonra, sekil nesnesi a nın boyutunu bir arttırarak aynı hesaplamaya koniyide ilave etmekten ibaret olacaktır. Bu tür uygulamalar bilgisayar kodunun değişim gereksinimini minimuma indirgediğinden nesne kokenli bilgisayar programcılığının onemli uygulamalarından biridir. 1.5.2 INTERFACE KOMUTU Abstract sınıfların dezavantajı sadece bir sınıfın kalıtım yoluyla ve extends sozcüğü kullanılarak bağlanabilir olmasıdır. Ve eğer başka bir sınıf halihazırda o sınıfa kalıtım yoluyla bağlanmışsa, bizim yeni bir sınıfı üst sınıf olarak kullanma olasılığımız yok olmuş demektir. Fakat bazı uygulamalar için bu gerekebilir.Bu zaman interface kullanırız. Interface de abstract sınıf gibi kendi içinde bir işlem yapmaz. Sadece öbür sınıfların bağlanmasını teşkil eden bir adres noktası olarak iş görür. İnterface’i bir başka sınıfa bağlamak gerektiğinde extends yerine implements sözcüğü kullanılır. Abstract sınıflar kendi başına bir bütün teşkil edebilmelerine rağmen interface’in sadece kendi başına bir anlamı yoktur. Interface sınıfında yer alan tüm metod ve değişkenlerin alt sınıflarda tanımlanması gerekir. Örnek olarak bir önceki problemi interface ile tanımlıyalım. Program 1.5.2-1 interface sekil (sekilY.java dosyasında yer alıyor) public interface sekilY { public abstract double alan(); public abstract double hacim(); public abstract String isim(); } Program 1.5.2-2 : interface sekilden implements kelimesiyle türeyen noktaY sınıfı (noktaY.java dosyasında yer alıyor) public class noktaY implements sekilY { protected double x, y; public noktaY(double a, double b) { x=a; y=b;} public void noktagir(double a, double b) { x=a;y=b;} public double Xoku() { return x;} public double Yoku() { return y; } public String toString() { return "["+x+","+y+"]";} public double alan() {return 0.0;} public double hacim() {return 0.0;} public String isim() {return "nokta";} } Görüldüğü gibi burada nokta sınıfının bir öncekinden farkı implements kelimesinin kullanılmış olaması ve bos alan ve hacim metotlarının bu dosyada yazılmasının gerekmesinden ibarettir. Interface programla yapılan ve alt sınıflarda bu metodların (veya değişkenlerin) tanımlanacağına dair yapılan bir kontrattır.DaireY ve silindirY sınıflarında bir fark mevcut degildir. İki seklin işlemsel sonuçları arasında da bir fark mevcut değildir. Yukardaki örneğe parelel olarak burada da daireY,SilindirY tanımlarını yapalım ve interfaceTesti_2000.java programında test edelim. Program 15.2-3 : interface sekilY’den implements kelimesiyle türeyen noktaY sınıfından extends yoluyla türeyen daireY sınıfı(daireY.java dosyasında yer alıyor) public class daireY extends noktaY { protected double yaricap; public daireY() {//daire kalıtım yaptığı nokta sınıfının kurucu metodunu // super deyimi ile cagirabilir. super(0,0); yaricapgir(0); } public daireY(double r, double a, double b) { super(a,b); yaricapgir(r); } public void yaricapgir(double r) { if(r >= 0.0) yaricap=r; else yaricap=0.0; } public double yaricapoku() { return yaricap;} public double alan() { return Math.PI*yaricap*yaricap;} public String toString() { return "Merkez = "+"["+x+","+y+"]"+"; Yaricap="+yaricap;} public String isim() {return "daire";} } Program 1.5.2-4 : interface sekilY’den implements kelimesiyle türeyen noktaY sınıfından extends yoluyla türeyen daireY sınıfından extends yoluyla türeyen silindirY sınıfı(silindirY.java dosyasında yer alıyor) public class silindirY extends daireY { protected double yukseklik; public silindirY() { super(0, 0, 0 ); yukseklikoku(0); } public silindirY( double h, double r, int a, int b) { super(r, a, b ); yukseklikoku( h); } public void yukseklikoku (double h ) { if(h>=0) yukseklik=h; else yukseklik=0; } public double yukseklikoku(){return yukseklik;} public double alan() {return 2* super.alan()+ 2*Math.PI*yaricap*yukseklik;} public double hacim(){return super.alan()*yukseklik;} public String toString() {return super.toString()+";yukseklik="+yukseklik;} public String isim(){return "silindir";} } Program 1.5.2-5 : interface sekilY’den türeyen sınıfları test eden ve indirek olarak referanslıyan interfaceTesti_2000.java programı import javax.swing.JOptionPane; public class interfaceTesti_2000 { public static void main(String args[]) { noktaY n; daireY d; silindirY s; sekilY a[]; n = new noktaY(7,11); d = new daireY(3.5,22,8); s = new silindirY(10,3.3,10,10); a = new sekilY[3]; a[0]=n; a[1]=d; a[2]=s; String st=""; st+=n.isim()+": "+n.toString()+"\n"; st+=d.isim()+": "+d.toString()+"\n"; st+=s.isim()+": "+s.toString()+"\n"; //indirek cağırma int y=85; for(int i=0;i<a.length;i++) { st+=a[i].isim()+": "+a[i].toString()+"\n"; st+="Alan : "+a[i].alan()+" Hacim : "+a[i].hacim()+"\n"; } JOptionPane.showMessageDialog(null,st,"interface test programı", JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Şekil 1.5.1-2 interface sınıf ve indirek referanslamayı test eden interfaceTesti_2000 sınıfının sonuclarının JoptionPane çıktısı olarak görülmesi BÖLÜM 1. 6 : GRAFİKLER, FONTLAR VE RENKLER 1.6.1 GRAFİKLERE GİRİŞ Daha önce applet çizerken java.awt kütüphanesindeki grafik (Graphics) sınıfını kullanmıştık. Ve grafik (Graphics) sinifinina ait drawString metotunu kullanarak applete yazı yazdırmıştık. Şimdi bu sınıfın diğer özelliklerini ve metotlarını öğreneceğiz. Graphics sınıfı java.lang.Object sınıfının altında yer alır. Bu gurupta aynı zamanda grafik çiziminin çeşitli fazlarında kullanılan java.awt.Color, java.awt:Font, java.awt.FontMetrics, java.awt, java.awt.Graphics, java.awt.Polygon yer alır. Daha detaylı grafik çizme işlemleri tanımlayabilen java.awt. Graphics2D paketi java.awt.Graphics paketinden türetilmiştir. Ayrıca java.awt.BasicStroke, java.awt.GradientPaint, java.awt.TexturePaint gibi temel grafik alt programları da java.lang.Object altında tanımlanmıştır. Temel şekilleri çizdirmeye yarayan java.awt.geom.GeneralPath, java.awt.geom.Line2D, java.awt.geom.RectangularShape de java.lang.Object altında tanımlanır. java.awt.geom.Arc2D, . java.awt.geom.Ellipse2D, . java.awt.geom.Rectangle2D, . java.awt.geom.RoundRectangle2D gibi çizim paketleri de java.awt.geom.RectangularShape paketinin alt paketleri olarak tanımlanmıştır. Graphics sınıfı, yazı yazma, çizgi çizme, dikdörtgen, oval çizme gibi bir dizi metotu barındırır. Bunun dışında awt kütüphanesinin önemli bir sınıfı da Color sınıfıdır. Color sınıfı rekleri tanımlar ve değişik renklerin kullanımına imkan verir. Font sınıfı grafikte kullanılan yazıların fontlarının (yazı tipinin ve boyutunun) belirlenmesi amacıyla kullanılır. FontMetrics sınıfı fontların boyutlarının belirlenmesiyle ilgili metotları içerir. Polygon sınıfı polygon çizimiyle ilgili metotları barındırır. Bu metodların bir kısmını burada göreceğiz. Temel olarak Graphics ve Graphics2D sınıflarını grafik çiziminde kullanacağız, Bu işlemi yaparken de diğer tüm yardımcı grafik sınıflarından yararlanacağız. Graphics2D sınıfı daha yeni olarak tanımlanmış ve Graphics sınıfından türetilmiş bir sınıftır. Fakat çok daha komleks grafik çizim kapasitelerini barındırır. Java appletlerinde çizim yaparken ilk hatırlamamız gereken nokta, koordinat merkezinin ekranın sol üst köşesi olduğudur. X ekseni sola doğru, Y ekseni aşağıya doğru gider. Şekil 1.6.1-1 Java grafik koordinat sistemi, x ve y eksenleri Y ekseninin alta doğru gitmesi konsol programlarında (ve ilk konsol programlama ortamı olan satır yazıcılarında) satırların alta dogru ilerlemesi gibi tarihi bir nedene dayanmaktadır. Bütün bilgisayar diileri ve ekranı grafik programlamalarında standartdır. 1.6.2 GRAPHICS VE GRAPHICS2D SINIFLARI Graphics sınıfı grafik çizimi için gerekli olan bir çok metotu içinde barındırır. Grafik sınıfı java.lang.Object sınıfının alt sınıflarındandır. Grafik çizme amacıyla genellikle Graphics sınıfından bir nesne paint veya paintComponent metotunun içinde çağırılır. Paint metotunun tanımı şöyledir public void paint (Graphics g) Bu tanım Applet, Japplet,JFrame extend etmiş programlardan çağırılabilir. Paint metodu tüm bu üç sınıfın türetildiği Component sınıfında tanımlanmıştır. javax.swing sınıfı altında tanımlanan JComponent sınıfında ise paintComponent metodu tanımlanmıştır. JComponentin alt metodu JPanel bu metodu kullanır. Tanımı paint metoduna benzer public void paintComponent (Graphics g) paint veya paintComponent metodları Applet, Japplet, Frame, JFrame, Panel, JPanel sınıfları tarafından direk olarak program açıldığında çağırılır. Kullanıcı tarafından çağırılmaz. Tekrar kullanıcı tarafından çağırılması gerektiğinde ise repaint metotu kullanılır ve repaint metotu üzerinden indirek olarak paint metotu çağırılır. Bu metodun tanımı : public void repaint () şeklindedir. İkinci ilginç metod update metodudur. Bu metod public void update (Graphics g) şeklinde tanımlanmıştır. Update metodu çağırıldığında Graphics metodu sistem tarafından otomatik olarak gönderilir. Graphics2D sınıfı Graphics sınıfının bir alt sınıfı olarak tanımlanmıştır. Bu sınıf Graphicss sınıfına göre çok daha kompleks çizimler yapabilen metodlara sahiptir. Burada graphics ve Graphics2D de yer alan bazı sınıf ve çizim tekniklerini yakından inceleyeceğiz. 1.6.1.1 drawString, drawChars ve drawBytes metotları Graphics sınıfının altmetodları olan bu metotların tanımları şu şekilde verilmiştir. public abstract void drawString( String stringYazı, int x,int y) public void drawChars( char charYazı[], int baslangıçindeksi,int yazılacakharfsayısı, int x,int y) public void drawBytes( byte byteYazı[], int başlangıçindeksi,int yazılacakharfsayısı, int x,int y) drawString metotu bir string değişkenini verilen x ve y koordinatlarından başlayarak çizer. DrawChars bir boyutlu Char tipi değişken dizisini başlangiçindeksi indeksinden baslayarak yazılacakharfsayısı kadar kısmını x ve y koordinatlarından başlıyarak çizer. DrawByte metotu da drawChars metotu gibidir tek değişikliği Byte türü boyutlu değişken kullanmasıdır. Program 6.1. de bu metotların kullanılmasını açıklayan bir program verilmiştir. Program 1.6.2-1 : ciz.java programı : drawString,drawChars,drawBytes metotlarının kullanılması import java.applet.Applet; import java.awt.*; public class ciz extends Applet { private String s ="Bunu drawString Metoduyla yazdır"; private char c[]={'c','h','a','r','s',' ','8'}; private byte b[]={'b','y','t','e',25,26,27}; public void paint(Graphics g) { g.setColor(new Color(0,0,100)); g.setFont(new Font("SansSerif",Font.PLAIN,24)); g.drawString(s,100,25); g.drawChars(c,2,3,100,50); g.drawBytes(b,0,5,100,75); } } Şekil 1.6.2-2 drawString drawChars drawBytes metotlarını kullanan ciz programının Applet çıktısı Şimdi aynı işlemi ve aynı metodları Graphics2D üzerinden yaptıralım : Program 1.6.2-2 : ciz2DSWF_2000.java programı : drawString,drawChars,drawBytes metotlarının swing JFrame ve Graphics2D ile birlikte kullanılması import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class ciz2DSWF_2000 extends JFrame { final static Color bg = Color.white; final static Color fg = Color.black; final static Color red = Color.red; final static Color white = Color.white; private String s ="Bunu drawString Metoduyla yazdır"; private char c[]={'k','a','r','e','k','t','e','r','l','e','r'}; public ciz2DSWF_2000() { //Initialize drawing colors super("String character çizimi"); setBackground(bg); setForeground(fg); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setFont(new Font("TimesRoman",Font.BOLD,14)); g2.drawString(s,100,50); //ikinci charecterden başlayarak 7 character yaz. g2.drawChars(c,1,7,100,100); } //===================================================== public static void main(String[] args) { ciz2DSWF_2000 pencere= new ciz2DSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Burada hemen belirtelimki swing sınıflarını kullanırken Graphics2D sınıfları kullanmak zorunda değiliz, ama burada genel olarak swing ve Graphics2D kullanımlarını birlikte sunacağız. Bu programın çıktısı da bir önceki programın çıktısında olduğu gibidir : Şekil 1.6.2-3 drawString drawChars metotlarını kullanan ciz2DSWF_2000 programının swing JFrame çıktısı Programdan da görüleceği gibi paint metodu yine Graphics cinsinden çağırılmakta, daha sonra Graphics2D g2 = (Graphics2D)g; Kullanılarak adres Graphics2D sınıfından nesneye yüklenmektedir. 1.6.3 RENK KONTROLÜ Appletlerde renk controlu Color sınıfını kullanarak yapılır. Renk olusumunda monitör ve Tv de kullanılan RGB (Red-Green-Blue=Kırmızı-Yesil-Mavi) sistemi temel alınır. Bu üç renk monitorde 0-255 arası değerler alabilir. Üç rengin karışımı toplam 256*256*256 renk tanımlar. Color sınıfı kurucu metotları şu şekilden tanımlanır. public Color( int kirmizi,int yesil,int mavi) //her renk 0-255 arası public Color(float kirmizi,float yeşil,float mavi) //her renk 0.0-1.0 arası Color sınıfında ayrıca renk degerlerini okuyabildiğimiz public int getRed() // Kırmızı tonunu oku public int getGreen()//Yesil tonunu oku public int getBlue()//Mavi tonunu oku public abstract Color getColor() //rengi oku metotları ve rengi değiştirebildiğimiz public abstract Color setColor(Color c) metotu mevcuttur. Color sınıfında sabit olarak tanımlanmış : Tablo 1.6.3-1 Color sınıfında tanımlanmış sabir renkler: Renk sabiti public final static Color orange public final static Color pink public final static Color cyan public final static Color magenta Renk portakal Pembe camgöbeği Mor RGB değeri 255,200,0 255,175,175 0,255,255 255,0,255 public final static Color yellow public final static Color black public final static Color white public final static Color gray public final static Color lightGray public final static Color darkGray public final static Color red public final static Color green public final static Color blue Sarı Siyah Beyaz Gri Açık gri Koyu Gri kırmızı Yeşil mavi 255,255,0 0,0,0 255,255,255 128,128,128 192,192,192 64,64,64 255,0,0 0,255,0 0,0,255 Color sınıfının daha iyi anlaşılabilmesi amacıyla Color sınıfının bir alt sınıfı olan renk sınıfını tanımladık. Program 1.6.3-1 : Color sınıfının alt sınıfı renk sınıfını tanımlayan renk.java programı : import java.io.*; import java.awt.*; import java.applet.Applet; public class renk extends Color { public final static renk kirmizi=new renk(255,0,0); public final static renk mavi=new renk(0,0,255); public final static renk siyah=new renk(0,0,0); public final static renk camgobegi=new renk(0,255,255); public final static renk koyugri=new renk(64,64,64); public final static renk gri=new renk(128,138,128); public final static renk yesil=new renk(0,255,0); public final static renk acikgri=new renk(192,192,192); public final static renk mor=new renk(255,0,255); public final static renk portakal=new renk(255,200,0); public final static renk pembe=new renk(255,175,175); public final static renk beyaz=new renk(255,255,255); public final static renk sari=new renk(255,255,0); public final static renk acikmavi=new renk(150,206,237); public final static renk lacivert=new renk(0,0,128); //burada kendi yeni renginizi tanımlayabilirsiniz. public renk(float kirmizi,float yesil, float mavi) {super(kirmizi,yesil,mavi);} public renk(double kirmizi,double yesil, double mavi) {super((float)kirmizi,(float)yesil,(float)mavi);} public renk(int kirmizi,int yesil, int mavi) {super(kirmizi,yesil,mavi);} public renk(int RGB) {super(RGB);} public renk(renk r) {super(r.getKirmizi(),r.getYesil(),r.getMavi());} public int getKirmizi() {return getRed();} public int getYesil() {return getGreen();} public int getMavi() {return getBlue();} public int getKYM() {return getRGB();} public Color toColor() {return (Color)this;} public static renk toRenk(Color r) {return (renk)r;} public String toString() {return "renk[ kirmizi "+getKirmizi()+" mavi "+getMavi()+" yesil "+getYesil()+"]";} //metodlar : bu metodlar direk olarak extends sözcüğüyle (bir üst sınıfta) tanımlanmıştır //static int HSBtoRGB(float hue,float saturation,float brightness) //getRed(),getGreen(),getBlue(),getRGB() } Renk sınıfını bir çok yerde Color sınıfı yerine kullanabiliriz. Kullanamadığımız durumlarda cast işlemcisi (Color) kullanılabilir. Applette renk değiştirdiğimiz küçük bir örnek program yazalım : Program 1.6.3.2 : renkTest.java import java.awt.*; import java.applet.Applet; public class RenkTest extends Applet { private int kirmizi,yesil,mavi; public void init() { kirmizi=150; yesil=255; mavi=125; // arka palanın rengi mavi olarak veriliyor setBackground(renk.mavi); } public void paint(Graphics g) { // yazının rengi 100,255,125 olarak alındı g.setColor(new renk(kirmizi,yesil,mavi)); g.drawString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",50,33); showStatus("Su andaki arkaplan rengi : "+getBackground()); } } Şekil 1.6.3-1 Renk.html çıktısı Bu programda kirmizi değeri 100, yesil değeri 255 ve mavi degeri de 125 alınmış ve setColor deyimiyle yeni renk tanımlanmıştır. Arka plan rengi ise public void setBackground(Color c) Metotunu kullanarak maviye dönüştürülmüştür. Aynı programın JApplet eşidi olan, aynı zamanda java komutuyla kendi çerçevesini de oluşturabilen bir eşdeğerini verelim. Renk2D sınıfında Graphics2D sınıfı kullanılmaktadır. Grafik kalitesini karşılaştırabilirsiniz. Program 1.6.3-3 : Renk2D.java programı import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class Renk2D extends JApplet { private int kirmizi,yesil,mavi; public void init() { kirmizi=100; yesil=255; mavi=125; setBackground(new Color(0,0,255)); setForeground(new Color(kirmizi,yesil,mavi)); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setPaint(new Color(kirmizi,yesil,mavi)); g2.drawString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",50,33); g2.drawString("Su andaki renk : "+g2.getColor(),50,53); } public static void main(String s[]) { JFrame f = new JFrame("Renk2D"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); JApplet applet = new Renk2D(); f.getContentPane().add("Center", applet); applet.init(); f.pack(); f.setSize(new Dimension(350,100)); f.show(); } } Renk2D sınıfının çıktısı : Şekil 1.6.3-2 Renk2D.java çıktısı Swing sınıfında renk seçimini yapabilmek amacıyla JColorChooser adlı bir program tanımlanmıştır. Bu programı kullanarak renk grafik kutusunun rengini değiştirebildiğimiz renkSeciciSWF swing JFrame programı aşağıda verilmiştir. Program 1.6.3-4 : renkSeciciSWF_2000.java import javax.swing.*; // java swing sinifini cagir import java.awt.*; // java pencere kullanma sinifini cagir import java.awt.event.*; // java pencereyi dinleme sinifini cagir import BasicWindowMonitor; public class renkSeciciSWF_2000 extends JFrame implements ActionListener { // Renk secme ornegi JButton renkdegistir; Color r=Color.lightGray; Container c; // pencereyi baslatma metodu public renkSeciciSWF_2000() { super("JColorChoser "); c=getContentPane(); c.setLayout(new FlowLayout()) ; renkdegistir=new JButton("renk değiştirmek için düğmeye basınız"); renkdegistir.addActionListener(this); c.add(renkdegistir); } // girdi alanindaki olan olaylari dinleme metodu public void actionPerformed(ActionEvent e) { r=JColorChooser.showDialog(this,"Renk seçiniz :",r); if(r==null) r=renk.acikgri; c.setBackground(r); repaint(); } //===================================================== public static void main(String[] args) { renkSeciciSWF_2000 pencere= new renkSeciciSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.6.3-3 renkSeciciSWF_2000.java java swing frame programı ve JcolorChooser renk seçme programı Renk seciciSWF_2000.java programında temel olarak JFrame grafik çıktısı kullanılmıştır. Bu programın içerisinde çağırılan r=JColorChooser.showDialog(this,"Renk seçiniz :",r); metodu java kütüphanesinde yer almaktadır. ShowDialog metodu bize Color sınıfındaki renk değişkenini aktarmakta ve c.setBackground(r); komutuylada arka plan renklerini değiştirmektedir. 1.6.4 YAZI KONTROLU Appletlerde yazı kontrolu Font sınıfını kullanarak yapılır. Şekil 5.3.1 de java 1.1.5 de kullanılabilecek tüm yazı stillerinin (font) listesini veren stil2D.java programını görüyoruz. Yine aynı programın swing JApplet eşitini verelim : Program 1.6.4-1 : stil2D.java programı, java kütüphanesinde mevcut olan yazı sitillerini gösterir import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class stil2D extends JApplet { public void init() { setBackground(Color.white); setForeground(Color.black); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; String stilListesi[]; stilListesi=getToolkit().getFontList(); int y=15; for(int i=0;i<stilListesi.length;i++) { g2.drawString(stilListesi[i],15,y); y+=15; } } public static void main(String s[]) { JFrame f = new JFrame("stil2D"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); JApplet applet = new stil2D(); f.getContentPane().add("Center", applet); applet.init(); f.pack(); f.setSize(new Dimension(550,300)); f.show(); } } Şekil 1.6.4-1 : stil2D.java program çıktısı Bu yazı sitillerinden birisi asağıda verilen yazı tiplerinden birisiyle beraber ve verilen belli bir yazı boyutunda gösterilebilir. public final static int PLAIN : düz yazı sitili public final static int BOLD : Kalın yazı sitili public static int ITALIC : İtalik (yatık) yazı sitili bu tanımlardaki final sözcüğü bu ifadelerin değişken değil sabit olduğunu gösterir.Font sınıfının kurucu metotu şu şekildedir. Public Font( String s, int yazı_sitili, int harf_boyutu); Bir appletin yazı sitili Graphics sınıfındaki setFont metotuyla değiştirilebilir. Public abstract void setFont(Font f) Örnek olarak aşağıdaki deyimi verebiliriz : g.setFont(new Font(“Serif”,Font.BOLD,12); Şimdi setFont metotunu küçük bir örnekte kullanarak gösterelim : Program 1.6.4-2 : : RenkFont2D.java swing JApplet programı, java kütüphanesindeki Font uygulamasını gösterir import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class RenkFont2D extends JApplet { private int kirmizi,yesil,mavi; public void init() { kirmizi=100; yesil=255; mavi=125; setBackground(new Color(0,0,255)); setForeground(new Color(kirmizi,yesil,mavi)); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(new Color(kirmizi,yesil,mavi)); setBackground(new Color(0,0,255)); Font font=g2.getFont(); g2.setFont(new Font(font.getName(),Font.BOLD,24)); g2.drawString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",50,33); g2.drawString("Su andaki font : "+g.getFont(),50,70); g2.setFont(new Font(font.getName(),Font.PLAIN,12)); g2.drawString("Su andaki font : "+g.getFont(),50,85); } public static void main(String s[]) { JFrame f = new JFrame("RenkFont2D"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); JApplet applet = new RenkFont2D(); f.getContentPane().add("Center", applet); applet.init(); f.pack(); f.setSize(new Dimension(550,200)); f.show(); } } Şekil 1.6.4-1 RenkFont2D.java JFrame programı, java kütüphanesindeki Font uygulamasını gösterir 1.6.5 ÇiZGi ÇiZiMi Javada çizgi çizmek için kullanılan temel metot Graphics sınıfında drawLine metotudur. Bu metot Graphics sınıfında tanımlanmıştır. Kurucu metotu : Public abstract void drawLine( int x1, // ilk noktanın x koordinatı int y1, //ilk noktanın y koordinatı int x2, // ikinci noktanın x koordinatı int y2) //ikinci noktanın y koordinatı Graphics2D sınıfında ise çizgi çiziminde java.awt.geom kütüphanesinde tanımlanan Line2D sınıfı, Graphics2D sınıfındaki draw metoduyla birlikte kullanılır. Bir küçük örnek problem cizgiciz.java'da drawLine metotunun kullanımını görelim: Program 1.6.5-1 : Çizgi çizim örneği cizgiciz.java import java.applet.*; import java.applet.Applet; import java.awt.*; public class cizgiciz extends Applet { public void paint(Graphics g) { g.setColor(new Color(0,0,0)); g.setFont(new Font("SansSerif",Font.PLAIN,24)); g.drawLine(10,10,230,95); } } Şekil 1.6.5-2 çizginin appletde görünümü Şimdi aynı problemin yaklaşık eşidini cizgiSWF_2000.java programında görelim : Program 1.6.5-2: Çizgi çizim örneği cizgiSWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import renk; public class cizgiSWF_2000 extends JFrame { final static Color bg = Color.white; final static Color fg = Color.black; final static Color red = Color.red; final static Color white = Color.white; public cizgiSWF_2000() { //Initialize drawing colors super("çizgi çizimi"); setBackground(bg); setForeground(fg); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.black); Line2D l=new Line2D.Double(50,50,100,75); g2.draw(l); g2.setStroke(new BasicStroke(1f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); Line2D l1=new Line2D.Double(50,150,100,175); g2.draw(l1); } //===================================================== public static void main(String[] args) { cizgiSWF_2000 pencere= new cizgiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.6.5.3 çizginin cizgiSWF_2000 JFrame çıktısında görünümü Bu programdaki temel çizim metodlarına göz atalım : Graphics2D g2 = (Graphics2D)g; Graphics sınıfı g nesnesini Graphics2D sınıfi g2 nesnesine aktarır. g2.setPaint(Color.black); Grafik çizim rengini siyah olarak tanımlar. Line2D l=new Line2D.Double(50,50,100,75); İlk devamlı çizginin koordinatlarını tanımlar g2.draw(l); İlk devamli çizgiyi çizer g2.setStroke(new BasicStroke(1f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); Çizgiyi noktalı çizme komutunu tanımlar Line2D l1=new Line2D.Double(50,150,100,175); Noktalı çizginin koordinatlarını tanımlar g2.draw(l1); Noktalı çizgiyi çizer. Burada bizim için yeni bir kavram olan noktalı çizgi çizmenin detaylarına biraz göz atalım. Noktalıçizgi oluşturmak için temel olarak setStroke metodunu kullanıyoruz. Bu metodun içinde Basic Stroke metodu bir nesne yaratıyoruz. BasicStroke türü nesne çizgi kalınlığı, çizgi bağlama sitili,çizgi ucu bitiş sitili ve çizgi-boşluk bilgisi içerir. Çizgi kalınlığı çizgi istikametine dik olarak ölçülür. Çizgi kalınlığı 1f (buradaki f sayının float temel değişken türü olduğunu belitir) 0.35277 milimetreye eşittir. Yalnız transformasyon kullanıldığında bu değişebilir. Transformasyonlara biraz sonra değineceğiz. Çizgi bağlama sitili iki çizginin birbirine bağlandığı noktadaki şeklini belirler. BasicStroke sınıfında 3 bağlanma sitili mevcuttur. Bunlar : JOIN_BEVEL JOIN_MITER JOIN_ROUND sitilleridir. Çizgi ucu bitiş sitilleri boş çizgi ucunun şeklini belirtir. Yine temel olarak 3 BasicStroke çizgi ucu bitiş sitili mevcuttur. Bunlar : CAP_BUTT CAP_ROUND CAP_SQUARE sitilleridir. Çizgi boşluk bilgisi birbirini takip eden şeffaf ve görünür çizgi parçacıkları ve bunların boylarını tanımlar. Bir ara boşluk değişkeni ve çizgi boşluk çizgi boşluk olmak üzere bir seriden oluşur. Son olarak son rakam serinin hangi elemanından çizime başlanacağını gösterir Örneğin: g2.setStroke(new BasicStroke(1,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,0,new float[] {10,5,2,5},0)); 10 boyutu bir çizgi 5 boşluk 2 boyutu çizgi 5 boşluk belirtir. g2.setStroke(new BasicStroke(1,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,5,new float[] {5},0)); 5 boşluk ve 5 çizgi belirtir. cizgiSWF_2000.java programında çeşitli stoke tiplerini deneyebilirsiniz. 1.6.6 DiKDÖRTGEN ÇİZİMİ Java Graphics sınıfında dikdörtgen çizmek için kullanılan temel metot drawRect metotudur. Bu metot Graphics sınıfında tanımlanmıştır. Bu metotların tanımı : Public abstract void drawRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik) // dikdörtgenin yüksekliği Bu metota ilave olarak dikdörtgenin içini verilen renkte boyayan Public abstract void fillRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik) // dikdörtgenin yüksekliği ve dikdörtgeni arkaplan renginde boyayan (silen) Public abstract void clearRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik) // dikdörtgenin yüksekliği metotları mevcuttur. DrawRect ve fillRec metotunun kullanımı Program 6.6 da verilmiştir. Program 1.6.6-1 : dikdortgenCiz.java import java.applet.Applet; import java.awt.*; public class dikdortgenCiz extends Applet { public void paint(Graphics g) { g.setColor(new Color(255,0,0)); g.drawRect(10,10,100,50); g.fillRect(129,10,100,50); } } Şekil 1.6.6-1 dikdortgenCiz.java programı ve dikdortgenCiz.html appleti Graphics2D metodunda dikdörtgen çizmek için g2.draw(new Rectangle2D.Double(x, y,dikdortgenEn,dikdortgenYukseklik)); kullanılır. Dikdörtgenin içini maviye boyamak için g2.setPaint(Color.blue); Rectangle2D dikdortgen2=new Rectangle2D.Double(50,50,100,40); g2.fill(dikdortgen2); kullanılabilir. Graphics2D de tek renk yerine değişen bir renk profiliyle boyamak da mümkündür. Örneğin : final static Color beyaz=Color.white; final static Color siyah=Color.black; GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Rectangle2D dikdortgen4=new Rectangle2D.Double(250,50,100,40); g2.fill(dikdortgen4); kodu dikdörtgeni kırmızıdan beyaza dönüşen bir spekturumla boyar. Tüm bu kodu bir örnek problemde gösterelim : Program 1.6.6-2: dikdortgenSWF-2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class dikdortgenSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public dikdortgenSWF_2000() { super("Dikdörtgen çizimi"); setBackground(Color.lightGray); setForeground(siyah); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); Rectangle2D dikdortgen1=new Rectangle2D.Double(55,55,90,30); g2.fill(dikdortgen1); g2.setPaint(siyah); Rectangle2D dikdortgen2=new Rectangle2D.Double(50,50,100,40); g2.draw(dikdortgen2); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); Rectangle2D dikdortgen3=new Rectangle2D.Double(50,150,100,40); g2.draw(dikdortgen3); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Rectangle2D dikdortgen4=new Rectangle2D.Double(250,50,100,40); g2.fill(dikdortgen4); GradientPaint kirmizidanmaviye=new GradientPaint(250,150,kirmizi,350,190,Color.blue); g2.setPaint(kirmizidanmaviye); Rectangle2D dikdortgen5=new Rectangle2D.Double(250,150,100,40); g2.fill(dikdortgen5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); g2.draw(dikdortgen5); } //===================================================== public static void main(String[] args) { dikdortgenSWF_2000 pencere= new dikdortgenSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.6-2 çeşitli dikdörtgen çizimlerinin dikdortgenSWF_2000 JFrame çıktısında görünümü Graphics sınıfında Köşeleri yuvarlatılmış dikdörtgen çizmek içinse drawRoundRect metotu kullanılır Public abstract void drawRoundRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik, // dikdörtgenin yüksekliği int koseeni, // yuvarlak kosenin eni int koseyuksekligi )// yuvarlak kosenin yuksekligi Bu metota ilave olarak dikdörtgenin içini verilen renkte boyayan Public abstract void fillRoundRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik, // dikdörtgenin yüksekliği int koseeni, // yuvarlak kosenin eni int koseyuksekligi )// yuvarlak kosenin yuksekligi metotu da paralel olarak tanımlanmıştır. Yine bir örnek problemde bu tanımı kullanacak olursak : Program 1.6.6-3 : yuvarlakKoseliDikdortgenCiz.java programı import java.applet.Applet; import java.awt.*; public class yuvarlakKoseliDikdortgenCiz extends Applet { public void paint(Graphics g) { g.setColor(new Color(0,0,255)); g.setFont(new Font("SansSerif",Font.PLAIN,12)); g.drawRoundRect(10,10,100,100,15,15); g.fillRoundRect(120,10,100,100,15,15); } } Şekil 1.6.6-3 yuvarlakKoseliDikdortgenCiz.html appleti Graphics2D sınıfında koşeleri yuvarlatılmış dikdörtgen çizmek için : g2.draw(new Rectangle2D.Double(x, y,dikdortgenEn,dikdortgenYukseklik,xKöşeYarıçapı,yKöşeYarıçapı)); metodları kullanılır. Rakamsal örnek verirsek : g2.setPaint(Color.blue); RoundRectangle2D dikdortgen2=new RoundRectangle2D.Double(50,50,100,40,15,15); g2.draw(dikdortgen2); kullanılabilir. Dikdörtgenin içini boyamak içinse: g2.setPaint(Color.blue); RoundRectangle2D dikdortgen2=new RoundRectangle2D.Double(50,50,100,40,15,15); g2.fill(dikdortgen2); kodu kullanılabilir. Elbette bir önceki örnekte olduğu gibi spektrumlu boyama da mümkündür. Tüm bu kodu bir örnek problemde gösterelim Program 1.6.6-4 : yuvarlakKoseliDikdortgenSWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class yuvarlakKoseliDikdortgenSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public yuvarlakKoseliDikdortgenSWF_2000() { super("Yuvarlak Köşeli Dikdörtgen Çizimi"); setBackground(Color.lightGray); setForeground(siyah); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); RoundRectangle2D dikdortgen1=new RoundRectangle2D.Double(55,55,90,30,15,15); g2.fill(dikdortgen1); g2.setPaint(siyah); RoundRectangle2D dikdortgen2=new RoundRectangle2D.Double(50,50,100,40,15,15); g2.draw(dikdortgen2); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); RoundRectangle2D dikdortgen3=new RoundRectangle2D.Double(50,150,100,40,15,15); g2.draw(dikdortgen3); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); RoundRectangle2D dikdortgen4=new RoundRectangle2D.Double(250,50,100,40,15,15); g2.fill(dikdortgen4); GradientPaint kirmizidanmaviye=new GradientPaint(250,150,kirmizi,350,190,Color.blue); g2.setPaint(kirmizidanmaviye); RoundRectangle2D dikdortgen5=new RoundRectangle2D.Double(250,150,100,40,15,15); g2.fill(dikdortgen5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); g2.draw(dikdortgen5); } //===================================================== public static void main(String[] args) { yuvarlakKoseliDikdortgenSWF_2000 pencere= new yuvarlakKoseliDikdortgenSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.6-4 çeşitli köşesi yuvarlatılmış dikdörtgen çizimlerinin yuvarlakKoselidikdortgenSWF_2000 JFrame çıktısında görünümü Graphics’de 3 boyutlu dikdortgen çizen draw3DRect ve fill3Drect metotları mevcutttur. Bu metotların tanımları şu şekilde verilmiştir. Public abstract void draw3DRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik, // dikdörtgenin yüksekliği boolean yukarıkaldırma) // yukarı kalkık 3üncü boyut Public abstract void fill3DRect( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // dikdörgenin genişliği int yukseklik, // dikdörtgenin yüksekliği boolean yukarıkaldırma) // yukarı kalkık 3üncü boyut Program 1.6.6-5 : ucBoyutluDikdortgenCiz.java programı import java.applet.Applet; import java.awt.*; public class ucBoyutluDikdortgenCiz extends Applet { public void paint(Graphics g) { g.setColor(Color.yellow); g.setFont(new Font("SansSerif",Font.PLAIN,12)); g.draw3DRect(10,10,100,100,true); g.fill3DRect(120,10,100,100,true); g.draw3DRect(10,120,100,100,false); g.fill3DRect(120,120,100,100,false); } } Şekil 1.6.6-5 ucBoyutluDikdortgenCiz.html appleti 1.6.7 ÇİZİLEN ŞEKİLLERİN DEĞİŞTİRİLEREK ÇİZİMİ (TRANSFORM) Graphics2D sınıfında çizilen şekiller dinamik olarak değiştirilebilirler. Bu değişimler döndürme, köşedençekip uzatma gibi değişik işlemler olabilir. Bu değiştirme prosesini önce bir örnekle gösterelim, sonrada izah etmeye çalışalım. Program 1.6.7-1 : donmusDikdortgenSWF-2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class donmusDikdortgenSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public donmusDikdortgenSWF_2000() { super("Dödürülmüş - çekilmiş Dikdörtgen çizimleri"); setBackground(Color.lightGray); setForeground(siyah); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); Rectangle2D dikdortgen1=new Rectangle2D.Double(55,55,90,30); AffineTransform at= AffineTransform.getRotateInstance(45,50,50); g2.setTransform(at); g2.fill(dikdortgen1); g2.setPaint(siyah); Rectangle2D dikdortgen2=new Rectangle2D.Double(50,50,100,40); g2.draw(dikdortgen2); g2.setTransform(new AffineTransform()); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); Rectangle2D dikdortgen3=new Rectangle2D.Double(50,150,100,40); AffineTransform at1= AffineTransform.getScaleInstance(1.5,1.5); g2.setTransform(at1); g2.draw(dikdortgen3); g2.setTransform(new AffineTransform()); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Rectangle2D dikdortgen4=new Rectangle2D.Double(250,50,100,40); AffineTransform at2= AffineTransform.getShearInstance(0.4,0); g2.setTransform(at2); g2.fill(dikdortgen4); g2.setTransform(new AffineTransform()); GradientPaint kirmizidanmaviye= new GradientPaint(250,150,kirmizi,350,190,Color.blue); g2.setPaint(kirmizidanmaviye); Rectangle2D dikdortgen5=new Rectangle2D.Double(250,150,100,40); g2.fill(dikdortgen5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); AffineTransform at3= AffineTransform.getTranslateInstance(0.0,10.0); g2.setTransform(at3); g2.draw(dikdortgen5); g2.setTransform(new AffineTransform()); } //===================================================== public static void main(String[] args) { donmusDikdortgenSWF_2000 pencere= new donmusDikdortgenSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.7-1 çeşitli şekli değiştirilmiş dikdörtgen çizimlerinin donmusDikdortgenSWF-2000 JFrame çıktısında görünümü AffineTransform at= AffineTransform.getRotateInstance(x,y,açıDerece); Şekli x,y noktası etrafında açıDerece kadar saat akranının tersi yönde döndürür. AffineTransform at2= AffineTransform.getShearInstance(xÇekişi,yÇekişi); Şekli x ekseninde xÇelişi kadar, y ekseninde yÇekişi kadar uzatır (orijinal şekilden elastik ve üst köşesi tutturulmuş şekilde) AffineTransform at1= AffineTransform.getScaleInstance(xBoyutFaktörü,yBoyutFaktörü); Şeklin boyutunu xBoyutFaktörü,yBoyutFaktörü faktörleriyle çarparak büyütür. AffineTransform at3= AffineTransform.getTranslateInstance(xTaşımaFaktörü,yTaşımaFaktörü); Şekli yerinden hareket ettirir. Orijinal transforma geri dönmek için : g2.setTransform(new AffineTransform()); metodu çağırılabilir. 1.6.8 OVAL VE AÇILI OVAL ÇİZİMİ Graphics sınıfıOval çizimi için drawOval ve fillOval metotları kullanılır bu metotların tanımı şöyledir : Public abstract void drawOval( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // ovalin genişliği int yukseklik) // ovalin yüksekliği Public abstract void fillOval( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // ovalin genişliği int yukseklik) // ovalin yüksekliği (x1,y1) koordinatının ovalle ilişkisini daha iyi anlayabilmek için aşağıdaki grafiği verebiliriz : 06023.JPG Şekil 1.6.8-1 Oval tanımı koordinat sistemi Oval programını küçük bir örnek programda kullanalım : Program 1.6.8-1 : daireCiz.java programı import java.applet.Applet; import java.awt.*; public class daireCiz extends Applet { public void paint(Graphics g) { g.setColor(new Color(0,0,255)); g.drawOval(10,10,50,50); g.fillOval(70,10,50,50); } } Şekil 1.6.8-2 daireCiz.html apleti Graphics ile bir ovalin tamamını değilde sadece bir bölümünü çizmek dilenilirse, drawArc ve fillArc metotları kullanılabilir. Bu metotların tanımı : Public abstract void drawArc( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // ovalin genişliği int yukseklik, // ovalin yüksekliği int başlangıçaçısı, //arkın başlangıç açısı, derece int çizimaçısı) // arkın çizim açısı, derece Public abstract void fillArc( int x1, // üst tepe noktanın x koordinatı int y1, // üst tepe noktanın y koordinatı int en, // ovalin genişliği int yukseklik, // ovalin yüksekliği int başlangıçaçısı, //arkın başlangıç açısı, derece int çizimaçısı) // arkın çizim açısı, derece Şimdi de bu metotu kullanan bir bilgisayar programı yazalım : Program 1.6.8-2 : arcCiz.java, arc çizimi programı import java.applet.Applet; import java.awt.*; public class arcCiz extends Applet { public void paint(Graphics g) { g.setColor(new Color(0,0,255)); g.setFont(new Font("SansSerif",Font.PLAIN,12)); g.drawOval(70,10,50,50); g.drawArc(10,10,50,50,30,60); g.fillArc(70,10,50,50,30,60); } } Şekil 1.6.8-3 arcCiz.html apleti Graphics2D sınıfında oval (elips) çizmek için : Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); Ellipse2D elips1=new Ellipse2D.Double(x,y,en,yükseklik); g2.draw(elips1); kullanabiliriz. İçini boyamak için ise : g2.fill(elips1); metodunu kullanırız. Yine örneğimizde kullanacak olursak : Program 1.6.8-3 : elipsSWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class elipsSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public elipsSWF_2000() { super("Elips çizimi"); setBackground(Color.lightGray); setForeground(siyah); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); Ellipse2D elips1=new Ellipse2D.Double(55,55,90,30); g2.fill(elips1); g2.setPaint(siyah); Ellipse2D elips2=new Ellipse2D.Double(50,50,100,40); g2.draw(elips2); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); Ellipse2D elips3=new Ellipse2D.Double(50,150,100,40); g2.draw(elips3); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Ellipse2D elips4=new Ellipse2D.Double(250,50,100,40); g2.fill(elips4); GradientPaint kirmizidanmaviye=new GradientPaint(250,150,kirmizi,350,190,Color.blue); g2.setPaint(kirmizidanmaviye); Ellipse2D elips5=new Ellipse2D.Double(250,150,100,40); g2.fill(elips5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); g2.draw(elips5); } //===================================================== public static void main(String[] args) { elipsSWF_2000 pencere= new elipsSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.8-4 çeşitli oval (elips) çizimlerinin elipsSWF_2000JFrame çıktısında görünümü 1.6.9 ÇİZİMİN SEÇİLEN BİR RESİMLE DOLDURULMASI Graphics2D sınıfında bir grafiği boyarken bir resim dosyasının içinde tanımlanan bir motifi de kullanabiliriz. Program 1.6.9-1 :textureElipsSWF_2000.java import javax.swing.*; import java.awt.geom.*; import java.awt.image.*; import java.net.URL; import java.awt.*; public class textureElipsSWF_2000 extends JFrame { TexturePaint tp = getImageTexture("sybex.gif"); final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public textureElipsSWF_2000() { super("Elips çizimi"); setBackground(beyaz); setForeground(siyah); } public TexturePaint getImageTexture(String imageFile) { URL url = getClass().getResource(imageFile); Image img = getToolkit().getImage(url); try { MediaTracker tracker = new MediaTracker(this); tracker.addImage(img, 0); tracker.waitForID(0); } catch (Exception e) {} int width = img.getWidth(this); int height = img.getHeight(this); BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics g = buffImg.getGraphics(); g.drawImage(img, 0, 0, this); Rectangle2D rect = new Rectangle(0, 0, width, height); return new TexturePaint(buffImg, rect); } //************ public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(tp); Ellipse2D elips1=new Ellipse2D.Double(55,55,90,30); g2.fill(elips1); g2.setPaint(siyah); Ellipse2D elips2=new Ellipse2D.Double(50,50,100,40); g2.draw(elips2); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); Ellipse2D elips3=new Ellipse2D.Double(50,150,100,40); g2.draw(elips3); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Ellipse2D elips4=new Ellipse2D.Double(250,50,100,40); g2.fill(elips4); g2.setPaint(tp); Ellipse2D elips5=new Ellipse2D.Double(250,150,100,40); g2.fill(elips5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); g2.draw(elips5); } //===================================================== public static void main(String[] args) { textureElipsSWF_2000 pencere= new textureElipsSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(300,300); pencere.setVisible(true); } //************ } Şekil 1.6.9-1 çeşitli oval (elips) çizimlerinin ve arkaplan resimli boyama işleminin textureElipsSWF_2000JFrame çıktısında görünümü Burada texture sybex.gif dosyasından public TexturePaint getImageTexture(String imageFile) metodu kullanılarak aktarılmış ve aynen yeni bir renk gibi çizim ortamında kullanılmıştır. Şimdi de Graphics2D metoduyla arc çizdirmeye bakalım arc yukarda da bahsettiğimiz gibi tamamlanmamış bir elipstir. Program 1.6.9-2 : arcSWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class arcSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public arcSWF_2000() { super("arc çizimi"); setBackground(Color.lightGray); setForeground(siyah); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setPaint(Color.blue); Arc2D arc1=new Arc2D.Double(55,55,90,30,90,270,Arc2D.PIE); g2.fill(arc1); g2.setPaint(siyah); Arc2D arc2=new Arc2D.Double(50,50,100,40,90,270,Arc2D.PIE); g2.draw(arc2); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,3f,new float[] {10f},0f)); g2.setPaint(Color.black); Arc2D arc3=new Arc2D.Double(50,150,100,40,90,270,Arc2D.PIE); g2.draw(arc3); GradientPaint kirmizidanbeyaza=new GradientPaint(250,50,kirmizi,350,90,beyaz); g2.setPaint(kirmizidanbeyaza); Arc2D arc4=new Arc2D.Double(250,50,100,40,90,270,Arc2D.PIE); g2.fill(arc4); GradientPaint kirmizidanmaviye=new GradientPaint(250,150,kirmizi,350,190,Color.blue); g2.setPaint(kirmizidanmaviye); Arc2D arc5=new Arc2D.Double(250,150,100,40,90,270,Arc2D.PIE); g2.fill(arc5); g2.setStroke(new BasicStroke(2f,BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,1f,new float[] {5f},0f)); g2.setPaint(Color.black); g2.draw(arc5); } //===================================================== public static void main(String[] args) { arcSWF_2000 pencere= new arcSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.9-2 çeşitli tamamlanmamış oval (ark) çizimlerinin arcSWF_20000 JFrame çıktısında görünümü 1.6.10 POLYGON ÇİZİMİ Graphics sınıfında Açık ve kapalı polygon şekilleri çizmek için drawPolygon ve fillPolygon metotları kullanılır. Metotların tanımı : public abstract void drawPolygon( int x[], // x koordinat vektörü int y[], // y koordinatı vektörü int nokta sayısı) // nokta sayısı public abstract void drawPolyline( int x[], // x koordinat vektörü int y[], // y koordinatı vektörü int nokta sayısı) // nokta sayısı public abstract void drawPolygon( Polygon p) //Graphics sınıfı metotu public Polygon() //Polygon sınıfı public Polygon( int x[], // x koordinat vektörü int y[], // y koordinatı vektörü int nokta sayısı) // nokta sayısı Metot tanımlarından da görüldüğü gibi polygon int türü vektörle çizilebileceği gibi bu vektörü içinde barındıran Polygon sınıfı bir nesne kullanılarak ta çizilebilir. Örnek olarak üçgen çizen bir program verelim : Program 1.6.10 : ucgenCiz.java, poligon çizim programı import java.applet.Applet; import java.awt.*; public class ucgenCiz extends Applet { public void paint(Graphics g) { int x[]={10,(int)(10+100*Math.cos(Math.PI/3.0)),110,10}; int y[]={100,(int)(100-100*Math.sin(Math.PI/3.0)),100,100}; int x1[]={130,(int)(130+100*Math.cos(Math.PI/3.0)),230,130}; int y1[]; y1=y; g.setColor(new Color(0,0,255)); g.drawPolygon(x,y,4); g.fillPolygon(x1,y1,4); } } Şekil 1.6.10-1 ucgenCiz.java programı ve apleti Graphics2D programında grafik çizdirmek için kullanılan metodlar Graphics sınıfına göre oldukça değişiktir. Burada önce örnek programımızı verelim: Program 1.6.10-2 : polygonSWF.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class polygonSWF extends JFrame { public polygonSWF() { super("Polygon çizimi"); } public void paint(Graphics g) { int x[]={55,67,109,73,83,55,27,37,1,43}; int y[]={0,36,36,54,96,72,96,54,36,36}; Graphics2D g2=(Graphics2D)g; GeneralPath yildiz=new GeneralPath(); yildiz.moveTo(x[0],y[0]); for(int i=1;i<x.length;i++) {yildiz.lineTo(x[i],y[i]);} yildiz.closePath(); g2.translate(200,200); for(int i=0;i<20;i++) { g2.rotate(Math.PI/10.0); g2.setColor(new Color((int)(Math.random()*256),(int)(Math.random()*256), (int)(Math.random()*256))); g2.fill(yildiz); g2.setStroke(new BasicStroke(2)); g2.setColor(Color.black); g2.draw(yildiz); } } public static void main(String[] args) { polygonSWF pencere= new polygonSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.10-2 çeşitli yıldızların (polygonun) çizim ve döndürme işlemi polygonSWF JFrame çıktısında görünümü bu programda önce int x[]={55,67,109,73,83,55,27,37,1,43}; int y[]={0,36,36,54,96,72,96,54,36,36}; GeneralPath yildiz=new GeneralPath(); yildiz.moveTo(x[0],y[0]); for(int i=1;i<x.length;i++) {yildiz.lineTo(x[i],y[i]);} yildiz.closePath(); ile yıldız tanımlanmış, ve g2.draw(yildiz); ile çizilmiş, ve g2.fill(yildiz); ile içi boyanmıştır. Ayrıca g2.translate(200,200); ile çizim başlama noktası 200,200 noktasına kaydırılmış ve g2.rotate(Math.PI/10.0); komutu ile döndürülmüştür. Programda setPAint kullanarak tesadüfi renkler seçilmiş ve yıldız çizimi doldurulmuştur. Programda kullanılan GeneralPath yildiz=new GeneralPath(); Terimine özellikle dikkatinizi çekmek isteriz. Bu terim GeneralPath nesnesi yıldızı tanımlar. 1.6.11 GENELLEŞTİRİLMİŞ EĞRİ ÇİZİMİ GeneralPath nesnesi kullanarak polinomdan çok daha kompleks çekiller de tanımlayabiliriz. Program 1.6.11-1 : generalPathSWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class generalPathSWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public generalPathSWF_2000() { super("ikinci ve üçüncü dereceden genel eğri çizimi"); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); setBackground(Color.lightGray); setForeground(siyah); Dimension boyut=getSize(); int dx=boyut.width; int dy=boyut.height; g2.setPaint(siyah); g2.setStroke(new BasicStroke(3)); g2.draw3DRect(0,0,dx-3,dy-3,true); g2.draw3DRect(3,3,dx-7,dy-7,false); GeneralPath sekil=new GeneralPath(GeneralPath.WIND_EVEN_ODD); sekil.moveTo(20,20); //quadratik ekleme sekil.quadTo(160,120,245,45); //kübik ekleme sekil.curveTo(195,95,295,145,245,195); sekil.curveTo(-80,110,345,110,20,195); sekil.curveTo(400,250,200,250,20,20); g2.draw(sekil); } //===================================================== public static void main(String[] args) { generalPathSWF_2000 pencere= new generalPathSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.11-1 ikinci ve üçüncü dereceden genel eğri çizimi, generalPathSWF_2000, JFrame çıktısında görünümü Bu çizimdeki çizginin oldukça düzgün olduğuna dikkatinizi çekeriz. Bunu sağlayan temel komut : g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Komutudur. Bu komut çizgileri daha düzgün hale getirir, fakat belli bir hesap ve hafıza kapasitesi harcar. Programı bu komutu çıkararak da çalıştırınız ve aradaki farkları inceleyiniz. Şekli oluşturan temel komutlar: GeneralPath sekil=new GeneralPath(GeneralPath.WIND_EVEN_ODD); sekil.moveTo(20,20); //quadratik ekleme sekil.quadTo(160,120,245,45); //kübik ekleme sekil.curveTo(195,95,295,145,245,195); komutlarıdır. Daha sonra bu şekiller g2.draw(sekil); komutuyla çizdirilmiştir. g2.fill(sekil); komutu burada kullanılmamakla birlikte, geçerli bir komuttur. Programda deneyiniz. Bu programda çizdirilen ikinci dereceden (quadratik eğriler) quadTo ve curveTo metodları kullanılarak oluşturulmuştur. Şimdi de ikinci derece polynom uydurmasını QuadCurve2D sınıfını kullanarak yapan bir programı inceleyelim : Program 1.6.11-2 : curve2SWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class curve2SWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public curve2SWF_2000() { super("ikinci dereceden eğri çizimi"); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); setBackground(Color.lightGray); setForeground(siyah); Dimension boyut=getSize(); int dx=boyut.width; int dy=boyut.height; g2.setPaint(siyah); g2.draw3DRect(0,0,dx-3,dy-3,true); g2.draw3DRect(3,3,dx-7,dy-7,false); g2.setPaint(siyah); QuadCurve2D qc2=new QuadCurve2D.Double(0,125,140,225,225,150); g2.draw(qc2); QuadCurve2D qc2_1=new QuadCurve2D.Double(0,200,155,225,225,170); g2.setPaint(Color.blue); g2.fill(qc2_1); } //===================================================== public static void main(String[] args) { curve2SWF_2000 pencere= new curve2SWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.11-2 ikinci dereceden genel eğri çizimi, curve2SWF_2000, JFrame çıktısında görünümü Şimdide üçüncü dereceden eğri uyduran bir program koduna göz atalım : Program 1.6.11-3 : curve3SWF_2000.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class curve3SWF_2000 extends JFrame { final static Color kirmizi=Color.red; final static Color beyaz=Color.white; final static Color siyah=Color.black; public curve3SWF_2000() { super("üçüncü dereceden eğri çizimi"); } public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); setBackground(Color.lightGray); setForeground(siyah); Dimension boyut=getSize(); int dx=boyut.width; int dy=boyut.height; g2.setPaint(siyah); g2.draw3DRect(0,0,dx-3,dy-3,true); g2.draw3DRect(3,3,dx-7,dy-7,false); g2.setPaint(siyah); CubicCurve2D cc3=new CubicCurve2D.Double(50,175,140,90,10,90,100,175); g2.draw(cc3); CubicCurve2D cc3_1=new CubicCurve2D.Double(50,275,140,190,10,190,100,275); g2.setPaint(Color.blue); g2.fill(cc3_1); } //===================================================== public static void main(String[] args) { curve3SWF_2000 pencere= new curve3SWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,300); pencere.setVisible(true); } } Şekil 1.6.11-3 üçüncü dereceden genel eğri çizimi, curve3SWF_2000, JFrame çıktısında görünümü 1.6.12 RESİM GÖSTERİMİ Java dili sadece .gif ve .jpg standartlarındaki resimleri gösterebilir. Resim önce getImage metotuyla bir Image sınıfı nesneye yuklenir, sonra drawImage metotuyla gösterilir. Orneğin Image resim=getImage(getDocumentBase(),”resim.gif”); Ve resim g.drawImage(resim,1,1,this); deyimiyle çizilir. Burada ikinci ve üçüncü noktalar başlangıç x ve y koordinatlarıdır.Son olarak this resmin çizileceği appletiniçinde bulunulan sınıfın appleti olduğunu belirtmektedir. Bir örnek problemle resim çizimini biraz daha belirgin hale getitelim : Program 1.6.12-1: resim.java resim aktarım programı import java.applet.Applet; import java.awt.*; public class resim extends Applet { private Image res; public void init() {res=getImage(getDocumentBase(),"ballarat.gif"); } public void paint(Graphics g) { g.drawImage(res,1,1,this); /* // resmi orijinalinin iki katı boyunda ciziniz int en=res.getWidth(this); int yukseklik=res.getWidth(this); g.drawImage(res,1,90,en*2,yukseklik*2,this); */ }} Şekil 1.6.12-1 : Resmin java üzerinden aktarılması, resim.html Java grafik çizim olasılıkları burada verilenden çok aha geniş boyutludur. Bu bölümde veremediğimiz bir çok detayı javanın parasız olarak çekebileceğiniz döküman kütüphanesinde bulabilirsiniz. 1.6.13 JAVA 2 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT Bilimsel grafikler verinin analizini kolaylaştırmaları ve görsel olarak bir dizi sayıya göre çok daha anlamlı olmalarıyla oldukça yoğun olarak kullanılan bilimsel ortamlardır. Profesyonel bilimsel bilgisayar ortamlarına ulaşmak için genelde belli bir ücret karşılığında aldığımız profesyonel programları kullanabiliriz. Örneğin Matlab oldukça güzel bir grafik ortamı sunmaktadır, ancak bu tür paketler programlama ortamını kendi dilleriyle sınırlandırmaktadır. Burada Java ortamında program yazan arkadaşlarımızın oldukça basit bir şekilde programlarına aktarabilecekleri genel maksatlı 2 boyutlu bir bilimsel grafik ortamı programı olan Plot sınıfının (ve ona bağlı çalışan sınıflar gurubu) java ortamında kullanımı tanımlanacaktır. Plot sınıfı tek bir dosya, bir dosya gurubu, java çok boyutlu değişkenleri, ve java fonksiyonlarından girdi alabilen, normal veya logaritmik ortamda çıktı verebilen, kübik şerit aradeğer, en küçük kareler ve ortogonal polinom en küçük kareler, Lagrange interpolasyonu gibi yöntemlerle yeterli olmayan verilerde ara değer hesaplayarak veriye eğri uydurabilen bir sistemdir. Burada Program kodlamasına girmeden programın kullanılması ile ilgili bilgi vermeye çalışacağız. Program 1.6.13-1 PlotT1.java örnek problemi İmport java.io.*; class PlotT1 { public static void main(String args[]) throws IOException {Plot pp=new Plot("in.txt"); pp.plot();}} Şekil 1.6.13-1 PlotT1 programı çıktısı : Plot sayfası İlk kodumuz PlotT1 in.txt dosyasındaki veriyi okuyarak ilkçıktımızı oluşturdu. Programda gördüğümüz ilk satır olan kurucu metod Plot pp=new Plot("in.txt"); veriyi aktardı ve pp.plot(); deyimi de grafik penceresini oluşturdu.Bu ikinci deyim hemen her zaman pencereyi açma komutu olarak kalacaktır. Pencereyi kapama komutu verilmemiştir. Elle kapatılacaktır. Grafik ortamının ikinci sayfasına baktığımızda değiştirilebilecek çeşitli parametreler görüyoruz. Bunlar eğride kullanılan çizgi çeşitleri, renk parametresi, grid, plot başlıkları, ek başlıklar, logaritmik skala gibi özelliklerdir. Bu özellikler değiştirilerek grafik daha küçük bir alt bölgede incelenebilir. Sayfa istenilen ölçeklerde karelere ayrılabilir. Şekil 1.6.13-2 PlotT1 programı çıktısı : Kontrol sayfası Şekil 1.6.13-3 PlotT1 programı çıktısı : Kontrol sayfasında grid eklenip x exseni logaritmik yapılıp x ve y eksen boyutları değiştikten sonra grafik ekranının görünümü Grafik rengi standart java renk editörünü kullanarak değiştirilebilir. Listeden seçilen çeşitli grafik seçenekleri kullanılabilir. Şekil 1.6.13-4 kontrol sayfası renk seçimi Bu programımızda dinamik tanım yerine statik tanım yaparsak aynı program aşağıdaki şekli alır Program 1.6.13-1A PlotT1.java örnek problemi import java.io.*; class plotT1 { public static void main(String args[]) throws IOException {Plot.file("in.txt");} } Çıktı aynı olacaktır. Burada statik tanımlamaları genelde tek bir adımda grafik çizdirmek için kullandığımızı, birden fazla adım olduğunda dinamik tanımlamaları tercih etmemizin daha iyi olacağını belirtelim. İkinci örneğimizde veriyi java programı boyutlu değişkenlerinden alıyoruz Program 1.6.13-2 import java.io.*; class PlotT2A { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.plot();}} Şekil 1.6.13-5 PlotT2A çıktısı programımızı çalıştırdığımızda Şekil 1.6.13-5 deki çıktıyı elde ederiz. Bu çıktıda ara değerleri daha iyi görmek istersek programdan ara değer hesabı yapmasını istiyebiliriz. Aynı programı statik metodla çağıracak olursak : Program 1.6.13-2A import java.io.*; class PlotT2A { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot.data(xx,yy);}} Çıktı yine üstte tanımlandığı gibidir. Program 1.6.13-3 import java.io.*; class PlotT2B { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addSpline(xx,yy,10); pp.plot();}} Şekil 1.6.13-5 PlotT2B çıktısı (addSpline aradeğer çıktısı kullanılıyor) aradeğer hesabı yapmak için sadece pp.addSpline(xx,yy,10); deyimini eklememiz kafi geldi. Buradaki her nokta arasını 10 eşit parçaya bölerek ara değerleri kübik şerit interpolasyonuyla hesaplamamız anlamına gelmektedir. Eğer verinin kaç numaralı eğri olarak Plot programına girdiğini bilirsek, veriyi Plot sınıfının okuduğu veriden alarak da aynı aradeğer oluşumunu yapabiliriz. Plot eğri setleri numaraları ekleme sıramıza göre 0 dan başlayarak artarak gider. Program 1.6.13-3A import java.io.*; class PlotT2B2 { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addSpline(0,10); pp.plot();}} Program 1.6.13-3 ve Program 1.6.13-3A çıktıları aynıdır. Kübik şerit interpolasyonunun detaylarını öğrenmek istersek eğri uydurma bölümümüzü inceleyebilirsiniz. Birden fazla grafik komutunu bir arada kullanmak isterseniz statik metodlara başvuramazsınız, örneğin yukardaki programda hem veriyi hemde verinin interpolasyon değerlerini çizdirdiğimizden statik kullanıma uygun değildir. Ancak kendi statik metodumuzda bu tür kompleks kullanımları birleştirerek kullanabiliriz. Program 1.6.13-3B, Program 1.6.13-3 ile aynı çıktıyı verecektir. Program 1.6.13-3B import java.io.*; class PlotT2B { public static void plot(double xx[],double yy[]) {Plot pp=new Plot(xx,yy); pp.addSpline(xx,yy,10); pp.plot();} public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; plot(xx,yy);}} Aynı aradeğer hesaplarını pp.addB_Spline(xx,yy,10); deyimini ekleyerek B şerit interpolasyonu kullanarak da yapabiliriz. Program 1.6.13-3C import java.io.*; class PlotT2B1 { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addB_Spline(xx,yy,10); pp.plot();}} Aynı aradeğer hesaplarını ikinci dereceden Ortogonal polinom uydurarak (her araya 10 değer olmak üzere) Program 1.6.13-4 import java.io.*; class PlotT2C { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addOPEKK(xx,yy,2,10); pp.plot();}} ikinci dereceden polinom uydurarak (fx=a0+a1*x+a2*x2 - her araya 10 değer olmak üzere) Program 1.6.13-5 import java.io.*; class PlotT2D { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addEKK(xx,yy,2,10); pp.plot();}} veya Lagrange aradeğer hesabıyla da ulaşabiliriz. Program 1.6.13-6 import java.io.*; class PlotT2E { public static void main (String args[]) throws IOException {double xx[]={1,2,3,4,5}; double yy[]={1,4,9,16,25}; Plot pp=new Plot(xx,yy); pp.addLagrange(xx,yy,10); pp.plot();}} Tüm interpolasyon hesap detaylarını kitabımızın 6. bölümünde inceleyebilirsiniz. Plot Programındaki kurucu metodumuz tamamen boş olabilir. Program 1.6.13-7 (Dinamik çağırma) import java.io.*; class PlotT01 {public static void main (String args[]) throws IOException {Plot pp=new Plot(); pp.plot();}} Program 1.6.13-7A (Statik çağırma) import java.io.*; class PlotT2B1 { public static void main (String args[]) throws IOException {Plot.file();}} Bu durumda programımız veri için Plot.txt dosyasına bakacaktır.Bu dosyada Plot başlığı x ekseni y ekseni 2 in.txt 0 0 0 0 out.txt 3 0 0 255 verisi olduğunu varsayalım. Bunun anlamı “Plot başlığı” “x ekseni” ve “y ekseni” grafik başlıklarını kullanarak in.txt ve out.txt dosyalarındaki verilerin çizilmesidir. Verilerin yanındaki ilk rakam grafik çizim türünü ondan sonraki 3 rakam da renk kodunu (kırmızı yeşil ve mavi olarak) ifade eder. Programın grafik çizim kodları : "1 __ __ __ __ ", "2 . _ . _ . _ ", "3 . _ _ . . _ _ .", "4 - - - - - - - - ", "5 ______", "6 __ __ __ __ ", "7 . _ . _ . _ ", "8 . _ _ . . _ _ .", "9 - - - - - ", "10 * ", "11 # ", "12 $ ", "13 % ", "14 & ", "15 ", "16 ~ ", "17 + ", "18 x ", "19 = ", "20 kare", "21 dolu kare", "22 daire", "23 dolu daire", "24 üçken", "25 eşkenar dörtgen", "26 beşken", "27 altıgen", "28 dolu üçgen", "28 dolu eşkenar dörtken", "30 dolu beşgen", "31 dolu altıgen", "32 üç köşe yıldız", "33 dört köşe yıldız", "34 beş köşe yıldız", "35 altı köşe yıldız", "36 dolu üç köşe yıldız", "37 dolu dört köşe yıldız", "38 dolu beş köşe yıldız", "39 dolu altı köşe yıldız", "40 çubuk grafik", "41 dolu çubuk grafik"}; şeklindedir. Grafik türü ve renk kodları burada bahsettiğimiz tüm metodlar için de mevcuttur. Örneğin Bir fonksiyonun grafiğinin çizilmesi için en basit yol fonksiyonu abstract sınıf f_x ten türeterek yapılır. Program 1.6.13-8 (Dinamik versiyon) import java.io.*; class f3 extends f_x {double func(double x) {return x*x*x+3.6*x*x-36.4;}} class PlotT06 {public static void main (String args[]) throws IOException {f3 ff2=new f3(); Plot pp=new Plot(ff2,0.0,7.0,400,2); pp.plot();}} Program 1.6.13-8A (Statik versiyon) import java.io.*; class f3 extends f_x {double func(double x) { return x*x*Math.abs(Math.sin(Math.sqrt(x)))-5.0;}} class PlotT06 { public static void main (String args[]) throws IOException {Plot.func(new f3(),0.0,10.0,400,0);} } bu programın grafik çıktısı şeklinde olacaktır. Bu fonksiyon matematik olarak ifade edilirse f(x)=x3+3.6x2-36.4 şeklindedir. 0 ile 7 arasında 400 nokta oluşturarak fonksiyonunun çizilmesi istenmiştir. Birden fazla fonksiyonun grafiğini tek bir sınıfta tanımlıyabiliriz. Program 1.6.13-9 (Dinamik versiyon) import java.io.*; class f3 extends fi_x { double[] func(double x) { double f[]=new double[2]; f[0]=x*Math.sin(10.0*Math.PI*x)+1.0; f[1]=x*x; return f;}} class PlotT03 {public static void main (String args[]) throws IOException { f3 ff2=new f3(); Plot pp=new Plot(ff2,-2.0,2.0,400,2); pp.plot();}} Program 1.6.13-9A (Statik versiyon) import java.io.*; class f3 extends fi_x { double[] func(double x) { double f[]=new double[2]; f[0]=x*Math.sin(10.0*Math.PI*x)+1.0; f[1]=x*x; return f;} } class PlotT03 {public static void main (String args[]) throws IOException { Plot.func(new f3(),-2.0,2.0,400,2);}} veya ayrı ayrı birden fazla sınıfta tanımlayarak da çizebiliriz. Program 1.6.13-10 import java.io.*; class f3 extends f_x {double func(double x) {return x*x;}} class f4 extends f_x {double func(double x) {return x*Math.sin(10.0*Math.PI*x)+1.0;}} class PlotT07 {public static void main (String args[]) throws IOException {f3 ff3=new f3(); f4 ff4=new f4(); Plot pp=new Plot(ff3,-3.0,2.0,400); pp.addFunction(ff4,-2.0,2.0,400); pp.plot();}} Fonksiyonlar ayrı ayrı çağrıldığında değişik sınır değerleri de tanımlayabiliriz. Burada kurucu metot birinci fonksiyon tarafından çağrıldığından ikinci fonksiyonun çağrılmasında pp.addFunction(ff4,-2.0,2.0,400); kullanılmıştır. addFunction metoduna benzer olarak addData metodu mevcuttur, java boyutlu değişken verilerinin eklenmesinde kullanılır. pp.addData(xx,yy,0,0,0,0); Son olarak çeşitli fonksiyon ve verileri kullanan ve diğer grafik verilerini de programın içinde değiştiren bir programa göz atalım Program 1.6.13-11 import java.io.*; class f3 extends fi_x { double[] func(double x) { double f[]=new double[2]; f[0]=Math.sin(x)+x/2; f[1]=Math.sqrt(x); return f; }} class PlotT3 { public static void main (String args[]) throws IOException {//Plot pp=new Plot(); String fi[]={"in.txt","out.txt"}; f3 ff=new f3(); int ipt[]={0,1}; int ir[]={0,0}; int ig[]={0,0}; int ib[]={0,2}; double xx[]={1,2,3,4,5,6}; double yy[]={2,3,4,5,6,7}; Plot pp=new Plot(fi); //read data from fi (in.txt,out.txt data are added up) //pp.addData(fi); pp.setPlotType(0,0);// pp.setPlotType(1,1);// pp.addData(xx,yy,0,0,0,0); //one set of addional data pp.setPlotType(2,41);//bar chart pp.setColor(2,0,0,255); //blue pp.addFunction(ff,0.0,20.0,50,2,ipt,ir,ig,ib); //two additional function pp.setPlabel("Fonksiyon Plot"); pp.setXlabel("x ekseni"); pp.setYlabel("y ekseni"); pp.plot();}} Bu program 2 fonksiyonu f3 sınıfından almakta, 2 set veriyi fi string’i aracılığıyla in.txt ve out.txt dosyalarından okumaktadır. 3. veri seti(2 no’lu veri) bar grafik (grafik tipi 41) olarak seçilmiştir. Bu paketleri kullanarak çok daha karmaşık grafik bileşenleri oluşturulabilir. Örneğin nemli havanın termodinamik özellikleri programında fare ile aktif veri girişi (Fareye basıldığında x ve y koordinatlarını alarak bu değerler için hesap yapma) gibi ek özellikler katılabilir. Bu özellikler burada verdiğimiz paketin içerisinde kullanıma hazır olarak mevcutsa da verdiğimiz şekliyle kullanılamaz. Grafik Paketi Temel Bileşenleri : Grafik Paketinin temel bileşenleri : Plot.java kurucu metotlar ve girdi çıktı metotlarını içerir PlotW.java : çizimi gerçekleştiren ana metodudur. Grafik sayfalarını ve bu sayfaların kontrollerini içerir. PlotShapesSW: çeşitli Plot alt elemanlarının çizim tekniklerini içerir, çizgi, üçgen,bar grafik gibi Plot2D : PlotShapes alt elemanlarını grafik çizimi haline getirir, sırasıyla alt elemanları çağırır. Şimdi bu paketlerin listelerini verelim. Bu tür program kodları programlamaya yeni başlayan arkadaşlarımız için kompleks olabilir, bu durumda sadece kullanımla yetinebilirler, ancak dileyen kodları alarak daha da geliştirebilir, Bu tür geliştirmelerde tek dileğim geliştirmelerden beni de haberdar etmeniz, eğer yeni kodlar uygunsa orijinal kodları değiştirebiliriz. Programlarımızın kodlarını vermeden önce tüm metodlarımızın bir listesini verelim : Kurucu metodlar : (grafik programını dinamik olarak kurar ve veriyi kullanıma hazırlar) public Plot() throws IOException public Plot(String pl,String xl,String yl,int xnt,int ynt,int xgo,int ygo,String fn[],int ipt[],int ir[],int ig[] ,int ib[]) throws IOException public Plot(String fn[],int ipt[],int ir[],int ig[],int ib[]) throws IOException public Plot(String fn[]) throws IOException : Read file names from String fn[] and plot them public Plot(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[]) : read plot data from xi[][] and yi[][] public Plot(double xiyi[][]) : read plot data xi[] and yi[] from xiyi[][] string public Plot(double xi[][],double yi[][]) : read plot data from xi[][] and yi[][] public Plot(double xi[],double yi[]) : read plot data from xi[] and yi[] public Plot(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib) public Plot(f_x f,double xm,double xma,int N) : create plot data from a simple function f_x f public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function) Statik metodlar : (verinin kısa yoldan grafiğinin çizilmesini sağlar) public static double[] data(double xmin,double xmax,double dx) public static double[] data(double xmin,double xmax,int n) public static Plot func(f_x ff1,double xmin,double xmax,int n,int pnumber) public static Plot func(f_x ff1,double xmin,double xmax,int n) public static Plot func(f_x ff1,double xmin,double xmax) public static Plot func(fi_x ff1,double xmin,double xmax,int n,int pnumber) public static Plot func(fi_x ff1,double xmin,double xmax,int n) public static Plot func(fi_x ff1,double xmin,double xmax) x , y ve ana başlığı eklemek public void setPlabel(String ip) {label=ip;} public void setXlabel(String ix) {xlabel=ix;} public void setYlabel(String iy) {ylabel=iy;} public void setXYlabel(String ix,String iy) {xlabel=ix;ylabel=iy;} kurucu metoddan sonra grafik penceresine ek veri eklemek public void addData(double xi[],double yi[]) public void addData(double xi[],double yi[],int iplottype) public void addData(double xi[],double yi[],int iplottype,int ir,int ig,int ib) public void addData(double xi[][],double yi[][]) public void addData(double xi[][],double yi[][],int ip[]) public void addData(double xi[][],double yi[][],int ip[],int ir[],int ig[],int ib[]) public void addFunction(f_x f,double xmi,double xma,int N,int ipt) public void addFunction(f_x f,double xmi,double xma,int N) public void addFunction(f_x f,double xmi,double xma,int N,int ipt,int ir,int ig,int ib) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function,int ipt[]) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function, ,int ipt[]) eğri uydurarak ek veri eklemek public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi) public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype) public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi) public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype) public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype) public void addEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addLagrange(double xi[],double yi[],int aradegersayisi) public void addLagrange(double xi[],double yi[],int aradegersayisi,int iplottype) public void addLagrange(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addLagrange(int linenumber,int aradegersayisi,int iplottype) public void addLagrange(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addB_Spline(double xi[],double yi[],int nSpline) public void addB_Spline(double ai[][],int nSpline) public void addB_Spline(double xi[],double yi[],int nSpline,int iplottype) public void addB_Spline(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addB_Spline(int linenumber,int nSpline) public void addB_Spline(int linenumber,int nSpline,int iplottype) public void addB_Spline(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addSpline(double xi[],double yi[],int nSpline) public void addSpline(double ai[][],int nSpline) public void addSpline(double xi[],double yi[],int nSpline,int iplottype) public void addSpline(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) public void addSpline(int linenumber,int nSpline) public void addSpline(int linenumber,int nSpline,int iplottype) public void addSpline(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) grafik özelliklerini değiştirmek ===========Grafik türü ===================== public void setPlotType(int plot_type[]) public void setPlotType(int dataset,int plot_no) public void setPlotType(int dataset,char plot_char) ===========x ve y grid =========================== public void setXgrid(int igx) public void setYgrid(int igy) public void setGrid(int igx,int igy) public void setXtic(int ixt) public void setYtic(int iyt) public void setXYtic(int ixt,int iyt) ==========logaritmik grafik skalası açma ve kapama ========== public void setXlogScaleOn() public void setYlogScaleOn() public void setXlogScaleOff() public void setYlogScaleOff() ==========renk seti========== public void setColor(int dataset,int ired,int igreen,int iblue) public void setColor(int dataset,Color c) public void setColor(int ired[],int igreen[],int iblue[]) public void setColor(Color c[]) ================ fonksiyon minimum ve maksimum değerleri =================== public void setMinMax() public void setMinMax(double xi[][],double yi[][]) public void setMinMax(double iminx,double imaxx,double iminy,double imaxy) =============== grafik penceresi formatlanması ================================== public void set_plotwindow(int width,int height,double xip,double yip,double dxp,double dyp) public void setabsMaxMin(int ixmin,int iymin,int idx,int idy) oluşan verinin dinamik ortamda çizilmesi public void plot() Program 1.6.13-12 Plot.java PLOT PROGRAMI //====================================================== // Numerical Analysis package in java // Plot class to plot 2D data // Dr. Turhan Coban // EGE University, Engineering School, Mechanical Eng. Div. // [email protected] // ===================================================== import java.io.*; import java.awt.Color; //This class organises data and reqired plot classes for actual plot //===== classes used by this class======= // PlotShapesSW // define shapes to draw in plot windows in real coordinate system // Plot2D // Plot and coordinates data // PLotW // defines actual graphic screens and pages //===== Example classes // PlotT0,PlotT01,PlotT02,PlotT03,PlotT1,PlotT2,PlotT3,PlotT4 abstract class f_x { //single function single independent variable // example f=x*x abstract double func(double x); } abstract class fi_x { // multifunction single independent variable // vector of dependent variables are returned // example f[0]=x+sin(x) // f[1]=x*x-x // func(x) returns the value of f[0] and f[1] // as a two dimensional vector abstract double[] func(double x); } public class Plot { // This class reads plot input variables // and sets relations between absolute scale and relative scale plot windows public Color bg=Color.blue; public String label="y=f(x)"; // Plot Label public String xlabel="x"; // X axis Label public String ylabel="y"; // Y axis Label public String filename; // file name public double xmin,ymin,xmax,ymax; // real max,min scale public int xabsmin,yabsmin,abswidth,absheight; // absolute max,min scale in Pixel dimension public int nmax; // max number of data points public int ni; // data set number with nmax data public int nline; // max number of data sets public double x[][]; // x data public double y[][]; // y=f(x) data public int n[]; // n : number of data in each line public int red[],green[],blue[]; // color code 0-255 public int xgridon=0; // x axis grid line on public int ygridon=0; // y axis grid line on public int xlog=0; // x axis logaritmic scale public int ylog=0; // y axis logaritmic scale public int plottype[]; public String plotst[]={"0 _____________", "1 __ __ __ __ ", "2 . _ . _ . _ ", "3 . _ _ . . _ _ .", "4 - - - - - ", "5 kalın _____________", "6 kalın __ __ __ __ ", "7 kalın . _ . _ . _ ", "8 kalın . _ _ . . _ _ .", "9 kalın - - - - - ", "10 * ", "11 # ", "12 $ ", "13 % ", "14 & ", "15 ", "16 ~ ", "17 + ", "18 x ", "19 = ", "20 kare", "21 dolu kare", "22 daire", "23 dolu daire", "24 üçken", "25 eşkenar dörtgen", "26 beşken", "27 altıgen", "28 dolu üçgen", "28 dolu eşkenar dörtken", "30 dolu beşgen", "31 dolu altıgen", "32 üç köşe yıldız", "33 dört köşe yıldız", "34 beş köşe yıldız", "35 altı köşe yıldız", "36 dolu üç köşe yıldız", "37 dolu dört köşe yıldız", "38 dolu beş köşe yıldız", "39 dolu altı köşe yıldız", "40 çubuk grafik", "41 dolu çubuk grafik"}; double xminmaxlog,yminmaxlog; // plottype = 0 continuous line // plottype = 1 dashed line // plottype = 2 // plottype = 3 // plottype = 10 variable character plot type // plottype = 20 rectangle // plottype = 21 filled rectangle // plottype = 22 circle // plottype = 23 filled circle // plottype = 24 triangle // plottype = 25 diamond // plottype = 26 pentagon // plottype = 27 hexagon // plottype = 28 filled triangle // plottype = 29 filled diamond // plottype = 30 filled pentagon // plottype = 31 filled hexagon // plottype = 32 tri sided star // plottype = 33 four sided star // plottype = 34 five sided star // plottype = 35 six sided star // plottype = 36 filled tri sided star // plottype = 37 filled four sided star // plottype = 38 filled five sided star // plottype = 39 filled six sided star // plottype = 40 bar plot // plottype = 41 filled bar plot public char ch[]; // plot character (used with plottype 10) public int xntic=10; // number of tics in x axis public int yntic=10; // number of tics in y axis BufferedReader fini; BufferedReader ffile; File plotFile; File lineDataFile; String fn[]; /* ========== constructors ======================= public Plot() throws IOException : Read actual data from file Plot.txt and plot filenames listed in this file public Plot(String pl,String xl,String yl,int xnt,int ynt ,int xgo,int ygo,String fn[],int ipt[],int ir[],int ig[] ,int ib[]) throws IOException : Read file names from String fn[] and plot them public Plot(String fn[],int ipt[],int ir[],int ig[],int ib[]) throws IOException public Plot(String fn[]) throws IOException : Read file names from String fn[] and plot them public Plot(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[]) : read plot data from xi[][] and yi[][] public Plot(double xiyi[][]) : read plot data xi[] and yi[] from xiyi[][] string public Plot(double xi[][],double yi[][]) : read plot data from xi[][] and yi[][] public Plot(double xi[],double yi[]) : read plot data from xi[] and yi[] public Plot(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib) : create plot data from a simple function f_x f public Plot(f_x f,double xm,double xma,int N) : create plot data from a simple function f_x f public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function) : create plot data from an array of simple functions fi_x f ======== Label settings ======================== public void setPlabel(String ip) {label=ip;} public void setXlabel(String ix) {xlabel=ix;} public void setYlabel(String iy) {ylabel=iy;} public void setXYlabel(String ix,String iy) {xlabel=ix;ylabel=iy;} ======== Setting additional data after initial construction ========= This groups's functions are similar to constructor classes public void addData(double xi[],double yi[]) public void addData(double xi[],double yi[],int iplottype) public void addData(double xi[],double yi[],int iplottype,int ir,int ig,int ib) public void addData(double xi[][],double yi[][]) public void addData(double xi[][],double yi[][],int ip[]) public void addData(double xi[][],double yi[][],int ip[],int ir[],int ig[],int ib[]) public void addFunction(f_x f,double xmi,double xma,int N,int ipt) public void addFunction(f_x f,double xmi,double xma,int N) public void addFunction(f_x f,double xmi,double xma,int N,int ipt,int ir,int ig,int ib) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function,int ipt[]) public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function, ================== Settings of additional plot information ================= ----------Plot Type ---------------------public void setPlotType(int plot_type[]) public void setPlotType(int dataset,int plot_no) public void setPlotType(int dataset,char plot_char) ----------x y grid on-off ---------------public void setXgrid(int igx) public void setYgrid(int igy) public void setGrid(int igx,int igy) public void setXtic(int ixt) public void setYtic(int iyt) public void setXYtic(int ixt,int iyt) ---------- Color setting for plot data -------public void setColor(int dataset,int ired,int igreen,int iblue) public void setColor(int ired[],int igreen[],int iblue[]) ================ Setting of Minimum Maximum fuctions =================== public void setMinMax() public void setMinMax(double xi[][],double yi[][]) public void setMinMax(double iminx,double imaxx,double iminy,double imaxy) =============== Plot Window Formatting ================================== public void set_plotwindow(int width,int height,double xip,double yip,double dxp,double dyp) public void setabsMaxMin(int ixmin,int iymin,int idx,int idy) ================ Actual Plotting of constructed data public void plot() */ public static double[] data(double xmin,double xmax,double dx) { int n=(int)((xmax-xmin)/dx)+1; double x[]=new double[n]; for(int i=0;i<n-1;i++) {x[i]=xmin+dx*i;} x[n-1]=xmax; return x; } public static double[] data(double xmin,double xmax,int n) { double dx=(xmax-xmin)/n; double x[]=new double[n]; for(int i=0;i<n;i++) {x[i]=xmin+dx*i;} return x; } public Plot() throws IOException { //read input variables from Plot.txt //adding max-min prompts and input fields //initial values of max and mins // Structure of input file // filename // xlabel // ylabel // nline // datafilename plottype redcolor greencolor bluecolor // ........ // datafilename plottype redcolor greencolor bluecolor // // A sample data file input : //========================== // filename // xaxislabel // yaxislabel // 4 // b.dat 22 0 0 0 // a.dat 21 0 255 0 // a.dat 0 0 255 0 // b.dat 0 0 0 255 //========================== xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; try{ fini=new BufferedReader(new FileReader("Plot.txt")); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } label=Text.readStringLine(fini); xlabel=Text.readStringLine(fini); ylabel=Text.readStringLine(fini); nline=Text.readInt(fini); n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; ch[10]='*'; ch[11]='#'; ch[12]='$'; ch[13]='%'; ch[14]='&'; ch[15]='@'; ch[16]='~'; ch[17]='+'; ch[18]='x'; ch[19]='='; //read all data to determine limit values String fn[]; fn=new String[nline]; int i,j; for(i=0;i<nline;i++) { plottype[i]=i; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; fn[i]=Text.readString(fini); plottype[i]=Text.readInt(fini); if((plottype[i] >= 10)&&(plottype[i] <= 19)) ch[i]=Text.readChar(fini); red[i]=Text.readInt(fini); green[i]=Text.readInt(fini); blue[i]=Text.readInt(fini); j=0; n[i]=0; //open ffile try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } try{ while(ffile!=null) { xtemp=Text.readDouble(ffile); ytemp=Text.readDouble(ffile); if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } } catch(EOFException e_eof) { //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } //End of EOFException if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } x=new double[nline][nmax]; y=new double[nline][nmax]; //re-read the data again to load it for(i=0;i<nline;i++) { //open ffile try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } for(j=0;j<n[i];j++) { x[i][j]=Text.readDouble(ffile); y[i][j]=Text.readDouble(ffile); } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } set_plotwindow(500,400,0.1,0.1,0.9,0.9); //close fini try{ fini.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } public Plot(String pl,String xl,String yl,int xnt,int ynt ,int xgo,int ygo,String fn[],int ipt[],int ir[],int ig[] ,int ib[]) throws IOException { // String pl : plot label // String x1 : plot x axis label // String y1 : Plot y axis label xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; setXtic(10); setYtic(10); setGrid(0,0); double xtemp,ytemp; setPlabel(pl); setXlabel(xl); setYlabel(yl); n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=fn.length; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; j=0; n[i]=0; //open ffile System.out.println("isim ="+fn[i]); try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } try{ while(ffile!=null) { xtemp=Text.readDouble(ffile); ytemp=Text.readDouble(ffile); if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } } catch(EOFException e_eof) { //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } //End of EOFException if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } //System.out.println("nline = "+nline+"nmax="+nmax); x=new double[nline][nmax]; y=new double[nline][nmax]; //re-read the data again to load it for(i=0;i<nline;i++) { //open ffile try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } for(j=0;j<n[i];j++) { x[i][j]=Text.readDouble(ffile); y[i][j]=Text.readDouble(ffile); } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public Plot(String fn[],int ipt[],int ir[],int ig[],int ib[]) throws IOException { // reading data from file and initilisation xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=fn.length; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; j=0; n[i]=0; //open ffile //System.out.println("isim ="+fn[i]); try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } try{ while(ffile!=null) { xtemp=Text.readDouble(ffile); ytemp=Text.readDouble(ffile); if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } } catch(EOFException e_eof) { //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } //End of EOFException if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } x=new double[nline][nmax]; y=new double[nline][nmax]; //re-read the data again to load it for(i=0;i<nline;i++) { //open ffile try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } for(j=0;j<n[i];j++) { x[i][j]=Text.readDouble(ffile); y[i][j]=Text.readDouble(ffile); } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public Plot(String fn[]) throws IOException { //reading data from file(s) nline=fn.length; int ipt[]=new int[nline]; int ir[]=new int[nline]; int ig[]=new int[nline]; int ib[]=new int[nline]; xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=fn.length; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; j=0; n[i]=0; //open ffile //System.out.println("isim ="+fn[i]); try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } try{ while(ffile!=null) { xtemp=Text.readDouble(ffile); ytemp=Text.readDouble(ffile); if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } } catch(EOFException e_eof) { //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } //End of EOFException if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } x=new double[nline][nmax]; y=new double[nline][nmax]; //re-read the data again to load it for(i=0;i<nline;i++) { //open ffile try{ ffile=new BufferedReader(new FileReader(fn[i])); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } for(j=0;j<n[i];j++) { x[i][j]=Text.readDouble(ffile); y[i][j]=Text.readDouble(ffile); } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public Plot(String fn) throws IOException { //reading data from file(s) nline=1; int ipt[]=new int[nline]; int ir[]=new int[nline]; int ig[]=new int[nline]; int ib[]=new int[nline]; xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=1; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; j=0; n[i]=0; //open ffile //System.out.println("isim ="+fn[i]); try{ ffile=new BufferedReader(new FileReader(fn)); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } try{ while(ffile!=null) { xtemp=Text.readDouble(ffile); ytemp=Text.readDouble(ffile); if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } } catch(EOFException e_eof) { //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } //End of EOFException if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } x=new double[nline][nmax]; y=new double[nline][nmax]; //re-read the data again to load it for(i=0;i<nline;i++) { //open ffile try{ ffile=new BufferedReader(new FileReader(fn)); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } for(j=0;j<n[i];j++) { x[i][j]=Text.readDouble(ffile); y[i][j]=Text.readDouble(ffile); } //close ffile try{ ffile.close(); } catch(IOException e) { System.err.println("Error Closing File\n"+e.toString()); System.exit(1); } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public Plot(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[]) { pp2(xi,yi,ipt,ir,ig,ib); } public void pp2(double xi[][],double yi[][]) { int ir[]; int ig[]; int ib[]; int ipt[]; int nn=xi.length; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; ipt=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; ipt[i]=0; } pp2(xi,yi,ipt,ir,ig,ib); } public void pp2(double xi[][],double yi[][],int ipt[]) { int ir[]; int ig[]; int ib[]; int nn=xi.length; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; } pp2(xi,yi,ipt,ir,ig,ib); } public void pp2(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[]) { // reading data from initial array xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=xi.length; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; nline=xi.length; n[i]=0; for(j=0;j<xi[i].length;j++) { xtemp=xi[i][j]; ytemp=yi[i][j]; if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } //end of for x=new double[nline][nmax]; y=new double[nline][nmax]; for(i=0;i<nline;i++) { for(j=0;j<n[i];j++) { x[i][j]=xi[i][j]; y[i][j]=yi[i][j]; } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public void pp2(double ai[][],int ipt[],int ir[],int ig[],int ib[]) { // reading data from initial array xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=ai.length-1; double xi[][]=new double[nline][ai[0].length]; double yi[][]=new double[nline][ai[0].length]; for(i=0;i<nline;i++) { plottype[i]=ipt[i]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='@'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='x'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i]; green[i]=ig[i]; blue[i]=ib[i]; nline=xi.length; n[i]=0; for(j=0;j<xi[i].length;j++) { xtemp=ai[0][j]; ytemp=ai[i+1][j]; xi[i][j]=xtemp; yi[i][j]=ytemp; if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[i]++; } if(i==0) {nmax=n[i];ni=i;} else { if(n[i]>nmax) {nmax=n[i];ni=i;} } } //end of for x=new double[nline][nmax]; y=new double[nline][nmax]; for(i=0;i<nline;i++) { for(j=0;j<n[i];j++) { x[i][j]=xi[i][j]; y[i][j]=yi[i][j]; } } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public void pp2(double ai[][],int ipt[]) { int ir[]; int ig[]; int ib[]; int nn=ai.length-1; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; } pp2(ai,ipt,ir,ig,ib); } public void pp2(double ai[][]) { int ir[]; int ig[]; int ib[]; int ipt[]; int nn=ai.length-1; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; ipt=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; } pp2(ai,ipt,ir,ig,ib); } public Plot(double ai[][]) { pp2(ai); } public Plot(double xi[][],double yi[][]) { pp2(xi,yi); } public void pp1( double xi[],double yi[]) { pp1(xi,yi,0,0,0,0); } public void pp1( double xi[],double yi[],int ipt) { pp1(xi,yi,ipt,0,0,0); } public void pp1( double xi[],double yi[],int ipt,int ir,int ig,int ib) { // reading data from initial array xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=1; plottype[0]=ipt; red[0]=ir; green[0]=ig; blue[0]=ib; nline=1; n[0]=0; plottype[0]=ipt; if(plottype[0] == 10) ch[0]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[0] == 11) ch[0]='#'; if(plottype[0] == 12) ch[0]='$'; if(plottype[0] == 13) ch[0]='%'; if(plottype[0] == 14) ch[0]='&'; if(plottype[0] == 15) ch[0]='£'; if(plottype[0] == 16) ch[0]='~'; if(plottype[0] == 17) ch[0]='+'; if(plottype[0] == 18) ch[0]='^'; if(plottype[0] == 19) ch[0]='='; for(j=0;j<xi.length;j++) { xtemp=xi[j]; ytemp=yi[j]; if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[0]++; } nmax=n[0];ni=0; x=new double[nline][nmax]; y=new double[nline][nmax]; i=0; for(j=0;j<n[0];j++) { x[i][j]=xi[j]; y[i][j]=yi[j]; } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public void pp1( double yi[],int ipt,int ir,int ig,int ib) { // reading data from initial array xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; n[0]=yi.length; double xi[]=new double[n[0]]; for(int i=0;i<n[0];i++) {xi[i]=i+1;} red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; //read all data to determine limit values int i,j; nline=1; plottype[0]=ipt; red[0]=ir; green[0]=ig; blue[0]=ib; nline=1; n[0]=0; plottype[0]=ipt; if(plottype[0] == 10) ch[0]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[0] == 11) ch[0]='#'; if(plottype[0] == 12) ch[0]='$'; if(plottype[0] == 13) ch[0]='%'; if(plottype[0] == 14) ch[0]='&'; if(plottype[0] == 15) ch[0]='£'; if(plottype[0] == 16) ch[0]='~'; if(plottype[0] == 17) ch[0]='+'; if(plottype[0] == 18) ch[0]='^'; if(plottype[0] == 19) ch[0]='='; for(j=0;j<xi.length;j++) { xtemp=xi[j]; ytemp=yi[j]; if(xtemp<xmin) xmin=xtemp; if(xtemp>xmax) xmax=xtemp; if(ytemp<ymin) ymin=ytemp; if(ytemp>ymax) ymax=ytemp; n[0]++; } nmax=n[0];ni=0; x=new double[nline][nmax]; y=new double[nline][nmax]; i=0; for(j=0;j<n[0];j++) { x[i][j]=xi[j]; y[i][j]=yi[j]; } set_plotwindow(500,500,0.1,0.1,0.9,0.9); } public void pp1( double yi[],int ipt) {pp1(yi,ipt,0,0,0);} public void pp1( double yi[]) {pp1(yi,0,0,0,0);} public Plot(double xi[],double yi[]) { pp1(xi,yi); } public Plot(double yi[]) { pp1(yi); } public Plot(double yi[],int ipt) { pp1(yi,ipt); } public Plot(double yi[],int ipt,int ir,int ig,int ib) { pp1(yi,ipt,ir,ig,ib); } public void pp3(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib) { // reading data from a given function//one data set only xmin=xm; xmax=xma; nmax=N; ni=0; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; double xi[]=new double[N]; double yi[]=new double[N]; double dx=(xmax-xmin)/(N-1); double xx=xmin; for(int j=0;j<N;j++) { xi[j]=xx; yi[j]=f.func(xx); xx+=dx; } pp1(xi,yi,ipt,ir,ig,ib); } public Plot(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib) { pp3(f,xm,xma,N,ipt,ir,ig,ib); } public Plot(f_x f,double xm,double xma,int N,int ipt) { // reading data from a given function//one data set only int ir=0; int ig=0; int ib=0; pp3(f,xm,xma,N,ipt,ir,ig,ib); } public Plot(f_x f,double xm,double xma,int N) { // reading data from a given function//one data set only int ipt=0; int ir=0; int ig=0; int ib=0; pp3(f,xm,xma,N,ipt,ir,ig,ib); } public void pp4(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function,int ipt[],int ir[],int ig[],int ib[]) { // reading data from a given functon set // same xmin xmax and Number_of_data for each function nline=Number_of_Function; xmin=xm; xmax=xma; ymin=9.99e50; ymax=-9.99e50; double xtemp,ytemp; n=new int[100]; red=new int[100]; green=new int[100]; blue=new int[100]; plottype=new int[100]; ch=new char[100]; int N=Number_of_Data; double dx=(xmax-xmin)/N; double xx=xmin; int NF=Number_of_Function; nline=NF; double xi[][]=new double[NF][N]; double yi[][]=new double[NF][N]; double yy[]=new double[NF]; for(int j=0;j<N;j++) { yy=f.func(xx); for(int i=0;i<NF;i++) { yi[i][j]=yy[i]; xi[i][j]=xx;} xx+=dx; } pp2(xi,yi,ipt,ir,ig,ib); } public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function, int ipt[],int ir[],int ig[],int ib[]) { pp4(f,xm,xma,Number_of_Data,Number_of_Function,ipt,ir,ig,ib); } public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function, int ipt[]) { int ir[]; int ig[]; int ib[]; int nn=Number_of_Function; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; } pp4(f,xm,xma,Number_of_Data,Number_of_Function,ipt,ir,ig,ib); } public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function) { int ir[]; int ig[]; int ib[]; int ipt[]; int nn=Number_of_Function; ir=new int[nn]; ig=new int[nn]; ib=new int[nn]; ipt=new int[nn]; for(int i=0;i<nn;i++) { ir[i]=0; ig[i]=0; ib[i]=0; ipt[i]=0; } pp4(f,xm,xma,Number_of_Data,Number_of_Function,ipt,ir,ig,ib); } public void setPlabel(String ip) {label=ip;} public void setXlabel(String ix) {xlabel=ix;} public void setYlabel(String iy) {ylabel=iy;} public void setXYlabel(String ix,String iy) {xlabel=ix;ylabel=iy;} public void set_plotwindow(int width,int height,double xip,double yip,double dxp,double dyp) { //sets rectangular plot window //function scale input variables : //real scale plot window width //real scale plot window height //xip: minimum real scale x //yip : minimum real scale y //dxp: real scale x width xmax=xip+dxp //dyp: real scale y height ymax=yip+dyp // xabsmin : absolute (pixel) scale minimum x // yabsmin : absolute (pixel) scale minimum y //abswidth : absolute (pixel) scale x width (maximum x=minimum x+abswidth) //absheight: absolute (pixel) scale y height (maximum y=minimum y+absheight) xabsmin = yabsmin = abswidth = absheight = (int)(width*(xip+0.2)); (int)(height*(yip+0.2)); (int)(width*dxp); (int)(height*dyp); } public void setabsMaxMin(int ixmin,int iymin,int idx,int idy) { xabsmin=ixmin; yabsmin=iymin; abswidth=idx; absheight=idy; } public void addData(double xi[],double yi[]) { addData(xi,yi,0,0,0,0); } public void addData(double ai[][]) { pp2(ai); } public void addData(double ai[][],int iplottype[],int ir[],int ig[],int ib[]) {pp2(ai,iplottype,ir,ig,ib);} public void addData(double ai[][],int iplottype[]) {pp2(ai,iplottype);} public void addData(double xi[],double yi[],int iplottype) { addData(xi,yi,iplottype,0,0,0); } public void addData(double xi[],double yi[],int iplottype,int ir,int ig,int ib) { int oldnmax=nmax; int oldnline=nline; nline+=1; n[oldnline]=xi.length; plottype[nline-1]=iplottype; if(plottype[nline-1] == 10) ch[nline-1]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[nline-1] == 11) ch[nline-1]='#'; if(plottype[nline-1] == 12) ch[nline-1]='$'; if(plottype[nline-1] == 13) ch[nline-1]='%'; if(plottype[nline-1] == 14) ch[nline-1]='&'; if(plottype[nline-1] == 15) ch[nline-1]='-'; if(plottype[nline-1] == 16) ch[nline-1]='~'; if(plottype[nline-1] == 17) ch[nline-1]='+'; if(plottype[nline-1] == 18) ch[nline-1]='^'; if(plottype[nline-1] == 19) ch[nline-1]='='; red[nline-1]=ir; green[nline-1]=ig; blue[nline-1]=ib; if(xi.length>nmax) { nmax=xi.length; ni=nline; } double xa[][]=new double[nline][nmax]; double ya[][]=new double[nline][nmax]; for(int i=0;i<oldnline;i++) { for(int j=0;j<n[i];j++) { xa[i][j]=x[i][j]; ya[i][j]=y[i][j]; } } for(int j=0;j<n[nline-1];j++) { xa[nline-1][j]=xi[j]; ya[nline-1][j]=yi[j]; } x=xa; y=ya; setMinMax(); } public void addData(double xi[][],double yi[][]) { int ip[]=new int[0]; int ir[]=new int[0]; int ig[]=new int[0]; int ib[]=new int[0]; addData(xi,yi,ip,ir,ig,ib); } public void addData(double xi[][],double yi[][],int ip[]) { int ir[]=new int[0]; int ig[]=new int[0]; int ib[]=new int[0]; addData(xi,yi,ip,ir,ig,ib); } public void addData(double xi[][],double yi[][],int ip[],int ir[],int ig[],int ib[]) { int oldnmax=nmax; int oldnline=nline; nline+=xi.length; for(int i=oldnline;i<nline;i++) { plottype[i]=ip[i-oldnline]; if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(plottype[i] == 11) ch[i]='#'; if(plottype[i] == 12) ch[i]='$'; if(plottype[i] == 13) ch[i]='%'; if(plottype[i] == 14) ch[i]='&'; if(plottype[i] == 15) ch[i]='£'; if(plottype[i] == 16) ch[i]='~'; if(plottype[i] == 17) ch[i]='+'; if(plottype[i] == 18) ch[i]='^'; if(plottype[i] == 19) ch[i]='='; red[i]=ir[i-oldnline]; green[i]=ig[i-oldnline]; blue[i]=ib[i-oldnline]; n[i]=xi[i-oldnline].length; if(xi[i-oldnline].length>nmax) { nmax=xi[i-oldnline].length; ni=i; } } double xa[][]=new double[nline][nmax]; double ya[][]=new double[nline][nmax]; for(int i=0;i<oldnline;i++) { for(int j=0;j<n[i];j++) { xa[i][j]=x[i][j]; ya[i][j]=y[i][j]; } } int k=0; for(int i=oldnline;i<nline;i++) { for(int j=0;j<n[i];j++) { xa[i][j]=xi[i-oldnline][j]; ya[i][j]=yi[i-oldnline][j]; } } x=xa; y=ya; setMinMax(); } public void addFunction(f_x f,double xmi,double xma,int N,int ipt) { addFunction(f,xmi,xma,N,ipt,0,0,0); } public void addFunction(f_x f,double xmi,double xma,int N) { addFunction(f,xmi,xma,N,0); } public void addFunction(f_x f,double xmi,double xma,int N,int ipt,int ir,int ig,int ib) { double xi[]=new double[N]; double yi[]=new double[N]; double dx=(xma-xmi)/N; double xx=xmi; for(int j=0;j<N;j++) { xi[j]=xx; yi[j]=f.func(xx); xx+=dx; } addData(xi,yi,ipt,ir,ig,ib); } public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function) { int ipt[]=new int[Number_of_Function]; int ir[]=new int[Number_of_Function]; int ig[]=new int[Number_of_Function]; int ib[]=new int[Number_of_Function]; addFunction(f,xmin,xmax,Number_of_Data,Number_of_Function,ipt,ir,ig,ib); } public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function,int ipt[]) { int ir[]=new int[Number_of_Function]; int ig[]=new int[Number_of_Function]; int ib[]=new int[Number_of_Function]; addFunction(f,xmin,xmax,Number_of_Data,Number_of_Function,ipt,ir,ig,ib); } public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function, int ipt[],int ir[],int ig[],int ib[]) { int N=Number_of_Data; double dx=(xmax-xmin)/N; double xx=xmin; int NF=Number_of_Function; double xi[][]=new double[NF][N]; double yi[][]=new double[NF][N]; double yy[]=new double[NF]; for(int j=0;j<N;j++) { yy=f.func(xx); for(int i=0;i<NF;i++) { yi[i][j]=yy[i]; xi[i][j]=xx;} xx+=dx; } addData(xi,yi,ipt,ir,ig,ib); } public void setPlotType(int plot_type[]) { for(int i=0;i<plot_type.length;i++) { setPlotType(i,plot_type[i]); } setMinMax(); } public void setXlogScaleOn() {xlog=1;xminmaxlog=Math.log10(xmax-xmin+10.0)-1.0;} public void setYlogScaleOn() {ylog=1;yminmaxlog=Math.log10(ymax-ymin+10.0)-1.0;} public void setXlogScaleOff() {xlog=0;} public void setYlogScaleOff() {ylog=0;} public void setPlotType(int dataset,int plot_no) { // plottype = 0 continuous line // plottype = 1 dashed line // plottype = 2 // plottype = 3 // plottype = 10 variable character plot type // plottype = 10 ch[i]='*';//you can change character set by using setPlotType(0,'%'); // plottype = 11 ch[i]='#' // plottype = 12 ch[i]='$' // plottype = 13 ch[i]='%' // plottype = 14 ch[i]='&' // plottype = 15 ch[i]='£' // plottype = 16 ch[i]='~' // plottype = 17 ch[i]='+' //plottype = 18 ch[i]='^' //plottype = 19 ch[i]='=' // plottype = 20 rectangle // plottype = 21 filled rectangle // plottype = 22 circle // plottype = 23 filled circle // plottype = 24 triangle // plottype = 25 diamond // plottype = 26 pentagon // plottype = 27 hexagon // plottype = 28 filled triangle // plottype = 29 filled diamond // plottype = 30 filled pentagon // plottype = 31 filled hexagon // plottype = 32 triangle star // plottype = 33 diamond star // plottype = 34 pentagon star // plottype = 35 hexagon star // plottype = 36 filled triangle star // plottype = 37 filled diamond star // plottype = 38 filled pentagon star // plottype = 39 filled hexagon star // plottype = 40 bar plot // plottype = 41 filled bar plot plottype[dataset]=plot_no; if(plot_no==10) ch[dataset]='*'; //user defined char is defined as * } public void setPlotType(int dataset,char plot_char) { // plottype = 10 user defined character plot plottype[dataset]=10; ch[dataset]=plot_char; } public void setXgrid(int igx) { xgridon=igx; } public void setYgrid(int igy) { ygridon=igy; } public void setGrid(int igx,int igy) { xgridon=igx; ygridon=igy; } public void setXtic(int ixt) { xntic=ixt; } public void setYtic(int iyt) { yntic=iyt; } public void setXYtic(int ixt,int iyt) { xntic=ixt; yntic=iyt; } public void setColor(int dataset,int ired,int igreen,int iblue) { red[dataset]=ired; green[dataset]=igreen; blue[dataset]=iblue; } public void setColor(int dataset,Color x) { red[dataset]=x.getRed(); green[dataset]=x.getGreen(); blue[dataset]=x.getBlue(); } public void setColor(int ired[],int igreen[],int iblue[]) { for(int i=0;i<nline;i++) { red[i]=ired[i]; green[i]=igreen[i]; blue[i]=iblue[i]; } } public void setColor(Color x[]) { for(int i=0;i<nline;i++) { red[i]=x[i].getRed(); green[i]=x[i].getGreen(); blue[i]=x[i].getBlue(); } } public void setMinMax() { xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; for(int i=0;i<nline;i++) { for(int j=0;j<n[i];j++) { if(x[i][j]>xmax) xmax=x[i][j]; if(x[i][j]<xmin) xmin=x[i][j]; if(y[i][j]>ymax) ymax=y[i][j]; if(y[i][j]<ymin) ymin=y[i][j]; } } } public void setMinMax(double xi[][],double yi[][]) { xmin=9.99e50; xmax=-9.99e50; ymin=9.99e50; ymax=-9.99e50; for(int i=0;i<nline;i++) { if(xi[i].length>nmax) {nmax=xi[i].length;ni=i;} for(int j=0;j<xi[i].length;j++) { if(xi[i][j]>xmax) xmax=xi[i][j]; if(xi[i][j]<xmin) xmin=xi[i][j]; if(yi[i][j]>ymax) ymax=yi[i][j]; if(yi[i][j]<ymin) ymin=yi[i][j]; } } } public void setMinMax(double iminx,double imaxx,double iminy,double imaxy) { xmin=iminx; ymin=iminy; xmax=imaxx; ymax=imaxy; } public void plot() { PlotW.plot(this); } //==== B-Spline intrepolation============= public static double[] hi(double ti[]) { int n=ti.length-1;//ti 0..n int nn=n+2; double h[]=new double[nn]; for(int i=1;i<=n;i++) {h[i]=ti[i]-ti[i-1]; } h[0]=h[1]; h[n+1]=h[n]; return h; } public static double [] B_Spline(double ti[],double yi[]) { int n=ti.length-1; int nn=n+2; int i; double delta,gamma,p,q,r; double a[]=new double[nn]; double h[]=new double[nn]; h=hi(ti); delta=-1; gamma=2.0*yi[0]; p=delta*gamma; q=2.0; for(i=1;i<=n;i++) {r=h[i+1]/h[i]; delta=-r*delta; gamma=-r*gamma+(r+1)*yi[i]; p=p+gamma*delta; q=q+delta*delta; } a[0]=-p/q; for(i=1;i<=(n+1);i++) {a[i]=((h[i-1]+h[i])*yi[i-1]-h[i]*a[i-1])/h[i-1];} return a; } public static double funcB_Spline(double ti[],double a[],double x) { double h[]=hi(ti); int i; int n=ti.length-1; double nn=n+2; double d,e; for(i=(n-1);i>=1;i--) {if((x-ti[i])>=0) break;} i++; d=(a[i+1]*(x-ti[i-1])+a[i]*(ti[i]-x+h[i+1]))/(h[i]+h[i+1]); e=(a[i]*(x-ti[i-1]+h[i-1])+a[i-1]*(ti[i-1]-x+h[i]))/(h[i-1]+h[i]); double bs=(d*(x-ti[i-1])+e*(ti[i]-x))/h[i]; return bs; } public static double[][] funcB_Spline(double ti[],double yi[],int aradegersayisi) { //aradegersayisi: x--o--o--x--o--o--x zincirinde x deneysel noktalar ise // ara değer sayısı 2 dir int n=ti.length; int nn=(n-1)*(aradegersayisi+1)+1; double z[][]=new double[2][nn]; double A[]=B_Spline(ti,yi); double dx=0; int k=0; int i; for(i=0;i<(n-1);i++) { z[0][k]=ti[i];z[1][k]=funcB_Spline(ti,A,z[0][k]);k++; for(int j=0;j<aradegersayisi;j++) {dx=(ti[i+1]-ti[i])/((double)aradegersayisi+1.0); z[0][k]=z[0][k-1]+dx;z[1][k]=funcB_Spline(ti,A,z[0][k]);k++;} } z[0][k]=ti[i];z[1][k]=funcB_Spline(ti,A,z[0][k]); return z; } public void addB_Spline(double xi[],double yi[],int nSpline) { addSpline(xi,yi,nSpline,0,0,0,0); } public void addB_Spline(double ai[][],int nSpline) { addSpline(ai[0],ai[1],nSpline,0,0,0,0); } public void addB_Spline(double xi[],double yi[],int nSpline,int iplottype) { addB_Spline(xi,yi,nSpline,iplottype,0,0,0); } public void addB_Spline(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) { double S[][]=funcB_Spline(xi,yi,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of spline function) } public void addB_Spline(int linenumber,int nSpline) {addB_Spline(linenumber,nSpline,0,0,0,0);} public void addB_Spline(int linenumber,int nSpline,int iplottype) {addB_Spline(linenumber,nSpline,iplottype,0,0,0);} public void addB_Spline(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double x2[]=new double[n[linenumber]]; double y2[]=new double[n[linenumber]]; if(linenumber<0) linenumber=0; else if(linenumber>nline) linenumber=nline; for(int j=0;j<n[linenumber];j++) { x2[j]=x[linenumber][j]; y2[j]=y[linenumber][j]; } double S[][]=funcB_Spline(x2,y2,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of spline function) } //==== spline interpolation=============== public static double [] thomas(double a[][],double r[]) { // int n=a.length; double f[]=new double[n]; double e[]=new double[n]; double g[]=new double[n]; double x[]=new double[n]; for(int i=0;i<n;i++) {f[i]=a[i][i];} for(int i=0;i<(n-1);i++) {g[i]=a[i][i+1];} for(int i=0;i<(n-1);i++) {e[i+1]=a[i+1][i];} for(int k=1;k<n;k++) {e[k]=e[k]/f[k-1]; f[k]=f[k]-e[k]*g[k-1]; } for(int k=1;k<n;k++) {r[k]=r[k]-e[k]*r[k-1]; } x[n-1]=r[n-1]/f[n-1]; for(int k=(n-2);k>=0;k--) {x[k]=(r[k]-g[k]*x[k+1])/f[k];} return x; } public static double [] thomas(double f[],double e[],double g[],double r[]) { int n=f.length; double x[]=new double[n]; for(int k=1;k<n;k++) {e[k]=e[k]/f[k-1]; f[k]=f[k]-e[k]*g[k-1]; } for(int k=1;k<n;k++) {r[k]=r[k]-e[k]*r[k-1]; } x[n-1]=r[n-1]/f[n-1]; for(int k=(n-2);k>=0;k--) {x[k]=(r[k]-g[k]*x[k+1])/f[k];} return x; } public static double [][] cubic_spline(double xi[],double yi[],double c0,double cn) { int n=xi.length; double h[]=new double[n]; double w[]=new double[n]; double f[]=new double[n]; double e[]=new double[n]; double g[]=new double[n]; double d[]=new double[n]; double x[]=new double[n]; double S[][]=new double[4][n]; int k; for(k=0;k<(n-1);k++) {h[k]=xi[k+1]-xi[k]; w[k]=(yi[k+1]-yi[k])/h[k]; } d[0]=c0; d[n-1]=cn; for(k=1;k<(n-1);k++) {d[k]=6.0*(w[k]-w[k-1]);} f[0]=1.0; f[n-1]=1.0; g[0]=0.0; g[n-1]=0.0; e[0]=0.0; e[n-1]=0.0; for(k=1;k<(n-1);k++) {f[k]=2.0*(h[k]+h[k-1]);e[k]=h[k-1];g[k]=h[k];} S[2]=thomas(f,e,g,d); S[3]=xi; for(k=0;k<(n-1);k++) {S[0][k]=(6.*yi[k+1]-h[k]*h[k]*S[2][k+1])/(6.0*h[k]); S[1][k]=(6.*yi[k]-h[k]*h[k]*S[2][k])/(6.0*h[k]); } return S; } public static double funcSpline(double S[][],double x) { int n=S[0].length; double xx1=0; double xx2=0; double y=0; double hk=0; for(int k=0;k<(n-1);k++) {if(S[3][k]<=x && x<=S[3][k+1]) {hk=(S[3][k+1]-S[3][k]); xx1=(x-S[3][k]); xx2=(S[3][k+1]-x); y=S[0][k]*xx1+S[1][k]*xx2+(xx1*xx1*xx1*S[2][k+1]+xx2*xx2*xx2*S[2][k])/(6.0*hk); break; } } if(y==0 && S[3][n-2]<=x ) { int k=n-2; hk=(S[3][k+1]-S[3][k]); xx1=(x-S[3][k]); xx2=(S[3][k+1]-x); y=S[0][k]*xx1+S[1][k]*xx2+(xx1*xx1*xx1*S[2][k+1]+xx2*xx2*xx2*S[2][k])/(6.0*hk); } return y; } public static double[][] funcSpline(double xi[],double yi[],int aradegersayisi) { //aradegersayisi: x--o--o--x--o--o--x zincirinde x deneysel noktalar ise // ara değer sayısı 2 dir int n=xi.length; int nn=(n-1)*(aradegersayisi+1)+1; double z[][]=new double[2][nn]; double S[][]=cubic_spline(xi,yi,0,0); double dx=0; int k=0; int i; for(i=0;i<(n-1);i++) { z[0][k]=xi[i];z[1][k]=funcSpline(S,z[0][k]);k++; for(int j=0;j<aradegersayisi;j++) {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0); z[0][k]=z[0][k-1]+dx;z[1][k]=funcSpline(S,z[0][k]);k++;} } z[0][k]=xi[i];z[1][k]=funcSpline(S,z[0][k]); return z; } public void addSpline(double xi[],double yi[],int nSpline) { addSpline(xi,yi,nSpline,0,0,0,0); } public void addSpline(double ai[][],int nSpline) { addSpline(ai[0],ai[1],nSpline,0,0,0,0); } public void addSpline(double xi[],double yi[],int nSpline,int iplottype) { addSpline(xi,yi,nSpline,iplottype,0,0,0); } public void addSpline(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) { double S[][]=funcSpline(xi,yi,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of spline function) } public void addSpline(int linenumber,int nSpline) {addSpline(linenumber,nSpline,0,0,0,0);} public void addSpline(int linenumber,int nSpline,int iplottype) {addSpline(linenumber,nSpline,iplottype,0,0,0);} public void addSpline(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double x2[]=new double[n[linenumber]]; double y2[]=new double[n[linenumber]]; if(linenumber<0) linenumber=0; else if(linenumber>nline) linenumber=nline; for(int j=0;j<n[linenumber];j++) { x2[j]=x[linenumber][j]; y2[j]=y[linenumber][j]; } double S[][]=funcSpline(x2,y2,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of spline function) } //==========orthogonal polynomial interpolation (curve fitting) public static double[][] OPEKK(double xi[],double fi[],int m) //ortogonal polinom en küçük kareler metodu //Referans : A First Course in Numerical Analysis // Anthony Ralston,Philip Rabinowitz, Mc Graw Hill ISBN 0-07-051158-6 //m polinom derecesi xi fi girdi verisi { int i,j,k; int n=xi.length; int mp2=n+2; int mp1=n+1; double p[][]=new double[mp2][n]; double gamma[]=new double[mp1]; double beta[]=new double[mp1]; double omega[]=new double[mp1]; double alpha[]=new double[mp1]; double b[]=new double[mp1]; double wi[]=new double[n]; double a[][]=new double[3][mp1]; for(i=0;i<n;i++) { p[1][i]=1.0; p[0][i]=0.0; wi[i]=1.0; } gamma[0]=0; for(i=0;i<n;i++) { gamma[0]+=wi[i]; } beta[0]=0.0; for(j=0;j<m+1;j++) { omega[j]=0; for(i=0;i<n;i++) {omega[j]+=wi[i]*fi[i]*p[j+1][i];} b[j]=omega[j]/gamma[j]; if( j != m) { alpha[j+1]=0; for(i=0;i<n;i++) { alpha[j+1]+=wi[i]*xi[i]*p[j+1][i]*p[j+1][i]/gamma[j];} for(i=0;i<n;i++) {p[j+2][i]=(xi[i]-alpha[j+1])*p[j+1][i]-beta[j]*p[j][i];} gamma[j+1]=0; for(i=0;i<n;i++) {gamma[j+1]+=wi[i]*p[j+2][i]*p[j+2][i];} beta[j+1]=gamma[j+1]/gamma[j]; } }//end of j for(j=0;j<m+1;j++) { a[0][j]=b[j]; a[1][j]=alpha[j]; a[2][j]=beta[j]; } return a; } public static double funcOPEKK(double a[][],double x) { // polinom değerleri hesaplama fonksiyonu double yy=0; int k; int m=a[0].length-1; int mp2=m+2; double q[]; q=new double[mp2]; //vector<double> q(m+2,0.0); for(k=m-1;k>=0;k--) { q[k]=a[0][k]+(x-a[1][k+1])*q[k+1]-a[2][k+1]*q[k+2]; yy=q[k]; } return yy; } public static double[][] funcOPEKK(double xi[],double yi[],int polinomkatsayisi,int aradegersayisi) { //aradegersayisi: x--o--o--x--o--o--x zincirinde x deneysel noktalar ise // ara değer sayısı 2 dir int n=xi.length; int nn=(n-1)*(aradegersayisi+1)+1; double z[][]=new double[2][nn]; double E[][]=OPEKK(xi,yi,polinomkatsayisi); double dx=0; int k=0; int i; for(i=0;i<(n-1);i++) {z[0][k]=xi[i];z[1][k]=funcOPEKK(E,z[0][k]);k++; for(int j=0;j<aradegersayisi;j++) {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0); z[0][k]=z[0][k-1]+dx;z[1][k]=funcOPEKK(E,z[0][k]);k++;} } z[0][k]=xi[i];z[1][k]=funcOPEKK(E,z[0][k]); return z; } public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi) { addOPEKK(xi,yi,npolinom,aradegersayisi,0,0,0,0); } public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype) { addOPEKK(xi,yi,npolinom,npolinom,iplottype,0,0,0); } public void addOPEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double S[][]=funcOPEKK(xi,yi,npolinom,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of OPEKK function) } public void addOPEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype) {addOPEKK(linenumber,npolinom,aradegersayisi,iplottype,0,0,0);} public void addOPEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double x2[]=new double[n[linenumber]]; double y2[]=new double[n[linenumber]]; if(linenumber<0) linenumber=0; else if(linenumber>nline) linenumber=nline; for(int j=0;j<n[linenumber];j++) { x2[j]=x[linenumber][j]; y2[j]=y[linenumber][j]; } double S[][]=funcOPEKK(x2,y2,npolinom,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of OPEKK function) } // en kucuk kareler public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static double[] EKK(double xi[],double yi[],int n) { int l=xi.length; int i,j,k; int np1=n+1; double A[][]; A=new double[np1][np1]; double B[]; B=new double[np1]; double X[]; X=new double[np1]; for(i=0;i<n+1;i++) { for(j=0;j<n+1;j++) {if(i==0 && j==0) A[i][j]=l; else for(k=0;k<l;k++) A[i][j] += Math.pow(xi[k],(i+j)); } for(k=0;k<l;k++) { if(i==0) B[i]+= yi[k]; else B[i] += Math.pow(xi[k],i)*yi[k];} } System.out.println(Matrix.toString(A)); System.out.println(Matrix.toStringT(B)); X=pivotlugauss(A,B); //X=B/A; double max=0; for(i=0;i<n+1;i++) if(Math.abs(X[i]) > max) max = Math.abs(X[i]); for(i=0;i<n+1;i++) if((Math.abs(X[i]/max) > 0) && (Math.abs(X[i]/max) < 1.0e-100)) X[i]=0; return X; } public static double funcEKK(double e[],double x) { // this function calculates the value of // least square curve fitting function int n=e.length; double ff; if(n!=0.0) { ff=e[n-1]; for(int i=n-2;i>=0;i--) { ff=ff*x+e[i]; } } else ff=0; return ff; } public static double hata(double x[],double y[],double e[]) { //calculates absolute square root error of a least square approach double n=x.length; int k; double total=0; for(k=0;k<n;k++) { total+=(y[k]-funcEKK(e,x[k]))*(y[k]-funcEKK(e,x[k])); } total=Math.sqrt(total); return total; } public static double[][] funcEKK(double xi[],double yi[],int polinomkatsayisi,int aradegersayisi) { //aradegersayisi: x--o--o--x--o--o--x zincirinde x deneysel noktalar ise // ara değer sayısı 2 dir int n=xi.length; int nn=(n-1)*(aradegersayisi+1)+1; double z[][]=new double[2][nn]; double E[]=EKK(xi,yi,polinomkatsayisi); double dx=0; int k=0; int i; for(i=0;i<(n-1);i++) {z[0][k]=xi[i];z[1][k]=funcEKK(E,z[0][k]);k++; for(int j=0;j<aradegersayisi;j++) {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0); z[0][k]=z[0][k-1]+dx;z[1][k]=funcEKK(E,z[0][k]);k++;} } z[0][k]=xi[i];z[1][k]=funcEKK(E,z[0][k]); return z; } public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi) { addEKK(xi,yi,npolinom,aradegersayisi,0,0,0,0); } public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype) { addEKK(xi,yi,npolinom,npolinom,iplottype,0,0,0); } public void addEKK(double xi[],double yi[],int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double S[][]=funcEKK(xi,yi,npolinom,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of EKK function) } public void addEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype) {addEKK(linenumber,npolinom,aradegersayisi,iplottype,0,0,0);} public void addEKK(int linenumber,int npolinom,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double x2[]=new double[n[linenumber]]; double y2[]=new double[n[linenumber]]; if(linenumber<0) linenumber=0; else if(linenumber>nline) linenumber=nline; for(int j=0;j<n[linenumber];j++) { x2[j]=x[linenumber][j]; y2[j]=y[linenumber][j]; } double S[][]=funcEKK(x2,y2,npolinom,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of EKK function) } //=====Lagrange interpolasyon public static double[][] Lagrange(double xi[],double yi[]) { int n=xi.length; double L[][]=new double[2][n]; for(int i=0;i<n;i++) {L[0][i]=yi[i]; for(int j=0;j<n;j++) {if(i!=j) L[0][i]/=(xi[i]-xi[j]);} } for(int i=0;i<n;i++) {L[1][i]=xi[i];} return L; } public static double funcLagrange(double L[][],double x) { int n=L[0].length; double carpim=1.0; double toplam=0; for(int i=0;i<n;i++) {carpim=L[0][i]; for(int j=0;j<n;j++) {if(i!=j) carpim*=(x-L[1][j]);} toplam+=carpim; } return toplam; } public static double[][] funcLagrange(double xi[],double yi[],int aradegersayisi) { //aradegersayisi: x--o--o--x--o--o--x zincirinde x deneysel noktalar ise // ara değer sayısı 2 dir int n=xi.length; int nn=(n-1)*(aradegersayisi+1)+1; double z[][]=new double[2][nn]; double Q[][]=Lagrange(xi,yi); double dx=0; int k=0; int i; for(i=0;i<(n-1);i++) { z[0][k]=xi[i];z[1][k]=funcLagrange(Q,z[0][k]);k++; for(int j=0;j<aradegersayisi;j++) {dx=(xi[i+1]-xi[i])/((double)aradegersayisi+1.0); z[0][k]=z[0][k-1]+dx;z[1][k]=funcLagrange(Q,z[0][k]);k++;} } z[0][k]=xi[i];z[1][k]=funcLagrange(Q,z[0][k]); return z; } public void addLagrange(double xi[],double yi[],int aradegersayisi) { addLagrange(xi,yi,aradegersayisi,0,0,0,0); } public void addLagrange(double xi[],double yi[],int aradegersayisi,int iplottype) { addLagrange(xi,yi,aradegersayisi,iplottype,0,0,0); } public void addLagrange(double xi[],double yi[],int aradegersayisi,int iplottype,int ir,int ig,int ib) { double S[][]=funcLagrange(xi,yi,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of Lagrange function) } public void addLagrange(int linenumber,int aradegersayisi,int iplottype) {addLagrange(linenumber,aradegersayisi,iplottype,0,0,0);} public void addLagrange(int linenumber,int aradegersayisi,int iplottype,int ir,int ig,int ib) { double x2[]=new double[n[linenumber]]; double y2[]=new double[n[linenumber]]; if(linenumber<0) linenumber=0; else if(linenumber>nline) linenumber=nline; for(int j=0;j<n[linenumber];j++) { x2[j]=x[linenumber][j]; y2[j]=y[linenumber][j]; } double S[][]=funcLagrange(x2,y2,aradegersayisi); addData(S[0],S[1],iplottype,ir,ig,ib); //one set of additional data (of Lagrange function) } public void setBackground(Color b1) {bg=b1;} public void setBackground(int ir,int ig,int ib) {bg=new Color(ir,ig,ib);} //Static plot functions //=========== public static Plot func(f_x ff1,double xmin,double xmax,int n,int pnumber) { Plot pp=new Plot(ff1,xmin,xmax,n,pnumber); pp.plot(); return pp; } public static Plot func(f_x ff1,double xmin,double xmax,int n) { Plot pp=new Plot(ff1,xmin,xmax,n,0); pp.plot(); return pp; } public static Plot func(f_x ff1,double xmin,double xmax) { Plot pp=new Plot(ff1,xmin,xmax,300,0); pp.plot(); return pp; } public static Plot func(fi_x ff1,double xmin,double xmax,int n,int pnumber) { Plot pp=new Plot(ff1,xmin,xmax,n,pnumber); pp.plot(); return pp; } public static Plot func(fi_x ff1,double xmin,double xmax,int n) { Plot pp=new Plot(ff1,xmin,xmax,n,0); pp.plot(); return pp; } public static Plot func(fi_x ff1,double xmin,double xmax) { Plot pp=new Plot(ff1,xmin,xmax,300,0); pp.plot(); return pp; } public static Plot file(String ff1)throws IOException { Plot pp=new Plot(ff1); pp.plot(); return pp; } public static Plot file()throws IOException { Plot pp=new Plot(); pp.plot(); return pp; } public static Plot file(String ff1,String ff2)throws IOException { String ff3[]={ff1,ff2}; Plot pp=new Plot(ff3); pp.plot(); return pp; } public static Plot file(String ff1,String ff2,String ff3)throws IOException { String ff4[]={ff1,ff2,ff3}; Plot pp=new Plot(ff4); pp.plot(); return pp; } public static Plot data(double x[],double y[]) { Plot pp=new Plot(x,y); pp.plot(); return pp; } public static Plot data(double a[][]) { Plot pp=new Plot(a); pp.plot(); return pp; } } Program 1.6.13-13 PlotW.java programı PLOTW PROGRAMI //====================================================== // Numerical Analysis package in java // Plot (Çizim ) programı // Dr. Turhan Coban // EGE Üniversitesi Mühendislik Fakultesi, Makina Bölümü // [email protected] // ===================================================== /* * Swing version. */ import java.lang.Integer; import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; import java.io.*; //import Plot2D; //import PlotShapesSW; //import BasicWindowMonitor; public class PlotW extends JFrame implements ItemListener,ActionListener, MouseListener,MouseMotionListener { private String s=""; //f2 ff=new f2(); boolean inAnApplet = true; final static String KONTROLPANEL = "Kontrol sayfası"; final static String PLOTPANEL = "Plot sayfası "; Plot2D jta; double xi1,yi1,xi2,yi2; JPanel p1,p2,p3; int n; JLabel altbar; //writing area JLabel promptXmin; // Label prompt in Xmin field JLabel promptXmax; // Label prompt in Xmax field JLabel promptYmin; // Label prompt in Ymin field JLabel promptYmax; // Label prompt in Ymax field JLabel promptLabel; // Label prompt Plot Label JLabel promptXLabel; // Label prompt Plot XLabel JLabel promptYLabel; // Label prompt Plot YLabel JLabel promptXntic; // Label prompt in Xmin field JLabel promptYntic; // Label prompt in Xmax field JLabel promptXgridon; // Label prompt in Ymin field JLabel promptYgridon; // Label prompt in Ymax field JLabel promptXlogon; // x axis log scale on JLabel promptYlogon; // y axis log scale on JTextField inputXmin; // input field Xmin JTextField inputXmax; // input field Xmax JTextField inputYmin; // input field Ymin JTextField inputYmax; // input field Ymax JTextField inputLabel; // input field Label JTextField inputXLabel; // input field XLabel JTextField inputYLabel; // input field YLabel JTextField inputXntic; // input field xntic JTextField inputYntic; // input field yntic JCheckBox inputXgridon; // input field xgridon JCheckBox inputYgridon; // input field ygridon JCheckBox inputXlogon; // check field xlogon JCheckBox inputYlogon; // check field ylogon JButton printButton; JLabel lab1[]; JComboBox c1[]; JTextField red1[]; JTextField green1[]; JTextField blue1[]; JButton col1[]; public PlotW() { super("Plot çizimi"); try{Plot pi=new Plot();plotWkur(pi); } catch(IOException e) { System.err.println("Error Opening File \n"+e.toString()); System.exit(1); } } public PlotW(Plot pi) { super(pi.label); plotWkur(pi); } public void plotWkur(Plot pi) { n=pi.nline; lab1=new JLabel[n]; c1=new JComboBox[n]; red1=new JTextField[n]; green1=new JTextField[n]; blue1=new JTextField[n]; col1=new JButton[n]; //System.out.println("n="+n); for(int i=0;i<n;i++) { Color color1=new Color(pi.red[i],pi.green[i],pi.blue[i]); lab1[i]=new JLabel("eğri "+i+" "); c1[i]=new JComboBox(pi.plotst); c1[i].setSelectedIndex(pi.plottype[i]); red1[i]=new JTextField(""+pi.red[i]); green1[i]=new JTextField(""+pi.green[i]); blue1[i]=new JTextField(""+pi.blue[i]); col1[i]=new JButton(" "); col1[i].setBackground(color1); } Container contentPane = getContentPane(); JTabbedPane tabbedPane = new JTabbedPane(); promptXmin=new JLabel("Xmin "); inputXmin=new JTextField(10); promptXmax=new JLabel("Xmax "); inputXmax=new JTextField(10); promptYmin=new JLabel("Ymin "); inputYmin=new JTextField(10); promptYmax=new JLabel("Ymax "); inputYmax=new JTextField(10); //******* promptLabel=new JLabel(" Plot başlığı : "); promptXLabel=new JLabel(" x ekseni başlığı : "); promptYLabel=new JLabel(" y ekseni başlığı : "); inputLabel=new JTextField(40); inputXLabel=new JTextField(40); inputYLabel=new JTextField(40); //******* promptXntic=new JLabel("X tik no"); inputXntic=new JTextField(10); promptYntic=new JLabel("Y tik no"); inputYntic=new JTextField(10); promptXgridon=new JLabel("X grid (küçük kare)"); if(pi.xgridon!=0) inputXgridon=new JCheckBox(" ",true); else inputXgridon=new JCheckBox(" ",false); promptYgridon=new JLabel("Y grid (küçük kare)"); if(pi.ygridon!=0) inputYgridon=new JCheckBox(" ",true); else inputYgridon=new JCheckBox(" ",false); promptXlogon=new JLabel("x log "); promptYlogon=new JLabel("y log "); if(pi.xlog!=0) inputXlogon=new JCheckBox(" ",true); else inputXlogon=new JCheckBox(" ",false); if(pi.ylog!=0) inputYlogon=new JCheckBox(" ",true); else inputYlogon=new JCheckBox(" ",false); // check field xlogon //******* JPanel pane1 = new JPanel() { public Dimension getPrefferedSize() { Dimension size=super.getPreferredSize(); size.width=800; return size; } }; JPanel mpane=new JPanel(); mpane.setLayout(new GridLayout(5,4)); mpane.add(promptXmin); mpane.add(inputXmin); mpane.add(promptXmax); mpane.add(inputXmax); mpane.add(promptYmin); mpane.add(inputYmin); mpane.add(promptYmax); mpane.add(inputYmax); mpane.add(promptXntic); mpane.add(inputXntic); mpane.add(promptYntic); mpane.add(inputYntic); mpane.add(promptXgridon); mpane.add(inputXgridon); mpane.add(promptYgridon); mpane.add(inputYgridon); mpane.add(promptXlogon); mpane.add(inputXlogon); mpane.add(promptYlogon); mpane.add(inputYlogon); pane1.add(mpane,BorderLayout.NORTH); JPanel xpane=new JPanel(); xpane.setLayout(new GridLayout(n,6)); for(int i=0;i<n;i++) { //c1.setBackground(new Color(pi.red[i],pi.green[i],pi.blue[i])); xpane.add(lab1[i]); xpane.add(c1[i]); xpane.add(red1[i]); xpane.add(green1[i]); xpane.add(blue1[i]); xpane.add(col1[i]); } pane1.add(xpane,BorderLayout.NORTH); //******** JPanel lpane=new JPanel(); lpane.setLayout(new GridLayout(3,2)); lpane.add(promptLabel); lpane.add(inputLabel); lpane.add(promptXLabel); lpane.add(inputXLabel); lpane.add(promptYLabel); lpane.add(inputYLabel); pane1.add(lpane,BorderLayout.SOUTH); //********* for(int i=0;i<n;i++) { //c1.setBackground(new Color(pi.red[i],pi.green[i],pi.blue[i])); c1[i].addItemListener(this); col1[i].addActionListener(this); red1[i].addActionListener(this); green1[i].addActionListener(this); blue1[i].addActionListener(this); } //********** inputXmin.addActionListener(this); inputXmax.addActionListener(this); inputYmin.addActionListener(this); inputYmax.addActionListener(this); inputLabel.addActionListener(this); inputXLabel.addActionListener(this); inputYLabel.addActionListener(this); inputXntic.addActionListener(this); inputYntic.addActionListener(this); inputXlogon.addItemListener(this); inputYlogon.addItemListener(this); inputXgridon.addItemListener(this); inputYgridon.addItemListener(this); jta=new Plot2D(pi); inputXmin.setText(Double.toString(jta.p1.xmin)); inputXmax.setText(Double.toString(jta.p1.xmax)); inputYmin.setText(Double.toString(jta.p1.ymin)); inputYmax.setText(Double.toString(jta.p1.ymax)); inputXntic.setText(Integer.toString(jta.p1.xntic)); inputYntic.setText(Integer.toString(jta.p1.yntic)); inputLabel.setText(jta.p1.label); inputXLabel.setText(jta.p1.xlabel); inputYLabel.setText(jta.p1.ylabel); JPanel pane2 = new JPanel(); pane2.setLayout(new BorderLayout()); altbar=new JLabel(); pane2.add(altbar,BorderLayout.SOUTH); pane2.addMouseListener(this); pane2.addMouseMotionListener(this); pane2.add(jta); tabbedPane.addTab(PLOTPANEL, pane2); tabbedPane.addTab(KONTROLPANEL, pane1); contentPane.add( tabbedPane, BorderLayout.CENTER); } public void itemStateChanged(ItemEvent e) { inputXmin.setText(Double.toString(jta.p1.xmin)); inputXmax.setText(Double.toString(jta.p1.xmax)); inputYmin.setText(Double.toString(jta.p1.ymin)); inputYmax.setText(Double.toString(jta.p1.ymax)); inputXntic.setText(Integer.toString(jta.p1.xntic)); inputYntic.setText(Integer.toString(jta.p1.yntic)); Object source=e.getItemSelectable(); if(source==inputXgridon) { if (e.getStateChange() == ItemEvent.DESELECTED) {jta.p1.xgridon=0;} else {jta.p1.xgridon=1;} } else if(source==inputYgridon) { if (e.getStateChange() == ItemEvent.DESELECTED) {jta.p1.ygridon=0;} else {jta.p1.ygridon=1;} } else if(source==inputXlogon) { if (e.getStateChange() == ItemEvent.DESELECTED) {jta.p1.xlog=0;} else {jta.p1.xlog=1;} } else if(source==inputYlogon) { if (e.getStateChange() == ItemEvent.DESELECTED) {jta.p1.ylog=0;} else {jta.p1.ylog=1;} } else { for(int i=0;i<n;i++) { if(source==c1[i]) {jta.p1.plottype[i]=c1[i].getSelectedIndex(); if(jta.p1.plottype[i] == 10) jta.p1.ch[i]='*';//you can change character set by using setPlotType(0,'%'); if(jta.p1.plottype[i] == 11) jta.p1.ch[i]='#'; if(jta.p1.plottype[i] == 12) jta.p1.ch[i]='$'; if(jta.p1.plottype[i] == 13) jta.p1.ch[i]='%'; if(jta.p1.plottype[i] == 14) jta.p1.ch[i]='&'; if(jta.p1.plottype[i] == 15) jta.p1.ch[i]='-'; if(jta.p1.plottype[i] == 16) jta.p1.ch[i]='~'; if(jta.p1.plottype[i] == 17) jta.p1.ch[i]='+'; if(jta.p1.plottype[i] == 18) jta.p1.ch[i]='x'; if(jta.p1.plottype[i] == 19) jta.p1.ch[i]='='; } } inputLabel.setText(jta.p1.label); inputXLabel.setText(jta.p1.xlabel); inputYLabel.setText(jta.p1.ylabel); jta.yenidenciz(); } } public void actionPerformed(ActionEvent e) { if (e.getSource()==printButton ) {jta.yazdir();} else if (e.getSource()==inputXmin ) {Double valXmin=new Double(inputXmin.getText()); jta.p1.xmin=valXmin.doubleValue();} else if (e.getSource()==inputXmax ) {Double valXmax=new Double(inputXmax.getText()); jta.p1.xmax=valXmax.doubleValue();} else if (e.getSource()==inputYmin ) {Double valYmin=new Double(inputYmin.getText()); jta.p1.ymin=valYmin.doubleValue();} else if (e.getSource()==inputYmax ) {Double valYmax=new Double(inputYmax.getText()); jta.p1.ymax=valYmax.doubleValue();} else if (e.getSource()==inputXntic ) {Integer valXntic=new Integer(inputXntic.getText()); jta.p1.xntic=valXntic.intValue();} else if (e.getSource()==inputYntic ) {Integer valYntic=new Integer(inputYntic.getText()); jta.p1.yntic=valYntic.intValue();} else if (e.getSource()==inputLabel ) {jta.p1.label=inputLabel.getText();} else if (e.getSource()==inputXLabel ) {jta.p1.label=inputXLabel.getText();} else if (e.getSource()==inputYLabel ) {jta.p1.label=inputYLabel.getText();} //***** for(int i=0;i<n;i++) { Color color1=new Color(jta.p1.red[i],jta.p1.green[i],jta.p1.blue[i]); Color color2; if (e.getSource()==red1[i] ) {Integer valred=new Integer(red1[i].getText()); jta.p1.red[i]=valred.intValue();} else if (e.getSource()==green1[i] ) {Integer valgreen=new Integer(green1[i].getText()); jta.p1.green[i]=valgreen.intValue();} else if (e.getSource()==blue1[i] ) { Integer valblue=new Integer(blue1[i].getText());} else if (e.getSource()==col1[i] ) { color2=JColorChooser.showDialog(null,"grafik programı eğri "+i,color1 ); jta.p1.red[i]=color2.getRed();jta.p1.green[i]=color2.getGreen();jta.p1.blue[i]=color2.getBlue(); red1[i].setText(""+jta.p1.red[i]);green1[i].setText(""+jta.p1.green[i]);blue1[i].setText(""+jta.p1.blue[i]); } color2=new Color(jta.p1.red[i],jta.p1.green[i],jta.p1.blue[i]); col1[i].setBackground(color2); } //***** jta.yenidenciz(); } public void degerleriGir(String e,int x,int y) { s=e; if(jta.p1.xlog!=0) {xi1=jta.p1.xmin+Math.pow(10.0,(double)((x-jta.p1.xabsmin)/(double)jta.p1.abswidth*(double)jta.p1.xminmaxlog+1.0))-10.0; } else {xi1=jta.p1.xmin+(double)(x-jta.p1.xabsmin)/(double)jta.p1.abswidth*(jta.p1.xmax-jta.p1.xmin);} if(jta.p1.ylog!=0) {yi1=jta.p1.ymin-10.0+Math.pow(10.0,((double)(1.0-(double)(y-jta.p1.yabsminjta.p1.absheight)/(double)jta.p1.absheight*(double)jta.p1.yminmaxlog))); } else {yi1=jta.p1.ymin-(double)(y-jta.p1.yabsmin-jta.p1.absheight)/(double)jta.p1.absheight*(jta.p1.ymax-jta.p1.ymin);} altbar.setText(e+" ["+xi1+" , "+yi1+"] "); //jta.yenidenciz(); } public void mouseClicked(MouseEvent e) { degerleriGir("Kliklendi",e.getX(),e.getY()); } public void mousePressed(MouseEvent e) { degerleriGir("Basıldı",e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { degerleriGir("Bırakıldı",e.getX(),e.getY()); } public void mouseEntered(MouseEvent e) { setTitle("Fare applet alanı içinde"); } public void mouseExited(MouseEvent e) { setTitle("Fare applet alanı dışında"); degerleriGir("Fare applet alanı dışında",e.getX(),e.getY()); } //MouseMotionListener (fare hareket dinleyicisi) metotlari public void mouseDragged(MouseEvent e) { degerleriGir("basilip cekiliyor",e.getX(),e.getY()); } public void mouseMoved(MouseEvent e) { degerleriGir("hareket halinde",e.getX(),e.getY()); } public static void plot() { //takes plot sata from Plot.txt file PlotW pencere= new PlotW(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(1000,800); pencere.setVisible(true); } public static void plot(Plot pi) { //take plot data from pi object PlotW pencere= new PlotW(pi); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(1000,800); pencere.setVisible(true); } public static void main(String[] args) { PlotW pencere= new PlotW(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(1000,800); pencere.setVisible(true); } } Program 1.6.13-14 PLOT2D PROGRAMI import java.io.*; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.awt.print.PrinterJob; import java.awt.print.*; public class Plot2D extends JPanel implements Printable { public Graphics2D g; public Plot p1; final static Color bg = Color.white; final static Color fg = Color.black; final static Color red = Color.red; final static Color white = Color.white; final static BasicStroke stroke = new BasicStroke(1.0f); final static BasicStroke boldStroke = new BasicStroke(2.0f); PlotShapesSW ps; double xx[],yy[]; int xn; public Plot2D(Plot pi) { //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); //read data from file Plot data previously defined p1=pi; xx=new double[200]; yy=new double[200]; xn=0; } public Plot2D() { //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); //read data from file Plot data previously defined try{p1=new Plot(); } catch(IOException ioe) {System.err.println("IOExceptionin opening plot");} xx=new double[200]; yy=new double[200]; xn=0; } public Plot2D(String pl,String xl,String yl,int xnt,int ynt ,int xgo,int ygo,String ifn[],int ipt[],int ir[],int ig[] ,int ib[]) { //input variables // pl : plot label // xl : x axis label // yl : y axis label //xnt : x axis tic (0=off, any other:on) //ynt : y axis tic (0=off, any other:on) //xgo : x axis grid on (0=off, any other:on) //ygo : y axis grid on (0=off, any other:on) //ifn :file name array variable //ipt : plot type array variable //ir : color red component array variable //ig : color green componenet array variable //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); try{ p1=new Plot(pl,xl,yl,xnt,ynt,xgo,ygo,ifn,ipt,ir,ig,ib); } catch(IOException ioe) {System.err.println("IOExceptionin opening plot");} xx=new double[200]; yy=new double[200]; xn=0; } public void setXY(double ixx[],double iyy[],int ixn) { xn=ixn; for(int i=0;i<xn;i++) {xx[i]=ixx[i];yy[i]=iyy[i];} } public void yenidenPlotDatasiOku() { try{ p1=new Plot(); } catch(IOException ioe) {System.err.println("IOExceptionin opening plot");} } public void yenidenPlotDatasiOku(Plot pi) { p1=pi; } public void plotVerisiEkle(double xi[],double yi[],int iplottype,int ir,int ig,int ib) { p1.addData(xi,yi,iplottype,ir,ig,ib); } public void plotVerisiEkle(double xi[][],double yi[][],int iplottype[],int ir[],int ig[],int ib[]) { p1.addData(xi,yi,iplottype,ir,ig,ib); } public void plotVerisiEkle(f_x f,double xmin,double xmax,int N,int iplottype,int ir,int ig,int ib) { p1.addFunction(f,xmin,xmax,N,iplottype,ir,ig,ib); } public void yenidenPlotDatasiOku(String pl,String xl,String yl,int xnt,int ynt ,int xgo,int ygo,String ifn[],int ipt[],int ir[],int ig[] ,int ib[]) { //input variables // pl : plot label // xl : x axis label // yl : y axis label //xnt : x axis tic (0=off, any other:on) //ynt : y axis tic (0=off, any other:on) //xgo : x axis grid on (0=off, any other:on) //ygo : y axis grid on (0=off, any other:on) //ifn :file name array variable //ipt : plot type array variable //ir : color red component array variable //ig : color green componenet array variable //Initialize drawing colors setBackground(Color.white); setForeground(Color.black); try{ p1=new Plot(pl,xl,yl,xnt,ynt,xgo,ygo,ifn,ipt,ir,ig,ib); } catch(IOException ioe) {System.err.println("IOExceptionin opening plot");} } public void yenidenciz() { repaint(); } public void yazdir() { PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setPrintable(this); if (printJob.printDialog()) { try { printJob.print();} catch (Exception ex) {ex.printStackTrace();} } } public int print(Graphics g, PageFormat pf, int pi) throws PrinterException { if (pi >= 1) { return Printable.NO_SUCH_PAGE; } super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; drawShapes(g2); return Printable.PAGE_EXISTS; } public void drawShapes(Graphics2D g2) { g=g2; //draw Plot Dimension d=getSize(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int gridWidth = d.width; int gridHeight = d.height; int rowspacing=(int)(d.width/100.0); int columnspacing=(int)(d.height/50.0); int rectWidth=gridWidth-columnspacing; int rectHeight=gridHeight-rowspacing; p1.xabsmin=(int)(0.25*rectWidth); p1.yabsmin=(int)(0.2*rectHeight); p1.abswidth=(int)(0.65*rectWidth); p1.absheight=(int)(0.7*rectHeight); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); g2.setStroke(stroke); g2.setPaint(fg); g2.drawRect(p1.xabsmin,p1.yabsmin,p1.abswidth,p1.absheight); ps=new PlotShapesSW(g2,p1.xabsmin,p1.yabsmin, p1.absheight,p1.abswidth,p1.xmin,p1.xmax,p1.ymin,p1.ymax,p1.xlog,p1.ylog); if(p1.xgridon!=0) ps.drawXGrid(p1.xntic); if(p1.ygridon!=0) ps.drawYGrid(p1.yntic); int i,j; ps.drawMouseTic(xx,yy,xn); for(i=0;i<p1.nline;i++) { // Select plot colors g2.setPaint(new Color(p1.red[i],p1.green[i],p1.blue[i])); ps.drawPlotLines(i,p1.plottype,p1.x,p1.y,p1.n,p1.ch); }//end of for(i=0 g2.setPaint(fg); ps.drawXTic(p1.xntic,(p1.ymax-p1.ymin)/80.0,0); ps.drawYTic(p1.yntic,(p1.xmax-p1.xmin)/80.0,0); ps.drawXNumbers(p1.xntic); ps.drawYNumbers(p1.xntic); ps.drawLabel(p1.label); ps.drawXLabel(p1.xlabel); ps.drawYLabel(p1.ylabel); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; drawShapes(g2); } } Program 1.6.13-15 PLOTSHAPESSW PROGRAMI //====================================================== // Numerical Analysis package in java // PlotShapes class // This class convert graphic draw methods to // plot coordinates and gives additional plotting methods // Dr. Turhan Coban // ===================================================== import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.awt.font.*; public class PlotShapesSW { public Graphics2D g; int xabsmin,yabsmin; int absheight,abswidth; double xmin,xmax,ymin,ymax; public int xlog,ylog; double xminmaxlog,yminmaxlog; Font f; final static float dash1[] = {10.0f}; final static float dash2[] = {10.0f,3.0f,3.0f}; final static float dash3[] = {10.0f,3.0f,3.0f}; final static float dash4[] = {5.0f,5.0f,5.0f}; final static BasicStroke d1 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash1, 2.0f); final static BasicStroke d2 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash2, 2.0f); final static BasicStroke d3 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash3, 2.0f); final static BasicStroke d4 = new BasicStroke(1.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash4, 2.0f); final static BasicStroke d5 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash1, 2.0f); final static BasicStroke d6 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash2, 2.0f); final static BasicStroke d7 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash3, 2.0f); final static BasicStroke d8 = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 3.0f, dash4, 2.0f); /* public PlotShapesSW(Graphics2D gi,int xabsmini ,int yabsmini, int absheighti,int abswidthi, double xmini,double xmaxi, double ymini,double ymaxi) { // xabsmin : absulute stating point x axis // yabsmin : absolute starting point y axis // absheight : absoulute height of plotting window // abswidth : absolute width of plotting window // xmin : minimum x value (real number) // xmax : maximum x value (real number) // ymin : minimum y value (real number) // ymax : maximum y value (real number) // g : graphic object that actual drawing is done through g=gi; Font fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); f=fonts[2].deriveFont(Font.BOLD,14);//You can change Fony from here g.setFont(f); xabsmin=xabsmini; yabsmin=yabsmini; absheight=absheighti; abswidth=abswidthi; xmin=xmini; xmax=xmaxi; ymin=ymini; ymax=ymaxi; xlog=0; ylog=0; } */ public PlotShapesSW(Graphics2D gi,int xabsmini ,int yabsmini, int absheighti,int abswidthi, double xmini,double xmaxi, double ymini,double ymaxi, int xlogi,int ylogi) { // xabsmin : absulute starting point x axis // yabsmin : absolute starting point y axis // absheight : absoulute height of plotting window // abswidth : absolute width of plotting window // xmin : minimum x value (real number) // xmax : maximum x value (real number) // ymin : minimum y value (real number) // ymax : maximum y value (real number) // g : graphic object that actual drawing is done through g=gi; //Font fonts[]=GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); //f=fonts[2].deriveFont(Font.BOLD,14);//You can change Fony from here //g.setFont(f); xabsmin=xabsmini; yabsmin=yabsmini; absheight=absheighti; abswidth=abswidthi; xmin=xmini; xmax=xmaxi; ymin=ymini; ymax=ymaxi; xlog=xlogi; ylog=ylogi; if(xlog!=0) {xminmaxlog=Math.log10(xmax-xmin+10.0)-1.0;} if(ylog!=0) {yminmaxlog=Math.log10(ymax-ymin+10.0)-1.0;} } public void drawLine(int plottype,double x1,double y1,double x2,double y2) { // draw a line from (x1,y1) to (x2,y2) int xx1,xx2,yy1,yy2; if(xlog!=0) { xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth)); xx2=(int)(xabsmin+((Math.log10(x2-xmin+10.0)-1.0)/xminmaxlog*abswidth)); } else { xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth); xx2=(int)(xabsmin+(x2-xmin)/(xmax-xmin)*abswidth); } if(ylog!=0) { yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight)); yy2=(int)(yabsmin+absheight-((Math.log10(y2-ymin+10.0)-1.0)/yminmaxlog*absheight)); } else { yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight); yy2=(int)(yabsmin+absheight-(y2-ymin)/(ymax-ymin)*absheight); } g.draw(new Line2D.Double( xx1,yy1,xx2,yy2)); } //end of drawLine public void drawPolyline(int plottype,double x1[],double y1[]) { // draw a line from (x1,y1) to (x2,y2) int points=y1.length; int xPoints[]=new int[points]; int yPoints[]=new int[points]; int xx1,yy1; for(int i=0;i<points;i++) { if(xlog!=0) {xx1=(int)(xabsmin+(Math.log10(x1[i]-xmin+10.0)-1.0)/xminmaxlog*abswidth);} else {xx1=(int)(xabsmin+(x1[i]-xmin)/(xmax-xmin)*abswidth);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-(Math.log10(y1[i]-ymin+10.0)-1.0)/yminmaxlog*absheight);} else {yy1=(int)(yabsmin+absheight-(y1[i]-ymin)/(ymax-ymin)*absheight);} xPoints[i]=xx1; yPoints[i]=yy1; } g.drawPolyline(xPoints,yPoints,points); } //end of drawPolyLine public void drawChar(char ch,double x1,double y1) { // draws a single character at (x1,y1) char ch1[]=new char[1]; ch1[0]=ch; int h=g.getFontMetrics().getHeight(); int w=h-2; int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/200.0));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/200.0);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight))+h/2;} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+h/2;} g.drawChars(ch1,0,1,xx1,yy1); } //end of PlotShapes.drawChar public void drawChars(char ch[],int firstspace,int numberofchars, double x1,double y1) { // draws a character array from space firstspace to (firstspace+numberofchars) // starting at (x1,y1) int h=g.getFontMetrics().getHeight(); int w=h-2; //g.drawChars(ch,firstspace,numberofchars, // (int)((xabsmin+(x1-xmin)/(xmax-xmin)*abswidth)+abswidth/80.0), // (int)((yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)+h/2)); int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/80.0));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/80.0);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} g.drawChars(ch,firstspace,numberofchars,xx1,yy1); } //end of PlotShapes.drawChars public void drawString(String s,double x1,double y1) { //draws a String at (x1,y1) int h=g.getFontMetrics().getHeight(); int w=h-2; int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} g.drawString(s,xx1,yy1); } //end of PlotShapes.drawStrings public void drawRect(double x1,double y1,int rectwidth,int rectheight) { // draw a rectangle starting at (x1,y1) // with dimensions of (rectwidth,rectheight) int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-rectwidth/2));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-rectheight/2));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-rectheight/2);} g.draw(new Rectangle2D.Double(xx1,yy1,rectwidth,rectheight)); }//end of drawRect public void drawBar(double x1,double y1) { // draw a rectangle starting at (x1,y1) // with dimensions of (rectwidth,rectheight) int xx1,yy1; double barheight; double barwidth=abswidth/300; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-barwidth/2.0));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0); } if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight)); barheight =(int)((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight); } else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight); barheight =(int)((y1-ymin)/(ymax-ymin)*absheight);} g.draw(new Rectangle2D.Double(xx1,yy1,barwidth,barheight)); }//end of drawBar public void fillBar(double x1,double y1) { int xx1,yy1; double barheight; double barwidth=abswidth/300; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-barwidth/2.0));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-barwidth/2.0); } if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight)); barheight =(int)((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight); } else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight); barheight =(int)((y1-ymin)/(ymax-ymin)*absheight);} g.fill(new Rectangle2D.Double(xx1,yy1,barwidth,barheight)); }//end of fillBar public void fillRect(double x1,double y1,int rectwidth,int rectheight) { // draw a rectangle starting at (x1,y1) // with dimensions of (rectwidth,rectheight) // draw a rectangle starting at (x1,y1) // with dimensions of (rectwidth,rectheight) int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-rectwidth/2);} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-rectwidth/2);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-rectheight/2));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-rectheight/2);} g.fill(new Rectangle2D.Double(xx1,yy1,rectwidth,rectheight)); } public void drawEllipse(double x1,double y1,int width,int height) { // draw an oval with the centre of (x1,y1) // with dimension of (width,height) int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-width/2));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-height/2));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-height/2);} g.draw(new Ellipse2D.Double(xx1,yy1,width,height)); }//end of drawRect public void fillEllipse(double x1,double y1,int width,int height) { // draw an oval with the centre of (x1,y1) // with dimension of (width,height) int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-width/2));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-width/2);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-height/2));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-height/2);} g.fill(new Ellipse2D.Double(xx1,yy1,width,height)); }//end of drawRect public void drawPolygon(double x1,double y1,int radius,int side) { //draw a polygon of n sides n=3(trinagle),n=4(dimond).... double Pi=Math.PI; int xvalues[]=new int[side+1]; int yvalues[]=new int[side+1]; GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD, xvalues.length); double angle_increase; double angle; angle_increase=2.0*Pi/side; angle=Pi/2.0; for(int i=0;i<=side;i++) { if(xlog!=0) {xvalues[i]=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth+radius*Math.cos(angle)));} else {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));} if(ylog!=0) {yvalues[i]=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-radius*Math.sin(angle)));} else {yvalues[i]=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-radius*Math.sin(angle));} angle+=angle_increase; if(i==0) { xvalues[side]=xvalues[i];yvalues[side]=yvalues[i]; polygon.moveTo(xvalues[0],yvalues[0]); } else { polygon.lineTo(xvalues[i],yvalues[i]); } } g.draw(polygon); }//end of drawPolygon public void fillPolygon(double x1,double y1,int radius,int side) { //draw a polygon of n sides n=3(trinagle),n=4(dimond).... //draw a polygon of n sides n=3(trinagle),n=4(dimond).... double Pi=Math.PI; int xvalues[]=new int[side+1]; int yvalues[]=new int[side+1]; GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD, xvalues.length); double angle_increase; double angle; angle_increase=2.0*Pi/side; angle=Pi/2.0; for(int i=0;i<=side;i++) { if(xlog!=0) {xvalues[i]=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth+radius*Math.cos(angle)));} else {xvalues[i]=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth+radius*Math.cos(angle));} if(ylog!=0) {yvalues[i]=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight-radius*Math.sin(angle)));} else {yvalues[i]=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight-radius*Math.sin(angle));} angle+=angle_increase; if(i==0) { xvalues[side]=xvalues[i];yvalues[side]=yvalues[i]; polygon.moveTo(xvalues[0],yvalues[0]); } else { polygon.lineTo(xvalues[i],yvalues[i]); } } g.fill(polygon); }//end of fillPolygon public void drawStar(double x1,double y1,int radius,int side) { double teta=2.0*Math.PI/side; double R=radius; double r=radius*0.35; int xvalues[]=new int[2*side+2]; int yvalues[]=new int[2*side+2]; GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD, xvalues.length); double teta1,teta2; for(int i=0;i<=side;i++) { teta1=teta*i+Math.PI/2.0; teta2=teta/2.0+teta1; if(xlog!=0) { xvalues[2*i]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/ xminmaxlog*abswidth+R*Math.cos(teta1)))); xvalues[2*i+1]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/ yminmaxlog*abswidth+r*Math.cos(teta2)))); } else { xvalues[2*i]= (int)(Math.floor(xabsmin+(x1-xmin)/ (xmax-xmin)*abswidth+R*Math.cos(teta1))); xvalues[2*i+1]= (int)(Math.floor(xabsmin+(x1-xmin)/ (xmax-xmin)*abswidth+r*Math.cos(teta2))); } if(ylog!=0) { yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/ yminmaxlog*absheight-R*Math.sin(teta1)))); yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/ yminmaxlog*absheight-r*Math.sin(teta2)))); } else { yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/ (ymax-ymin)*absheight-R*Math.sin(teta1))); yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/ (ymax-ymin)*absheight-r*Math.sin(teta2))); } if(i==side) { xvalues[2*i]=xvalues[0]; yvalues[2*i]=yvalues[0]; } } for(int i=0;i<=2*side;i++) { if(i==0) { polygon.moveTo(xvalues[0],yvalues[0]); } else { polygon.lineTo(xvalues[i],yvalues[i]); } } g.draw(polygon); }//end of drawStar public void fillStar(double x1,double y1,int radius,int side) { double teta=2.0*Math.PI/side; double R=radius; double r=radius*0.35; int xvalues[]=new int[2*side+2]; int yvalues[]=new int[2*side+2]; GeneralPath polygon=new GeneralPath(GeneralPath.WIND_EVEN_ODD, xvalues.length); double teta1,teta2; for(int i=0;i<=side;i++) { teta1=teta*i+Math.PI/2.0; teta2=teta/2.0+teta1; if(xlog!=0) { xvalues[2*i]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/ xminmaxlog*abswidth+R*Math.cos(teta1)))); xvalues[2*i+1]= (int)(Math.floor(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/ yminmaxlog*abswidth+r*Math.cos(teta2)))); } else { xvalues[2*i]= (int)(Math.floor(xabsmin+(x1-xmin)/ (xmax-xmin)*abswidth+R*Math.cos(teta1))); xvalues[2*i+1]= (int)(Math.floor(xabsmin+(x1-xmin)/ (xmax-xmin)*abswidth+r*Math.cos(teta2))); } if(ylog!=0) { yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/ yminmaxlog*absheight-R*Math.sin(teta1)))); yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/ yminmaxlog*absheight-r*Math.sin(teta2)))); } else { yvalues[2*i]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/ (ymax-ymin)*absheight-R*Math.sin(teta1))); yvalues[2*i+1]= (int)(Math.floor(yabsmin+absheight-(y1-ymin)/ (ymax-ymin)*absheight-r*Math.sin(teta2))); } if(i==side) { xvalues[2*i]=xvalues[0]; yvalues[2*i]=yvalues[0]; } } for(int i=0;i<=2*side;i++) { if(i==0) { polygon.moveTo(xvalues[0],yvalues[0]); } else { polygon.lineTo(xvalues[i],yvalues[i]); } } g.fill(polygon); }//end of drawStar public void drawXTic(int ticNumber,double ticHeight,int ticSide) { //draw a series of x axis tics double dtic=(xmax-xmin)/ticNumber; double x1=xmin; double y1=ymin; double dy; dy=ticHeight; int xx1,yy1,yy2,yy3; for(int i=0;i<=ticNumber;i++) { if(xlog!=0) { xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth)); } else { xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth); } yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight); yy2=(int)(yabsmin+absheight-(y1-dy-ymin)/(ymax-ymin)*absheight); yy3=(int)(yabsmin+absheight-(y1+dy-ymin)/(ymax-ymin)*absheight); if(ticSide==0) {g.draw(new Line2D.Double( xx1,yy1,xx1,yy2));} else {g.draw(new Line2D.Double( xx1,yy1,xx1,yy3));} x1=x1+dtic; } } public void drawYTic(int ticNumber,double ticWidth,int ticSide) { //draw a series of y axis tics double dtic=(ymax-ymin)/ticNumber; double x1=xmin; double y1=ymin; double dx; dx=ticWidth; double xx1,xx2,xx3,yy1; for(int i=0;i<=ticNumber;i++) { if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth); xx2=(int)(xabsmin+(x1-dx-xmin)/(xmax-xmin)*abswidth); xx3=(int)(xabsmin+(x1+dx-xmin)/(xmax-xmin)*abswidth); if(ticSide==0) {g.draw(new Line2D.Double( xx1,yy1,xx2,yy1));} else {g.draw(new Line2D.Double( xx1,yy1,xx3,yy1));} y1=y1+dtic; } } public void drawXGrid(int ticNumber) { //draw x gridlies ||||||| double dtic=(xmax-xmin)/ticNumber; double x1=xmin; for(int i=0;i<=ticNumber;i++) { drawLine(0,x1,ymin,x1,ymax); x1=x1+dtic; } } public void drawYGrid(int ticNumber) { //draw y gridlines ===== double dtic=(ymax-ymin)/ticNumber; double y1=ymin; for(int i=0;i<=ticNumber;i++) { drawLine(0,xmin,y1,xmax,y1); y1=y1+dtic; } } public void drawXNumbers(int ticNumber) { //draw x numbers double dtic=(xmax-xmin)/ticNumber; double x1=xmin; double y1=ymin; int xx1,yy1; String s; s=" "; for(int i=0;i<=ticNumber;i++) { if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/200.0));} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth-abswidth/200.0);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight)+absheight/20.0);} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+absheight/20.0);} s=Double.toString(Math.floor(x1*100.0)/100.00); g.drawString(s,xx1,yy1); x1=x1+dtic; } } public void drawYNumbers(int ticNumber) { // draw y numbers double dtic=(ymax-ymin)/ticNumber; double x1=xmin; double y1=ymin; int xx1,yy1; String s; s=" "; for(int i=0;i<=ticNumber;i++) { if(xlog!=0) {xx1=(int)(xabsmin+((Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth-abswidth/200.0)-abswidth/10.0);} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth/200.0-abswidth/10.0);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} s=Double.toString(Math.floor(y1*1000)/1000.0)+" "; g.drawString(s,xx1,yy1); y1=y1+dtic; } } public void drawXLabel(String xLabel) { // draw x labels double x1=xmin+(xmax-xmin)/2.0; double y1=ymin; int xx1,yy1; if(xlog!=0) {xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth);} else {xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-(Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight+abswidth/12.0);} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight+abswidth/12.0);} g.drawString(xLabel,xx1,yy1); } public void drawYLabel(String yLabel) { // draw y labels double x1; double y1=ymax-(ymax-ymin)/2.0; int xx1,yy1; if(xlog!=0) {x1=xmin-2.7;xx1=(int)(xabsmin+(Math.log10(x1-xmin+10.0)-1.0)/xminmaxlog*abswidth);} else {x1=xmin-(xmax-xmin)/6.0;xx1=(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth);} if(ylog!=0) {yy1=(int)(yabsmin+absheight-((Math.log10(y1-ymin+10.0)-1.0)/yminmaxlog*absheight));} else {yy1=(int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight);} int n=yLabel.length(); char ch[]=new char[n]; yLabel.getChars(0,n,ch,0); TextLayout t=new TextLayout(yLabel,g.getFont(),g.getFontRenderContext()); AffineTransform at=AffineTransform.getRotateInstance(3.0*Math.PI/2.0,xx1,yy1); g.setTransform(at); t.draw(g,xx1,yy1); at=AffineTransform.getRotateInstance(0,xx1,yy1); g.setTransform(at); } public void drawLabel(String Label) { //draw graphic label double x1=xmin+(xmax-xmin)/2.0; double y1=ymax; g.drawString(Label,(int)(xabsmin+(x1-xmin)/(xmax-xmin)*abswidth), (int)(yabsmin+absheight-(y1-ymin)/(ymax-ymin)*absheight)-(int)(abswidth/40.0)); } public void drawMouseTic(double xi[],double yi[],int xn) { for(int i=0;i<xn;i++) { if((xi[i]>=xmin && xi[i]<=xmax) && (yi[i]>=ymin && yi[i]<=ymax)) { drawStar(xi[i],yi[i],(int)(abswidth/80.0),5); } } } public void drawPlotLines(int i,int plottype[],double x[][],double y[][],int n[],char ch[]) { int j; //draw lines if((plottype[i] >= 0) && (plottype[i] < 10) ) { switch ( plottype[i] ) { case 0 : g.setStroke(new BasicStroke(1.0f));break; case 1 : g.setStroke(d1);break; case 2 : g.setStroke(d2);break; case 3 : g.setStroke(d3);break; case 4 : g.setStroke(d4);break; case 5 : g.setStroke(new BasicStroke(2.0f));break; case 6 : g.setStroke(d5);break; case 7 : g.setStroke(d6);break; case 8 : g.setStroke(d7);break; case 9 : g.setStroke(d8);break; }; for(j=0;j<n[i]-1;j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { if((x[i][j+1]>=xmin && x[i][j+1]<=xmax) && (y[i][j+1]>=ymin && y[i][j+1]<=ymax)) { drawLine(0,x[i][j],y[i][j],x[i][j+1],y[i][j+1]); } else if(x[i][j+1]>xmax) { double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]); double a=y[i][j]-b*x[i][j]; drawLine(0,x[i][j],y[i][j],xmax,(a+b*xmax)); } else if(y[i][j+1]>ymax) { double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]); double a=y[i][j]-b*x[i][j]; drawLine(0,x[i][j],y[i][j],(ymax-a)/b,ymax); } else if(x[i][j+1]>xmax && y[i][j+1]>ymax) { double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]); double a=y[i][j]-b*x[i][j]; drawLine(0,x[i][j],y[i][j],(ymax-a)/b,(a+b*xmax)); } } else if((x[i][j+1]>=xmin && x[i][j+1]<=xmax ) && (y[i][j+1]>=ymin && y[i][j+1]<=ymax)) { if(x[i][j]<xmin) { double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]); double a=y[i][j+1]-b*x[i][j+1]; drawLine(0,xmin,(a+b*xmin),x[i][j+1],y[i][j+1]); } if(y[i][j]<ymin) { double b=(y[i][j+1]-y[i][j])/(x[i][j+1]-x[i][j]); double a=y[i][j+1]-b*x[i][j+1]; drawLine(0,(ymin-a)/b,ymin,x[i][j+1],y[i][j+1]); } } }//end of for(j=0 g.setStroke(new BasicStroke(1.0f)); }//end of if(plottype //draw characters else if(plottype[i]>=10 && plottype[i]<=19) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawChar(ch[i],x[i][j],y[i][j]); } }//end of for(j=0; }//end else if(plottype[i]==10..19) //draw rectangles else if(plottype[i]==20) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawRect(x[i][j],y[i][j],abswidth/100,abswidth/80); } }//end of for(j=0; }//end else if(plottype[i]==20) else if(plottype[i]==21) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { fillRect(x[i][j],y[i][j],abswidth/100,abswidth/80); } }//end of for(j=0; }//end else if(plottype[i]==20) //draw circle else if(plottype[i]==22) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawEllipse(x[i][j],y[i][j],abswidth/100,abswidth/80); } }//end of for(j=0; }//end else if(plottype[i]==22) else if(plottype[i]==23) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { fillEllipse(x[i][j],y[i][j],abswidth/100,abswidth/80); } }//end of for(j=0; }//end else if(plottype[i]==21) else if(plottype[i]>=24 && plottype[i]<=27) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawPolygon(x[i][j],y[i][j],abswidth/100,(plottype[i]-21)); } }//end of for(j=0; }//end else if(plottype[i]==24..27) else if(plottype[i]>=28 && plottype[i]<=31) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { fillPolygon(x[i][j],y[i][j],abswidth/100,(plottype[i]-25)); } }//end of for(j=0; }//end else if(plottype[i]==24..27) else if(plottype[i]>=32 && plottype[i]<=35) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawStar(x[i][j],y[i][j],abswidth/100,(plottype[i]-29)); } }//end of for(j=0; } else if(plottype[i]>=36 && plottype[i]<=39) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { fillStar(x[i][j],y[i][j],abswidth/100,(plottype[i]-33)); } }//end of for(j=0; } else if(plottype[i]==40) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { drawBar(x[i][j],y[i][j]); } }//end of for(j=0; } else if(plottype[i]==41) { for(j=0;j<n[i];j++) { if((x[i][j]>=xmin && x[i][j]<=xmax ) && (y[i][j]>=ymin && y[i][j]<=ymax)) { fillBar(x[i][j],y[i][j]); } }//end of for(j=0; } } } 1.6.14 JAVA 3 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT3D Java’da 3 Boyutlu grafik çıktıları oluşturmak için serbest dağıtım sisteminin içerisinde yer alan mükemmel bir java programlama seti olan VisAD programlama paketinden yararlanılmıştır. VisAD çok çeşitli 3 boyutlu uygulamalar için Java 3D grafik paketinikullanan bir program paketidir. Visad Paketini http://www.ssec.wisc.edu/~billh/visad.html veya çeşitli adreslerden indirebilirsiniz. İsterseniz kendiniz kodları derleyerek kurabilirsiniz, isterseniz, hazır visad.jar dosyasını javanın jre dosyası altındaki lib dosyası altındaki ext dosyasına kopyalıyarak (örneğin benim bilgisayarımda c:\co\java\jre\lib\ext) bilgisayarınızı VisAD paketini direk kullanabilir hale getirebilirsiniz. 3 boyutlu grafikler için aynı zamanda Java 3D grafik paketine de ihtiyacınız olacaktır. bu paketin en son versiyonuna www.java.sun.com adresinden temin edebilirsiniz (benim şu anda kullandığım versiyonu java3d-1_4_0_01-windows-i586) paket açtığınızda kendi kendine yüklenecektir. Java 3D paketi default olarak Windows ortamında openGL kullanır (diğer ortamlardaki grafik kullanımı ile ilgili Java 3D paketini inceleyiniz). Eğer grafik kartınız openGL sistemini destekliyorsa bu bölümde verdiğimiz programları direk olarak kullanabilirsiniz. Eğer openGL’i desteklemeyen bir grafik kartınız varsa DirectX9.0 veya daha sonraki bir versiyonunu kullanmanız gerekecektir. Bu durumda programı çalıştırırken Java 3D paketine default değer olan openGL yerine directX kullandığınızı belirtmeniz gerekecektir. Bunun için java programını çalıştırırken : java -Dj3d.rend=d3d sınıfismi komutunu kullanmanız gerekir. directX’in Windows için en son versiyonunu http://www.microsoft.com/windows/directx/ adresinden bulabilirsiniz. Oluşturduğumuz 3D programı Plot3D için temel olarak VisAD paketinin örnek problemlerini kullandık, bu örnek programları bizim iki boyutlu grafik ortamlarında da kullandığımız fonksiyon abstract sınıf ve veri yapılarına uygun hale getirdik. Plot3D Program çıktısı Program 1.6-14-1 de verilmiştir. Program 1.6.14-1 Plot3D 3 boyutlu bilimsel grafik programı import visad.*; import visad.java3d.DisplayImplJ3D; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.awt.event.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+0.01*(x[0]-1.0)*(x[0]-1.0); return -ff; } } public class Plot3D{ public static double[] grid(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS) { //create 1D Z grid for Z value from a given function value float[][] zi = new float[2][NCOLS * NROWS]; float xx[][]=new float[2][NCOLS * NROWS]; double zz[]=new double[NCOLS * NROWS]; double x[]=new double[2]; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) { xx[0][ c * NROWS + r ]=(float)(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); x[0]=(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); xx[1][ c * NROWS + r ]=(float)(x2min+(x2max-x2min)/(float)(NROWS-1)*r); x[1]=(x2min+(x2max-x2min)*r/(float)(NROWS-1)); zz[ c * NROWS + r ]=f.func(x); } return zz; } public static double[][] grid2D(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS) { //create 2D Z grid for Z value from a given function value float[][] zi = new float[2][NCOLS * NROWS]; float xx[][]=new float[2][NCOLS * NROWS]; double zz[][]=new double[NCOLS][NROWS]; double x[]=new double[2]; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) { xx[0][ c * NROWS + r ]=(float)(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); x[0]=(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); xx[1][ c * NROWS + r ]=(float)(x2min+(x2max-x2min)/(float)(NROWS-1)*r); x[1]=(x2min+(x2max-x2min)*r/(float)(NROWS-1)); zz[c][r]=f.func(x); } return zz; } public static void plot3D_CD2(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { plot3D_CD2(grid2D(f,x1min,x1max,x2min,x2max,NCOLS, NROWS),x1min,x1max,x2min,x2max,NCONTOUR,sx,sy,sz);} public static void plot3D_CD2(double zz[][],double x1min,double x1max,double x2min,double x2max,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { RealType longitude, latitude; RealType altitude; // Tuple to pack longitude and latitude together RealTupleType domain_tuple; // The function (domain_tuple -> altitude ) FunctionType func_domain_alt; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altMap, altRGBMap; ScalarMap altAlphaMap; ColorControl colCont; // Our color table float[][] myColorTable; // Create the quantities // Use RealType(String name, Unit unit, Set set); latitude = RealType.getRealType(sx, SI.meter, null); longitude = RealType.getRealType(sy, SI.meter, null); domain_tuple = new RealTupleType(latitude, longitude); altitude = RealType.getRealType(sz, SI.meter, null); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_alt = new FunctionType( domain_tuple, altitude); // Create the domain Set, with 12 columns and 6 rows, using an // LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) // note the "inverted" first and last values of latitude int NCOLS = zz[0].length;; int NROWS = zz.length; domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // The actal altitudes values // ordered as float[ NROWS ][ NCOLS ] double[][] alt_samples = zz; // Our 'flat' array double[][] flat_samples = new double[1][NCOLS * NROWS]; // Fill our 'flat' array with the altitude values // by looping over NCOLS and NROWS // Note the use of an index variable, indicating the order of the samples int index = 0; double zmin=2.0e60,zmax=-2e60;; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) { flat_samples[0][ index ] = alt_samples[c][r]; if(flat_samples[0][ index ]<zmin) zmin=flat_samples[0][ index ]; if(flat_samples[0][ index ]>zmax) zmax=flat_samples[0][ index ]; index++; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_alt, domain_set); // ...and put the altitude values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( flat_samples , false ); // Create Display and its maps display = new DisplayImplJ3D("display1"); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Also enable Texture dispGMC.setTextureEnable(false); // Create the ScalarMaps: latitude to XAxis, longitude to YAxis and // altitude to ZAxis and to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( latitude, Display.YAxis ); lonMap = new ScalarMap( longitude, Display.XAxis ); altRGBMap = new ScalarMap( altitude, Display.RGB ); altMap = new ScalarMap( altitude, Display.ZAxis ); altAlphaMap = new ScalarMap( altitude, Display.Alpha ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); display.addMap( altMap ); display.addMap( altRGBMap ); display.addMap( altAlphaMap ); // Create a different color table // Note: table has red, green and blue components // and is 10 units long, i.e float[3][10] int tableLength = 10; myColorTable = new float[3][tableLength]; for(int i=0;i<tableLength;i++){ myColorTable[0][i]= (float) 1.0f - (float)i / ((float)tableLength-1.0f); // red component myColorTable[1][i]= (float) (float)i / ((float)tableLength-1.0f); // green component myColorTable[2][i]= (float) 0.50f; // blue component } // Force top of table to be white myColorTable[0][9]=1.0f; myColorTable[1][9]=1.0f; myColorTable[2][9]=1.0f; // Get the ColorControl from the altitude RGB map colCont = (ColorControl) altRGBMap.getControl(); // Set the table colCont.setTable(myColorTable ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); display.addReference( data_ref); // Set maps ranges latMap.setRange(x1min, x1max); altMap.setRange(zmin, zmax); // Create application window and add display to window JFrame jframe = new JFrame("VisAD Tutorial example 4_06"); jframe.getContentPane().add(display.getComponent()); // Add the LabeledColorWidget to the frame // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void plot3D_CD1(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { plot3D_CD1(grid2D(f,x1min,x1max,x2min,x2max,NCOLS, NROWS),x1min,x1max,x2min,x2max,NCONTOUR,sx,sy,sz);} public static void plot3D_CD1(double zz[][],double x1min,double x1max,double x2min,double x2max,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { RealType longitude, latitude; RealType altitude; // Tuple to pack longitude and latitude together RealTupleType domain_tuple; // The function (domain_tuple -> altitude ) FunctionType func_domain_alt; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altMap, altRGBMap; ColorControl colCont; // Our color table float[][] myColorTable; // Create the quantities // Use RealType(String name, Unit unit, Set set); latitude = RealType.getRealType(sx, SI.meter, null); longitude = RealType.getRealType(sy, SI.meter, null); domain_tuple = new RealTupleType(latitude, longitude); altitude = RealType.getRealType("z", SI.meter, null); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_alt = new FunctionType( domain_tuple, altitude); // Create the domain Set, with 12 columns and 6 rows, using an // LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) // note the "inverted" first and last values of latitude int NCOLS = zz.length; int NROWS = zz[0].length; domain_set = new Linear2DSet(domain_tuple, x1min,x1max, NROWS, x2min, x2max, NCOLS); // The actal altitudes values // ordered as float[ NROWS ][ NCOLS ] double[][] alt_samples = zz; double[][] flat_samples = new double[1][NCOLS * NROWS]; int index = 0; double zmin=2.0e60,zmax=-2e60;; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) { flat_samples[0][ index ] = alt_samples[c][r]; if(flat_samples[0][ index ]<zmin) zmin=flat_samples[0][ index ]; if(flat_samples[0][ index ]>zmax) zmax=flat_samples[0][ index ]; index++; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_alt, domain_set); FlatField der_vals_ff ;//= new FlatField( func_domain_alt, domain_set); // ...and put the altitude values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( flat_samples , false ); der_vals_ff = (FlatField) vals_ff.derivative( longitude, Data.NO_ERRORS );//.setSamples( flat_samples , false ); // Create Display and its maps display = new DisplayImplJ3D("display1"); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Also enable Texture dispGMC.setTextureEnable(false); // Create the ScalarMaps: latitude to XAxis, longitude to YAxis and // altitude to ZAxis and to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( latitude, Display.YAxis ); lonMap = new ScalarMap( longitude, Display.XAxis ); altRGBMap = new ScalarMap( altitude, Display.RGB ); altMap = new ScalarMap( altitude, Display.ZAxis ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); display.addMap( altMap ); display.addMap( altRGBMap ); // Create a color table // Note: table has red, green and blue components // and is 8 units long, i.e float[3][8] myColorTable = new float[][]{{0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f}, // red component {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f}, // green component {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}}; // blue component // Get the ColorControl from the altitude RGB map colCont = (ColorControl) altRGBMap.getControl(); // Set the table colCont.setTable(myColorTable ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); display.addReference( data_ref); // Set maps ranges latMap.setRange(x1min, x1max); altMap.setRange(zmin, zmax); // Create application window and add display to window JFrame jframe = new JFrame(sz); jframe.getContentPane().add(display.getComponent()); // Add the LabeledColorWidget to the frame // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void plot3D_CD(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { plot3D_CD(grid2D(f,x1min,x1max,x2min,x2max,NCOLS, NROWS),x1min,x1max,x2min,x2max,NCONTOUR,sx,sy,sz);} public static void plot3D_CD(double zz[][],double x1min,double x1max,double x2min,double x2max,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { //=============== // Declare variables // The domain quantities longitude and latitude // and the dependent quantity altitude RealType longitude, latitude; RealType altitude; // Tuple to pack longitude and latitude together RealTupleType domain_tuple; // The function (domain_tuple -> altitude ) FunctionType func_domain_alt; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altMap, altRGBMap; ColorControl colCont; // Our color table float[][] myColorTable; // Create the quantities // Use RealType(String name, Unit unit, Set set); latitude = RealType.getRealType(sx, SI.meter, null); longitude = RealType.getRealType(sy, SI.meter, null); domain_tuple = new RealTupleType(latitude, longitude); altitude = RealType.getRealType("z", SI.meter, null); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_alt = new FunctionType( domain_tuple, altitude); // Create the domain Set, with 12 columns and 6 rows, using an // LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) // note the "inverted" first and last values of latitude // The actal altitudes values // ordered as float[ NROWS ][ NCOLS ] double[][] alt_samples =zz; int NROWS=alt_samples.length; int NCOLS=alt_samples[0].length; domain_set = new Linear2DSet(domain_tuple, x1min,x1max, NROWS, x2min, x2max, NCOLS); // Our 'flat' array double[][] flat_samples = new double[1][NCOLS * NROWS]; // Fill our 'flat' array with the altitude values // by looping over NCOLS and NROWS // Note the use of an index variable, indicating the order of the samples int index = 0; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++){ // set altitude altitude flat_samples[0][ index ] = alt_samples[r][c]; // increment index index++; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_alt, domain_set); // ...and put the altitude values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( flat_samples , false ); // Code for slope data // Data in a FlatField FlatField slope_vals_ff ; // Calculate derivative of altitude with respect to longitude; assume no errors slope_vals_ff = (FlatField) vals_ff.derivative( longitude, Data.NO_ERRORS ); // Get the funtionc from the FlatField for slope FunctionType func_domain_slope = ((FunctionType)slope_vals_ff.getType()); // "slope" is a RealType; RealType slope = (RealType) func_domain_slope.getRange(); // Create a ScalarMap to color slope's surface ScalarMap slopeRGBMap = new ScalarMap( slope, Display.RGB ); // Create Display and its maps display = new DisplayImplJ3D("display1"); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Also enable Texture dispGMC.setTextureEnable(false); // Create the ScalarMaps: latitude to XAxis, longitude to YAxis and // altitude to ZAxis and to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( latitude, Display.YAxis ); lonMap = new ScalarMap( longitude, Display.XAxis ); altRGBMap = new ScalarMap( altitude, Display.RGB ); altMap = new ScalarMap( altitude, Display.ZAxis ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); display.addMap( altMap ); display.addMap( altRGBMap ); display.addMap( slopeRGBMap ); // Create a color table // Note: table has red, green and blue components // and is 8 units long, i.e float[3][8] myColorTable = new float[][]{{0, 1, 0, 0, 0, 1, 1, 1}, // red component {0, 0, 1, 0, 1, 0, 1, 1}, // green component {0, 0, 0, 1, 1, 1, 0, 1}}; // blue component // Get the ColorControl from the altitude RGB map colCont = (ColorControl) altRGBMap.getControl(); // Set the table colCont.setTable(myColorTable ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); // Data reference for slope DataReferenceImpl data_ref2 = new DataReferenceImpl("data_ref2"); data_ref2.setData( slope_vals_ff ); // Add reference to display ConstantMap[] constAlpha_CMap = { new ConstantMap( 0.50f, Display.Alpha)}; ConstantMap[] constZ_CMap = { new ConstantMap( -1.0f, Display.ZAxis)}; // Add references to display // order MATTERS! display.addReference( data_ref2, constZ_CMap ); display.addReference( data_ref, constAlpha_CMap ); // Set maps ranges latMap.setRange(x1min, x1max); altMap.setRange(x2min, x2max); // Create application window and add display to window JFrame jframe = new JFrame(sz); jframe.getContentPane().add(display.getComponent()); // Add the LabeledColorWidget to the frame // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } //================ public static void plot3D_RGB(double zz[][],double x1min,double x1max,double x2min,double x2max,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { int NROWS=zz[0].length; int NCOLS=zz.length; RealType x1, x2; RealType z, temperature, precipitation; // Two Tuples: one to pack longitude and latitude together, as the domain // and the other for the range (altitude, temperature) RealTupleType domain_tuple, range_tuple; // The function (domain_tuple -> range_tuple ) FunctionType func_domain_range; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altZMap, tempRGBMap; ScalarMap tempZMap, altRGBMap; ScalarMap tempIsoMap; // Create the quantities // Use RealType(String name); x1 = RealType.getRealType(sx,null,null); x2 = RealType.getRealType(sy,null,null); domain_tuple = new RealTupleType(x1, x2); temperature = RealType.getRealType("temperature",null,null); z = RealType.getRealType("z",null,null); range_tuple = new RealTupleType( z, temperature ); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_range = new FunctionType( domain_tuple, range_tuple); // Create the domain Set // Use LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // Get the Set samples to facilitate the calculations float[][] x_j = domain_set.getSamples( true ); // We create another array, with the same number of elements of // altitude and temperature, but organized as // float[2][ number_of_samples ] float[][] zi = new float[2][NCOLS*NROWS]; // ...and then we fill our 'flat' array with the generated values // by looping over NCOLS and NROWS double xx[]=new double[2]; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) {xx[0]=(float)(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); xx[1]=(float)(x2min+(x2max-x2min)*r/(float)(NROWS-1)); zi[0][ c * NROWS + r ] = (float)zz[c][r]; zi[1][ c * NROWS + r ] = (float)xx[1]; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_range, domain_set); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( zi , false ); // Create Display and its maps // A 2D display display = new DisplayImplJ3D(sz); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps: latitude to YAxis, longitude to XAxis and // altitude to ZAxis and temperature to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( x1,Display.YAxis ); lonMap = new ScalarMap( x2,Display.XAxis ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); // altitude to z-axis and temperature to color altZMap = new ScalarMap( z, Display.ZAxis ); tempRGBMap = new ScalarMap( temperature, Display.RGB ); //tempIsoMap = new ScalarMap( temperature, Display.IsoContour ); display.addMap( tempRGBMap ); //display.addMap( tempIsoMap ); // Add maps to display display.addMap( altZMap ); // Uncomment following lines to have different data depiction // temperature to z-axis and altitude to color //altRGBMap = new ScalarMap( zi, Display.RGB ); //tempZMap = new ScalarMap( temperature, Display.ZAxis ); //display.addMap( altRGBMap ); //display.addMap( tempZMap ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); // Add reference to display display.addReference( data_ref ); // Create application window and add display to window JFrame jframe = new JFrame(sz); jframe.getContentPane().add(display.getComponent()); // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void plot3D_RGB(double zz[],double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { RealType x1, x2; RealType z, temperature, precipitation; // Two Tuples: one to pack longitude and latitude together, as the domain // and the other for the range (altitude, temperature) RealTupleType domain_tuple, range_tuple; // The function (domain_tuple -> range_tuple ) FunctionType func_domain_range; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altZMap, tempRGBMap; ScalarMap tempZMap, altRGBMap; ScalarMap tempIsoMap; // Create the quantities // Use RealType(String name); x1 = RealType.getRealType(sx,null,null); x2 = RealType.getRealType(sy,null,null); domain_tuple = new RealTupleType(x1, x2); temperature = RealType.getRealType("temperature",null,null); z = RealType.getRealType("z",null,null); range_tuple = new RealTupleType( z, temperature ); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_range = new FunctionType( domain_tuple, range_tuple); // Create the domain Set // Use LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // Get the Set samples to facilitate the calculations float[][] x_j = domain_set.getSamples( true ); // We create another array, with the same number of elements of // altitude and temperature, but organized as // float[2][ number_of_samples ] float[][] zi = new float[2][NCOLS*NROWS]; // ...and then we fill our 'flat' array with the generated values // by looping over NCOLS and NROWS double xx[]=new double[2]; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) {xx[0]=(float)(x1min+(x1max-x1min)*c/(float)(NCOLS-1)); xx[1]=(float)(x2min+(x2max-x2min)*r/(float)(NROWS-1)); zi[0][ c * NROWS + r ] = (float)zz[ c * NROWS + r ]; zi[1][ c * NROWS + r ] = (float)xx[1]; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_range, domain_set); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( zi , false ); // Create Display and its maps // A 2D display display = new DisplayImplJ3D(sz); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps: latitude to YAxis, longitude to XAxis and // altitude to ZAxis and temperature to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( x1,Display.YAxis ); lonMap = new ScalarMap( x2,Display.XAxis ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); // altitude to z-axis and temperature to color altZMap = new ScalarMap( z, Display.ZAxis ); tempRGBMap = new ScalarMap( temperature, Display.RGB ); //tempIsoMap = new ScalarMap( temperature, Display.IsoContour ); display.addMap( tempRGBMap ); //display.addMap( tempIsoMap ); // Add maps to display display.addMap( altZMap ); // Uncomment following lines to have different data depiction // temperature to z-axis and altitude to color //altRGBMap = new ScalarMap( zi, Display.RGB ); //tempZMap = new ScalarMap( temperature, Display.ZAxis ); //display.addMap( altRGBMap ); //display.addMap( tempZMap ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); // Add reference to display display.addReference( data_ref ); // Create application window and add display to window JFrame jframe = new JFrame(sz); jframe.getContentPane().add(display.getComponent()); // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void plot3D_RGB(f_xj f,double x1min,double x1max,double x2min,double x2max,int NCOLS,int NROWS,int NCONTOUR,String sx,String sy,String sz) throws RemoteException, VisADException { RealType x1, x2; RealType z, temperature, precipitation; // Two Tuples: one to pack longitude and latitude together, as the domain // and the other for the range (altitude, temperature) RealTupleType domain_tuple, range_tuple; // The function (domain_tuple -> range_tuple ) FunctionType func_domain_range; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap altZMap, tempRGBMap; ScalarMap tempZMap, altRGBMap; ScalarMap tempIsoMap; // Create the quantities // Use RealType(String name); x1 = RealType.getRealType(sx,null,null); x2 = RealType.getRealType(sy,null,null); domain_tuple = new RealTupleType(x1, x2); temperature = RealType.getRealType("temperature",null,null); z = RealType.getRealType("z",null,null); range_tuple = new RealTupleType( z, temperature ); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_range = new FunctionType( domain_tuple, range_tuple); // Create the domain Set // Use LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // Get the Set samples to facilitate the calculations float[][] x_j = domain_set.getSamples( true ); // We create another array, with the same number of elements of // altitude and temperature, but organized as // float[2][ number_of_samples ] float[][] zi = new float[2][NCOLS * NROWS]; // ...and then we fill our 'flat' array with the generated values // by looping over NCOLS and NROWS double xx[]=new double[2]; for(int c = 0; c < NCOLS; c++) for(int r = 0; r < NROWS; r++) {xx[0]=x_j[0][ c * NROWS + r ]; xx[1]=x_j[1][ c * NROWS + r ]; zi[0][ c * NROWS + r ] = (float)f.func(xx); zi[1][ c * NROWS + r ] = x_j[1][ c * NROWS + r ]; } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_range, domain_set); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( zi , false ); // Create Display and its maps // A 2D display display = new DisplayImplJ3D(sz); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps: latitude to YAxis, longitude to XAxis and // altitude to ZAxis and temperature to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( x1,Display.YAxis ); lonMap = new ScalarMap( x2,Display.XAxis ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); // altitude to z-axis and temperature to color altZMap = new ScalarMap( z, Display.ZAxis ); tempRGBMap = new ScalarMap( temperature, Display.RGB ); //tempIsoMap = new ScalarMap( temperature, Display.IsoContour ); display.addMap( tempRGBMap ); //display.addMap( tempIsoMap ); // Add maps to display display.addMap( altZMap ); // Uncomment following lines to have different data depiction // temperature to z-axis and altitude to color //altRGBMap = new ScalarMap( zi, Display.RGB ); //tempZMap = new ScalarMap( temperature, Display.ZAxis ); //display.addMap( altRGBMap ); //display.addMap( tempZMap ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); // Add reference to display display.addReference( data_ref ); // Create application window and add display to window JFrame jframe = new JFrame(sz); jframe.getContentPane().add(display.getComponent()); // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void contour_Plot1(f_xj f, double x1min,double x1max,double x2min,double x2max,int NROWS,int NCOLS,int NCONTOUR,String s1,String s2,String s3) throws RemoteException, VisADException { // Declare variables // The domain quantities longitude and latitude // and the dependent quantity temperature RealType longitude, latitude; RealType temperature; // Tuple to pack longitude and latitude together, as the domain RealTupleType domain_tuple; // The function (domain_tuple -> temperature ) // Remeber, range is only "temperature" FunctionType func_domain_temp; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap tempIsoMap, tempRGBMap; // These objects are for drawing isocontours RealType isoTemperature; FunctionType func_domain_isoTemp; FlatField iso_vals_ff; DataReferenceImpl iso_data_ref; // Create the quantities // Use RealType(String name); latitude = RealType.getRealType(s1); longitude = RealType.getRealType(s2); domain_tuple = new RealTupleType(latitude, longitude); temperature = RealType.getRealType("temperature", SI.kelvin, null); isoTemperature = RealType.getRealType("isoTemperature", SI.kelvin, null); // Create a FunctionType (domain_tuple -> temperature ) // Use FunctionType(MathType domain, MathType range) func_domain_temp = new FunctionType( domain_tuple, temperature); // ... the same for isoTemperature func_domain_isoTemp = new FunctionType( domain_tuple, isoTemperature); // Create the domain Set // Use LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // Get the Set samples to facilitate the calculations float[][] set_samples = domain_set.getSamples( true ); // The actual temperature values are stored in this array // float[1][ number_of_samples ] double x[]=new double[2]; float[][] z_j = new float[1][NCOLS * NROWS]; // We fill our 'flat' array with the generated values // by looping over NCOLS and NROWS for(int c = 0; c < NCOLS; c++) {x[0]=x1min+(x1max-x1min)/(double)NCOLS*(double)c; for(int r = 0; r < NROWS; r++) {x[1]=x2min+(x2max-x2min)/(double)NROWS*(double)r; z_j[0][ c * NROWS + r ] = (float)f.func(x); } } // Create the FlatFields // Use FlatField(FunctionType type, Set domain_set) // For the colored image vals_ff = new FlatField( func_domain_temp, domain_set); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( z_j , false ); // ...and for the isocontours iso_vals_ff = new FlatField( func_domain_isoTemp, domain_set); // Get the values from the temperature FlatField // create flat_isoVals array for clarity's sake // "false" argument means "don't copy" float[][] flat_isoVals = vals_ff.getFloats(false); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied again iso_vals_ff.setSamples( flat_isoVals , false ); // Create Display and its maps // A 2D display display = new DisplayImplJ2D(s3); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps: latitude to YAxis, longitude to XAxis and // temperature to RGB and // isoTemperature to IsoContour // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( latitude, Display.YAxis ); lonMap = new ScalarMap( longitude, Display.XAxis ); tempIsoMap = new ScalarMap( isoTemperature, Display.IsoContour ); tempRGBMap = new ScalarMap( temperature, Display.RGB ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); display.addMap( tempIsoMap ); display.addMap( tempRGBMap ); // The ContourControl // Note that we get the control from the IsoContour map ContourControl isoControl = (ContourControl) tempIsoMap.getControl(); // Define some parameters for contour lines float interval = (float)((x1max-x1min)/NCONTOUR); // interval between lines float lowValue = (float)x1min; // lowest value float highValue = (float)x1max; // highest value float base = (float)x1min; // starting at this base value // ...and set the lines with the method isoControl.setContourInterval(interval, lowValue, highValue, base); isoControl.enableLabels(true); // Create data references and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); iso_data_ref = new DataReferenceImpl("iso_data_ref"); data_ref.setData( vals_ff ); iso_data_ref.setData( iso_vals_ff ); // Add reference to display display.addReference( data_ref ); display.addReference( iso_data_ref ); // Create application window and add display to window JFrame jframe = new JFrame(s3); jframe.getContentPane().add(display.getComponent()); // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void contour_Plot(f_xj f, double x1min,double x1max,double x2min,double x2max,int NROWS,int NCOLS,int NCONTOUR,String s1,String s2,String s3) throws RemoteException, VisADException { RealType longitude, latitude; RealType temperature; // Tuple to pack longitude and latitude together, as the domain RealTupleType domain_tuple; // The function (domain_tuple -> temperature ) // Remeber, range is only "temperature" FunctionType func_domain_range; // Our Data values for the domain are represented by the Set Set domain_set; // The Data class FlatField FlatField vals_ff; // The DataReference from data to display DataReferenceImpl data_ref; // The 2D display, and its the maps DisplayImpl display; ScalarMap latMap, lonMap; ScalarMap tempIsoMap, tempRGBMap; // Create the quantities // Use RealType(String name); latitude = RealType.getRealType(s1); longitude = RealType.getRealType(s2); domain_tuple = new RealTupleType(latitude, longitude); temperature = RealType.getRealType("temperature"); // Create a FunctionType (domain_tuple -> range_tuple ) // Use FunctionType(MathType domain, MathType range) func_domain_range = new FunctionType( domain_tuple, temperature); // Create the domain Set // Use LinearDSet(MathType type, double first1, double last1, int lengthX, // double first2, double last2, int lengthY) //int NCOLS = 50; //int NROWS = NCOLS; domain_set = new Linear2DSet(domain_tuple, x1min, x1max, NROWS, x2min, x2max, NCOLS); // Get the Set samples to facilitate the calculations float[][] set_samples = domain_set.getSamples( true ); // The actual temperature values are stored in this array // float[1][ number_of_samples ] double x[]=new double[2]; float[][] z_j = new float[1][NCOLS * NROWS]; // We fill our 'flat' array with the generated values // by looping over NCOLS and NROWS for(int c = 0; c < NCOLS; c++) {x[0]=x1min+(x1max-x1min)/(double)NCOLS*(double)c; for(int r = 0; r < NROWS; r++) {x[1]=x2min+(x2max-x2min)/(double)NROWS*(double)r; z_j[0][ c * NROWS + r ] = (float)f.func(x); } } // Create a FlatField // Use FlatField(FunctionType type, Set domain_set) vals_ff = new FlatField( func_domain_range, domain_set); // ...and put the values above into it // Note the argument false, meaning that the array won't be copied vals_ff.setSamples( z_j , false ); // Create Display and its maps // A 2D display display = new DisplayImplJ2D(s3); // Get display's graphics mode control and draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps: latitude to YAxis, longitude to XAxis and // temperature to IsoContour and eventualy to RGB // Use ScalarMap(ScalarType scalar, DisplayRealType display_scalar) latMap = new ScalarMap( latitude, Display.YAxis ); lonMap = new ScalarMap( longitude, Display.XAxis ); // This is new! tempIsoMap = new ScalarMap( temperature, Display.IsoContour ); // this ScalarMap will color the isolines // don't foget to add it to the display tempRGBMap = new ScalarMap( temperature, Display.RGB ); // Add maps to display display.addMap( latMap ); display.addMap( lonMap ); display.addMap( tempIsoMap ); display.addMap( tempRGBMap ); // Create a data reference and set the FlatField as our data data_ref = new DataReferenceImpl("data_ref"); data_ref.setData( vals_ff ); // Add reference to display display.addReference( data_ref ); // Create application window and add display to window JFrame jframe = new JFrame(s3); jframe.getContentPane().add(display.getComponent()); jframe.setSize(300, 300); jframe.setVisible(true); } public static void main(String[] args) throws RemoteException, VisADException { f1 f=new f1(); double a[][]=grid2D(f,-1,1,-1,1,20,20); //double a[][]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20}}; //System.out.println(Matrix.toStringT(a)); /* double a[][]=new double[][]{ {3000.0, 3000.0, 6500.0, 4000.0, 3500.0, 4000.0, 5500.0, 4000.0, 4000.0, 4000.0, 5000.0, 1000 }, {1000.0, 1500.0, 4000.0, 3500.0, 6300.0, 4500.0, 4000.0, 3800.0, 3800.0, 3800.0, 5000.0, 6400 }, { 0.0, 0.0, 0.0, 1500.0, 3000.0, 6500.0, 4500.0, 5000.0, 4000.0, 3800.0, 3800.0, 6200 }, {-3000.0, -2000.0, -1000.0, 0.0, 1500.0, 1000.0, 4000.0, 5800.0, 4000.0, 4000.0, 3900.0, 3900 }, {-3000.0, -4000.0, -2000.0, -1000.0, 0.0, 1000.0, 1500.0, 4000.0, 5700.0, 4500.0, 4000.0, 4000.0 }, {-6500.0, -6000.0, -4000.0, -3000.0, 0.0, 100.0, 1500.0, 4500.0, 6000.0, 4000.0, 4000.0, 4000.0 }}; */ plot3D_CD1(a,-1,2.0,-1.0,1.0,40,"x","y","z=f(x,y)"); //contour_Plot1(f,-1.0,1.0,-1.0,1.0,100,100,20,"x","y","z=f(x,y)"); } } //end of Plot3D Bu programı ne şekilde kullanabileceğimizi çeşitli örnek problemlerle görelim.Kodu bir araya getirirken Plot programında olduğu gibi çok basit bir şekilde kullanılır olmasını düşündük. Kartınız openGL’i desteklemiyorsa(Windows sistemleri için) programı directX ile çalıştırmak için java komutunu java -Dj3d.rend=d3d Plot3DT1 şeklinde kullanınız. Program 1.6.14-2 Plot3D 3 boyutlu bilimsel grafik programı kullanım örneği import visad.*; import visad.java3d.DisplayImplJ3D; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class Plot3DT1 { public static void main(String[] args) throws RemoteException, VisADException { double a[][]=new double[][]{ {3000.0, 3000.0, 6500.0, 4000.0, 3500.0, 4000.0, 5500.0, 4000.0, 4000.0, 4000.0, 5000.0, 1000 }, {1000.0, 1500.0, 4000.0, 3500.0, 6300.0, 4500.0, 4000.0, 3800.0, 3800.0, 3800.0, 5000.0, 6400 }, { 0.0, 0.0, 0.0, 1500.0, 3000.0, 6500.0, 4500.0, 5000.0, 4000.0, 3800.0, 3800.0, 6200 }, {-3000.0, -2000.0, -1000.0, 0.0, 1500.0, 1000.0, 4000.0, 5800.0, 4000.0, 4000.0, 3900.0, 3900 }, {-3000.0, -4000.0, -2000.0, -1000.0, 0.0, 1000.0, 1500.0, 4000.0, 5700.0, 4500.0, 4000.0, 4000.0 }, {-6500.0, -6000.0, -4000.0, -3000.0, 0.0, 100.0, 1500.0, 4500.0, 6000.0, 4000.0, 4000.0, 4000.0 }}; Plot3D.plot3D_CD1(a,-1,2.0,-1.0,1.0,40,"x","y","z=f(x,y)"); } } Çıktı 1.6.14-1 Plot3D 3 boyutlu bilimsel grafik programı veri ile kullanım örneği Gördüğünüz gibi grafik çıktısını alabilmek için çok fazla bir bilgiye ihtiyacınız olmayacak, veriyi verip çiz demeniz temel olarak yeterli olacaktır. Şimdi veriyi bir fonksiyondan alalım. Program 1.6.14-3 Plot3D 3 boyutlu bilimsel grafik programı fonksiyon ile kullanım örneği import visad.*; import visad.java3d.DisplayImplJ3D; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.awt.event.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+0.01*(x[0]-1.0)*(x[0]-1.0); return -ff; } } public class Plot3DT2 { public static void main(String[] args) throws RemoteException, VisADException { f1 f=new f1(); Plot3D.plot3D_CD1(f,-1,1,-1,1.0,100,100,40,"x","y","z=f(x,y)"); } } Çıktı 1.6.14-2 Plot3D 3 boyutlu bilimsel grafik programı fonksiyon ile kullanım örneği Program 1.6.14-4 Plot3D 3 boyutlu bilimsel grafik programı CONTOUR grafiği fonksiyon ile kullanım örneği import visad.*; import visad.java3d.DisplayImplJ3D; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.awt.event.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+0.01*(x[0]-1.0)*(x[0]-1.0); return -ff; } } public class Plot3DT3 { public static void main(String[] args) throws RemoteException, VisADException { f1 f=new f1(); Plot3D.contour_Plot1(f,-1.0,1.0,-1.0,1.0,100,100,20,"x","y","z=f(x,y)"); } } Çıktı 1.6.14-4 Plot3D 3 boyutlu bilimsel grafik programı CONTOUR grafiği fonksiyon ile kullanım örneği Contour grafikleri 3 boyutlu eğrinin ikiboyuta izdüşümüdür. Haritalarda da bu yöntemi kullanmaktayız. Program 1.6.14-5 Plot3D 3 boyutlu bilimsel grafik programı plot_RGB grafiği fonksiyon ile kullanım örneği import visad.*; import visad.java3d.DisplayImplJ3D; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; import java.awt.event.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+0.01*(x[0]-1.0)*(x[0]-1.0); return -ff; } } public class Plot3DT5 { public static void main(String[] args) throws RemoteException, VisADException { f1 f=new f1(); Plot3D.plot3D_RGB(f,-1.0,1.0,-1.0,1.0,100,100,80,"x","y","z=f(x,y)"); } } Çıktı 1.6.14-4 Plot3D 3 boyutlu bilimsel grafik programı RGB grafiği fonksiyon ile kullanım örneği Burada verdiğimiz kadarı size 3 boyutlu grafiklere bir giriş sağlamak ve aynı zamanda sayısal çözümleme sonuçlarını gözlemleyebileceğimiz 3 boyutlu grafik ortamını oluşturmak amacı ileydi. Eğer daha detaylı kullanımlara girmek isterseniz VisAD veya benzeri paketleri detaylı inceleyerek bu konuda kendinizi rahatlıkla geliştirebilirsiniz. 1.6.15 JAVA 3 BOYUTLU BİLİMSEL GRAFİK ÇIKTI SINIFI : PLOT3D_JM Java ile ilgili serbesramlarını incelerken üst bölümde verdiğimiz VisAD paketine göre oldukça basit, kullanımı kolay ikinci bir grafik paketine ulaştım. JMath isimli bu paket yukarda verdiğimiz ve genel 3 boyutlu grafik paketi kadar sofistike değil ama basitliği bazı kullanıcılarımız için rahatlık getirebilir diye bu paketi de nasıl kullanacağımız ve 3 boyutlu rafik çıktılarını sayısal çözümleme problemlerimize adapte edebilecek temel bir programı burada sunuyoruz. JMath paketini http://jmathtools.sourceforge.net/doku.php adresinden edinebilirsiniz bu adresten kopyalayacağınız jmathio.jar, jmathplot.jar, ve jmatharray.jar dosyalarını JAVAHOME dosya dizinimizin altındaki /jre/lib/ext dosya dizine atarsak bu grafik sistemi sizin için çalışmaya hazır hale gelecektir. Bu paketi sadece fonksiyon grafikleri için adape ettim. Adaptasyon programımız Plot3D_JM.java kodu altta verilmiştir: Program 1.6.15-1 Plot3D_JM 3 boyutlu bilimsel grafik programı //====================================================== // Numerical Analysis package in java // Plot3D_JM class to plot 3D data // Dr. Turhan Coban // EGE University, Engineering School, Mechanical Eng. Div. // [email protected] // ===================================================== // utilizes JMath 3D Plot // http://jmathtools.sourceforge.net/doku.php // to use this program please add to : javahome/jre/lib/ext // jmathio.jar jmathplot.jar ve jmatharray.jar jar files import javax.swing.*; import org.math.plot.*; import static java.lang.Math.*; import static org.math.array.DoubleArray.*; import java.awt.*; import java.awt.event.*; class f2 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=7.9+0.13*x[0]+0.21*x[1]-0.05*x[0]*x[0]-0.016*x[1]*x[1]-0.007*x[0]*x[1]; //ff=sin(x[0])*cos(x[1]); return ff; } } public class Plot3D_JM{ Plot3DPanel plot; public Plot3D_JM(f_xj f, double x1min,double x1max,double x2min,double x2max,int NX,int NY,String sz,Color c) { plot = new Plot3DPanel("SOUTH"); add(f,x1min,x1max,x2min,x2max,NX,NY,sz,c); } public Plot3D_JM(f_xj f, double x1min,double x1max,double x2min,double x2max,int NX,int NY) { plot = new Plot3DPanel("SOUTH"); add(f,x1min,x1max,x2min,x2max,NX,NY,"z=f(x,y)",Color.blue); } public Plot3D_JM(f_xj f, double x1min,double x1max,double x2min,double x2max) { plot = new Plot3DPanel("SOUTH"); add(f,x1min,x1max,x2min,x2max,20,20,"z=f(x,y)",Color.blue); } public Plot3D_JM(f_xj f, double x1min,double x1max,double x2min,double x2max,String sz) { plot = new Plot3DPanel("SOUTH"); add(f,x1min,x1max,x2min,x2max,20,20,sz,Color.blue); } public void add(f_xj f, double x1min,double x1max,double x2min,double x2max,int NX,int NY,String sz,Color c) { double dx1=(x1max-x1min)/(double)NX; double dx2=(x2max-x2min)/(double)NY; ; double[] xx0 = increment(x1min, dx1, x1max); double[] xx1 = increment(x2min, dx2, x2max); double x[]=new double[2]; double[][] z = new double[NY][NX]; for (int i = 0; i < NX; i++) for (int j = 0; j < NY; j++) {x[0]=xx0[i];x[1]=xx1[j];z[j][i] = f.func(x);} // add grid plot to the PlotPanel plot.addGridPlot(sz,c, xx0, xx1, z); } public void add(f_xj f, double x1min,double x1max,double x2min,double x2max,String sz,Color c) {add(f,x1min,x1max,x2min,x2max,20,20,sz,c);} public void add(f_xj f, double x1min,double x1max,double x2min,double x2max,String sz) {add(f,x1min,x1max,x2min,x2max,20,20,sz,Color.blue);} public void add(f_xj f, double x1min,double x1max,double x2min,double x2max) {add(f,x1min,x1max,x2min,x2max,20,20,"z=f(x,y)",Color.blue);} public void plot(String sz) {JFrame frame = new JFrame(sz); frame.setSize(600,600); frame.setContentPane(plot); frame.setVisible(true); } public void plot() {plot("z=f(x,y)");} public static void func(f_xj f, double x1min,double x1max,double x2min,double x2max,int NX,int NY,String sz) { double dx1=(x1max-x1min)/(double)NX; double dx2=(x2max-x2min)/(double)NY; ; double[] xx0 = increment(x1min, dx1, x1max); double[] xx1 = increment(x2min, dx2, x2max); double x[]=new double[2]; double[][] z = new double[NY][NX]; for (int i = 0; i < NX; i++) for (int j = 0; j < NY; j++) {x[0]=xx0[i];x[1]=xx1[j];z[j][i] = f.func(x);} Plot3DPanel plot = new Plot3DPanel("SOUTH"); // add grid plot to the PlotPanel plot.addGridPlot("z=f(x,y)",Color.black, xx0, xx1, z); JFrame frame = new JFrame(sz); frame.setSize(600,600); frame.setContentPane(plot); frame.setVisible(true); } public static void func(f_xj f, double x1min,double x1max,double x2min,double x2max) {func(f, x1min,x1max,x2min,x2max,40,40,"z=f(x,y)");} public static void func(f_xj f, double x1min,double x1max,double x2min,double x2max,String sz) {func(f, x1min,x1max,x2min,x2max,40,40,sz);} public static void main(String[] args) { f2 f=new f2(); func(f,-10.0,10.0,0.0,20.0,"fx"); } } //end of Plot3D Çıktı 1.6.15-1 Plot3D_JM 3 boyutlu bilimsel grafik programı Programı verilen fonksiyonu değiştirerek tek başına kullanabileceğiniz gibi başka bir programdan da çağırarak grafiği çizdirebilirsiniz. Program hoşunuza gidebilecek bir çok özellikler barındırıyor(benim yazdığım değil bizzat paketten hazır olarak gelen) Bunlardan birkaçına bakalım: Program değişkenlerinin maksimum-minimum değerlerini değiştirerek detayları inceleyebiliriz. Verileri direk olarak JTable sınıfı tablolardan alarak kullanabiliriz . Görüleceği gibi b programda VisAD paketi için yazdığımız Plot3D setindekifonksiyon çizme metod formatları aynen korunmaya çalışılmıştır. 3 boyutlu fonksiyon grafik programımızı kendi programımız içinde de çağırabiliriz. Program 1.6.15-2 Plot3D_JM 3 boyutlu bilimsel grafik programını çağırarak kullanan Plot3DMT3 programı import java.awt.*; import javax.swing.*; import java.awt.event.*; class f1 extends f_xj {public double func(double x[]) {double ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; }} public class Plot3DMT3 { public static void main(String[] args) { f1 fa=new f1(); Plot3D_JM pp=new Plot3D_JM(fa,-10,10,0.0,20); pp.plot(); }} Çıktı 1.6.15-2 Plot3D_JM 3 boyutlu bilimsel grafik programını çağırarak kullanan Plot3DMT3 programı 1.7: GRAFİK APPLET VE ÇERÇEVE OLUŞTURMA METOTLARI, GRAFİK KULLANICISI ARABİRİM PROGRAMLARI (GUI) , 1.7.1 GRAPHIC INTERFACE) KULLANICISI ARABİRİM PROGRAMLARI, GUI, (GRAPHICS USER Grafik kullanıcı arabirim programları, GUI, programınıza kullanıcının daha iyi anlıyabileceği bir görünüş verme ve aynı zamanda grafik ekrandan girdi cve çıktı yapabilme amacıyla oluşturulur. Kullanıcıya sunulan programın onun rahatlıkla anlayabileceği bir formata sahip olması günümüz programlamacılığında oldukça önemlidir. Reklamlarla büyüyen bir kuşak için paket bazen paketin içindekinden bile önemli hale gelebilmektedir. Grafik Kullanıcısı Arabirim programları kullanıcıya sunduğumuz paketi oluşturmaktadır. Java’da temel grafik arabirim kütüphaneleri java.awt sınıfında yer almaktadır. Java 1.2 den itibaren awt kütüphanesine ek olarak java swing grafik arabirim kütüphanesi javax.swing tanımlanmıştır. Bu bölümde awt ve swing yapılarını paralel olarak vermeye çalışacağız.. Yalnız swing kütüphanesi kapsam olarak çok daha geniş olduğundan swing ile yapılan tüm işlemlerin ve grafik arabirim alt programlarını awt’de karşılıkları mevcut değildir. Bir önceki grafik çiziminde olduğu gibi grafik arabirim elemanlarının tanıtımı da oldukça geniş bir yelpaze oluşturduğuundan mümkün olduğunca detay verilmeye çalışılsa bile tüm kapsamı burada işlemek mümkün değildir. Örneğin java swing konusundaki kapsamlı bir kitap olan “Java Swing , O’Reily basım evi” kitabı yaklaşık 1200 sayfalık bir kitabı sadece bu konuya ayırmıştır. GUI metotları java.awt (Abstract windowing toolkit) paketinde yer almaktadır. Bu pakette Container ve Component isimli iki alt pakette yer almaktadır. Her zaman kullandığımız Applet sınıfı Component sınıfından türiyen Panel sınıfının alt sınıfıdır. Yani Component Appletlerin süper sınıfıdır. Burada Component sınıfının TextComponent TextField TextArea Button Label Checkbox List Choice Canvas Scrollbar Container Panel Java.applet.Applet sınıfının ScrollPane Window Frame Dialog Sınıflarını incelemeye calışacağız. Paralel olarak javax.swing paketinde yer alan grafik arayüz programlarında yer alan üst seviye paketler Japplet, JDialog, JFrame,JWindow ve JComponent’dir JComponent sınıfının altında yer alan sınıfların bazıları : JcomboBox JLabel JList JMenuBar JPanel JPopupMenu JScrollBar JScrollPane JTable JTree JInternalFrame JOptionPane JProgressBar JRootPane JSeperator JSlider JSplitPane JTabbedPane JToolBar JToolTip JViewePort JColorChooser JTextComponent JTextArea JTextField JPasswordField JEditorPAne JTextPane JFileChooser JLayeredPane AbstractButton JToggleButton JCheckBox JRadioButton JButton JMenuItem JMenu JRadioButtonMenuItem JCheckButtonMenuItem Yine yineleyelim, swing sınıfındaki tüm alt metodları kapsamak bu kitabın kapsamını oldukça büyütecektir, bu yüzden şimdilik buna imkan göremiyoruz, fakat pratikte ne oldukları hakkında iyi bir fikir verebilecek genişlikte bir spektrum vermeye çalışacağız. Burada özellkle awt ve swing sınıfı grafik işlemcilerini bir arada vermeye çalıştık. Kullanıcı her iki tip grafik ortamıyla da karşılaşacağı için (Kendi yazmasa bile hazır programlar karşısına çıkacaktır), her ikisini de bilmesi gereklidir. Zaten bu kitabın tüm konularında da hem awt hem de swing ile yazılmış program örnekleri vermeye çalıştık. Bu konudan sonra geriye dönüp tüm program örneklerini grafik ortamı gözüyle inceliyebilirsiniz. 1.7.2 AWT LABEL (ETİKET) SINIFI , JAVAX JLABEL VE ICON SINIFLARI Label sınıfı Appletin içine sadece okunabilen fakat değiştirilemeyen yazılar yazma amacıyla kullanılırlar. Label sınıfında tanımlanan metotlar şunlardır: Kurucu Metotlar : public Label() // Label sınıfı nesneyi olusturur herhangi bir yazı göstermez public Label(String s) // Label sınıfı nesneyi olusturur ve s stringini gösterir public void Label(String s,int pozisyon) // Label sınıfı nesneyi olusturur ve s stringi gösterir aynı zamanda Labeli pozisyonda verilen değere göre istenilen yere yerleştirir. Yerleştirme konumları :Label.LEFT,Label.CENTER,Label.RIGHT (sol,orta,sağ) konumlarıdır. Giriş çıkış metotları public String getText() // Label sınıfının String değişkenini okur. public void setText(String s) // Label sınıfının String değişkenine yeni değer girer. public void setAlignment(int pozisyon) Label pozisyon değişkeninde verilen değere göre istenilen yere yerleştirir. Yerleştirme konumları :Label.LEFT,Label.CENTER,Label.RIGHT (sol,orta,sağ) konumlarıdır. Örnek olarak bir bir program verelim : Program 1.7.2-1 : LabelTesti.java import java.applet.Applet; import java.awt.*; public class LabelTesti extends Applet { private Label L1,L2; public void init() { L1=new Label(); L1.setText("Bu etiket once bos tanimlandi"); add(L1); L2=new Label("Bu etiket yazisi ilk tanimda tanimlandi"); add(L2); } public void paint(Graphics g) { g.drawString("L1 : "+L1.getText(),25,80); g.drawString("L2 : "+L2.getText(),25,95); } } Şekil 1.7.2-1 LabelTesti.java appleti LabelTesti programında kullanılan add metotu Label’i Container sınıfına(Appletin alt sınıfı olduğu) bağlar, diğer deyimle applete veya verilen üst komponente ilave eder. Swing sınıfı Jlabel Lable sınıfındandan farklı olarak bize sadece yazı değil aynı zamanda görüntü ekleme olasılıkları da sunar. Temel sınıf olarak kurucu metodları : JLabel() JLabel(Icon Resim) Jlabel(Icon Resim,int yazı_pozisyonu) Jlabel(String etiket) Jlabel(String etiket, Icon Resim) Jlabel(String etiket, Icon Resim, int yazı_pozisyonu) Jlabel(String etiket, int yatay_yazı_pozisyonu) Buradaki yatay yazı pozisyonu JLabel.LEFT JLabel .CENTER JLabel.RIGHT Veya SwingConstants.LEFT SwingConstants.CENTER SwingConstants.RIGHT Değerlerinden birini alabilir. Jlabel sınıfının çok kullanacağımız bazı metotlarını sayacak olursak : Jcomponent sınıfından gelen metodlar : void setBackground(Color c) : arkaplan rengini değiştiri Color getBackground() : arkaplan rengini okur void setForeground(Color c) : önpaln rengini değiştiri Color getForeground() : ön plan rengini okur. void setFont(Font f) : yazı fontunu seçer Font getFont() : yazı fontunu okur Boolean isVisible : görünür olup olmadığını kontrol eder Void setVisible(Boolean b) : görünür veya görünmez yapar. Jlabel sınıfında tanımlanmış bazı alt sınıflar : void setText(String s) : JLabel’ın text değişkeninin değerine yeni verilen değeri atar String getText() : JLabel’ın String text değişkenini okur. void setVerticalAlignment(int düşey_pozisyon) : Label’in Pencere içindeki düşey pozisyonunu ayarlar Buradaki düşey pozisyon JLabel.TOP JLabel.CENTER JLabel.BOTTOM Veya SwingConstants.TOP SwingConstants.CENTER SwingConstants.BOTTOM Değerlerinden birini alabilir. int getVerticalAlignment() void setVerticalTextPosition(int düşey_pozisyon) : Label’in içindeki yazının Label içindeki düşey pozisyonunu ayarlar. Sabitler üsttekilerin aynıdır. int getVerticalTextPosition() : Label’in içindeki yazının Label içindeki düşey pozisyonunu okur. void setHorizontalTextPosition(int düşey_pozisyon) : Label’in içindeki yazının Label içindeki yatay pozisyonunu ayarlar. Sabitler üsttekilerin aynıdır(LEFT,CENTER,RİGHT). int getHorizontallTextPosition() : Label’in içindeki yazının Label içindeki yatay pozisyonunu okur. void setIcon(Icon resim) : Label içindeki resmi değiştirir veya eğer yoksa ilk defa atar Icon getIcon() : Label içindeki resmi okur. void setDisplayedMnemonic(int c) : Mnemoic alt harf kontrolunu kullanarak belli bir girişe ulaşmayı sağlar. (örneğin ‘m’ harfine set edilmişse alt-m bu komuta gider. Örnek problemlerle bu kavram açılacaktır. int getDisplayedMnemonic(int c) : Mnemonic değerini okur. Şimdi örnek problemlerle swing JLabel kullanımına daha detaylı olarak bakalım. Birinci örneğimizde basit bir şekilde String label yazdıracağız. Çerçeve olarak JFrame kullandık. Program 1.7.2-2 : Label1SW.java swing java Jlabel örneği import javax.swing.*; public class label1SW { public static void main(String[] args) { JLabel etiket=new JLabel("JLabel sınıfına hoş geldiniz"); JFrame cerceve=new JFrame(); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(etiket); cerceve.pack(); cerceve.setVisible(true); } } Şekil 1.7.2-2 Label1SW.java JFrame penceresi İkinci örneğimizde resimli, hem resim hem yazılı ve yalnız yazılı bir JApplet programı olşturduk. Bu programın aynı zamanda main metodu da olduğundan hem applet hem de frame olarak çağırılması mümkündür. Çerçeve olarak JFrame kullandık. Program 1.7.2-3 LabelTestiSW Japplet türü JLabel örnek programı import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class LabelTestiSW extends JApplet { protected String iconname1="images/kuş.gif"; ImageIcon icon1; protected String iconname2="images/köpek.gif"; ImageIcon icon2; protected JLabel j1,j2,j3; public LabelTestiSW() { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); } public void init() { icon1=new ImageIcon(iconname1); icon2=new ImageIcon(iconname2); j1 = new JLabel(icon1); j2 = new JLabel("Label (Etiket) yazısı",icon2,JLabel.CENTER); j2.setVerticalTextPosition(JLabel.BOTTOM); j2.setHorizontalTextPosition(JLabel.CENTER); j3 = new JLabel("Font 16 mavi Label"); Font font=j3.getFont(); j3.setFont(new Font(font.getName(),Font.BOLD,16)); j3.setForeground(Color.blue); JPanel pane=new JPanel(); JPanel pane1=new JPanel(); JPanel pane2=new JPanel(); pane1.add(j1); pane1.add(j2); pane1.add(j3); pane1.setBackground(new Color(255,255,204)); pane1.setForeground(Color.black); pane1.setBorder(BorderFactory.createMatteBorder(1,1,2,2,Color.black)); pane.setLayout(new BorderLayout()); pane.add(pane1,BorderLayout.NORTH); setContentPane(pane); } public static void main(String s[]) { JFrame f = new JFrame("Label testi "); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); JApplet applet = new LabelTestiSW(); f.getContentPane().add("Center", applet); applet.init(); f.pack(); f.setSize(new Dimension(550,200)); f.show(); } } Şekil 1.7.2-3 LabelTestiSW.java JFrame penceresi Program 1.7.2-4 LabelDemo JPanel türü JLabel örnek programı import java.awt.GridLayout; import java.awt.BorderLayout; import java.awt.event.WindowListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.ImageIcon; public class LabelDemo extends JPanel { JLabel label1, label2, label3; public LabelDemo() { ImageIcon icon = new ImageIcon("images/middle.gif", "bir damla resmi"); setLayout(new GridLayout(3,1)); //3 satır, 1 sütun label1 = new JLabel("Resim ve Yazı", icon, JLabel.CENTER); //resme göreceli olarak yazı pozisyonunu ayarla: label1.setVerticalTextPosition(JLabel.BOTTOM); label1.setHorizontalTextPosition(JLabel.CENTER); label2 = new JLabel("Sadece yazılı Label (Etiket)"); label3 = new JLabel(icon); //Add labels to the JBufferedPane. add(label1); add(label2); add(label3); } public static void main(String[] args) { JFrame frame = new JFrame("LabelDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.getContentPane().add(new LabelDemo(), BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } } Şekil 1.7.2-4 LabelDemo.java JPanel penceresi Bu programda resim ImageIcon icon = new ImageIcon("images/middle.gif","bir damla resmi"); Tanımıyla ImageIcon sınıfı aracılığıyla resmi Jlabel’a aktardı. images/middle.gif middle.gif dosyasının images alt direktorysinde yer aldığını belirtir. Burada Icon interphase’ine biraz daha yakından göz atalım. Icon interphase sınıfı olduğundan tanımlanan sınıfı içerisinde public int getIconWidth() public int getIconHeight() public void paintIcon(Component c, Graphics g, int x,int y) metodları tanımlanmak zorundadır. Şimdi Icon sınıfının alt sınıfı olan OvalIcon sınıfını tanımlayalım Program 1.7.2-5 Jlabel’da kullanılacak Icon oluşturan OvalIcon sınıfı import javax.swing.*; import java.awt.geom.*; import java.awt.*; public class OvalIcon implements Icon { int genislik, yukseklik; public OvalIcon(int w,int h) { genislik=w; yukseklik=h; } public void paintIcon(Component c,Graphics g,int x,int y) { Graphics2D g2=(Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Ellipse2D elips1=new Ellipse2D.Double(x,y,genislik-1,yukseklik-1); g2.draw(elips1); } public int getIconWidth() {return genislik;} public int getIconHeight() {return yukseklik;} } Şimdi de OvalIcon sınıfını kullanan JLabel sınıflarını oluşturup gösterelim : Program 1.7.2-6 OvalIcon sınıfını kullanarak JLabel’da daire Icon’u (resmi) gösteren label2SW programı import javax.swing.*; import java.awt.*; public class label2SW { public static void main(String[] args) { JFrame f=new JFrame(); f.addWindowListener(new BasicWindowMonitor()); JLabel etiket1=new JLabel(new OvalIcon(20,50)); JLabel etiket2=new JLabel(new OvalIcon(50,20)); JLabel etiket3=new JLabel("daire",new OvalIcon(60,60),SwingConstants.CENTER); etiket3.setHorizontalTextPosition(SwingConstants.CENTER); Container c=f.getContentPane(); c.setLayout(new FlowLayout()); c.add(etiket1); c.add(etiket2); c.add(etiket3); f.pack(); f.setVisible(true); } } Bu sınıfın çıktısı : Şekil 1.7.2-5 label2SW.java JFrame penceresi Buradan da görüldüğü gibi JLabel sınıfını çok daha geniş bir platformda, oluşturduğumuz bir grafiğin veya çizimin sonuçlarını grafik ortama aktarmak amacıyla da kullanabiliriz. 1.7.3 BUTTON VE JBUTTON (DÜĞME) SINIFLARI Button (düğme) basılınca belirli işlemlerin yapılmasını başlatan bir sınıftır. Graphic arabirim kullanım (GUI) programlarını veya aplet programlarını konsol programlarından ayıran en önemli özellik, GUI lerin işlem kökenli olmasıdır. Diğer bir deyimle kullanıcının başlatacağı işlemleri yapar ve kullanıcının yeni bir işlem tanımlamasını beklerler. Bu işlemleri yapan sınıflar java.awt.event kütüphanesinde tanımlanmıştır. Bu kütüphanede en çok kullanacağımız sınıflar hiyerarşi düzeninde şöyle verilebilir : Java.util.EventObject Java.awt.AWTEvent ActionEvent // Bir dügme(Button) basıldığında,Listeden (List) iki klikle bir seçim yapıldığında veya menuden seçim yapıldığında kullanılır. AdjustmentEvent // asağı yukarı kaydırma cubugunda (scroll bar) bir işlem yapıldığında kullanılır. ItemEvent // List veya CheckBox kliklendiginde (bir kere) kullanılır ComponentEvent //appletteki elemanların gizlenmesi, boylarının değiştirilmesi, veya değişik yerlere alınması amacıyla kullanılır. ContainerEvent //Containera(applete) yeni bir eleman eklenilir veya çıkarılırken kullanılır. FocusEvent//herhangi bir applet elemanı kullanılmaya baslandıgında on plana cıkarılmakk, ve kullanılmadıgında arka plana atılmak istendiğinde kullanılır. PaintEvent WindowEvent //pencere acılıp kapandığında,kücültülüp büyütüldüğünde vb kullanılır. InputEvent KeyEvent //keyboarddan bir girdi alındığında kullanılır MouseEvent //mouse dan bir girdi alındığında kullanılır Kullanıcı bir applet veya pencere tipi başka Container programı yazarken dinleme ile ilgili iki işlem yapar ilk işlem herhangi bir GUI dan bir girdi olup olmadığını dinlemek olduysa kaydetmek ikincisi ise bu işlemin sebep olacağı işlemleri oluşturmaktır. Dinleme işlemini yapan metotlar şunlardır : Java.util.EventListener ActionListener AdjustmentListener ComponentListener ContainerListener FocusListener ItemListener KeyListener MouseListener MouseMotionListener TextListener WindowListener Bu metotların bir çoğunu ilgili örneklerde yeri geldiğinde kullanacağız. Şimdi aynı sonucu veren iki button orneği ile bu kavramı biraz daha açmaya çalışalım : Program 1.7.3-1 : ButtonTesti.java, düğme kullanım testi import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class ButtonTesti extends Applet { private Button B1,B2; public void init() { B1=new Button("B1"); B1.addActionListener(new B1Basilinca(this)); add(B1); B2=new Button("B2"); B2.addActionListener(new B2Basilinca(this)); add(B2); } } class B1Basilinca implements ActionListener { Applet applet; public B1Basilinca(Applet a) {applet=a;} public void actionPerformed(ActionEvent e) { applet.showStatus(" "+e.getActionCommand()+"dugmesine basildi"); } } class B2Basilinca implements ActionListener { Applet applet; public B2Basilinca(Applet a) {applet=a;} public void actionPerformed(ActionEvent e) { applet.showStatus(" "+e.paramString()+"dugmesine basildi"); } } Şekil 1.7.3-1 ButtonTesti.java sınıfı sonuçlarının appletde görünmesi Program 1.7.3-2 ButtonTesti1.java sınıfı (sonuclar ButtonTesti.java ile aynıdır) import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class ButtonTesti1 extends Applet implements ActionListener { private Button B1,B2; public void init() { B1=new Button("B1"); B1.addActionListener(this); add(B1); B2=new Button("B2"); B2.addActionListener(this); add(B2); } public void actionPerformed(ActionEvent e) { if(e.getSource()==B1) {showStatus(" "+e.getActionCommand()+"dugmesine basildi");} else if(e.getSource()==B2) {showStatus(" "+e.paramString()+"dugmesine basildi");} } } Birinci programda düğmelere basıldığında oluşan eylemler (showStatus köşesine basılan düğmeyi yazdırma) ayrı sınıflarda yaptırılmış ve Applet sınıfı üzerinden bizim ButtonTesti sınıfına aktarılmıştır. İkinci programda ise aynı işlemler tek bir sınıfın içerisinde yer almıştır. Programdan da görülecegi gibi düğme basma eylemi ActionEvent sınıfı üzerinden aktarılmıştır. JButton sınıfı ile Button sınıfı arasında kullanım açısından Label ve Jlabel sınıfının arasındakilere benzer farklar vardır. JButton sınıfının sınıf tanımı : public class JButton extends AbstractButton implements Accessible { public JButton() public JButton(Icon resim) public JButton(String yazı); public JButton(String yazı, Icon resim) public AccessibleContext getAccessibleContext(); public String getUIClassID(); public boolean isDefaultButton(); public boolean isDefaultCapable(); public void setDefaultCapable(boolean b); pubkic void updateUI(); } şeklindedir. Görüldüğü gibi JButton fazla metod barındırmaz bir çok önemli metodu Abstract button ve onun tepe sınıfı JComponent sınıflarından alır. JButton sınıfında Jlabel sınıfında da kullandığımız JComponent sınıfından gelen metodlar : public void setBackground(Color c) : arkaplan rengini değiştiri public Color getBackground() : arkaplan rengini okur public void setForeground(Color c) : önpaln rengini değiştiri public Color getForeground() : ön plan rengini okur. public void setFont(Font f) : yazı fontunu seçer public Font getFont() : yazı fontunu okur public Boolean isVisible() : görünür olup olmadığını kontrol eder public Void setVisible(Boolean b) : görünür veya görünmez yapar. AbstractButton sınıfında tanımlanmış bazı alt sınıflar : public void setText(String s) : JLabel’ın text değişkeninin değerine yeni verilen değeri atar public String getText() :AbstractButton’ın String text değişkenini okur. public void setVerticalAlignment(int düşey_pozisyon) : AbstractButton’in Pencere içindeki düşey pozisyonunu ayarlar Buradaki düşey pozisyon SwingConstants.TOP SwingConstants.CENTER SwingConstants.BOTTOM Değerlerinden birini alabilir. public int getVerticalAlignment() public void setVerticalTextPosition(int düşey_pozisyon) : AbstractButton‘ın içindeki yazının Label içindeki düşey pozisyonunu ayarlar. Sabitler üsttekilerin aynıdır. public int getVerticalTextPosition() : AbstractButton‘ın içindeki yazının AbstractButton içindeki düşey pozisyonunu okur. public void setHorizontalTextPosition(int düşey_pozisyon) : AbstractButton‘ın içindeki yazının AbstractButton içindeki yatay pozisyonunu ayarlar. Sabitler SwingConstants.LEFT SwingConstants.CENTER SwingConstants.RIGHT public int getHorizontallTextPosition() : AbstractButton‘ın içindeki yazının AbstractButton‘ içindeki yatay pozisyonunu okur. Public void setIcon(Icon resim) : AbstractButton‘ın içindeki resmi değiştirir veya eğer yoksa ilk defa atar public Icon getIcon() : AbstractButton içindeki resmi okur. public void setDisplayedMnemonic(int c) : Mnemoic alt harf kontrolunu kullanarak belli bir girişe ulaşmayı sağlar. (örneğin ‘m’ harfine set edilmişse alt-m bu komuta gider. Örnek problemlerle bu kavram açılacaktır. Public int getDisplayedMnemonic(int c) : Mnemonic değerini okur. Listener (pencere dinleme) metod ve neslerinden ise : protected ActionListener actionListener; protected Itemlistener itemListener protected ChangeListener changeListener public void addActionListener(ActionListener l) public void addChangeListener(ChangeListener l) public void addItemListener(ItemListener l) public void removeActionListener(ActionListener l) public void removeChangeListener(ChangeListener l) public void removeItemListener(ItemListener l) public String getActionCommand() public void setActionCommand(String com) gibi metodlar mevcuttur. Şimdi örnekler üzerinden JButton sınıfını kullanmayı deneyelim : Program 1.7.3-3 Jbutton sınıfının gösterilmesini örnekleyen ButtonTestiSWF programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ButtonTestiSWF extends JFrame implements ActionListener { private JButton B1,B2; private JTextArea cikti; public ButtonTestiSWF() { super("button örneği"); Container c=getContentPane(); c.setLayout(new FlowLayout()); ImageIcon icon1 = new ImageIcon("images/middle.gif"); B1=new JButton("B1",icon1); B1.setHorizontalTextPosition(SwingConstants.LEFT); B1.addActionListener(this); c.add(B1); B2=new JButton("B2",icon1); B2.addActionListener(this); c.add(B2); cikti=new JTextArea(" "); c.add(cikti); cikti.setBackground(c.getBackground()); } public static void main(String[] args) { ButtonTestiSWF pencere= new ButtonTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } public void actionPerformed(ActionEvent e) { String gs=""; if(e.getSource()==B1) gs = " "+e.getActionCommand()+"dügmesine basildi\n"; else if(e.getSource()==B2) gs = " "+e.paramString() +"dügmesine basildi"; cikti.setText(gs); } } Şekil 1.7.3-2 ButtonTestiSWF.java sonuçlarının JFrame penceresinde görüntüsü Button ve JButton arasındaki farkları görmek amacıyla birbirinin aynı olan ButtonDemoApplet.java awt applet programını, ButtonDemoApplet.java swing programıyla karşılaştıralım. Not :isimler aynı olduğundan bu iki programı aynı dosyalarda saklıyamayız. Program 1.7.3-4 Button sınıfının gösterilmesini örnekleyen ButtonDemoApplet programı import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.applet.Applet; public class ButtonDemoApplet extends Applet implements ActionListener { protected Button b1, b2, b3; protected static final String DISABLE = "disable"; protected static final String ENABLE = "enable"; public void init() { b1 = new Button(); b1.setLabel("Disable middle button"); b1.setActionCommand(DISABLE); b2 = new Button("Middle button"); b3 = new Button("Enable middle button"); b3.setEnabled(false); b3.setActionCommand(ENABLE); //Listen for actions on buttons 1 and 3. b1.addActionListener(this); b3.addActionListener(this); //Add Components to the Applet, using the default FlowLayout. add(b1); add(b2); add(b3); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals(DISABLE)) { b2.setEnabled(false); b1.setEnabled(false); b3.setEnabled(true); } else { b2.setEnabled(true); b1.setEnabled(true); b3.setEnabled(false); } } } Şekil 8. ButtonDemoApplet.java sonuçlarının AppletViewer browserında görüntüsü Program 1.7.3-5 Button sınıfının gösterilmesini örnekleyen ButtonDemoApplet programı (bu program 1.7.10 ile aynı işlevi yapmaktadır) /* * Swing version. */ import javax.swing.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.BorderLayout; import java.net.URL; public class ButtonDemoApplet extends JApplet implements ActionListener { protected JButton b1, b2, b3; protected static final String DISABLE = "disable"; protected static final String ENABLE = "enable"; protected String leftButtonFilename = "images/right.gif"; protected String middleButtonFilename = "images/middle.gif"; protected String rightButtonFilename = "images/left.gif"; public void init() { ImageIcon leftButtonIcon = new ImageIcon( getURL(leftButtonFilename)); ImageIcon middleButtonIcon = new ImageIcon( getURL(middleButtonFilename)); ImageIcon rightButtonIcon = new ImageIcon( getURL(rightButtonFilename)); b1 = new JButton("Disable middle button", leftButtonIcon); b1.setVerticalTextPosition(AbstractButton.CENTER); b1.setHorizontalTextPosition(AbstractButton.LEFT); b1.setMnemonic('d'); b1.setActionCommand(DISABLE); b2 = new JButton("Middle button", middleButtonIcon); b2.setVerticalTextPosition(AbstractButton.BOTTOM); b2.setHorizontalTextPosition(AbstractButton.CENTER); b2.setMnemonic('m'); b3 = new JButton("Enable middle button", rightButtonIcon); //Use the default text position of CENTER, RIGHT. b3.setMnemonic('e'); b3.setActionCommand(ENABLE); b3.setEnabled(false); //Listen for actions on buttons 1 and 3. b1.addActionListener(this); b3.addActionListener(this); //Add Components to a JPanel, using the default FlowLayout. JPanel pane = new JPanel(); pane.add(b1); pane.add(b2); pane.add(b3); //Add JPanel to this applet, using the default BorderLayout. getContentPane().add(pane, BorderLayout.CENTER); } public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getActionCommand().equals(DISABLE)) { b2.setEnabled(false); b1.setEnabled(false); b3.setEnabled(true); } else { b2.setEnabled(true); b1.setEnabled(true); b3.setEnabled(false); } } protected URL getURL(String filename) { URL codeBase = getCodeBase(); URL url = null; try { url = new URL(codeBase, filename); } catch (java.net.MalformedURLException e) { System.out.println("Couldn't create image: badly specified URL"); return null; } return url; } } Şekil 9. ButtonDemoApplet.java sonuçlarının swing JApplet olarak Appletviewer browserında görüntüsü Programdan da görüldüğü gibi bu program bir önce verilmiş olan programın swing frame benzeridir. İki program da Applet olarak verilmiştir. Programlarda setEnabled(Boolean b) metodu kullanılarak düğmenin çalışması etkisisz hale getirilmiştir. Ayrıca swing versiyonunda resim dosyasını kullanırken URL sınıfı üzerinden okuduk. URL network ortamında bilgi aktarmaya yarayan bir sınıftır. Resim dosyası başka bir bilgisayarda olabilirdi. 1.7.4 TEXTFIELD (YAZIM ALANI) SINIFI TextField bir satırlık yazım alanlarıdır. TextField’in metotları aşağıda verilmiştir : Kurucu Metotlar : public TextField() public TextField(int satırsayısı) // satır sayısı uzunluğunda bir yazı kutusu açar. public TextField(String s) // s uzunluğunda bir yazı kutusu açr ve s yi içine yazar public TextField(String s,int satırsayısı) ) // satır sayısı uzunluğunda bir yazı kutusu açr ve s yi içine yazar Diğer Metotlar: Public void setEchoChar(char c) // kutudaki gerçek yazıyı gizleyerek onun yerine c karacter değişkenini yazar. Public void setEditable(boolean b) //kutunun içine yazılan yazının degiştirileblmesini sağlar veya engeller b=true yazı yazılabilir b=false yazı yazılamaz. Bu metotların kullanımını yine bir program örneğiyle izleyelim : Program 1.7.4-1 TextFieldTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class TextFieldTesti extends Applet implements ActionListener { private TextField T1,T2,T3,T4; public void init() { setBackground(Color.lightGray); //bos textField T1=new TextField(); T1.addActionListener(this); add(T1); T2=new TextField("Buraya yazi yaziniz"); T2.addActionListener(this); add(T2); T2=new TextField("gizli yazi"); T2.setEchoChar('*'); T2.addActionListener(this); add(T2); T3=new TextField("gizli yazi"); T3.setEditable(false); add(T3); } public void actionPerformed(ActionEvent e) { showStatus("Yazi : "+e.getActionCommand()); } } Şekil 1.7.4-1 TextFieldTesti.java programı sonuçlarının appletde görünümü Bu programda her yazı alanına (TextField) addActionListener metotu eklenmiş ve bir yazı girildiğinde actionPerformed metotundaki showStatus metotu yoluyla en son girilen yazı showStatus penceresine aktarılmıştır. TextField sınıfının java swing eşdeğeri JTextField sınıfıdır. JTextField sınıfı kurucu metotları : JTextField() JTextField(String) JTextField(String, int) JTextField(int) JTextField(Document, String, int) Şeklindedir. TextFielde Paralel olarak Özel bir TextField türü olan PasswordField de swingde tanımlanmıştır. PassWord fieldin kurucu metod tanımları : JPasswordField() JPasswordField(String) JPasswordField(String, int) JPasswordField(int) JPasswordField(Document, String, int) Şeklinde tanımlanmıştır. Bu iki sınıfın Text değerini girmak veya okumak için void setText(String) String getText() metodları tanımlanmıştır. void setEditable(boolean) boolean isEditable() metodları Yazı alanındaki yazıyı kullanıcının değiştirp değiştiremeyaceğini saptar veya bu müsadeyi değiştirir. void setColumns(int); int getColumns() int getColumnWidth() metodları yazı alanının byutunu değiştirmek veya saptamak amacıyla kullanılabilir. void setHorizontalAlignment(int); int getHorizontalAlignment() metodları yazıı alanındaki yazının ne şekilde yerleştirildiğini saptar veya isteğe göre yerleştirir. JTextField.LEFT, JTextField.CENTER, veya JTextField.RIGHT void setEchoChar(char) char getEchoChar() JpasswordField sınıfında tanımlanmış yazılan yazının yerine geçecek karekteri tanımlayan veya soran metodlardır. void addActionListener(ActionListener) metodları ise TextFieldin dinlenmesini ve giriş tuşu basıldığında yapılacak eylemlerin verildiği ActionListener implement’inden gelen public void actionPerformed(ActionEvent e) metodunu çalıştırmaya yarar. void removeActionListener(ActionListener) ise ActionListener dinleme metodunu iptal eder. JTextField ve JPasswordField metodlarının kullanılmasını bir örnek problemle inceleyelim. Bu bir önceki problemin hemen hemen aynı işlemleri yapan JFrame ortamında yazılmış bir örnek problemdir. Program 1.7.4-2 TextFieldTestiSWF.java programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TextFieldTestiSWF extends JFrame implements ActionListener { private JTextField T1,T2,T3; private JPasswordField T4; Container c; public TextFieldTestiSWF() { super("JTestField ve JPassword Field Testleri"); c=getContentPane(); c.setLayout(new FlowLayout()); c.setBackground(Color.lightGray); //bos textField T1=new JTextField(10); T1.addActionListener(this); c.add(T1); T2=new JTextField("Buraya yazı yazınız"); T2.addActionListener(this); c.add(T2); T3=new JTextField("değiştirilemez yazı"); T3.setEditable(false); T3.addActionListener(this); c.add(T3); T4=new JPasswordField("gizli yazı"); c.add(T4); } public void actionPerformed(ActionEvent e) { String s="Kaynak = "; if(e.getSource()==T1) s+="T1 Yazı : "+e.getActionCommand(); else if(e.getSource()==T2) s+="T2 Yazı : "+e.getActionCommand(); else if(e.getSource()==T3) s+="T3 Yazı : "+e.getActionCommand(); else if(e.getSource()==T4) s+="T4 Yazı : "+e.getActionCommand(); JOptionPane.showMessageDialog(this,s,"JTestField ve JPassword Field Testleri", JOptionPane.PLAIN_MESSAGE); } public static void main(String[] args) { TextFieldTestiSWF pencere= new TextFieldTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.7.4-2 TextFieldTestiSWF.java programı sonuçlarının JFrame ve JoptionPane’de görünümü 1.7.5 YAZIM ALANI AWT TEXTAREA VE SWING JTEXTAREA SINIFLARI awt kütüphanesinde tanımlanan Text Area sınıfı yapı olarak TextField sınıfına benzer. En onemli farkı bir satır yerine birden fazla satır girdi alabilme olasılığıdır. TextField ve TextArea sınıfları TextComponent sınıfının alt sınıflarıdır. Bu yüzden üstte belirttiğimiz Public void setEchoChar(char c) // kutudaki gerçek yazıyı gizleyerek onun yerine c karacter değişkenini yazar. Public void setEditable(boolean b) //kutunun içine yazılan yazının degiştirileblmesini sağlar veya engeller b=true yazı yazılabilir b=false yazı yazılamaz. Metotları burada da aynen geçerlidir.TextArea’nınkurucu metotlarıda şöyledir: public TextArea() public TextArea(int sütun,int satır) sütun x satır boyutunda yazı alanı tanımlar public TextArea(String s) String değişkeni s nin boyuna göre yazı alanı tanımlar ve s yi içine yazar. public TextArea(String s,int sütun,int satır) sütun x satır boyutunda yazı alanı tanımlar ve s yi içine yazar public TextArea(String s,int sütun,int satır,int scrollbar) scroll bar (kontrolçubuğu) değişkeni şu değerleri alabilir : SCROLLBARS_BOTH Hem yatay hemdüşey kontrol çubuğu tanımlar SCROLLBARS_HORİZONTAL_ONLY Yatay kontrol çubuğu tanımlar SCROLBARS_NONE Kontrol çubuğu tanımlamaz SCROLLBARS_VERTİCAL_ONLY Düşey kontrol çubuğu tanımlar Şimdi TextArea metotunu Küçük bir örnekte kullanalım : Program 1.7.5-1 TextAreaTesti.java programı import java.applet.Applet; import java.awt.*; public class TextAreaTesti extends Applet { private TextArea T1; public void init() { setBackground(Color.lightGray); //bos textField String s="buraya denemek icin\nyazi yazildi\n\t sonrada bu yazi aktarildi"; //not \n satirbasi kontrolu // \t bir sonraki tab setine git T1=new TextArea(s,5,40); add(T1); } } Şekil 1.7.5-1 TextAreaTesti.java Programı applet çıktısı Bu programda gördüğünüz \n ve \t string komutlarıdır. Alt satıra geç ve gelecek tab noktasına git anlamına gelir Bu komutlar aslında c dilinden alınmadır ve c dilindeki tüm \ komutları java stringlerinde de geçerlidir. Şimdi TextArea metotunu biraz daha detaylı bir programda kullanalım Program 1.7.5-2 : TextArea sınıfını kullanan TextAreaTesti1.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class TextAreaTesti1 extends Applet implements ActionListener,TextListener { private TextArea T1,T2; private Button kopye; public void init() { setBackground(Color.lightGray); //bos textField String s="buraya denemek icin\nyazi yazildi\n\t sonrada bu yazi aktarildi"; //not \n satrbaŸ kontrol // \t bir sonraki tab setine git T1=new TextArea(s,5,20,TextArea.SCROLLBARS_NONE); T1.addTextListener(this); add(T1); kopye=new Button("Kopye "); kopye.addActionListener(this); add(kopye); T2=new TextArea(5,20); T2.setEditable(false); add(T2); } public void actionPerformed(ActionEvent e) { // T1 penceresinden seçilen yazıyı // kopye düğmesine basıldığında T2 penceresine aktar T2.setText(T1.getSelectedText()); } public void textValueChanged(TextEvent e) { //Birinci pencereye yeni yazı yazıldığında ikinci pencereye aktar TextComponent kaynak=(TextComponent)(e.getSource()); T2.setText(kaynak.getText()); } } Şekil 1.7.5-2 TextAreaTesti1.java Programı sonuçlarını gösteren appletler Bu programda TextListener kullanıldığından textValueChange metotu da kullanılmıştır. Buradaki metot birinci kutuya yazılan yazıyı ikinci kutuya kopyalamaktadır. Kopye düğmesine basılınca ise sadece T1.getSelectedText() metotuyla secilmiş olan text actionPerforned metotu üzerinden T2 Yazım Alanına (TextArea) aktarılmaktadır. Java swing JTextArea sınıfı awt deki TextArea sınıfının benzeridir. Sınıfın kurucu metodlarının tanımı public JTextArea(); public JTextArea(int rows,int cols); public JTextArea(Document doc); public JTextArea(Document doc, String Text, int satırsayısı int sütun sayısı); public JTextArea(String Text) public JTextArea(String Text,int satırsayısı int sütun sayısı) şeklindedir. JTextArea sınıfını kullanan Bir örnek problem verelim: Program 1.7.5-3 TextAreaTesti1SWF.java programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TextAreaTesti1SWF_2000 extends JFrame implements ActionListener,TextListener { private JTextArea T1,T2; private JButton kopye; public TextAreaTesti1SWF_2000() { super("JTextAreaTesti"); Container c=getContentPane(); c.setLayout(new FlowLayout()); c.setBackground(Color.lightGray); //bos textField String s="buraya denemek icin\nyazı yazıldı\n\t sonrada bu yazı aktarıldı"; //not \n satırbaşı kontrol // \t bir sonraki tab setine git Box b=Box.createHorizontalBox(); T1=new JTextArea(s,10,15); b.add(new JScrollPane(T1)); kopye=new JButton("Kopye >>>"); kopye.addActionListener(this); b.add(kopye); c.add(kopye); T2=new JTextArea(10,15); T2.setEditable(false); b.add(new JScrollPane(T2)); c.add(b); } public void actionPerformed(ActionEvent e) { // T1 penceresinden seçilen yazıyı // kopye düğmesine basıldığında T2 penceresine aktar T2.setText(T1.getSelectedText()); } public void textValueChanged(TextEvent e) { //Birinci pencereye yeni yazı yazıldığında ikinci pencereye aktar TextComponent kaynak=(TextComponent)(e.getSource()); T2.setText(kaynak.getText()); } public static void main(String[] args) { TextAreaTesti1SWF_2000 pencere= new TextAreaTesti1SWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(600,200); pencere.setVisible(true); } } Şekil 1.7.5-3 TextAreaTesti1SWF.java programı sonuçlarının JFrame penceresindede görünümü 1.7.6 AWT CHOICE , SWING JCOMBOBOX SEÇIM SINIFLARI awt kütüphanesi Choice (Seçim) sınıfı birden fazla maddeden seçim yapılması gerektiğinde kullanılan bir sınıftır. Choice sınıfının kurucu metotu ve diger metotlarının listesi aşağıda verilmiştir : public Choice() // Kurucu metot public String getItem(int indeks) İndeksteki seçimi verir public synchronised void add(String s) verilen Stringi Choice listesine ekler. public synchronised String getSelectedItem() Fareyle seçilmiş olan liste elemanını verir public synchronised String insert(String s, int indeks) verilen stringi listeye indeks sırasındaki madde olarak ekle public synchronised void remove(String s) verilen stringi listeden siler Choice (Seçim) sınıfını bir programda kullanalım : Program 1.7.6-1 Choice sınıfının kullanımı, ChoiceTesti.java import java.awt.*; import java.applet.Applet; import java.awt.event.*; public class ChoiceTesti extends Applet { private Choice F; private TextField T; public void init() { F=new Choice(); F.add("MonoSpaced"); // Courier F.add("SansSerif"); // Helvetica F.add("Serif"); // Times T=new TextField(F.getItem(0),30); T.setEditable(false); T.setFont(new Font(F.getItem(0),Font.PLAIN,12)); F.addItemListener(new FontIsmiKontrolu(T)); F.addItemListener(new TextFieldKontrolu(T)); add(F); add(T); } } class FontIsmiKontrolu implements ItemListener { private Component C; public FontIsmiKontrolu(Component C) { this.C=C; } public void itemStateChanged(ItemEvent e) { C.setFont(new Font(e.getItem().toString(), C.getFont().getStyle(), C.getFont().getSize())); } } class TextFieldKontrolu implements ItemListener { private TextField T; public TextFieldKontrolu(TextField T) { this.T=T; } public void itemStateChanged(ItemEvent e) { Choice C=(Choice)e.getItemSelectable(); T.setText("Indeks : "+ C.getSelectedIndex()+"; Font : "+e.getItem()); }} Choice seçimlerini yukarıdaki ChoiceTesti.html de de görüleceği gibi aktarılırken ItemListener ve ItemEvent kullanılmıştır. Bu metotla kullanılması gereken method ItemStateChanged metotudur. Şekil 1.7.6-1 ChoiceTesti.java programının sonuçlarının appletde görülmesi Java swing sınıfında Choice sınıfının benzeri Jchoice sınıfı mevcut değildir. Onun yerini JComboBox sınıfı almıştır JComboBox sınıfının Kurucu metodları : public JComboBox(); public JComboBox(ComboBoxModel m); public JComboBox(Object obj[]); public JComboBox(Vector v); şeklindedir. Vector gelişmiş bir boyutlu değişken türüdür detayları 11 inci bölüm, gelişmiş java bilgi işleme yapıları kısmında verilmiştir. ComboBox Jcomponent sınıfından türetilmiştir. ActionListener, ItemSelectable, ListDataListener ve Accessible sınıflarını implement eder. JComboBox sınıfı, seçilen sınıfı size veren veya seçilme opsiyonunu tanımlayan şu sınıfları barındırır : getSelectedItem() : bu noktadaki Object değerini çağırır. getSelectedIndex() : bu noktanın indeks değerini çağırır getSelectedObjects() : birden fazla seçim yapıldığında tüm seçilen object listesini iletir. setSelectedIndex(int pozisyon) : pozisyon indeksini seçer setSelectedItem(Object nesne) nesne ‘yi seçer Program 1.7.6-2 JComboBox sınıfının kullanımı, JComboBoxTestiSWF.java import java.awt.*; import javax.swing.*; import java.awt.event.*; public class JComboBoxTestiSWF extends JFrame { private JComboBox F; private JTextField T; public JComboBoxTestiSWF() { super("JComboBox örneği"); Container co=getContentPane(); String Liste[]={"MonoSpaced","SansSerif","Serif"}; F=new JComboBox(Liste); T=new JTextField((String)F.getItemAt(0)); T.setEditable(false); T.setFont(new Font((String)F.getItemAt(0),Font.BOLD,12)); F.addItemListener(new FontIsmiKontrolu(T)); F.addItemListener(new TextFieldKontrolu(T)); co.add(F,BorderLayout.NORTH); co.add(T,BorderLayout.CENTER); } public static void main(String[] args) { JComboBoxTestiSWF pencere= new JComboBoxTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(300,150); //pencere.pack(); pencere.setVisible(true); } } class FontIsmiKontrolu implements ItemListener { private Component C; public FontIsmiKontrolu(Component C) { this.C=C; } public void itemStateChanged(ItemEvent e) { C.setFont(new Font(e.getItem().toString(), C.getFont().getStyle(), C.getFont().getSize())); } } class TextFieldKontrolu implements ItemListener { private JTextField T; public TextFieldKontrolu(JTextField T) { this.T=T; } public void itemStateChanged(ItemEvent e) { JComboBox C=(JComboBox)e.getItemSelectable(); T.setText("Indeks : "+ C.getSelectedIndex()+"; Font : "+e.getItem()); }} Sekil 1.7.6-2 JComboBoxTestiSWF.java programının sonuçlarının appletde görülmesi 1.7.7 AWT, CHECKBOX VE CHECKBOXGROUP VE SWING JCHECKBOX VE JRADIOBUTTON SINIFLARI awt sınıfında yer alan Check box ve CheckBoxGroup sınıfları çesitli opsiyonlar arasından seçim yapabilme olasılığını sağlayan sınıflardır. Kurucu metotları : Public CheckBox(String s) Tek bir kare kontrol kutusu oluşturur. Kontrol kutusu başta boştur Public CheckBox(String s, CheckBoxGroup c,boolean durum) Tekbir daire şeklinde kontrol kutusu oluşturur ve bu kontrol kutusunu CheckBoxGroup nesnesine ilave eder. Public CheckboxGroup() CheckboxGroup nesnesini oluşturur bu gruba checkboxlar ilave edilebilir CheckBox kullanımını anlamak amacıyla CheckBoxTesti.java programına göz atalım : Program 1.7.7-1 CheckBoxTest.java, CheckBox kullanım test programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class CheckBoxTesti extends Applet implements ItemListener { private TextField T; private Checkbox Kalin,Italic; public void init() { setBackground(Color.lightGray); //bos textField T=new TextField("Buradaki yazinin degismesini izleyiniz"); add(T); Kalin=new Checkbox("Kalin"); Kalin.addItemListener(this); add(Kalin); Italic=new Checkbox("Italik"); Italic.addItemListener(this); add(Italic); } public void itemStateChanged(ItemEvent e) { int KalinAyari; if(Kalin.getState()) {KalinAyari=Font.BOLD;} else {KalinAyari=Font.PLAIN;} int ItalicAyari; if(Italic.getState()) {ItalicAyari=Font.ITALIC;} else {ItalicAyari=Font.PLAIN;} T.setFont(new Font("Serif",KalinAyari+ItalicAyari,14)); } } Şekil 1.7.7-1 CheckBoxTesti.java programının sonuçlarının appletde görülmesi Şimdi de checkBoxGroup programının çalışmasını ornekleyen RadioButtonTesti programına göz atalım. Burada guruplanmış olan checkbox’lardan sadece bir tanesini seçme izni verilmiştir. Program 1.7.7-2 : RadioButtonTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class RadiobuttonTesti extends Applet implements ItemListener { private TextField T; private Font NormalFont,KalinFont,ItalicFont,KalinItalicFont; private Checkbox Normal,Kalin,Italic,KalinItalic; private CheckboxGroup fontGurubu; public void init() { setBackground(Color.lightGray); //bos textField T=new TextField("Buradaki yazinin degismesini izleyiniz"); add(T); fontGurubu=new CheckboxGroup(); Normal=new Checkbox("Normal",fontGurubu,true); Normal.addItemListener(this); add(Normal); Kalin=new Checkbox("Kalin",fontGurubu,true); Kalin.addItemListener(this); add(Kalin); Italic=new Checkbox("Italik",fontGurubu,true); Italic.addItemListener(this); add(Italic); KalinItalic=new Checkbox("Kalin Italik",fontGurubu,true); KalinItalic.addItemListener(this); add(KalinItalic); NormalFont=new Font("Serif",Font.PLAIN,14); KalinFont=new Font("Serif",Font.BOLD,14); ItalicFont=new Font("Serif",Font.ITALIC,14); KalinItalicFont=new Font("Serif",Font.BOLD+Font.ITALIC,14); T.setFont(NormalFont); } public void itemStateChanged(ItemEvent e) { int KalinAyari; if(e.getSource()== Normal) {T.setFont(NormalFont);} else if(e.getSource()== Kalin) {T.setFont(KalinFont);} else if(e.getSource()== Italic) {T.setFont(ItalicFont);} else if(e.getSource()== KalinItalic) {T.setFont(KalinItalicFont);} } } Şekil 1.7.7-2 RadioButtonTesti.java programı sonuçlarının applette gösterilmesi Swing gurubundaki aynı işler için kullandığımız sınıflar JCheckBox, JRadioButton ve JButtonGroup sınıflarıdır. JCheckBox sınıfının kurucu metodları : public JCheckBox() public JCheckBox(Icon resim) public JCheckBox(Icon resim,boolean kutuişareti) public JCheckBox(String yazı) public JCheckBox(String yazı, boolean kutuişareti) public JCheckBox(String yazı, Icon resim) public JCheckBox(String yazı, , Icon resim ,boolean kutuişareti) Burada da daha önceki JLabel, JButton gibi sınıflarda gördüğümüz gibi yazının yanında resim yerleştirme seçimimiz de mevcuttur. Buradaki örnek problemde bir önceki problemin aynısı JcheckBox ile çözülmüştür. Program 1.7.7-3 CheckBoxTestiSWF.java, JCheckBox kullanım test programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class CheckBoxTestiSWF extends JFrame implements ItemListener { private JTextField T; private JCheckBox Kalin,Italik; int KalinAyari=Font.PLAIN;; int ItalikAyari=Font.PLAIN; public CheckBoxTestiSWF() { super("check box örneği"); Container c=getContentPane(); c.setBackground(Color.lightGray); //c.setLayout(new FlowLayout()); JPanel Check=new JPanel(); Check.setLayout(new GridLayout(0,1)); //bos textField Kalin=new JCheckBox("Kalın"); Kalin.setMnemonic('K'); Kalin.setSelected(false); Kalin.addItemListener(this); Check.add(Kalin); Italik=new JCheckBox("İtalik"); Italik.setMnemonic('İ'); Italik.setSelected(false); Italik.addItemListener(this); Check.add(Italik); c.add(Check,BorderLayout.WEST); T=new JTextField("Buradaki yazının değişmesini izleyiniz"); T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); c.add(T,BorderLayout.CENTER); } public void itemStateChanged(ItemEvent e) { Object kutu=e.getItemSelectable(); if(Kalin==kutu && e.getStateChange()==ItemEvent.SELECTED) {KalinAyari=Font.BOLD;} else if(Kalin==kutu && e.getStateChange()==ItemEvent.DESELECTED) {KalinAyari=Font.PLAIN;} if(Italik==kutu && e.getStateChange()==ItemEvent.SELECTED) {ItalikAyari=Font.ITALIC;} else if(Italik==kutu && e.getStateChange()==ItemEvent.DESELECTED) {ItalikAyari=Font.PLAIN;} T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); } public static void main(String[] args) { CheckBoxTestiSWF pencere= new CheckBoxTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,100); pencere.setVisible(true); } } Şekil 1.7.7-3CheckBoxTestiSWF.java programının sonuçlarının JFrame’de görülmesi Java swing JRadioButton sınıfı JcheckBox tanımına benzerdir. Kurucu metodları : public JRadioButton() public JRadioButton(Icon resim) public JRadioButton(Icon resim,boolean kutuişareti) public JRadioButton(String yazı) public JRadioButton(String yazı, boolean kutuişareti) public JRadioButton(String yazı, Icon resim) public JRadioButton(String yazı, , Icon resim ,boolean kutuişareti) Burada JRadioButton sınıfına ilave olarak bir tane daha ilave olarak bir tane daha yardımcı sınıf kullanacağız. Bu sınıf ButtonGroup sınıfıdır. Bu sınıf düğmeleri bir gurup altında toplayarak sadece bir tanesinin basılı durumda olması işlevini kontrol eder. Bu sınıfın tanımı : public class ButtonGroup extends Object implements Serializable { protected Vector düğmeler; public ButtonGroup(); public void add(AbstractButton ab); public Enumeration getElements(); public ButtonModel getSelection(); public boolean isSelected(ButtonModel bm); public void remove(AbstractButton ab); public void setSelected(ButtonModel bm,boolean b); } şeklindedir. Şimdi yine bir öncekine benzer bir örnekte JradioButton ve ButtonGroup sınıflarının birarada kullanımını görelim. Program 1.7.7-4 RadioButtonTestiSWF.java, JRadioButton kullanım test programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class RadioButtonTestiSWF extends JFrame implements ItemListener { private JTextField T; private JRadioButton normal,kalin,italik,kalinitalik; private ButtonGroup gurup; int KalinAyari=Font.PLAIN;; int ItalikAyari=Font.PLAIN; public RadioButtonTestiSWF() { super("Radio Button örneği"); Container c=getContentPane(); c.setBackground(Color.lightGray); JPanel Check=new JPanel(); Check.setLayout(new GridLayout(4,0)); //bos textField gurup=new ButtonGroup(); normal=new JRadioButton("Normal"); normal.setMnemonic('N'); normal.setSelected(true); normal.addItemListener(this); gurup.add(normal); Check.add(normal); kalin=new JRadioButton("Kalın"); kalin.setMnemonic('K'); kalin.setSelected(false); kalin.addItemListener(this); gurup.add(kalin); Check.add(kalin); italik=new JRadioButton("İtalik"); italik.setMnemonic('t'); italik.setSelected(false); italik.addItemListener(this); gurup.add(italik); Check.add(italik); kalinitalik=new JRadioButton("Kalın-İtalik"); kalinitalik.setMnemonic('a'); kalinitalik.setSelected(false); kalinitalik.addItemListener(this); gurup.add(kalinitalik); Check.add(kalinitalik); c.add(Check,BorderLayout.WEST); T=new JTextField("Buradaki yazının değişmesini izleyiniz"); T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); c.add(T,BorderLayout.CENTER); } public void itemStateChanged(ItemEvent e) { Object kutu=e.getItemSelectable(); if(kutu==normal) { KalinAyari=Font.PLAIN; ItalikAyari=Font.PLAIN; } else if(kutu==kalin) { KalinAyari=Font.BOLD; ItalikAyari=Font.PLAIN; } else if(kutu==italik) { KalinAyari=Font.PLAIN; ItalikAyari=Font.ITALIC; } else if(kutu==kalinitalik) { KalinAyari=Font.BOLD; ItalikAyari=Font.ITALIC; } T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); repaint(); } public static void main(String[] args) { RadioButtonTestiSWF pencere= new RadioButtonTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,100); pencere.setVisible(true); } } Şekil 1.7.7-4 RadioButtonTestiSWF.java programının sonuçlarının JFrame’de görülmesi Son olarak bu guruptan JToggleButton sınıfına değinelim. JToggleButton sınıfı işlevsel olarak JcheckBox sınıfının aynıdır. Sadece basılım alanı düğme(button) şeklindedir. JcheckBox için verdiğimiz programın JToggleButton’a dönüştürülmüş şekli aşağıda verilmiştir. Program 1.7.7-5 ToggleButtonTestiSWF.java, JToggleButton kullanım test programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ToggleButtonSWF extends JFrame implements ItemListener { private JTextField T; private JToggleButton Kalin,Italik; int KalinAyari=Font.PLAIN;; int ItalikAyari=Font.PLAIN; public ToggleButtonSWF() { super("ToggleButton örneği"); Container c=getContentPane(); c.setBackground(Color.lightGray); //c.setLayout(new FlowLayout()); JPanel Check=new JPanel(); Check.setLayout(new GridLayout(0,1)); //bos textField Kalin=new JToggleButton("Kalın"); Kalin.setMnemonic('K'); Kalin.setSelected(false); Kalin.addItemListener(this); Check.add(Kalin); Italik=new JToggleButton("İtalik"); Italik.setMnemonic('t'); Italik.setSelected(false); Italik.addItemListener(this); Check.add(Italik); c.add(Check,BorderLayout.WEST); T=new JTextField("Buradaki yazının değişmesini izleyiniz"); T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); c.add(T,BorderLayout.CENTER); } public void itemStateChanged(ItemEvent e) { Object kutu=e.getItemSelectable(); if(Kalin==kutu && e.getStateChange()==ItemEvent.SELECTED) {KalinAyari=Font.BOLD;} else if(Kalin==kutu && e.getStateChange()==ItemEvent.DESELECTED) {KalinAyari=Font.PLAIN;} if(Italik==kutu && e.getStateChange()==ItemEvent.SELECTED) {ItalikAyari=Font.ITALIC;} else if(Italik==kutu && e.getStateChange()==ItemEvent.DESELECTED) {ItalikAyari=Font.PLAIN;} T.setFont(new Font("Serif",KalinAyari+ItalikAyari,20)); } public static void main(String[] args) { ToggleButtonSWF pencere= new ToggleButtonSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,100); pencere.setVisible(true); } } Şekil 1.7.7-5 ToggleButtonTestiSWF.java programının sonuçlarının JFrame’de görülmesi 1.7.8 MOUSE(FARE) KONTROLU Modern bilgisayarlarda bilgisayar işlemlerinin çok büyük bir kısmı mouse (fare) ile kontrol edilir. Javada gurubunda temel fare kontrollarını sağlayan sınıflar MouseListener ve MouseMotionListener sınıflarıdır. Bu sınıfların en çok kullanılan metotları şunlardır : 1. MouseListener Metotları : public void mousePressed(MouseEvent e) bir mouse düğmesi basılınca çağırılır public void mouseClicked(MouseEvent e) bir mouse düğmesi basılıp bırakılırsa çağırılır. public void mouseReleased(MouseEvent e) Bir mouse düğmesi basılı olarak mouse çekildikten sonra düğme bırakılınca çağırılır. public void mouseEntered(MouseEvent e) mouse pencere içine girince çağırılır. public void mouseExited(MouseEvent e) mouse pencere çerçevesinin dışındaysa çağırılır. 2. MouseMotionListener Metotları public void mouseDragged(MouseEvent e) Mouse düğmesi basılı iken mouse hareket ettirilirse çağırılır public void mouseMoved(MouseEvent e) Mouse hareket ederse çağırılır. Bu metotların kullanımlarını göstermek amacıyla FareTesti.java programı aşağıda verilmiştir. Bu program awt Applet programı olarak hazırlanmıştır. Program 1.7.8-1 : FareTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class FareTesti extends Applet implements MouseListener, MouseMotionListener { private int nx,ny=-10; private String s=""; public void init() { addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g) { g.drawString(s+"["+nx+","+ny+"]",nx,ny); } public void degerleriGir(String e,int x,int y) { s=e; nx=x; ny=y; repaint(); } //fare dinleyicisinin dinledikleriyle ilgili cikti metotlari public void mouseClicked(MouseEvent e) { degerleriGir("Kliklendi",e.getX(),e.getY()); } public void mousePressed(MouseEvent e) { degerleriGir("Basildi",e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { degerleriGir("Birakildi",e.getX(),e.getY()); } public void mouseEntered(MouseEvent e) { showStatus("Fare applet alani icinde"); } public void mouseExited(MouseEvent e) { showStatus("Fare applet alani disinda"); } //MouseMotionListener (fare hareket dinleyicisi) metotlari public void mouseDragged(MouseEvent e) { degerleriGir("basilip cekiliyor",e.getX(),e.getY()); } public void mouseMoved(MouseEvent e) { degerleriGir("hareket halinde",e.getX(),e.getY()); } } Şekil 1.7.8-1 FareTesti.html applet çıktısı Aynı programın JFrame’de yazılmış bir benzeri aşağıda sunulmuştur. Program 1.7.8-2 FareTestiSWF.java, Fare(Mouse) kontrol sınıfları kullanım test programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class FareTestiSWF extends JFrame implements MouseListener, MouseMotionListener { private int nx,ny=-10; private String s=""; private JLabel altbar; public FareTestiSWF() { super("Fare Testi"); altbar=new JLabel(); getContentPane().add(altbar,BorderLayout.SOUTH); addMouseListener(this); addMouseMotionListener(this); } public void degerleriGir(String e,int x,int y) { s=e; nx=x; ny=y; altbar.setText(e+"["+x+" , "+y+"] "); repaint(); } //fare dinleyicisinin dinledikleriyle ilgili cikti metodlari public void mouseClicked(MouseEvent e) { degerleriGir("Kliklendi",e.getX(),e.getY()); } public void mousePressed(MouseEvent e) { degerleriGir("Basıldı",e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { degerleriGir("Bırakıldı",e.getX(),e.getY()); } public void mouseEntered(MouseEvent e) { setTitle("Fare applet alanı içinde"); } public void mouseExited(MouseEvent e) { setTitle("Fare applet alanı dışında"); degerleriGir("Fare applet alanı dışında",e.getX(),e.getY()); } //MouseMotionListener (fare hareket dinleyicisi) metotlari public void mouseDragged(MouseEvent e) { degerleriGir("basilip cekiliyor",e.getX(),e.getY()); } public void mouseMoved(MouseEvent e) { degerleriGir("hareket halinde",e.getX(),e.getY()); } public static void main(String[] args) { FareTestiSWF pencere= new FareTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,150); pencere.setVisible(true); } } Şekil 1.7.8-2 FareTestiSWF.java JFrame penceresi çıktısı 1.7.9 SWING JTABLE SINIFI JTable şu ana kadar gördüğümüz sınıflara göre daha kompleks bir yapı arzeder, fakat oldukça kullanışlı bir yapıdır ve sadece swing kütüphanesinde tanımlanmıştır. JTable sınıfının kurucu sınıfları : public JTable(); public JTable(TableModel tm); public JTable(TableModel tm, TableColumnModel tcm); public JTable(TableModel tm, TableColumnModel tcm, ListSelectionModel lm); public JTable(int satırsayısı,int sütunsayısı); public JTable(Object[][] tablogirdisi ,Object[] tablobaşlığıgirdisi); public JTable(Vector tablogirdisi ,Vector tablobaşlığıgirdisi); şeklindedir. Kurucu metodlarda girdi olarak görünen TableModel sınıfı public interface TableModel{ public abstract void addTableModelListener(TableModelListener l); public abstract Class getColumnClass(int sütun); public abstract int getColumnCount(); public abstract String getColumnName(int Column); public abstract int getRowCount(); public abstract Object getValueAt(int satır, int sütun); public abstract boolean isCellEditable(int satır, int sütun); public abstract void removeTableModelListener(TableModelListener l); public abstract void setValueAt(Object o.int satır,int sütun); } görüldüğü gibi bu sınıf interface olduğundan bu sınıftan türetilen sınıfların bu sınıftaki tüm metodları tanımlamaları gerekir. Bu yüzden AbstractTableModel gibi Table Model’den türetilen sınıflar üzerinden yeni sınıfın türetilmesine gidilebilir. public abstract class AbstractTableModel implements TableModel { public AbstractTableModel(); public abstract void addTableModelListener(TableModelListener l); public int findColumn(String ColumnName); public void fireTableCellUpdated(int satır,int sütun); public void fireTableChanged(TableModelEvent e); public void fireTableDataChanged(); public void fireTableRowsDeleted(int satır,int sütun); public void fireTableRowsInserted(int satır,int sütun); public void fireTableRowsUpdated(int satır,int sütun); public void fireTableStructureChanged(); public abstract Class getColumnClass(int sütun); public abstract String getColumnName(int Column); public abstract boolean isCellEditable(int satır, int sütun); public abstract void removeTableModelListener(TableModelListener l); public abstract void setValueAt(Object o.int satır,int sütun); } Örnek problemlerde önce AbstractTableModel’den türetilen ve Tablonun giriş değerlerini veren TableModel sınıfı yaratılmış, sonra bu sınıf tabloda girdi olarak kullanılmıştır. Program 1.7.9-1 tableSWF_2000.java, TableModel, JTable ve TableModelListener sınıfları kullanım test programı import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; class TableModel extends AbstractTableModel implements TableModelListener { Object[][] veri={{"satır bir - sütun bir","satır bir - sütun iki"}, {"satır iki - sütun bir","satır iki - sütun iki"}}; String[] baslik={"sütun bir","sütun iki"}; public TableModel() { addTableModelListener(this); } public int getRowCount() {return veri.length;} public int getColumnCount() {return baslik.length;} public Object getValueAt(int satir,int sutun) {return veri[satir][sutun];} public String getColumnName(int c) {return baslik[c];} public void setValueAt(Object val, int row, int col) { veri[row][col] = val; // Değişimin olduğunu göster: fireTableDataChanged(); } public void tableChanged(TableModelEvent e) { String s="Tablodaki değer değiştirildi "; JOptionPane.showMessageDialog(null,s,"Tablodaki değer değiştirildi", JOptionPane.WARNING_MESSAGE); } public boolean isCellEditable(int row, int col) {return true;} } public class tableSWF_2000 extends JFrame { private Container c; public tableSWF_2000() { super("Tablo örneği"); c=getContentPane(); c.setLayout(new BorderLayout()); setSize(300,300); addWindowListener(new BasicWindowMonitor()); TableModel tm=new TableModel(); JTable jt=new JTable(tm); JScrollPane jsp=new JScrollPane(jt); c.add(jsp,BorderLayout.NORTH); f=new JTextField(); c.add(f,BorderLayout.SOUTH); } //===================================================== public static void main(String[] args) { tableSWF_2000 pencere= new tableSWF_2000(); pencere.setVisible(true); } } Şekil 1.7.9-1 26 tableSWF_2000.java JFrame ve JoptionPane penceresi çıktısı Program 1.7.9-2 table1SWF_2000.java, TableModel, JTable ve TableModelListener sınıfları kullanım test programı // JTable örneği import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; // The TableModel controls all the data: class DataModel extends AbstractTableModel { Object[][] data = { {"bir", "iki", "üç", "dört"}, {"beş", "altı", "yedi", "sekiz"}, {"dokuz", "on", "onbir", "oniki"}, }; String[] baslik={"sütun 1","sütun 2","sütun 3","sütun 4"}; // Tablo dinleme metodu ve sınıfı : Tabloda bir değişiklik yapıldığında // JOption pane ile yeni değişikliği göster class TML implements TableModelListener { public void tableChanged(TableModelEvent e) { String s=""; for(int i = 0; i < data.length; i++) { for(int j = 0; j < data[0].length; j++) s+=data[i][j] + " "; s+="\n"; } JOptionPane.showMessageDialog(null,s,"Tablodaki data değiştirildi", JOptionPane.PLAIN_MESSAGE); } } //kurucu metod DataModel() { addTableModelListener(new TML()); } public int getColumnCount() {return data[0].length;} public int getRowCount() { return data.length;} public Object getValueAt(int row, int col) {return data[row][col];} public String getColumnName(int c) {return baslik[c];} public void setValueAt(Object val, int row, int col) { data[row][col] = val; // Değişimin olduğunu göster: fireTableDataChanged(); } public boolean isCellEditable(int row, int col) { return true; } }; public class table1SWF_2000 extends JFrame { public table1SWF_2000() { super("Tablo örneği"); Container c=getContentPane(); c.setLayout(new BorderLayout()); JTable table = new JTable(new DataModel()); JScrollPane jsp=new JScrollPane(table); c.add(jsp, BorderLayout.CENTER); } public static void main(String args[]) { table1SWF_2000 pencere= new table1SWF_2000(); pencere.setSize(300,300); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setVisible(true); } } Şekil 1.7.9-2 table1SWF_2000.java JFrame ve JOPtionPane çıktısın görünümü 1.7.10 AWT, LIST SINIFI VE JAVA SWING JLIST SINIFI , LİSTEDEN SEÇİM Bu gurup aslında bölüm 1.7.6 da tanımlanan awt Choice , swing JcomboBox seçim sınıflarının bir devamı niteliğindedir. List ve Jlist sınıfları bir listeden seçim yapmaya ve bu seçim sonucu gerekli işlemleri oluşturmaya yarar. List sınıfı ItemListener ve ActionListener sınıf implementlerini kullanır. Örnek programımızda Listeden seçilen renge göre arkaplan rengi değişmektedir. Program 1.7.10-1 ListTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class ListTesti extends Applet implements ActionListener,ItemListener { private List renkListesi; private String renkIsmi[]={"Siyah","Mavi","Cam Gobegi","Koyu Gri","Gri", "Yesil","Acik gri","Mor","Portakal","Pembe","Kirmizi","Beyaz","Sari"}; private Color C[]={Color.black,Color.blue,Color.cyan,Color.darkGray, Color.gray,Color.green,Color.lightGray,Color.magenta,Color.orange, Color.pink,Color.red,Color.white,Color.yellow}; public void init() { //Ekranda 5 isim g”rlebilecel bir liste ac //ayn ismi birden fazla tekrarlama renkListesi=new List(5,false); renkListesi.addActionListener(this); renkListesi.addItemListener(this); //listeye ekle for(int i=0;i<renkIsmi.length;i++) { renkListesi.add(renkIsmi[i]); } add(renkListesi); } public void actionPerformed(ActionEvent e) { setBackground(C[renkListesi.getSelectedIndex()]); repaint(); } public void itemStateChanged(ItemEvent e) { showStatus(renkListesi.getSelectedItem()+"; indeks : "+ renkListesi.getSelectedIndex()); } } Şekil 1.7.10-1 ListTesti.java programı sonuçların appletviewer da görünümü List sınıfının swing grubundaki paraleli daha gelişmiş bir liste kullanma metodu JList metodudur. Jlist metodu pencereye ilave edilirken direk olarak ilave edilmez, JscrollPane alt pencere programı üzerinden ilave edilir. Aynı zamanda dinleme metodu olarak ListSelectionListener metodu kullanılır. Bu metod java swing kütüphanesi javax.swing.event de tanımlanmıştır. JList metoduyla bir seçim yapıldığı gibi birden fazla seçim yapmakta mümkündür. JList metodunun kurucu metodları : public JList(); public JList(ListModel lm); public JList(Object o[]); public JList(Vector v); dir. Seçimde kullanılan bazı önemli metodları : public int GetSelectedIndex() : seçilen (veya en son seçilen) elemanın indisini verir public int[] getSelectedIndices() : seçilen elemanların (birden fazla olabilir) indislerini boyut üzerinden aktarır public Object getSelectedValue() : son seçilen elemandaki değeri Object olarak aktarır. public object[] getSelectedValues() : seçilen elemanlardaki değerleri boyutlu object olarak aktarır void setSelectionMode(int mode) : tek eleman mı seçileceğini yoksa çok sayıda eleman mı seçileceğini belirler. Girdi int değişkeni ListSelectionModel.SINGLE_SELECTION (tek eleman seçimi) ListSelectionModel .INTERVAL_SELECTION (bir gurup seçimi) ListSelectionModel .MULTIPLE_INTERVAL_SELECTION (birden fazla gurup seçimi) Değerlerinden birini alabilir. Public void setVisibleRowCount(int sayı) : listenin kaç elemanının görüntüleneceğini verir. Listenin kenar kayma çubukları, listenin içinde yer alacağı JScrollPane penceresi tarafından oluşturulur. JScrollPane metodunun kurucu metodları public JScrollPane(); public JScrollPane(int düşeyçubukçeşidi,int yatayçubukçeşidi); public JScrollPane(Component pencere); public JScrollPane(Component pencere ,int düşeyçubukçeşidi,int yatayçubukçeşidi); Buradaki pencere JScrollPane’in içinde yeralacağı container’ı gösterir. Düşeyçubukçeşidi JScrollPane.VERTICAL_SCROLLBAR_ALWAYS : her zaman düşey kaydırma çubuğu tanımla JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED : sadece gerektiği zaman zaman düşey kaydırma çubuğu tanımla JScrollPane.VERTICAL_SCROLLBAR_NEVER : hiçbir zaman düşey kaydırma çubuğu tanımlama Değerlerini alır. Yatayçubukçeşidi ise JScrollPane. HORIZONTAL _SCROLLBAR_ALWAYS : her zaman yatay kaydırma çubuğu tanımla JScrollPane. HORIZONTAL _SCROLLBAR_AS_NEEDED : sadece gerektiği zaman yatay kaydırma çubuğu tanımla JScrollPane. HORIZONTAL _SCROLLBAR_NEVER : hiçbir zaman yatay kaydırma çubuğu tanımlama Değerlerini alır. Birkaç örnek problemle Jlist sınıfını vermetye çalışalım. İlk örnek yukarıdaki JcomboBox problemlerin aynı işlemini yapmaktadır. Listeden yapılan seçime göre JtextField alanındaki fontu değiştirecektir. Listenin iki elemanının görülmesi müsadesi verilmiştir. Liste tek seçimli listedir. Program 1.7.10-2 JListTestiSWF.java, JList sınıfı kullanım test programı import java.awt.*; import javax.swing.*; import java.awt.event.*; import javax.swing.event.*; public class JListTestiSWF extends JFrame implements ListSelectionListener { private JList F; private JTextField T; public JListTestiSWF() { super("JList ve JScrollPane örneği"); Container co=getContentPane(); String Liste[]={"MonoSpaced","SansSerif","Serif"}; F=new JList(Liste); F.setVisibleRowCount(2); F.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); F.setSelectedIndex(0); T=new JTextField((String)F.getSelectedValue()); T.setEditable(false); T.setFont(new Font((String)F.getSelectedValue(),Font.BOLD,12)); F.addListSelectionListener(this); JScrollPane sp=new JScrollPane(F); co.add(sp,BorderLayout.NORTH); co.add(T,BorderLayout.CENTER); } public void valueChanged(ListSelectionEvent e) { T.setFont(new Font((String)F.getSelectedValue(), T.getFont().getStyle(), T.getFont().getSize())); T.setText("Indeks : "+ F.getSelectedIndex()+" Font : "+F.getSelectedValue()); } public static void main(String[] args) { JListTestiSWF pencere= new JListTestiSWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(300,200); pencere.setVisible(true); } } Şekil 1.7.10-2 JListTestiSWF.java programı sonuçların JFrame penceresinde görünümü Bu örnekte ise listeden yapacağımız seçime göre arka plan rengini değiştiriyoruz. Bu program yukarıda verilen List programının oldukça benzeridir. Listede dört elemanın görülmesi izni verilmiştir. Liste tek seçimli bir listedir. Program 1.7.10-3 JlistTesti1SWF.java, JList sınıfı kullanım test programı import javax.swing.*; // java swing sinifini cagir import javax.swing.event.*; import java.awt.*; // java pencere kullanma sinifini cagir import java.awt.event.*; // java pencereyi dinleme sinifini cagir import BasicWindowMonitor; import renk; public class JListTesti1SWF extends JFrame implements ListSelectionListener { // Renk secme ornegi private String renkler[]={"siyah","Mavi","camgöbeği","Koyu Gri","Gri", "Yeşil","Açık gri","mor","Portakal","Pembe","Kırmızı","beyaz","sarı"}; private renk re[]={renk.siyah,renk.mavi,renk.camgobegi,renk.koyugri, renk.gri,renk.yesil,renk.acikgri,renk.mor,renk.portakal,renk.pembe, renk.kirmizi,renk.beyaz,renk.sari}; JList renklistesi; Color r=Color.lightGray; Container c; // pencereyi baslatma metodu public JListTesti1SWF() { super("JListTesti1 renk seçici"); c=getContentPane(); c.setLayout(new FlowLayout()) ; renklistesi=new JList(renkler); renklistesi.setVisibleRowCount(4); renklistesi.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); c.add(new JScrollPane(renklistesi)); renklistesi.addListSelectionListener(this); } // girdi alanindaki olan olaylari dinleme metodu public void valueChanged(ListSelectionEvent e) { r=re[renklistesi.getSelectedIndex()]; if(r==null) r=renk.acikgri; c.setBackground(r); repaint(); } //===================================================== public static void main(String[] args) { JListTesti1SWF pencere= new JListTesti1SWF(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.7.10-3 JlistTesti1SWF.java programı sonuçların JFrame penceresinde görünümü Diğer bir Liste kullanma örneği : Bu örnekte Listeye JtextField üzerinden ilave yapabiliyoruz ve çıkarabiliyoruz. Örnek Java döküman kütüphanesinden alınıp adapte edilmiştir. Program 1.7.10-4 ListDemoSWF.java, JList sınıfı kullanım test programı import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; public class ListDemoSWF extends JFrame implements ListSelectionListener { private JList list; private DefaultListModel listModel; private static final String hireString = "İşe al"; private static final String fireString = "İşten at"; private JButton fireButton; private JTextField employeeName; public ListDemoSWF() { super("ListDemo"); listModel = new DefaultListModel(); listModel.addElement("Turhan Çoban"); listModel.addElement("İrfan Çoban"); listModel.addElement("Birsen Çeliker"); listModel.addElement("Nurhan Erel"); //Listeyi oluştur ve scrollPane'e yerleştir list = new JList(listModel); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); list.addListSelectionListener(this); JScrollPane listScrollPane = new JScrollPane(list); JButton hireButton = new JButton(hireString); hireButton.setActionCommand(hireString); hireButton.addActionListener(new HireListener()); fireButton = new JButton(fireString); fireButton.setActionCommand(fireString); fireButton.addActionListener(new FireListener()); employeeName = new JTextField(10); employeeName.addActionListener(new HireListener()); String name = listModel.getElementAt(list.getSelectedIndex()).toString(); employeeName.setText(name); //Create a panel that uses FlowLayout (the default). JPanel buttonPane = new JPanel(); buttonPane.add(employeeName); buttonPane.add(hireButton); buttonPane.add(fireButton); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(listScrollPane, BorderLayout.CENTER); contentPane.add(buttonPane, BorderLayout.SOUTH); } class FireListener implements ActionListener { public void actionPerformed(ActionEvent e) { //Bu metod hala listede seçilebilecek eleman kalmışsa çağırılır. int index = list.getSelectedIndex(); listModel.remove(index); int size = listModel.getSize(); //Listede eleman kalmadı işten atmayı durdur if (size == 0) { fireButton.setEnabled(false); //seçimi düzenle } else { if (index == listModel.getSize()) index--; list.setSelectedIndex(index); } } } class HireListener implements ActionListener { public void actionPerformed(ActionEvent e) { //Eğer yeni isim girilmemişse if (employeeName.getText().equals("")) { Toolkit.getDefaultToolkit().beep(); return; } int index = list.getSelectedIndex(); int size = listModel.getSize(); if (index == -1 || (index+1 == size)) { listModel.addElement(employeeName.getText()); list.setSelectedIndex(size); } else { listModel.insertElementAt(employeeName.getText(), index+1); list.setSelectedIndex(index+1); } } } public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting() == false) { if (list.getSelectedIndex() == -1) { fireButton.setEnabled(false); employeeName.setText(""); } else { fireButton.setEnabled(true); String name = list.getSelectedValue().toString(); employeeName.setText(name); } } } public static void main(String s[]) { JFrame frame = new ListDemoSWF(); frame.addWindowListener(new BasicWindowMonitor()); frame.pack(); frame.setVisible(true); } } Şekil 1.7.10-4 ListDemoSWF.java programı sonuçların JFrame penceresinde görünümü Listelerin sadece tek seçim değil aynı zamanda birden fazla seçim yapmak içinde kullanıldığından bahsetmiştik. Aşağıdaki örnekte listeden Liste türü değişkeninde yaptığımız değişikliğe göre bir veya birden fazla seçim yapabiliyoruz . Bu program hem JFrame hem de Japplet olarak çalışabilmektedir. Program 1.7.10-5 ListSelectionDemo.java, JList sınıfı kullanım test programı import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import java.util.*; import java.awt.*; import java.awt.event.*; public class ListSelectionDemo extends JApplet { JTextArea output; JList list; JTable table; String newline = "\n"; ListSelectionModel listSelectionModel; private boolean inAnApplet = true; //bazı sistemlerde ana kurucu metod olmayınca hata verebileceği // için tanımlandı. public ListSelectionDemo() { this(true); } public ListSelectionDemo(boolean inAnApplet) { this.inAnApplet = inAnApplet; if (inAnApplet) { getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); } } public void init() { String[] listData = { "bir", "iki", "üç", "dört", "beş", "altı", "yedi" }; String[] columnNames = { "Fransızca", "İngilizce", "Italyanca" }; String[][] tableData = {{"un", "obe", "uno" }, {"deux", "two", "due" }, {"trois", "three", "tre" }, { "quatre", "four", "quattro"}, { "cinq", "five", "cinque" }, { "six", "six", "sei" }, { "sept", "seven", "sette" } }; list = new JList(listData); listSelectionModel = list.getSelectionModel(); listSelectionModel.addListSelectionListener( new SharedListSelectionHandler()); JScrollPane listPane = new JScrollPane(list); table = new JTable(tableData, columnNames); table.setSelectionModel(listSelectionModel); JScrollPane tablePane = new JScrollPane(table); //Kontrol alanını JPAnel olarak oluştur (FlowLayout kullan) JPanel controlPane = new JPanel(); String[] modes = { "SINGLE_SELECTION", "SINGLE_INTERVAL_SELECTION", "MULTIPLE_INTERVAL_SELECTION" }; final JComboBox comboBox = new JComboBox(modes); comboBox.setSelectedIndex(2); comboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String newMode = (String)comboBox.getSelectedItem(); if (newMode.equals("SINGLE_SELECTION")) { listSelectionModel.setSelectionMode( ListSelectionModel.SINGLE_SELECTION); } else if (newMode.equals("SINGLE_INTERVAL_SELECTION")) { listSelectionModel.setSelectionMode( ListSelectionModel.SINGLE_INTERVAL_SELECTION); } else { listSelectionModel.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); } output.append("----------" + "Liste seçim türü: " + newMode + "----------" + newline); } }); controlPane.add(new JLabel("Liste Türü :")); controlPane.add(comboBox); //Çıktı alanı oluştur output = new JTextArea(10, 40); output.setEditable(false); JScrollPane outputPane = new JScrollPane(output, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); //JFrame'i Split pane kullanarak ikiye böl JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); getContentPane().add(splitPane, BorderLayout.CENTER); // JPanel topHalf = new JPanel(); topHalf.setLayout(new BoxLayout(topHalf, BoxLayout.X_AXIS)); JPanel listContainer = new JPanel(new GridLayout(1,1)); listContainer.setBorder(BorderFactory.createTitledBorder( "Türkçe Liste")); listContainer.add(listPane); JPanel tableContainer = new JPanel(new GridLayout(1,1)); tableContainer.setBorder(BorderFactory.createTitledBorder( "Tablo")); tableContainer.add(tablePane); tablePane.setPreferredSize(new Dimension(300, 100)); topHalf.setBorder(BorderFactory.createEmptyBorder(5,5,0,5)); topHalf.add(listContainer); topHalf.add(tableContainer); topHalf.setMinimumSize(new Dimension(400, 50)); topHalf.setPreferredSize(new Dimension(400, 110)); splitPane.add(topHalf); JPanel bottomHalf = new JPanel(new BorderLayout()); bottomHalf.add(controlPane, BorderLayout.NORTH); bottomHalf.add(outputPane, BorderLayout.CENTER); //XXX: the next line is necessary if bottomHalf is a scroll pane: //bottomHalf.setMinimumSize(new Dimension(400, 50)); bottomHalf.setPreferredSize(new Dimension(450, 135)); splitPane.add(bottomHalf); } public static void main(String[] args) { JFrame frame = new JFrame("Listeden seçme örneği"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); ListSelectionDemo listDemo = new ListSelectionDemo(false); listDemo.init(); frame.setContentPane(listDemo); frame.pack(); frame.setVisible(true); } class SharedListSelectionHandler implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { ListSelectionModel lsm = (ListSelectionModel)e.getSource(); int firstIndex = e.getFirstIndex(); int lastIndex = e.getLastIndex(); boolean isAdjusting = e.getValueIsAdjusting(); output.append("Seçilen indeks bölgesi: " + firstIndex + " - " + lastIndex + "; isAdjusting " + isAdjusting + "; Listeden seçilen indeks sayısı:"); if (lsm.isSelectionEmpty()) { output.append(" <none>"); } else { // Find out which indexes are selected. int minIndex = lsm.getMinSelectionIndex(); int maxIndex = lsm.getMaxSelectionIndex(); for (int i = minIndex; i <= maxIndex; i++) { if (lsm.isSelectedIndex(i)) { output.append(" " + i); } } } output.append(newline); } } } Şekil 1.7.310-5 ListSelectionDemo.java programı sonuçların JFrame penceresinde görünümü (not bu program hem applet hem frame olark görüntülenebilir) 1.7.11 SWING JMENU Window türü programlamaya alışık olan herkes menu kullanmaya da alışıktır. Menuler pencerenin tepesinden açılan ve çeşitli görevler yüklenen komponentlerdir. Java swing menu’leri temel olarak JMenuBar, JMenu ve JMenuItem sınıflarından oluşur. Ayrıca menulerde JcheckBoxMenuItem, JradioButtonMenuItem gibi alt elemanlar da bulunabilir. JmenuBar kurucu metodu : Public JmenuBar(); Şeklindedir. Bazı önemli metodları : public JMenu add(JMenu menu); : menu ilave eder public Component getComponent(); public Component getComponentAtIndex(int indeks); public Insets getMargin(); public Jmenu getMenu(int) public int getMenuCount(); public SingleSelectionModel getSelectionModel(); public MenuElement[] getSubElements(); protected void paintBorder(Graphics g); public void processMouseEvent(MouseEvent e,MouseElement path[],MouseSelectionManager mgr); public void setBorderPainted(boolean b); public void setHelpMenu(Jmenu menu); public void setMargin(Insets in); pubic void setSelected(Component c); Jmenu kurucu metodları : public JMenu(); public JMenu(String Label); public JMenu(String label,boolean menudenayır); Bazı önemli JMenu metodları : public JMenuItem add(Action act); public JMenuItem add(JMenuItem item); public Component add(Component c); public void add(String Jlabel); public void addMenuListener(MenuListener l); public void addSeperator(); public JMenuItem getItem(int pos); public int getItemCount(); public Component getMenuComponent(int pos); public int getMenuComponentCount(); public Component[] getMenuComponents(public MenuElement[] getSubElements(); public JMenuItem insert(JMenuItem item,int pos); public void insert(String etiket,int pos); public void remove(int pos); public void remove(MenuItem item); public void removeAll(); public void removeMenuListener(MenuListener l); public void setAccelerator(KeyStroke s); public void setDealy(int delay); public void setMenuLocation(int x,int y); public void setPopUpMenuVisible(boolean b) public void setSelected(boolean b); JMenuItem kurucu metodları : public JMenuItem(); public JMenuItem(Icon resim); public JMenuItem(String Label); public JMenuItem(String Label,int mnemonic); public JMenuItem(String Label,Icon resim); bazı metodları : publci Component getComponent(); public menuElement[] getSubElements(); JCheckBoxMenuItem, JMenuItem sınıfının bir alt sınıfı olarak oluşturulmuştur. Davranışı JCheckBox sınıfı gibidir. Kurucu metodları : public JCheckBoxMenuItem(); public JCheckBoxMenuItem(Icon resim); public JCheckBoxMenuItem(String Label); public JCheckBoxMenuItem(String Label,Icon resim); public JCheckBoxMenuItem(String Label,Boolean seçildimi); public JCheckBoxMenuItem(String Label,Icon resim, Boolean seçildimi); JRadioButtonMenuItem’ da JMenuItem’ın alt sınıfı olarak oluşturulmuştur. Kurucu metodları : public JRadioButtonMenuItem (); public JRadioButtonMenuItem (Icon resim); public JRadioButtonMenuItem (String Label); public JRadioButtonMenuItem (String Label,Icon resim); Şimdi bu metodları kullanan bir örnek menu oluşturalım. Örnek menu sadece menu yapısını göstermek amaçlı olduğundan fazla bir eyem yamamaktadır. Gerçek programlarınızda gerekli eylemleri yereştirebilirsiniz. Program 1.7.11-1 MenuDemo.java, JMenu,JmenuBar,JMenuItem,JCheckBoxMenuItem ve JRadioButtonMenuItem sınıfları kullanım test programı import java.awt.*; import java.awt.event.*; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JCheckBoxMenuItem; import javax.swing.JRadioButtonMenuItem; import javax.swing.ButtonGroup; import javax.swing.JMenuBar; import javax.swing.KeyStroke; import javax.swing.ImageIcon; import javax.swing.JTextArea; import javax.swing.JScrollPane; import javax.swing.JFrame; /* * Menu Demo */ public class MenuDemo extends JFrame implements ActionListener, ItemListener { JTextArea output; JScrollPane scrollPane; String newline = "\n"; public MenuDemo() { JMenuBar menuBar; JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; addWindowListener(new BasicWindowMonitor()); //Add regular components to the window, using the default BorderLayout. Container contentPane = getContentPane(); output = new JTextArea(5, 30); output.setEditable(false); scrollPane = new JScrollPane(output); contentPane.add(scrollPane, BorderLayout.CENTER); //Create the menu bar. menuBar = new JMenuBar(); setJMenuBar(menuBar); //Build the first menu. menu = new JMenu("Menu Listesi"); menu.setMnemonic('M'); menu.getAccessibleContext().setAccessibleDescription( "Programdaki sadece bu Menunun alt listeleri mevcuttur"); menuBar.add(menu); //a group of JMenuItems menuItem = new JMenuItem("Sadece yazı olan bir menu elemanı", KeyEvent.VK_T); menuItem.setMnemonic('S'); //used constructor instead menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_1, ActionEvent.ALT_MASK)); menuItem.getAccessibleContext().setAccessibleDescription( "Bu sadece bir örnek olduğundan bu eleman bir şey yapmıyor"); menuItem.addActionListener(this); menu.add(menuItem); menuItem = new JMenuItem("Yazı ve resim", new ImageIcon("images/middle.gif")); menuItem.setMnemonic(KeyEvent.VK_B); menuItem.addActionListener(this); menu.add(menuItem); menuItem = new JMenuItem(new ImageIcon("images/middle.gif")); menuItem.setMnemonic('d'); menuItem.addActionListener(this); menu.add(menuItem); //a group of radio button menu items menu.addSeparator(); ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("radio düğmesi menu elemanı"); rbMenuItem.setSelected(true); rbMenuItem.setMnemonic('r'); group.add(rbMenuItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("ikinci bir radyo düğmesi"); rbMenuItem.setMnemonic('i'); group.add(rbMenuItem); rbMenuItem.addActionListener(this); menu.add(rbMenuItem); //a group of check box menu items menu.addSeparator(); cbMenuItem = new JCheckBoxMenuItem("check box menu elemanı"); cbMenuItem.setMnemonic('c'); cbMenuItem.addItemListener(this); menu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("ikinci bir check box menu elemanı"); cbMenuItem.setMnemonic('k'); cbMenuItem.addItemListener(this); menu.add(cbMenuItem); //a submenu menu.addSeparator(); submenu = new JMenu("Alt menu"); submenu.setMnemonic('A'); menuItem = new JMenuItem("Alt menude bir eleman"); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK)); menuItem.addActionListener(this); submenu.add(menuItem); menuItem = new JMenuItem("Alt menude ikinci bir eleman"); menuItem.addActionListener(this); submenu.add(menuItem); menu.add(submenu); //Build second menu in the menu bar. menu = new JMenu("İknci bir Menu"); menu.setMnemonic('n'); menu.getAccessibleContext().setAccessibleDescription( "Bu menu hiç bir şey yapmaz ve alt elemanı yoktur"); menuBar.add(menu); } public void actionPerformed(ActionEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); String s = "Action event kaydedildi" + newline + " Event kaynağı: " + source.getText() + " (sınıfın adı " + getClassName(source) + ")"; output.append(s + newline); } public void itemStateChanged(ItemEvent e) { JMenuItem source = (JMenuItem)(e.getSource()); String s = "Item event kaydedildi." + newline + " Event kaynağı: " + source.getText() + " (sınıfın adı " + getClassName(source) + ")" + newline + " New state: " + ((e.getStateChange() == ItemEvent.SELECTED) ? "seçildi":"seçim iptal edildi"); output.append(s + newline); } // Sınıfın adını verir protected String getClassName(Object o) { String classString = o.getClass().getName(); int dotIndex = classString.lastIndexOf("."); return classString.substring(dotIndex+1); } public static void main(String[] args) { MenuDemo window = new MenuDemo(); window.setTitle("MenuDemo"); window.setSize(450, 260); window.setVisible(true); } } Şekil 1.7.11-1 MenuDemo.java programı sonuçların JFrame penceresinde görünümü 1.7.12 SWING JSLIDER SINIFI VE JPANEL TEMEL ÇİZİM ELEMANI (PANELİ) JSlider sınıfı bir değişkenin değerini verilen sınırlar içerisinde değiştirmeye yarayan bir grafik kullanıcı arayüz sınıfıdır. JSlider sınıfının kurucu metodları : public JSlider(); public JSlider(BoundedRAngeModel brm); public JSlider(int konum); public JSlider(int minimumdeğer, int maksimumdeğer); Program 1.7.12-1 ovalPanelSWP.java, JPanel sınıfı import javax.swing.*; import java.awt.*; import yildizSW; import java.awt.geom.*; import renk; public class ovalPanelSWP extends JPanel { int xi,yi,yaricap; public ovalPanelSWP(int xi1, int yi1,int yaricap1) { xi=xi1; yi=yi1; yaricap=(yaricap1 >= 0 ? yaricap1:10); } public void setOvalPanelSWP(int xi1, int yi1,int yaricap1) { xi=xi1; yi=yi1; yaricap=(yaricap1 >= 0 ? yaricap1:10); repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(renk.mavi); Graphics2D g2=(Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Ellipse2D elips1=new Ellipse2D.Double(xi,yi,yaricap,yaricap); g2.draw(elips1); } } Program 1.7.12-2 ovalPanelTestSWP_2000.java, JSlider sınıfı test program import javax.swing.*; // java swing sinifini cagir import java.awt.*; // java pencere kullanma sinifini cagir import java.awt.event.*; // java pencereyi dinleme sinifini cagir import BasicWindowMonitor; import ovalPanelSWP; import javax.swing.event.*; public class ovalTestSWF_2000 extends JFrame implements ChangeListener { // Renk secme ornegi private ovalPanelSWP p; private JSlider cap; Color r=Color.lightGray; Container c; // pencereyi baslatma metodu public ovalTestSWF_2000() { super("JSlider Testi"); c=getContentPane(); p=new ovalPanelSWP(30,30,30); cap=new JSlider(SwingConstants.HORIZONTAL,0,200,10); cap.setMajorTickSpacing(20); cap.setPaintTicks(true); cap.setPaintLabels(true); cap.addChangeListener(this); c.add(p,BorderLayout.CENTER); c.add(cap,BorderLayout.SOUTH); } // girdi alanindaki olan olaylari dinleme metodu public void stateChanged(ChangeEvent e) { p.setOvalPanelSWP(30, 30,cap.getValue()); repaint(); } //===================================================== public static void main(String[] args) { ovalTestSWF_2000 pencere= new ovalTestSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.7.12-1 ovalPanelTestSWP_2000.java programı sonuçların JFrame penceresinde görünümü Bu programda uyguladığımız bir çizim şekline daha detaylı göz atalım. Daire JPanel sınıfında çizilmiştir. Daireyi çizmek için ovalPanelSWP sınıfını yarattık. JPanel sınıfında kurucu metodlarımızı herhangi bir sınıfta olduğu gibi tanımladık ve public void paintComponent(Graphics g) metodu ve Graphics sınıfı üzerinden çizimimizi tanımladık. Tekrar çizdirmek için repaint() metodunu kullandık. İkinci JFrame proramımızda private ovalPanelSWP p; p=new ovalPanelSWP(30,30,30); Container c; c=getContentPane(); c.add(p,BorderLayout.CENTER); komutlarını kullanarak panelimizi ana panele monte ettik. StateChanged event metodundaki p.setOvalPanelSWP(30, 30,cap.getValue()); komutuyla da çapını değiştirip repaint(); komutuyla tekrar çizdirdik. Panel programında g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); komutu kullanıldığından dairenin oldukça düzgün çizilmiş olduğuna dikkatinizi çekeriz. 1.7.13 FLOWLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI Grafik arayüz programlarının daha düzgün bir şekilde gösterilmesi amacıyla Layout sınıfları kullanılır. awt grafik interface’inde default değer olarak kullanılan Layout sınıfı FlowLayout sınıfıdır. Swing arayüz programlarında ise BorderLayout sınıfı default olarak kullanılar. Flow layout sınıfı grafik ortamına (Panel, Applet, Frame, Jpanel, Japplet, JFrame vs.) alt elemanları yerleştirirken soldan sağa doğru akleme (add) sırasıyla yerleştirir. Penceredeki yer bittiyse bir alt satıra geçer. Kurucu metotu şu şekillerde tanımlanır : public Flowlayout() public Flowlayout(int formatbolgesi) format bölgesi değişkeni FlowLayout.RIGHT, FlowLayout.CENTER veya FlowLayout.LEFT değerlerini alabilir. Bu değerlere göre içerdiği elemanları sağa ortaya veya sola yerleştirir. public Flowlayout(int formatbolgesi,int yatay_bosluk,int dikey_bosluk); formatbolgesi FlowLayout.RIGHT, FlowLayout.CENTER veya FlowLayout.LEFT değerlerini alabilir. Yatay_bosluk pixel olarak yatay posisyonda elemanlar arasında kalan boslugu gosterir. Dikey bosluk ise dikey dogrultudaki pixel olarak boşluktur. Küçuk bir örnek problemle FlowLayout kullanımını daha açık hale getirebiliriz. Program 1.7.13-1 : FlowLayout.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class FlowLayoutTesti extends Applet implements ActionListener { private Button B[]; public void init() { B=new Button[3]; B[0]=new Button("Sol"); B[1]=new Button("Orta"); B[2]=new Button("Sag"); for(int i=0;i<B.length;i++) { B[i].addActionListener(this); add(B[i]); } } public void actionPerformed(ActionEvent e) { int pozisyon=FlowLayout.LEFT;; if(e.getSource()==B[0]) { pozisyon=FlowLayout.LEFT; } else if(e.getSource()==B[1]) { pozisyon=FlowLayout.CENTER; } else if(e.getSource()==B[2]) { pozisyon=FlowLayout.RIGHT; } setLayout(new FlowLayout(pozisyon)); validate(); } } Şekil 1.7.13-1 FlowLayout sınıfı ve sonuçlarının Appletde görülmesi Aynı programın bir de swing JFrame versiyonunu inceleyelim. Program 1.7.13-2 : FlowLayoutTestiSWF_2000.java programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class FlowLayoutTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private Container c; public FlowLayoutTestiSWF_2000() { super("Flow Layout formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new FlowLayout()); B=new JButton[3]; B[0]=new JButton("Sol"); B[1]=new JButton("Orta"); B[2]=new JButton("Sağ"); for(int i=0;i<B.length;i++) { B[i].addActionListener(this); c.add(B[i]); } } public void actionPerformed(ActionEvent e) { int pozisyon=FlowLayout.LEFT;; if(e.getSource()==B[0]) { pozisyon=FlowLayout.LEFT; } else if(e.getSource()==B[1]) { pozisyon=FlowLayout.CENTER; } else if(e.getSource()==B[2]) { pozisyon=FlowLayout.RIGHT; } c.setLayout(new FlowLayout(pozisyon)); c.validate(); } public static void main(String[] args) { FlowLayoutTestiSWF_2000 pencere= new FlowLayoutTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(350,200); pencere.setVisible(true); } } Şekil 1.7.13-3 FlowLayout sınıfı ve sonuçlarının JFrame penceresinde görülmesi 1.7.14 BORDERLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI BorderLayout sınıfı GUI elemanlarını beş bolgeye ayırarak guruplar, kuzey(NORTH), güney(SOUTH), dogu(EAST),Batı(WEST),orta(CENTER), Kuzey Appletin üst ısmı anlamına gelir. Bu sınıf swing grafik kütüphanesinde default formatlama sınıfı olarak seçilmiştir. BorderLayout sınıfının kurucu metotları şunlardır : public BorderLayout() public BorderLayout(int yatay_bosluk,int dikey_bosluk); yatay_bosluk ve dikey_basluk pixel olarak alınır. GUI elemanlarının arasındaki bosluk miktarını tanımlar. Şimdi bir örnekle sınıfı açıklamaya çalışalım. Program 1.7.14-1 : BorderLayoutTesti.java Programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class BorderLayoutTesti extends Applet implements ActionListener { private Button B[]; private String S[]={"Kuzeyi Gizle","Guneyi Gizle","Doguyu Gizle", "Batiyi Gizle","Ortayi Gizle"}; public void init() { setLayout(new BorderLayout(5,5)); B=new Button[5]; for(int i=0;i<B.length;i++) { B[i]=new Button(S[i]); B[i].addActionListener(this); } add(B[0],BorderLayout.NORTH); add(B[1],BorderLayout.SOUTH); add(B[2],BorderLayout.EAST); add(B[3],BorderLayout.WEST); add(B[4],BorderLayout.CENTER); } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setVisible(false); else B[i].setVisible(true); } validate(); } } Şekil 1.7.14-1 BorderLayoutTesti.java programının sonuçlarının applette görulmesi Program 1.7.14-2 : BorderLayoutTestiSWF_2000.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class BorderLayoutTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private String S[]={"Kuzeyi Gizle","Güneyi Gizle","Doğuyu Gizle", "Batıyı Gizle","Ortayı Gizle"}; private Container c; public BorderLayoutTestiSWF_2000() { super("Border Layout formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[5]; for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); } c.add(B[0],BorderLayout.NORTH); c.add(B[1],BorderLayout.SOUTH); c.add(B[2],BorderLayout.EAST); c.add(B[3],BorderLayout.WEST); c.add(B[4],BorderLayout.CENTER); } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setVisible(false); else B[i].setVisible(true); } c.validate(); } public static void main(String[] args) { BorderLayoutTestiSWF_2000 pencere= new BorderLayoutTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,200); pencere.setVisible(true); } } Şekil 1.7.14-2 BorderLayoutTestiSWF_2000.java programının sonuçlarının JFrame penceresinde görulmesi 1.7.15 GRIDLAYOUT SINIFI KULLANARAK GRAFİK ARAYÜZ FORMATLANMASI GridLayout sınıfı pencereyi (Applet,Japplet,Panel,JPAnel,Frame,JFrame vs.) eşit boyutta gridlere böler ve her grid elemanının içine bir GUI yerleştirilebilmesine olanak sağlar. GridLayout sınıfının kurucu metotları şöyledir : public GridLayout(int satırlar,int sütunlar) publicGridLayout(int satırlar,int sütunlar,int yatay_bosluk,int dikey_bosluk); yatay_bosluk ve dikey_basluk pixel olarak alınır. GUI elemanlarının arasındaki bosluk miktarını tanımlar. Şimdi bir örneklerle bu sınıfı açıklamaya çalışalım. Program 1.7.15-1 GridLayoutTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class GridLayoutTesti extends Applet { private Button B[]; private String S[]={"1","2","3", "4","5","6"}; public void init() { setLayout(new GridLayout(3,2,5,5)); B=new Button[6]; for(int i=0;i<B.length;i++) { B[i]=new Button(S[i]); add(B[i]); } } } Şekil 1.7.15-1 GridLayoutTesti.java programı sonuçlarının applette görulmesi Programın birde JFrame eşdeğerini inceleyelim. Program 1.7.15-2 : GridLayoutTestiSWF_2000.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class GridLayoutTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private String S[]={"Düğme 1","Düğme 2","Düğme 3", "Düğme 4","Düğme 5","Düğme 6"}; private Container c; public GridLayoutTestiSWF_2000() { super("Grid Layout formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new GridLayout(3,2,5,5)); B=new JButton[6]; for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); c.add(B[i]); } } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setVisible(false); else B[i].setVisible(true); } c.validate(); } public static void main(String[] args) { GridLayoutTestiSWF_2000 pencere= new GridLayoutTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,200); pencere.setVisible(true); } } Şekil 1.7.15-2 GridLayoutTestiSWF_2000.java programı sonuçlarının JFRame’de görülmesi 1.7.16 JTABBEDPANE SINIFI KULLANILARAK FORMATLAMA JTabbedPane sadece swing sınıfında kullanılabilir. Değişik sayfalar halinde bir grafik arayüzü çağırır. Bu sayfalardan istenilen seçilerek kullanılabilir. Her sayfa bağımsız bir grafik ortamı oluşturur. Program 1.7.16-1 : JTabbedPaneTestiSWF_2000.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JTabbedPaneTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private String S[]={"Düğme 1","Düğme 2","Düğme 3", "Düğme 4","Düğme 5","Düğme 6"}; private Container c; public JTabbedPaneTestiSWF_2000() { super("JTabbedPane formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[6]; JTabbedPane jtp=new JTabbedPane(); for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); jtp.addTab(S[i],B[i]); } c.add(jtp); } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setText(S[i]+" düğmeye basıldı"); else B[i].setText(S[i]); } c.validate(); } public static void main(String[] args) { JTabbedPaneTestiSWF_2000 pencere= new JTabbedPaneTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,200); pencere.setVisible(true); } } Şekil 1.7.16-1 JTabbedPaneTestiSWF_2000.java programı sonuçlarının JFrame’de görülmesi 1.7.17 JSPLITPANE SINIFI KULLANILARAK GRAFİK ARAYÜZ FORMATLAMA JSplitPane ekranı ikiye böler. Bu ikiye bölme işlemlerini yineleyerek istediğimiz alt parçaları oluşturabiliriz. JSplitPane ile bölünen alt parçalar fare ile çekilerek büyütülüp küçültülebilir. Örnek problemdeki c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[4]; jsp=new JSplitPane[3]; for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); } jsp[0]=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,B[0],B[1]); jsp[1]=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,B[2],B[3]); jsp[2]=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,jsp[0],jsp[1]); c.add(jsp[2]); kod parçacığında ekranı önce B[0] ve B[1] düğmelerini yerleştirdiğimimiz yatay iki parçaya, sonra B[2] ve B[3] düğmelerini yerleştirdiğimz iki yatay parçaya böldükten sonra bu parçaları (jsp[0] ve jsp[1]) iki düşey parçaya ayırıyoruz. Böylece birbirinden bağımsız dört ayrı alt parça (split) oluşturuyoruz. Program 1.7.17-1 : JSplitPaneTestiSWF_2000.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JSplitPaneTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private String S[]={"Düğme 1","Düğme 2","Düğme 3","Düğme 4"}; private Container c; JSplitPane jsp[]; public JSplitPaneTestiSWF_2000() { super("JSplitPane formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[4]; jsp=new JSplitPane[3]; for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); } jsp[0]=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,B[0],B[1]); jsp[1]=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,B[2],B[3]); jsp[2]=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,jsp[0],jsp[1]); c.add(jsp[2]); } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setText(S[i]+" düğmeye basıldı"); else B[i].setText(S[i]); } c.validate(); } public static void main(String[] args) { JSplitPaneTestiSWF_2000 pencere= new JSplitPaneTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,200); pencere.setVisible(true); } } Şekil 1.7.17-1 JSplitPaneTestiSWF_2000.java programı sonuçlarının JFrame’de görülmesi 1.7.18 JSCROLLPANE SINIFI KULLANILARAK GRAFİK ARAYÜZ FORMATLAMA JscrollPane sınıfını Jlist sınıfını incelerken görmüştük. Bu formatlama sınıfı Scrollbar adını verdiğimiz yatay ve düşey kaydırma çubukları yardımıyla küçük bir pencereye sığmayacak kadar büyükolan grafiklerin kullanılmasını sağlar. Program 1.7.18-1 : JScrollPaneTestiSWF_2000.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class JScrollPaneTestiSWF_2000 extends JFrame implements ActionListener { private JButton B[]; private String S[]={"Düğme 1","Düğme 2","Düğme 3","Düğme 4", "Düğme 5","Düğme 6","Düğme 7","Düğme 8","Düğme 9","Düğme 10","Düğme 11", "Düğme 12","Düğme 13","Düğme 14","Düğme 15","Düğme 16"}; private Container c; JScrollPane jscroll; JPanel jsp; public JScrollPaneTestiSWF_2000() { super("JScrollPane formatlama Grafik ara yüz (GUI) testi"); c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[16]; jsp=new JPanel(); for(int i=0;i<B.length;i++) { B[i]=new JButton(S[i]); B[i].addActionListener(this); jsp.add(B[i]); } jscroll=new JScrollPane(jsp); c.add(jscroll,BorderLayout.CENTER); } public void actionPerformed(ActionEvent e) { for(int i=0;i<B.length;i++) { if(e.getSource()==B[i]) B[i].setText(S[i]+" düğmeye basıldı"); else B[i].setText(S[i]); } c.validate(); } public static void main(String[] args) { JScrollPaneTestiSWF_2000 pencere= new JScrollPaneTestiSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,200); pencere.setVisible(true); } } Şekil 1.7.18-1 JScrollPaneTestiSWF_2000.java programı sonuçlarının JFrame’de görülmesi 1.7.19 PANEL VE JPANEL SINIFI Daha kompleks formatlamalara gereksinme duyulduğunda panel sınıfını kullanabiliriz. Panel sınıfı applete yerleştirebileceğimiz alt bolgeler oluşturur. Hemen bir ornekle paneli nasıl kulandığımızı açıklamaya çalışalım. Program 1.7.19-1 PanelTesti.java programı import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Paneltesti extends Applet { private Panel buttonPanel; private Button buttons[]; public void init() { buttonPanel=new Panel(); buttons=new Button[5]; buttonPanel.setLayout(new GridLayout(1,buttons.length)); for(int i=0;i<buttons.length;i++) { buttons[i]=new Button("Button "+(i+1)); buttonPanel.add(buttons[i]); } setLayout(new BorderLayout()); add(buttonPanel,BorderLayout.SOUTH); } } Şekil 1.7.19-1 PanelTesti.java programı ve sonuçlarının applette görulmesi JPanel sınıfını daha önce çeşitli alıştırmalarda zaten kullanmıştık. JPanel’i formatlama işleminde aynı Panel sınıfında olduğu gibi bir alt formatlama elemanı olarak kullanabiliriz. Zaten bütün swing programlarının temeli de JPanel sınıfıdır. Swing gurubunda bir üstteki problemin aynısını JApplet olarak yineledik. Awt penceresi ve swing penceresi arasındaki en önemli farkın awt de add terimini appletin bir alt terimi gibi kullanabilirken, swingde getContentPane() deyimiyle ana JPanel’i çağırmak ve çizimleri bunun üzerine yapmak olduğunu bir kere daha yineleyelim. Program 1.7.19-2 : PanelTestiSWA.java Programı import javax.swing.*; import java.awt.*; import java.awt.event.*; public class PaneltestiSWA extends JApplet { private JPanel buttonPanel; private JButton buttons[]; public void init() { buttonPanel=new JPanel(); buttons=new JButton[5]; buttonPanel.setLayout(new GridLayout(1,buttons.length)); for(int i=0;i<buttons.length;i++) { buttons[i]=new JButton("Düğme "+(i+1)); buttonPanel.add(buttons[i]); } Container c=getContentPane(); c.setLayout(new BorderLayout()); c.add(buttonPanel,BorderLayout.SOUTH); } } Şekil 1.7.19-2 PanelTestiSWA.java programı ve sonuçlarının JAppletde appletviewer ile görulmesi Şu ana kadarki format örneklerinde anlatımı basitleştirmek amacıyla hep düğmeler (button) kullandık. Şimdi de başka bir problemde Panel sınıfının kullanılmasına bakalım : Program 1.7.19-3 : PolinomunKokleri.java programı import java.awt.*; import java.applet.Applet; import java.awt.event.*; public class PolinomunKokleri extends Applet implements ActionListener { // polinom a*x^2+b*x+c=0 private Panel YaziPaneli; Label prompt1; Label prompt2; Label prompta; TextField inputa; // Label promptb; // TextField inputb; // Label promptc; // TextField inputc; // double a,b,c; //polinomun katsayilari double delta=0.0; //determinant double x1,x2; //kokler public void init() { setBackground(Color.lightGray); YaziPaneli=new Panel(); YaziPaneli.setFont(new Font("Serif",Font.BOLD,12)); YaziPaneli.setLayout( new GridLayout(4,2) ); prompt1=new Label("a*x^2+b*x+c = 0"); prompt2=new Label("Polinomunun kokleri"); prompta=new Label(" a : "); inputa =new TextField(5); inputa.addActionListener(this); promptb=new Label(" b : "); inputb =new TextField(5); inputb.addActionListener(this); promptc=new Label(" c : "); inputc =new TextField(5); inputc.addActionListener(this); YaziPaneli.add(prompt1); YaziPaneli.add(prompt2); YaziPaneli.add(prompta); YaziPaneli.add(inputa); YaziPaneli.add(promptb); YaziPaneli.add(inputb); YaziPaneli.add(promptc); YaziPaneli.add(inputc); add(YaziPaneli); } public void paint(Graphics g) { g.setColor(Color.blue); g.setFont(new Font("Serif",Font.BOLD,14)); g.drawString("Polinomun Kokleri: ",70,175); g.setColor(Color.black); g.setFont(new Font("Serif",Font.BOLD,12)); if(delta<0) { g.drawString("Kok 1 :"+(-b/2.0/a)+"+ i* "+Math.sqrt(- delta)/2.0/a,100,190 ); g.drawString("Kok 2 :"+(-b/2.0/a)+"- i* "+Math.sqrt(-delta)/2.0/a,100,205); } if(delta==0) { g.drawString("Kok 1 :"+(-b/2.0/a),100,190 ); g.drawString("Kok 2 :"+(-b/2.0/a),100,205 ); } if(delta0) { x1=-b/2.0/a+Math.sqrt(delta)/20/a; x2=-b/2.0/a-Math.sqrt(delta)/2.0/a; g.drawString("Kok 1 :"+x1,100,190 ); g.drawString("Kok 2 :"+x2,100,205); } } public void actionPerformed( ActionEvent e) { Double sayi1=new Double(inputa.getText() ); Double sayi2=new Double(inputb.getText() ); Double sayi3=new Double(inputc.getText() ); a=sayi1.doubleValue(); b=sayi2.doubleValue(); c=sayi3.doubleValue(); delta=b*b-4.0*a*c; repaint(); } } Şekil 1.7.19-3 İkinci dereceden denklemin koklerini hesaplayan PolinomunKokleri.java programı ve sonuçlarının applette görulmesi Şimdi aynı problemi JPanel kullanarak Japplet içinde gerçekleştirelim. Program 1.7.19-4 : PolinomunKokleriSWA.java programı import java.awt.*; import javax.swing.*; import java.awt.event.*; public class PolinomunKokleriSWA extends JApplet implements ActionListener { // polinom a*x^2+b*x+c=0 private JPanel YaziPaneli; JLabel prompt1; JLabel prompt2; JLabel prompta; JTextField inputa; // JLabel promptb; // JTextField inputb; // JLabel promptc; // JTextField inputc; // JTextArea cikti; double a,b,c; //polinomun katsayilari double delta=0.0; //determinant double x1,x2; //kokler public void init() { Container c=getContentPane(); cikti=new JTextArea(); cikti.setBackground(c.getBackground()); setBackground(Color.lightGray); YaziPaneli=new JPanel(); YaziPaneli.setFont(new Font("Serif",Font.BOLD,12)); YaziPaneli.setLayout( new GridLayout(4,2) ); prompt1=new JLabel("a*x^2+b*x+c = 0"); prompt2=new JLabel("Polinomunun kokleri"); prompta=new JLabel(" a : "); inputa =new JTextField(); inputa.addActionListener(this); promptb=new JLabel(" b : "); inputb =new JTextField(); inputb.addActionListener(this); promptc=new JLabel(" c : "); inputc =new JTextField(); inputc.addActionListener(this); YaziPaneli.add(prompt1); YaziPaneli.add(prompt2); YaziPaneli.add(prompta); YaziPaneli.add(inputa); YaziPaneli.add(promptb); YaziPaneli.add(inputb); YaziPaneli.add(promptc); YaziPaneli.add(inputc); c.add(YaziPaneli,BorderLayout.NORTH); c.add(cikti,BorderLayout.CENTER); } public String toString() { String s=""; s=s+"Polinomun Kokleri: \n"; if(delta<0) { s+= "Kok 1 :"+(-b/2.0/a)+"+ i* "+Math.sqrt(- delta)/2.0/a+"\n"; s+= "Kok 2 :"+(-b/2.0/a)+"- i* "+Math.sqrt(-delta)/2.0/a+"\n"; } if(delta==0) { s+= "Kok 1 :"+(-b/2.0/a)+"\n"; s+= "Kok 2 :"+(-b/2.0/a)+"\n"; } if(delta>0) { x1=-b/2.0/a+Math.sqrt(delta)/20/a; x2=-b/2.0/a-Math.sqrt(delta)/2.0/a; s+= "Kok 1 :"+x1+"\n"; s+= "Kok 2 :"+x2+"\n"; } return s; } public void actionPerformed( ActionEvent e) { Double sayi1=new Double(inputa.getText() ); Double sayi2=new Double(inputb.getText() ); Double sayi3=new Double(inputc.getText() ); a=sayi1.doubleValue(); b=sayi2.doubleValue(); c=sayi3.doubleValue(); delta=b*b-4.0*a*c; cikti.setText(toString()); repaint(); } } Şekil 1.7.19-4 İkinci dereceden denklemin koklerini hesaplayan PolinomunKokleriSWA.java programı ve sonuçlarının applette görulmesi 1.7.20 JOPTIONPANE SINIFI Şu ana kadar gördüğümüz sınıflar grafik arayüzü dizaynı yapmaya yarayan sınıflardı. Java swing gurubunda aynı zamanda kullanılmaya hazır bir çok grafik arayüzleri tanımlanmıştır. Bunların en çok kullanılanı, ve bu kitapta da şu ana kadar yoğun olarak kullanageldiğimiz JOPtionPane sınıfıdır. Bu sınıfın ana gayesi pop-up mesaj ve girdi ortamı sağlamaktır. JoptionPane sınıfını programımızda kurucu metod kullanarak kurmamız gerekmez. Temel olarak direk statik metodlarını çağırırız. JoptionPane panelinde genellikle bir resim,bir yazı alanı, bir girdi alanı (JtextField alanı), birde Seçilebilen düğmeler bulunur. JoptionPane’in girdi/çıktı olarak kullanılabilen başlıca metodları şunlardır : public static String showInputDialog(Object mesaj) public static String showInputDialog(Component anapencere,Object mesaj) public static String showInputDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü) public static String showInputDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü, Icon resim, Object[] listeseçmedeğerleri, Object girişdeğeri) public static String showInternalInputDialog(Component anapencere,Object mesaj) public static String showInternalInputDialog(Component anapencere,Object mesaj, String başlık,int mesajtürü) public static String showInternalInputDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü, Icon resim, Object[] listeseçme değerleri,, Object girişdeğeri) public static void showMessageDialog(Component anapencere,Object mesaj); public static void showMessageDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü); public static void showMessageDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü, Icon resim); public static void showInternalMessageDialog(Component anapencere,Object mesaj); public static void showInternalMessageDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü); public static void showInternalMessageDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü, Icon resim); public static int showConfirmDialog(Component anapencere,Object mesaj); public static int showConfirmDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü); public static int showConfirmDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü); public static int showConfirmDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü,Icon resim); public static int showInternalConfirmDialog(Component anapencere,Object mesaj); public static int showInternalConfirmDialog(Component anapencere,Object mesaj,String başlık,int mesajtürü); public static int showInternalConfirmDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü); public static int showInternalConfirmDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü,Icon resim); public static int showOptionDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü,Icon resim, Object[] listeseçmedeğerleri,Object listedekiilkdeğer); public static int showInternalOptionDialog(Component anapencere,Object mesaj,String başlık,int opsiyontürü,int mesajtürü,Icon resim, Object[] listeseçmedeğerleri,Object listedekiilkdeğer); mesajtürü değişkeni (int) alabildiği değerler şunlardır : JOptionPane.ERROR_MESSAGE JOptionPane.INFORMATION_MESSAGE JOptionPane.PLAIN_MESSAGE JOptionPane.QUESTION_MESSAGE JOptionPane.WARNING_MESSAGE Opsiyon türü değişkeni JOptionPane.DEFAULT_OPTION : Sadece OK düğmesi verir JOptionPane.OK_CANCEL_OPTION : Ok ve Cancel(iptal et) düğmesi verir JOptionPane.YES_NO_CANCEL_OPTION : “Yes (evet) ve No(hayır) ve Cancel(İptal et) düğmeleri verir JOptionPane.YES_NO_OPTION : “Yes (evet) ve No(hayır) düğmeleri verir OptionDialog kullanıldığında Metod bir integer değer gönderir JOptionPane.CANCEL_OPTION JOptionPane.CLOSED_OPTION JOptionPane.NO_OPTION JOptionPane.OK_OPTION JOptionPane.YES_OPTION JOptionPane.UNINITILIZED_VALUE dur. Program 1.7.20-1 : JoptionPane1.java Programı import javax.swing.*; import java.awt.*; public class JOptionPane1 { public static void main(String[] args) { Object[] o=new Object[]{"Turhan","Meral","İrfan","Hatice","Osman", "Nurhan","Birsen","Ali","Veli","Mustafa","Ahmet","Mehmet","Ayhan"}; ImageIcon resim=new ImageIcon("images/Kuş.gif"); JOptionPane.showInputDialog(null,"Lütfen bir isim seçin : ", "JOptionPane örnek 1",JOptionPane.QUESTION_MESSAGE,resim,o,"Turhan"); System.exit(0); } } Şekil 1.7.20-1 JoptionPane1.java programı sonucunun JoptionPane çıktısında görülmesi 1.7.21 SWING, JCOLORCHOOSER SINIFI JcolorChooser’da JoptionPane gibi kullanılmaya hazır bir dialog sınıfıdır. Renk seçmeye yarar ve renk seçilmesi gereken her yerde kullanılabilir. Bir önceki bölümdeki bir alıştırmada bu özelliği kullanmıştık. İkinci bir örnekle pekiştirelim : Program 1.7.21-1 : ColorChooserDemo.java Programı import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.colorchooser.*; public class ColorChooserDemo extends JFrame { public ColorChooserDemo() { super("ColorChooser Renk seçici"); //Pencerenin tepesinde bir JLabel açalım final JLabel etiket = new JLabel("Java Programlama diline Hoş geldiniz!", JLabel.CENTER); etiket.setForeground(Color.yellow); etiket.setBackground(Color.blue); etiket.setOpaque(true); etiket.setFont(new Font("SansSerif", Font.BOLD, 24)); etiket.setPreferredSize(new Dimension(100, 65)); JPanel etiketPaneli = new JPanel(new BorderLayout()); etiketPaneli.add(etiket, BorderLayout.CENTER); etiketPaneli.setBorder(BorderFactory.createTitledBorder("etiket")); //JColorChooser sınıfını çağırıp rengi değiştir final JColorChooser tcc = new JColorChooser(etiket.getForeground()); tcc.getSelectionModel().addChangeListener( new ChangeListener() { public void stateChanged(ChangeEvent e) { Color newColor = tcc.getColor(); etiket.setForeground(newColor); } } ); tcc.setBorder(BorderFactory.createTitledBorder( "Yazı Rengini Seçiniz")); //Add the components to the demo frame Container c = getContentPane(); c.add(etiketPaneli, BorderLayout.CENTER); c.add(tcc, BorderLayout.SOUTH); } public static void main(String[] args) { JFrame frame = new ColorChooserDemo(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.pack(); frame.setVisible(true); } } Şekil 1.7.21-1 ColorChooserDemo.java programı sonucunun JFrame çıktısında görülmesi 1.7.22 JFILECHOOSER SINIFI JFileChooser’da JcolorChooser gibi hazır bir program demetidir. Bilgisayardan bir dosyayı seçme ileminde yararlanılır. Dosya prosesleri konusunda Java Girdi çıktı programlanması bölümüne bakınız. Program 1.7.22-1 : FileChooserDemo.java Programı import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.filechooser.*; public class FileChooserDemo extends JFrame { static private final String newline = System.getProperty("line.separator"); public FileChooserDemo() { super("FileChooser Dosya seçme örneği"); final JTextArea log = new JTextArea(5,20); log.setMargin(new Insets(5,5,5,5)); JScrollPane logScrollPane = new JScrollPane(log); //dosya seçiciyi yarat final JFileChooser fc = new JFileChooser(); //aç düğmesi yarat ImageIcon openIcon = new ImageIcon("images/open.gif"); JButton acmaDugmesi = new JButton("Dosya aç", openIcon); acmaDugmesi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int returnVal = fc.showOpenDialog(FileChooserDemo.this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); //gerçek dosyanın açılma yeri. log.append("Dosya açılıyor: " + file.getName() + "." + newline); } else { log.append("Dosyanın açılması kullanıcı tarafından iptal edildi." + newline); } } }); //kaydet düğmesi yarat ImageIcon saveIcon = new ImageIcon("images/save.gif"); JButton kayıtDugmesi = new JButton("Dosya kaydet", saveIcon); kayıtDugmesi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int returnVal = fc.showSaveDialog(FileChooserDemo.this); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); //gerçek dosyanın kaydedilme yeri.. log.append("Kaydediliyor : " + file.getName() + "." + newline); } else { log.append("Dosyanın kaydedilmesi kullanıcı tarafından iptal edildi" + newline); } } }); //Güzel bir görünüm için aç ve kapa düğmelerini ayrı bir panele yerleştir. JPanel buttonPanel = new JPanel(); buttonPanel.add(acmaDugmesi); buttonPanel.add(kayıtDugmesi); //Düğmeleri pencereye ekle Container c = getContentPane(); c.add(buttonPanel, BorderLayout.NORTH); c.add(logScrollPane, BorderLayout.CENTER); } public static void main(String s[]) { JFrame frame = new FileChooserDemo(); frame.addWindowListener(new BasicWindowMonitor()); frame.pack(); frame.setVisible(true); } } Şekil 1.7.22-1 FileChooserDemo.java programı sonucunun JFrame çıktısında görülmesi Şekil 1.7.22-2 FileChooserDemo.java programı dosya açıcısının JFileChooser çıktısında görülmesi 1.7.23 JAVA JAR (JAVA ARCHIVES - JAVA ARŞİVİ) YAPILARININ KULLANIMI JAR çeşitli sınıf ve ilgili dosyaları bir arada bir pakete dönüştürmek için geliştirilmiş bir teknolojidir. JAR teknolojisi peogramların taşınmasını ve yeniden yüklenmesini daha kolay bir hale getirir. Aynı zamanda JAR dosyasının içindeki elementler sıkıştırılmış halde bulunduklarından daha az yer kaplarlar. Bu yüzden bir JAR dosyasının internet üzerinden aktarılması, açık dosyaların tek tek aktarılmasından daha kısa süren bir prosestir. Yeni JAR dosyalarını oluşturmak için : eğer isim.jar dosyasını oluşturmak ve bu dosyaya isim.class, program1.class ve resim.gif dosyalarını aktarmak istersek : jar cf isim.jar isim.class program1.class resim.gif Alıştırma 5deki H7AL1 örneği için JAR dosyası oluşturmak istersek : jar cf H7AL1.jar H7AL1.class yildiz.class renk.class polar.class komutunu kullanabiliriz. Programi incelediğnizde JAR dosyasının içine ilave edilen tüm sınıfların bu problemle direk olarak ilgili olduğunu görebilirsiniz. jar dosyasının içindeki dosyalara bakmak için : jar tf isim.jar jar dosyası içindeki dosyaların listesini almak için : jar xf isim.jar jar dosyasını applet içinden çalıştırmak için html içinde : <applet code=AppletClassIsmi.class archive="JarDosyasiIsmi.jar" width=width height=height </applet komutu kullanılır. Örnek olarak yine alıştırma 5 de kullanılan jar dosyasının html dosyasını verebiliriz. <HTML <HEAD <TITLE yildiz cizim ornegi</TITLE </HEAD <BODY <H3yildiz cizim ornegi </H3 <applet code=H7AL1.class archive="H7AL1.jar" width=600 height=500 </applet </BODY </HTML Jar komutuyla kullanılan kontrol karakterleri Tablo 1.7.1 de verilmiştir. Tablo 1.7.1 Jar kontrol komut karekterleri ve anlamları c Yeni arşiv yarat f Listedeki ilk ismi arşiv dosyasının ismi olarak tanımla m Listedeki ikinci ismi arşiv dosyasının ismi olarak tanımla t arşiv içeriğini listele x dosyalar arşivden geri çağırılacaktır. eğer listede sadece bir isim varsa bunu jar dosyası olarak alır ve içindeki tüm dosyaları listeler, eğer ilk simden sonra komutta başka isimler yer alıyorsa, sadece bu isimleri (eğer jarda mevcutsa) listeler. 0 sıkıştırma kullanma BÖLÜM 1.8 JAVA GİRDİ - ÇIKTI PROGRAMLANMASI 1.8.1 JAVANIN I/O (GİRDİ ÇIKTI ) KÜTÜPHANESİNDE YER ALAN SINIFLAR VE İNTERFACE’LER Javadaki tüm girdi çıktı programlaması veri akış (stream) kavramına dayanır. Veri akışını bir su akışı veya bir kablolu sistem üzerinden bilgi akışı gibi düşünebiliriz. Javada sadece dosya değil yazıcı, scanner gibi herhangi bir kaynağa veri iletmek istediğimizde bu veri akış sistemini kullanırız. Javada oldukça geniş bir veri akış kütüphanesi bulunmaktadır. java.io kütüphanesinde yer alan girdi çıktı programlama sınıfları şunlardır : InputStream FilterInputStream LineNumberInputStream BufferedInputStream DataInputStream PushbackInputStream ByteArrayInputStream FileInputStream ObjectInputStream PipedInputStream SequenceInputStream StringBufferInputStream OutputStram ByteArrayOutputStream FileOutputStream FilterOutputStream BufferedOutputStream DataOutputStream PrintStream ObjectOutputStream PipedOutputStream ObjectStreamClass StreamTokenizer Reader FileReader BufferedReader LineNumberReader CharArrayReader FilterReader PushbackReader InputStreamReader FileReader PipedReader StringReader Writer BufferedWriter CharArrayWriter FilterWriter OutputStreamWriter PipedWriter PrintWriter StringWriter File FileDescriptor RandomAccessFile Bu sınıfların hepsinin genel görevi javaya girdi sağlamak ve çıktı almaktır. Burada bunlardan bir kısmının işlevlerini ve nasıl çalıştıklarını inceleyeceğiz. Önce temel ana sınıfların bazılarının tanımlarına daha detaylı bakalım. InputStream sınıfı byte türü yazı okuma sınıfıdır. Tüm byte türü bilgi akış kanalı sınıflarının ana sınıfıdır. Tanımı : public abstract class InputStream extends Object { public InputStream(); public int available() throws IOException; public void close() throws IOException; public synchronized void mark(int readlimit); public boolean markSupported(); public abstract int read() throws IOException; public int read(byte b[]) throws IOException; public int read(byte b[],int off,int len) throws IOException; public synchronized void reset() throws IOException; public long skip(long n) throws IOException; } InputStream sınıfının byte türü yazma pareleli olan OutputStream sınıfının tanımı ise : public abstract class OutputStream extends Object { public outputStream(); public void close() throws IOException; public void flush() throws IOException; public abstract void write(int b) throws IOException; public void write(byte b[]) throws IOException; public void write(byte b[],int başlamanoktası,int uzunluk) throws IOException; } Abstract sınıf Reader, InputStream sınıfına olduça yakındır, yalnız data transferinde byte yerine char kullanır, böylece girdi çıktıda unicode stream kullanabilme olasılığı yakalar. public abstract class Reader extends Object { protected Reader(); protected Reader(Object o); public abstract void close() throws IOException; public void mark(int readlimit) throws IOException; public boolean markSupported() ; public abstract int read() throws IOException; public int read(char c[]) throws IOException; public int read(char c[],int başlamanoktası,int uzunluk) throws IOException; public boolean ready() throws IOException; public void reset() throws IOException; public long skip(long n) throws IOException; } Abstract sınıf Writer da Output straem sınıfına eşdeğerdir. Fakat aynı readerda olduğu gibi bu sınıf da veri akışında char ve string kullanır. public abstract class Writer extends Object { public outputStream(); public void close() throws IOException; public void flush() throws IOException; public abstract void write(int b) throws IOException; public void write(char c[]) throws IOException; public void write(char c[],int başlamanoktası,int uzunluk) throws IOException; public void write(String s) throws IOException; public void write(String s,int başlamanoktası,int uzunluk) throws IOException; } Bu sınıflar temel sınıflardır. Bunların altında yer alan çeşitli sınıflara aşağıdaki bölümlerde daha detaylı bakacağız. 1.8.2 FİLE (DOSYA) SINIFI File sınıfı girdi çıktı işlemlerini sağlarken, dosya isimleri ve bulundukları dizin ile ilgili bilgi verir. File sınıfının tanımı : Public class File extends Object implements Serializable, Comparable { public static final String pathSeperator; public static final char pathSeperatorChar; public static final String seperator; public static final char seperatorChar; public File(String dosya_ismi); public File(String dizin_ismi, String dosya_ismi); public File(File file_tipi_nesne,String dosya_ismi); public boolean canRead(); public boolean canWrite(); public boolean compareTo(Object o); public boolean compareTo(File başkabirdosya); public boolean createNewFile(); public static File createTempFile(String isim) throws IOException; public static File createTempFile(String isim,File dosya) throws IOException; public boolean delete(); public void deleteOnExit(); public boolean equals(Object o); public boolean exists(Object o); public File getAbsooluteFile(); public File getAbsoolutePath(); public File getCanonicalFile() throws IOException; public File getCanonicalPath() throws IOException; public String getName(); public String getParent(); public File getParentFile(); public String getPath(); public int hashCode(); public boolean isAbsolute(); public boolean isDirectory(); public boolean isFile(); public boolean isHidden(); public long lastModified(); public long length(); public String[] list(); public String[] list(FilenameFilter filitrefonksiyonu); public static File[] listRoots(); public boolean mkdir(); public boolean mkdirs(); public boolean renameTo(File yeniisim); public boolean setLastModified(long nezaman); public boolean setReadOnly(); public String toString(); public URL toURL() throws MAlformedURLException; } Kurucu metotların çağırılmasına örnek olarak : File f1=new File(“/”); File f2=new File(“/”,”autoexec.bat”); File f3=new File(f1,”autoexec.bat”); tanımlarını verebiliriz. File sınıfında tanımlanmış olan Metotlardan bazılarının tanımları şunlardır. canRead() Tanımlanan dosyadan bilgi okunulabilirliğini test eder. canWrite() Tanımlanan dosyaya bilgi yazılabilirliğini test eder. delete() Dosyayı siler equals(Object) Dosya ismini Object te verilen dosya ismiyle karşılaştırır. exists() Dosyanın mevcut olup olmadığını kontrol eder. getAbsolutePath() Dosyanın tam dizin ismini ve dosya ismini verir( co/java/prog/Hosgeldiniz.java). getName() Dosyanın ismini verir.(Hosgeldiniz.java) getParent() Dosyanın içinde bulunduğu dizinin ismini verir.(prog) getPath() dosyanın ismini ve içinde bulunduğu dizinin ismini verir.(prog/Hosgeldiniz.java) isAbsolute() Dosya isminin mutlak isim olup olmadığını kontrol eder.(Eğer dosya ismi co/java/prog/Hosgeldiniz.java olarak verilmişse true değeri verir.) isDirectory() verilen isimin bir dizin ismi olup olmadığını kontrol eder. isFile() verilen isimin birdosya isimi olup olamdığını kontrol eder. lastModified() Dosyanın en son değiştirildiği tarihi verir length() Dosyanın boyutunu Byte olarak verir. list() Verilen dizinin içindeki dosyaların listesini verir. list(FilenameFiltre) Verilen dizinin içindeki Filtre nesnesindeki tanıma uyan dosyaların listesini verir. mkdir() Yeni bir dizin oluşturur. mkdirs() O anda tanımlı olan dizinin içine bir alt dizin oluşturur. renameTo(File) Dosyanın ismini değiştirir. toString() Dosya ve dizin isimleri topluluğunun String değişkeni eşdeğerini verir. File(dosya) sınfındaki metodlardan da görülebileceği gibi bu sınıf dosyadan okuyup yazma gibi bir işlem yürütmez. File sınıfının temel işlevi girdi çıktı dosyasının adlandırılması ve isimle ilgili fonksiyonlara ulaşılmasıdır. File sınıfının bazı metotlarını ufak bir program içinde kullanalım. Program 1.8.2-1 . FileTestiSW.java programı import java.awt.*; import java.io.File; import java.util.HashMap; import java.awt.event.*; import javax.swing.*; import javax.swing.filechooser.*; import javax.swing.event.*; public class FileTestiSW { public static void main(String args[]) { //önce JFileChooser kullanarak dosyayı seç, sonra dosya özelliklerini göster. File f=new File("Hosgeldiniz.java"); JFileChooser dosyasec=new JFileChooser(); int onay = dosyasec.showOpenDialog(null); //veya kayıt için int onay = dosyasec.showSaveDialog(null); if(onay==JFileChooser.APPROVE_OPTION) { f=dosyasec.getSelectedFile(); } String s=""; s+="Dosya ismi : "+f.getName()+"\n"; s+="Dizin ismi : "+f.getPath()+"\n"; s+="Mutlak Dizin ismi : "+f.getAbsolutePath()+"\n"; s+="Üst Dizin ismi : "+f.getParent()+"\n"; s+=f.exists() ? "Mevcut " : " Mevcut değil "+"\n"; s+=f.canWrite() ? "Yazılabilir " : " Yazılamaz"+"\n"; s+=f.canRead() ? "Okunabilir " : " Okunamaz"+"\n"; s+=f.isDirectory() ? "Dizin " : " Dizin degil"+"\n"; s+=f.isFile() ? "Dosya " : " Dosya degil"+"\n"; s+=f.isAbsolute() ? "Mutlak dizin ismi " : " Mutlak dizin ismi değil"+"\n"; s+="Son Degisiklik : "+f.lastModified()+"\n"; s+="Dosya boyutu : "+f.length()+" Byte"+"\n"; JOptionPane.showMessageDialog(null,s,"Dosya testi",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Şekil 1.8.2-1 FileTestiSW.java programının içindeki dosya seçim penceresi Şekil 1.8.2-2 FileTestiSW.java programının sonucları Burada swing hazır dosya seçme programı JfileChooser kullanılarak dosya ismi seçilmiş, sonar bu dosya ile ilgili çeşitli bilgiler JoptionPane grafik ortamında aktarılmıştır. 1.8.3 ARDIŞIK (SEQUENTIAL) DOSYA YARATILMASI Java bilgi dosyalarını birbiri ardısıra gelen byte veya char (unicode) akışı olarak görür. Her dosya dosya-bitiş işaretiyle sonlanır. Yeni bir dosya açıldığında bu dosyayla ilgili bir nesne oluşturulur. Yeni bir java programı açıldığında üç akış nesnesi otomatik olarak açılır. Bunlar System.in , System.out, System.err nesneleridir. Eğer kendimiz bir girdi veya çıktı akış nesnesi oluşturmak istersek FileInputStream veya FileOutputStream sınıfı bir nesne tanımlıyabiliriz. Akısın içindeki değişkenleri sadece byte olarak okumak yerine direk olarak double veya integer gibi değişkenler türünden okumak istersek DataInputStream ve DataOutputStream sınıflarını kullanabiliriz. Genel olarak FileOutputStream ve DataOutputStream sınıflarını aşağıdaki gibi bir arada kullanabiliriz: DataOutputStream ciktiakimi; try{ ciktiakimi=new DataOutputStream(new FileOutputStream(“isim.dat”));} catch(IOException e) {System.err.println(“Dosya acilamadi\n”+e.toString());} Bu deyim bize isim.dat isimli dosyadan bir fileOutputStream aracılığıyla açılan dosyayı DataOutputStream’e çevirip gerçek değişkenler cinsinden akış kanalı açar. DataOutputStream ve FileOutputStream sınıflarının tanımları : public class DataOutputStream extends FilterOutputStream implements DataOutput { public DataOutputStream(OutputStram o); protected int written public void flush() public final void size() public synchronized void write(byte[],int baslangıçnoktası,int uzunluk); public synchronized void write(int); public final void writeBoolean(boolean b); public final void writeBytes(String s) public final void writeChar(int) public final void writeChars(String) public final void writeDouble(double) public final void writeFloat(float) public final void writeInt(int) public final void writeLong(long) public final void writeShort(int) public final void writeUTF(String) } FileOutputStream ise dosya sınıfı File ile DataOutputStream sınıfı arasındaki gerekli tanımları sağlar public class FileOutputStream extends OutputStream { public FileOutputStream(File file) throws IOException; public FileOutputStream(FileDescriptor fd) throws IOException; public FileOutputStream(String s) throws IOException; public FileOutputStream(String s, boolean b) throws IOException; public void close() throws IOException; protected void finalize() throws IOException; public void getFD() throws IOException; public void write(byte[]) throws IOException; public void write(byte[], int, int) throws IOException; public void write(int) throws IOException; public final FileDescriptor getFD() throws IOException; } Kanal açıldıktan sonra DataOutputStream sınıfının metodlarını kullanarak dosyaya yazı yazabiliriz. Yazma metodlarının işlevlerine bir göz atarsak : write(byte B[] ) byte tipi boyutludeğişkeni açılmış olan DataOutputStream kanalına yazar. write(byte B[], int baslangıcindeksi, int indeksboyutu) byte tipi boyutludeğişkeni açılmış olan DataOutputStream kanalına yazar. Baslangiç indeksinden baslar ve indeksboyutu uzunluğundaki kısmı yazar. write(int B) int datayı data output stream’e yazar. writeBoolean(boolean B) Boolean değişkeni DataOutputStream’e yazar. writeByte(int) int değişkeni byte olarak DataOutputStream’e yazar. writeBytes(String) String değişkeni byte boyutlu değişken olarak DataOutputStream’e yazar. writeChar(int) int değişkeni char değişken olarak DataOutputStream’e yazar. writeChars(String) String değişkeni Char değişken olarak DataOutputStream’e yazar. writeDouble(double) double değişkeni double değişken olarak DataOutputStream’e yazar. writeFloat(float) float değişkeni float değişken olarak DataOutputStream’e yazar. writeInt(int) float değişkeni float değişken olarak DataOutputStream’e yazar. writeLong(long) long değişkeni long değişken olarak DataOutputStream’e yazar. writeShort(int) int değişkeni short (short integer) değişken olarak DataOutputStream’e yazar. writeUTF(String) String değişkeni unicode UTF-8 formatı karekter boyutu olarak yazar. Bu şekilde yazdığımız bir veri akışın okumak için ise : DataInputStream girdiakimi; try{ girdiakimi=new DataInputStream(new FileInputStream(“isim.dat")); } catch(IOException e) { System.err.println("Dosya acilamadi\n"+e.toString()); System.exit(1); } tanımını kulanabiliriz. Buradaki DataInputStream sınıfının tanımı : public class DataInputStream extends FilterInputStream implements DataInput { public DataInputStream(InputStream in); public DataInputStream(InputStream in); public final int read(byte b[]) throws IOException; public final int read(byte b[], int başlangıçdeğeri, int uzunluk) throws IOException; public final void readFully(byte b[]) throws IOException; public final void readFully(byte b[],int başlangıçdeğeri, int uzunluk) throws IOException; public final int skipBytes(int n) throws IOException; public final boolean readBoolean() throws IOException; public final byte readByte() throws IOException; public final int readUnsignedByte() throws IOException; public final short readShort() throws IOException; public final int readUnsignedShort() throws IOException; public final char readChar() throws IOException; public final int readInt() throws IOException; public final long readLong() throws IOException; public final float readFloat() throws IOException; public final double readDouble() throws IOException; public final String readLine() throws IOException; public final String readUTF() throws IOException; public final static String readUTF(DataInput in) throws IOException; } şeklindedir. FileInputStream ise : public FileInputStream(File file) throws FileNotFoundException { public FileInputStream(FileDescriptor fdObj); public int read() throws IOException; public int read(byte b[]) throws IOException; public int read(byte b[],int başlangıçnoktası,int uzunluk) throws IOException; public long skip(long n) throws IOException; public int available() throws IOException; public void close() throws IOException; public final FileDescriptor getFD() throws IOException; protected void finalize() throws IOException; } şeklinde tanımlıdır. DataInputStream metdunun alt okuma metodlarına biraz daha detaylı göz atarsak: read(byte[]) byte veri akışını direk okur. read(byte[], int başlangıçnoktası, int boyut) byte veri akışını başlangıçnoktası indeksinden boyut uzunluğuna kadar okurdirek okur. readBoolean() boolean değişken (true veya false) okur. readByte() 8-bit byte integer okur readChar() unicode karecter(char) okur readDouble() double okur readFloat() float okur readFully(byte[]) byte boyutlu değişkenini, byte[] boyutlu girdi değişkeninin boyutuna göre okur. readFully(byte[], int, int) readInt() Integer okur readLine() Bir satırı satırbaşı yap komutuna kadar okur. Java 1.0 komutudur. 1.1 ve üzerinde bazı okuma hataları yaptığı görüldüğünden kullanılmaması tavsiye edilir. readLong() Long tamsayı değişkeni okur. readShort() Short tamsayı değişkeni okur readUnsignedByte() 8-bitlik işaretsiz tamsayı değişkeni okur. readUnsignedShort() 16-bitlik işaretsiz tamsayı değişkeni okur. readUTF() Unicode karekteri okur. readUTF(DataInput) Unicode Karakterini (Character) DataInput girdi akışından okur. skipBytes(int n) n byte değeri okumadan atlar. Şimdi bir örnek problem ile bu yazma ve okuma işlemine daha yakından bir göz atalım. Program 1.8.2 de yeni bir dosya açılmakta, ve dosyaya veri girilmektedir. Program 1.8.3 de aynı programın swing kullanılarak yazılmış versiyonu mevcuttur. Program 1.8.4 de ise yaratılan dosyaya girilen veriler okunmaktadır. Program 1.8.3-1 ardisikDosyaYaratSWF_2000.java programı import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ardisikDosyaYaratSWF_2000 extends JFrame implements ActionListener { private JTextField hesapIsmiKutusu,isimKutusu,soyIsimKutusu,hesapKutusu; private JButton enter,done; private DataOutputStream cikti; private JLabel H,I,S,P; Container c; public ardisikDosyaYaratSWF_2000() { super("Müşteri dosyasi Aç"); c=getContentPane(); try{ cikti=new DataOutputStream(new FileOutputStream("musteri.txt")); } catch(IOException e) { System.err.println("Dosya doğru açılamadı\n"+e.toString()); System.exit(1); } c.setLayout(new GridLayout(5,2)); H=new JLabel("Hesap numarasi :"); c.add(H); hesapIsmiKutusu=new JTextField(); c.add(hesapIsmiKutusu); I=new JLabel("isim : "); c.add(I); isimKutusu=new JTextField(20); c.add(isimKutusu); S=new JLabel("Soyisim : "); c.add(S); soyIsimKutusu=new JTextField(20); c.add(soyIsimKutusu); P=new JLabel("Hesaptaki para : "); c.add(P); hesapKutusu=new JTextField(20); c.add(hesapKutusu); enter=new JButton("Gir"); enter.addActionListener(this); c.add(enter); done=new JButton("Cikis"); done.addActionListener(this); c.add(done); setVisible(true); } public void hesapEkle() { int accountNumber=0; Double d; if(!hesapIsmiKutusu.getText().equals("")) { try{ accountNumber=Integer.parseInt(hesapIsmiKutusu.getText()); if(accountNumber>0) { cikti.writeInt(accountNumber); cikti.writeUTF(isimKutusu.getText()); cikti.writeUTF(soyIsimKutusu.getText()); d=new Double(hesapKutusu.getText()); cikti.writeDouble(d.doubleValue()); } hesapIsmiKutusu.setText(""); isimKutusu.setText(""); soyIsimKutusu.setText(""); hesapKutusu.setText(""); } catch(NumberFormatException nfe) { System.err.println("Hesap numarasi tamsayi degisken olamalidir"); } catch(IOException io) { System.err.println("Dosyaya yazarken hata olustu\n"+io.toString()); System.exit(1); } } } public void actionPerformed(ActionEvent e) { hesapEkle(); if(e.getSource()==done) { try{ cikti.close();} catch(IOException io) { System.err.println("Dosya kapatilamadi\n"+io.toString()); } System.exit(0); } } public static void main(String[] args) { ardisikDosyaYaratSWF_2000 pencere= new ardisikDosyaYaratSWF_2000(); pencere.setSize(300,150); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setVisible(true); } } Şekil 1.8.3-1 ArdisikDosyaYaratSWF.java programı ve sonuclarının Frame çıktısında görülmesi import java.io.*; import java.awt.*; import java.awt.event.*; public class ardisikDosyaOku extends Frame implements ActionListener { private TextField accountField,firstNameField,lastNameField,balanceField; private Button next,done; private DataInputStream input; public ardisikDosyaOku() { super("Musteri dosyasini oku"); try{ input=new DataInputStream(new FileInputStream("musteri.dat")); } catch(IOException e) { System.err.println("Dosya acilamadi\n"+e.toString()); System.exit(1); } setSize(300,150); setLayout(new GridLayout(5,2)); add(new Label("Hesap Numarasi :")); accountField=new TextField(); add(accountField); add(new Label("isim : ")); firstNameField=new TextField(20); add(firstNameField); add(new Label("soyisim : ")); lastNameField=new TextField(20); add(lastNameField); add(new Label("Hesaptaki para : ")); balanceField=new TextField(20); add(balanceField); next=new Button("bir sonraki hesap"); next.addActionListener(this); add(next); done=new Button("cikis"); done.addActionListener(this); add(done); setVisible(true); } public void readRecord() { int account; String first,last; double balance; { try{ account=input.readInt(); first=input.readUTF(); last=input.readUTF(); balance=input.readDouble(); accountField.setText(String.valueOf(account)); firstNameField.setText(first); lastNameField.setText(last); balanceField.setText(String.valueOf(balance)); } catch(EOFException eof) { closeFile(); } catch(IOException io) { System.err.println("Dosyay okurken hata olustu\n"+io.toString()); System.exit(1); } } } public void actionPerformed(ActionEvent e) { if(e.getSource()==next) readRecord(); else closeFile(); } private void closeFile() { try{ input.close(); System.exit(0); } catch(IOException e) { System.err.println("Dosya Kapama Hatası oluştu\n"+e.toString()); System.exit(1); } } public static void main(String args[]) { new ardisikDosyaOku(); } } Şekil 1.83-2 ArdisikDosyaOku.java programı ve sonuclarının Frame çıktısında görülmesi ArdisikDosyaYarat.java programında musteri.txt dosyası try{ cikti=new DataOutputStream(new FileOutputStream("musteri.txt")); } catch(IOException e) { System.err.println("Dosya dogru acilamadi\n"+e.toString()); System.exit(1); } gurubunu kullanarak açılmıştır. Bu gurubu File sınıfını da kullanarak File f=new File(“musteri.txt”); f=f.getAbsolutePath(f); try{ cikti=new DataOutputStream(new FileOutputStream(f)); } catch(IOException e) { System.err.println("Dosya dogru acilamadi\n"+e.toString()); System.exit(1); } şeklinde de yaratabilirdik. İkinci şekilde dosyayı tanımlarken tam dizin ismini de otomatik olarak tanımlamış olurduk. Dosyanın okunması içinse try{ input=new DataInputStream(new FileInputStream("musteri.dat")); } catch(IOException e) { System.err.println("Dosya acilamadi\n"+e.toString()); System.exit(1); } gurubunu kullandık. Eğer dosya ismi de değişkende dışarıdan okuduktan sonra ismi File sınıfına yükleyip sonra akış kanalı açabiliriz. Dosya ile işlemler bittikten sonra dosya kapanır. private void closeFile() { try{ input.close(); System.exit(0); } catch(IOException e) { System.err.println("Dosya Kapama Hatası oluştu\n"+e.toString()); System.exit(1); } } closeFile() metotu dosya akışını kapatmak amacıyla oluşturulmuştur. Bu örnekte kullandığımız, DataOutputStream, FileOutputStream, DataInputStream, FileInputStream girdi çıktı akış kontrolları temel olarak daha önce tanımlarını vermiş olduğumuz OutputStream ve InputStream sınıflarından türetilmiş sınıflardı. Ve temel olarak byte değişken türü üzerinden veri akışını sağlamaktadırlar. Yine yukarıda tanımlanmış olan Reader ve Writer sınıfları ise aynı işlemi char sınıfı veri akışı üzerinden yapmaktadır ve char sınfı direk olarak unicode olarak tanımlandığından herhangibir hataya sebep vermeden daha iyi bir veri akışı sağlar. Bu sınıfın alt sınıfları olarak tanımlanan ve yazma işleminde kullanılan sınıfların kullanılmasına bir göz atalım. Genel olarak Writer sınıfından türetilen ve en çok kullanılan Yazma kanalı PrintWriter, BufferedWriter, FileWriter veya OutputStreamWriter sınıflarının beraber kullanılmasıyla gerçekleştirilebilir. Bu sınıfların birlikte kulanılmalarını şu deyimlerle örnekleyebiliriz : dosya "a.txt" e yazdırmak için : PrintWriter cfout=new PrintWriter(new BufferedWriter(new FileWriter("a.txt"))); tanımı kullanılabilir. PrintWriter sınıfının tanımı : public class PrintWriter extends Writer { public PrintWriter(OutputStream o) ; public PrintWriter(OutputStream o, boolean b) ; public PrintWriter(Writer w) ; public PrintWriter(Writer w, boolean b); public void flush(); public void close(); public boolean checkError(); protected void setError(); public void write(int c); public void write(char buf[]); public void write(String s,int baslamaindeksi,int uzunluk); public void write(String s); public void print(boolean b); public void print(char c); public void print(int i); public void print(long l); public void print(float f); public void print(double d); public void print(Object obj); public void println(); public void println(boolean x); public void println(char x); public void println(int x); public void println(long x); public void println(float x); public void println(double x); public void println(char x[]); public void println(Object x); } PrintWriter sınıfının mevcut metotlarının işlevleri şunlardır : checkError() Tüm veriyi gönderir ve hata kontrolu yapar. close() veri akış kanalını kapatır. flush() veri akış kanalındaki tüm veriyi gönderir (ve bufferi yeni veri için boşaltır). print (boolean) boolean değişken yazar. print (char) character değişken yazar. print (char[]) boyutlu chracter değişkenleriyazar. print (double) double yazar. print (float) float yazar. print (int) integer yazar. print (long) long yazar. print (Object) object sınıfının tanımladığı çıktıyı (object türüne göre değişebilir) yazar. print(String) String yazar println () satır sonu yapar alt satıra geçer. println (boolean) boolean yazar ve satır sonu yapar alt satıra geçer. println (char) character yazar ve satır sonu yapar alt satıra geçer. println (char[]) boyutlu character değişkenleri yazar ve satır sonu yapar alt satıra geçer. println (double) double yazar ve satır sonu yapar alt satıra geçer. println (float) float yazar ve satır sonu yapar alt satıra geçer. println (int) Print an integer, and then finish the line. println (long) long yazar ve satır sonu yapar alt satıra geçer. println (Object) object sınıfının tanımladığı çıktıyı (object türüne göre değişebilir) yazar ve satır sonu yapar alt satıra geçer. println(String) String yazar ve satır sonu yapar alt satıra geçer. setError() bir hata oluştuğunu gösterir write (char[]) boyutlu character değişkenlerini yazar write (char[], int, int) boyutlu character değişkenlerini birinci integer(tamsayı) boyutundan ikinci integer boyutuna kadar yazar. write (int) tek bir character yazar. write (String) string yazar write(String, int, int) string değişkenini birinci integer(tamsayı) boyutundan ikinci integer boyutuna kadar yazar. BufferedWriter sınıfının tanımı : public class BufferedWriter extends Writer { public BufferedWriter(Writer cikti); public BufferedWriter(Writer cikti,int boyut); public void write(int c) throws IOException; public void write(char c[],int başlamaindeksi,int uzunluk) throws IOException; public void write(String s, int başlamaindeksi,int uzunluk) throws IOException; public void newLine() throws IOException; public void flush() throws IOException; public void close() throws IOException; } şeklindedir. Yazma verimini arttırmak için akışa ilave edilmektedir. FileWriter sınıfı ise File sınıfı ile bağlantımızı kuran (dosyayı tanımlayan sınıfımızdır.). Writer sınıfının altında yer alan OutputStreamWriter Sınıfının alt sınıfıdır. tanımı : public class FileWriter extends OutputStreamWriter { public FileWriter(String fileName) throws IOException; public FileWriter(String fileName,boolean append) throws IOException; public FileWriter(File file) throws IOException; public FileWriter(FileDescriptor fd); } OutputStreamWriter sınıfının tanımı : public class OutputStreamWriter extends Writer { public OutputStreamWriter(OutputStream o,String enc) throws UnsupportedEncodingException; public OutputStreamWriter(OutputStream o); public String getEncoding(); public void write(int c) throws IOException; public void write(char c[],int başlamaindeksi,int uzunluk) throws IOException; public void write(String str,int başlamaindeksi,int uzunluk) throws IOException; public void flush() throws IOException; public void close() throws IOException; } Bu sınıfları kullanarak bir yazma kanalı açmak istersek : PrintWriter cfout=new PrintWriter(new BufferedWriter(new FileWriter("a.txt"))); cfout.println("hello"); Komutunu kullanabiliriz. Bu komut hello string değişkenini a.txt dosyasına yazdırır. Dosya veya ekrandan okumak için ise paralel olarak BufferedReader, FileReader ve InputStreamReader sınıflarını kullanabiliriz. BufferedReader sınıfının tanımı : public class BufferedReader extends Reader { public BufferedReader(Reader giriş,int boyut); public BufferedReader(Reader giriş); public int read(char c[],int off,int len) throws IOException; public int read() throws IOException; public String readLine() throws IOException; public long skip(long n) throws IOException; public boolean ready() throws IOException; public boolean markSupported(); public void mark(int readAheadLimit) throws IOException; public void reset() throws IOException; public void close() throws IOException; } BufferedReader ve FileReader sınıflarını birarada kullanarak bir okuma kanalı açabiliriz. örneğin a.txt dosyasından okumak için : BufferedReader cfin=new BufferedReader(new FileReader("a.txt")); deyimini kullanabiliriz. Bu terimleri kullanarak dosyaya yazma ve okumayla ilgili ufak bir örnek verelim Program 1.8.3-2 : YazOku.java programı import java.io.*; class YazOku { public static void main (String args[]) throws IOException { String s1="ilk deger"; String s2="ilk deger"; String s3="ilk deger"; PrintWriter cfout=new PrintWriter(new BufferedWriter(new FileWriter("a.txt"))); cfout.println("Merhaba"); cfout.println("isminiz nedir"); cfout.println("sizinle tanistigima memnun oldum"); cfout.close(); BufferedReader cfin=new BufferedReader(new FileReader("a.txt")); s1=cfin.readLine(); s2=cfin.readLine(); s3=cfin.readLine(); cfin.close(); System.out.println("s1 = "+s1); System.out.println("s2 = "+s2); System.out.println("s3 = "+s3); } } Program çıktısı : s1 = Merhaba s2 = isminiz nedir s3 = sizinle tanistigima memnun oldum dosya a.txt : Merhaba isminiz nedir sizinle tanistigima memnun oldum Şeklinde olacaktır. Programımız a.txt dosyasını oluşturup, üç string değerini yazdıktan sonra okuma kanalı açarak bu veriyi okudu. 1.8.4 JAVA VERİ GİRDİ-ÇIKTI SINIFI TEXT Komplike verilerin bilgisayara giriş ve çıkışlarının yapılması için java programlama dili mükemmel araçlar sunmuştur. Ancak bu araçların kullanımları çok basit olmadığından programlamaya yeni başlayanlar için bir engel teşkil edebilirler. Text sınıfı bu karmaşıklığı arka plandaki sınıfların içine gizlemek amacıyla geliştirilmiştir. Burada Text sınıfını kullanarak girdi çıktı yapılması örnekleriyle verilecektir. Ekrandan tek bir veri okumak için: import java.io.*; public class SCO12E {public static void main(String[] args) throws IOException {BufferedReader cin=new BufferedReader(new InputStreamReader(System.in)); double number=Text.readDouble(cin); System.out.println(number);}} Veya Program 1.8.4-2 Ekrandan tek veri okuma örneği SCO12D.java import java.io.*; public class SCO12D { public static void main(String[] args) throws IOException { double number; Text cin=new Text(); number=cin.readDouble(); System.out.println(number); }} örneklerinde görülen işlemler uygulanabilir. Program 1.8.4-3 Dosyadan tek bir veri okumak için: import java.io.*; public class SCO12F {public static void main(String[] args) throws IOException { BufferedReader fin=new BufferedReader(new FileReader("girdi.txt")); double number=Text.readDouble(fin); System.out.println(number);}} Veya Program 1.8.4-4 Dosyadan tek bir veri okumak için: import java.io.*; public class SCO12G {public static void main(String[] args) throws IOException { Text cin=new Text("girdi.txt"); double number=cin.readDouble(); System.out.println(number);}} Örneklerinde görülen işlemler uygulanabilir. Program 1.8.4-4 Dosyadan bir matris okumak için : import java.io.*; public class SCO12H {public static void main(String[] args) throws IOException { double number[][]=Text.readDouble("girdi.txt");}} işlemi kullanılır. burada hata oluşmaması için girdi dosyasının her satırının sonunda yeni satır basılmış olmalıdır(‘\n’ yenisatır karekteri – return ) Program 1.8.4-4 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12I.java programı import java.io.*; public class SCO12I {public static void main(String[] args) throws IOException { double number[][]=Text.readDouble(3);}} değerler her satır için açılan pencereden veriler arasında bir boşluk bırakarak girilir. Şekil 1.8.4-1 SCO12I.java programı çıktısı Üstte verilen program parçacığında satır sayısı 3 dür, sütun sayısını birinci satıra girilen veri sayısı tayin eder. Veya Program 1.8.4-5 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12J.java programı import java.io.*; public class SCO12J {public static void main(String[] args) throws IOException { double number[][]=Text.readDouble(3,4);}} Şekil 1.8.4-1 SCO12J.java programı çıktısı Üstte verilen program parçacığında satır sayısı 3 dür, sütun sayısı 4 tür. Satıra girilen veri sayısı daha fazla olduğunda ihmal edilir. 3x3 Matris verisini JTextArea çıktı grafiği üzerinden girmek ister isek : Program 1.8.4-6 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12M.java programı import java.io.*; import javax.swing.*; public class SCO12M {public static void main(String[] args) throws IOException { double A[][]=Text.readDouble_TextArea(3,3);}} Burada açılacak olan girdi penceresi: Şekil 1.8.4-2 SCO12M.java programı çıktısı şeklindir. Veri ekrana direk olarak girilir. Her satırdan sonra return tuşuna basmak gerekir. Veriyi girdikten sonra alttaki düğmeye bastığımızda veri A boyutlu değişkenine aktarılır. Bu örnekte boyut 3 x 3 verildiğinden daha büyük veri verilse de fazla veri girilir, sadece verilen boyutlardaki kısmı aktarılır. İstenilen matris boyutunu programın içinde tanımlamak yerine girişte grafik ortamında tanımlama istersek içi boş readDouble_TextArea(); metodu kullanırız. Bu metod önce boyut tanımlama penceresi açar. Program 1.8.4-7 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12L.java programı import java.io.*; import javax.swing.*; public class SCO12L {public static void main(String[] args) throws IOException,Throwable { double A[][]=Text.readDouble_TextArea(); Text.print(A); }} Şekil 1.8.4-3 SCO12L.java programı çıktısı Program çıktısı almak için : bir üstteki aynı pencere açılır. 3x3 Matris verisini JTable çıktı grafiği üzerinden girmek ister isek : Program 1.8.4-8 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12N.java programı import java.io.*; import javax.swing.*; public class SCO12N {public static void main(String[] args) throws IOException { double A[][]=Text.readDouble_Table(3,3); Text.print(A);}} Burada açılacak olan girdi penceresi Şekil 1.8.4-4 SCO12N.java programı çıktısı tablo formatındadır. Bu pencerede return komutu her seferinde bir alt satıra geçtiğinden veriyi sütunlar halinde girmek daha kolaydır. Veriyi girdikten sonra alttaki düğmeye bastığımızda veri A boyutlu değişkenine aktarılır. Bu örnekte boyut 3 x 3 verildiğinden daha büyük veri verilse de fazla veri kesilir, sadece verilen boyutlardaki kısmı aktarılır. İstenilen matris boyutunu proğramın içinde tanımlamak yerine girişte grafik ortamında tanımlama istersek Program 1.8.4-8 Ekrandan grafik veri girdisi penceresi açarak matris değerlerini girmek için SCO12O.java programı import java.io.*; import javax.swing.*; public class SCO12O {public static void main(String[] args) throws IOException { double A[][]=Text.readDouble_Table(); Text.print(A);}} içi boş readDouble_Table(); metodu kullanırız. Bu metod önce boyut tanımlama penceresi açar. Şekil 1.8.4-5 SCO12O.java programı girdisi Program çıktısı almak için : bir üstteki aynı pencere açılır. . Text.printf komutunu kullanabiliriz (f : file – dosya kelimesinden) Bir değişkenin değerini ekrana grafik formda yazmak için mevcut olan metodlar : Program 1.8.4-8 veri girdisini dosyadan alaran matris değerlerini grafik olarak çıkan SCO12B.java programı import javax.swing.*; public class SCO12B {public static void main(String[] args) {double A[][]=Text.readDouble("R134a_S_TPln.txt"); Text.print(A);}} Çıktı penceresi Şekil 1.8.4-6 SCO12B.java programı çıktısı şeklinde oluşacaktır. Buradaki başlıkları da kendimiz verebiliriz. Program 1.8.4-9 veri girdisini dosyadan alaran matris değerlerini grafik olarak çıkan SCO12B1.java programı import javax.swing.*; public class SCO12B1 {public static void main(String[] args) {double A[][]=Text.readDouble("R134a_S_TPln.txt"); String baslik[]={"x ekseni","y ekseni"}; String genelbaslik="R134a_S_TPln.txt verisi"; Text.print(A,baslik,genelbaslik);}} Çıktı penceresi Şekil 1.8.4-6 SCO12B1.java programı çıktısı durumunu alacaktır. Bir üstte dosyadan okuma ve ekrana bastırma iki kademeli işlemini tek kademede de yapabiliriz. Program 1.8.4-10 veri girdisini dosyadan alaran matris değerlerini grafik olarak çıkan SCO12C.java programı import javax.swing.*; public class SCO12C {public static void main(String[] args) {String baslik[]={"Sıcaklık C","log(Basınç, kPa)"}; String genelbaslik="R134a_S_TPln.txt verisi"; Text.print("R134a_S_TPln.txt",baslik,genelbaslik);}} Şekil 1.8.4-7 SCO12C.java programı çıktısı Son olarak da birden fazla verimiz (matrisimiz) olduğunda bu verilerin hepsini aynı pencerede görmek istediğimizde nasıl yapacağımıza bir göz atalım. Burada Tüm verinin JPanel sınıfı x değişkeninde toplanmasını istiyoruz. Toplanan veri en sonunda Text.print(x,s1) metodu tarafından ekrana aktarılır. Bu metodu kullanmadan önce istediğimiz miktarda veriyi arka arkaya Text.add komutunu kullanarak sıralayabiliriz. Program 1.8.4-11 veri girdisini dosyadan alan matris değerlerini grafik olarak çıkan SCO12A.java programı import javax.swing.*; public class SCO12A { public static void main(String[] args) {double A[][]={{1.0,2.0,3.0,4.0},{3.0,4.0,5.0,6.0},{6.0,7.0,8.0,9.0}}; double B[][]=Text.readDouble("R134a_S_TPln.txt"); String s[]={"başlık 1","başlık 2","başlık 3"}; String s1="Genel başlık"; JPanel x=new JPanel(); Text.add(x,A,s,"A"); Text.add(x,B,s,"B"); Text.add(x,B,s,"C"); Text.print(x,s1);}} Şekil 1.8.4-7 SCO12A.java programı çıktısı Text sınıfında oluşan çıktı pencerelerinden veriyi direk olarak alabiliriz. Bunun için veriyi fare ile seçtikten sonra <Ctrl>C tuşuyla kopyalamak ve bir text dosyası açarak <Ctrl>V tuşuyla yapıştırmak kafidir. Yukarıda bahsi geçen programı kullanabilmek için gerekli sınıflar altta listelenmiştir. Program 1.8.4-12 TEXT SINIFI //============================================ // Numerical Analysis Package in Java // Class Text to read data from screen or file // and dısplay data in matrix form // Dr. Turhan Coban //============================================ import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.table.*; import java.awt.*; class Text { BufferedReader in; /* --------------------------------------------------Static routines provided are: --------------------------------------------------public static void prompt(String s); public static int readInt(BufferedReader in); public static double readDouble(BufferedReader in); public static String readString(BufferedReader in); public static char readChar(BufferedReader in); ---------------------------------------------------Dynamic routines provided are : ---------------------------------------------------public void Text() public void Text(String s1) public void Text(File f1) public int readInt(); public double readDouble(); public String readString(); public char readChar(); Sample use : --------- reading a double-------------BufferedReader cin=new BufferedReader(new InputStreamReader(System.in)); double number; number=Text.readDouble(cin); veya double number; Text cin=new Text(); number=cin.readDouble(); ------ reading data from a file "datafile.dat"-----double number; BufferedReader fin=new BufferedReader(new FileReader("datafile.dat")); double number; number=Text.readDouble(fin); veya double number; Text cin=new Text("dataFile.dat"); number=cin.readDouble(); ------ reading double array data from a file "datafile.dat"-----double a[][]=Text.readDouble("datafile.dat"); ------ reading double array data from screen -----double a[][]=Text.readDouble(3); double a[][]=Text.readDouble(3,4); double a[][]=Text.readDouble_TextArea(3,4); double a[][]=Text.readDouble_TextArea(); double a[][]=Text.readDouble_Table(3,4); double a[][]=Text.readDouble_Table(); ------ displaying array data from screen -----double a[][]=new double{{1,2,3},{4,5,6},{7,8,9}}; String heading={"column 1","column 2",column 3"}; Text.print(a); Text.print(a'heading); Text.print("datafile.dat",heading); Text.print("datafile.dat"); double a[][]=Text.readDouble(3,4); ------ printing data into a file "printfile.dat"---doub PrintStream fout=new PrintStream (new FileOutputStream("printfile.dat")); String a="turhan"; fout.println(a); veya BufferedWriter fout=new BufferedWriter(new FileWriter("datafile.dat")); String a="Turhan"); fout.println(a); ---------------------------------------------------*/ private static StringTokenizer T; private static String S; public Text() { in=new BufferedReader(new InputStreamReader(System.in)); } public Text(String s1) throws IOException { in=new BufferedReader(new FileReader(s1)); } public static void prompt (String s) { System.out.print(s + " "); System.out.flush(); } public int readInt() throws IOException {return Text.readInt(in);} public double readDouble() throws IOException {return Text.readDouble(in);} public String readString() throws IOException {return Text.readString(in);} public char readChar() throws IOException {return Text.readChar(in);} public static int readInt (BufferedReader in) throws IOException { if (T==null) refresh(in); while (true) { try { String item = T.nextToken(); return Integer.valueOf(item.trim()).intValue(); } catch (NoSuchElementException e1) { refresh (in); } catch(NumberFormatException e2) { //System.err.println("Error in number, try again."); } } } public static char readChar (BufferedReader in) throws IOException { if (T==null) refresh(in); while (true) { try { return T.nextToken().charAt(0); } catch(NoSuchElementException e1) {refresh (in);} } } public static double readDouble(BufferedReader in) throws IOException { if(T==null) refresh(in); while (true) { try { String item = T.nextToken(); return Double.valueOf (item.trim()).doubleValue(); } catch(NoSuchElementException e1) { refresh (in); } catch(NumberFormatException e2) { //System.err.println("Error in number, try again."); } } } public static String readString(BufferedReader in) throws IOException { if(T==null) refresh (in); while (true) { try {return T.nextToken();} catch (NoSuchElementException e1) { refresh (in); } } } public static String readStringLine(BufferedReader in) throws IOException { //reads a line of strings from BufferedReader in int ch; String r = ""; boolean done = false; while (!done) { try { ch = in.read(); if(ch < 0 || (char)ch == '\n' || (char)ch == '\0') done = true; else r = r + (char) ch; } catch(java.io.IOException e) { done = true;} } return r.substring(0,(r.length()-1)); } public static String readStringLine(String s) { //reads a line of strings from String s int ch; String r = ""; boolean done = false; int i=0; while (!done) { ch = s.charAt(i);i++; if(ch < 0 || (char)ch == '\n' || (char)ch == '\0') done = true; else r = r + (char) ch; } return r; } public static String[] readStringLines(String s) { String s1=s; String s11; String ss[]=new String[1000]; int n=0; int n1,n2; while(s1.length()!=0) { s11=Text.readStringLine(s1); ss[n]=s11; n1=s11.length()+1; n2=s1.length(); //System.out.println("n1 ="+n1+"n2="+n2); n++; if(n1>=(n2-2)) break; s1=s1.substring(n1,n2); if(s1=="\n" || s1=="\n " || s1=="\n " || s1==" " || s1==" " || s1==" ") break; //System.out.println("sline="+s11); //System.out.println("sgeri kalan= *"+s1+"*"); } String sa[]=new String[n]; for(int i=0;i<n;i++) sa[i]=ss[i]; return sa; } private static void refresh (BufferedReader in) throws IOException { String s = in.readLine(); if (s==null) throw new EOFException(); T = new StringTokenizer(s); } public static double[][] readDoubleS(String s) { //read data in matrix form // data length is not limited Vector<String> xi=new Vector<String>(); if(s.charAt(s.length())!='\n') s+="\n"; int nn; int m=2; int i=0; String s1=Text.readStringLine(s); s=s.substring(s1.length()+1,s.length()); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; m=n+1; //m tokens boyutludeğişken kolon sayısı while(token.hasMoreTokens()) { String s2=token.nextToken(); xi.add(s2); } i=0; while(s.length()!=0) { i++; String s11=Text.readStringLine(s); s=s.substring(s11.length()+1,s.length()); if(s11=="") break; StringTokenizer token1=new StringTokenizer(s11); while(token1.hasMoreTokens()) { String s2=token1.nextToken(); xi.add(s2); } //if(s.length()==0) {break;} } nn=i+1; double aa[][]=new double[nn][m]; Enumeration nx=xi.elements(); for(i=0;i<nn;i++) { for(int j=0;j<m;j++) { String ss1=(String)nx.nextElement(); Double ax=new Double(ss1); aa[i][j]=ax.doubleValue(); } } return aa; } public static double[][] readDoubleS(String s,int n,int m) { //read data in matrix form // data length is not limited Vector<String> xi=new Vector<String>(); if(s.charAt(s.length()-1)!='\n') s+="\n"; int i,j; for(i=0;i<n;i++) { String s11=Text.readStringLine(s); s=s.substring(s11.length()+1,s.length()); if(s11=="") break; StringTokenizer token1=new StringTokenizer(s11); for(j=0;j<m;j++) { String s2=token1.nextToken(); xi.add(s2); } //if(s.length()==0) {break;} } double aa[][]=new double[n][m]; Enumeration nx=xi.elements(); for(i=0;i<n;i++) { for(j=0;j<m;j++) { String ss1=(String)nx.nextElement(); Double ax=new Double(ss1); aa[i][j]=ax.doubleValue(); } } return aa; } public static double[][] readDouble(String filename) { //read data in matrix form // data length is not limited Vector<String> xi=new Vector<String>(); int nn; int m=2; int i=0; BufferedReader fin; try{ fin=new BufferedReader(new FileReader(filename)); try { try{ try{ try{ String s1=Text.readStringLine(fin); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; m=n+1; //m tokens boyutludeğişken kolon sayısı while(token.hasMoreTokens()) { String s2=token.nextToken(); xi.add(s2); } i=0; while(fin != null) { i++; String s11=Text.readStringLine(fin); //System.out.println(s11); if(s11=="") break; StringTokenizer token1=new StringTokenizer(s11); while(token1.hasMoreTokens()) { String s2=token1.nextToken(); xi.add(s2); } } } catch(ArrayIndexOutOfBoundsException e_eof) { } } catch(StringIndexOutOfBoundsException e_eof) { } } catch(EOFException e_eof) {System.out.println("end of file"); } } catch(NumberFormatException e_nfe) {System.out.println("non-number input"); } } catch(IOException e_io) {System.out.println("file name is not existed"); } nn=i; //System.out.println("m="+m+"nn="+nn); double aa[][]=new double[nn][m]; Enumeration nx=xi.elements(); for(i=0;i<nn;i++) { for(int j=0;j<m;j++) { String s1=(String)nx.nextElement(); Double ax=new Double(s1); aa[i][j]=ax.doubleValue(); } } return aa; } public static double[][] readDoubleT(String filename) {//veriyi ters matris olarak okur(satir ve sutun degisir) double a[][]=readDouble(filename); int n=a.length; int m=a[0].length; double b[][]=new double[m][n]; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { b[j][i]=a[i][j]; } } return b; } public static double[][] readDouble(int n,int m) { String s="line 0 "; String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); double a[][]=new double[n][m]; int j=0; for(j=0;j<m;j++) {Double ax=new Double(token.nextToken()); a[0][j]=ax.doubleValue();} for(int i=1;i<n;i++) { s="line "+i; s1=JOptionPane.showInputDialog(s); token=new StringTokenizer(s1); j=0; for(j=0;j<m;j++) {Double ax=new Double(token.nextToken()); a[i][j]=ax.doubleValue();} } return a; } public static double[][] readDouble(int n) { // column number determined by number of data entered in first column String s="line 0 "; String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int nn=token.countTokens()-1; int m=nn+1; double a[][]=new double[n][m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[0][j++]=ax.doubleValue(); } for(int i=1;i<n;i++) { s="line "+i; s1=JOptionPane.showInputDialog(s); token=new StringTokenizer(s1); for(j=0;j<m;j++) {Double ax=new Double(token.nextToken()); a[i][j]=ax.doubleValue();} } return a; } public static double[] readDoubleV() { // column number determined by number of data entered in first column String s="line 0 "; String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int nn=token.countTokens()-1; int m=nn+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static double[] readDoubleV(String s) { // column number determined by number of data entered in first column String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int nn=token.countTokens()-1; int m=nn+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static double[][] readDouble_TextArea(int n,int m) { girdi g=new girdi(n,m); double a[][]=g.vericiktisi(); return a; } public static fa return2Dfunction() {createfunction(); fa ff=new fa(); return ff; } public static fa return2Dfunction(String fonksiyon) {createfunction(fonksiyon); fa ff=new fa(); return ff; } public static String createfunction() { girdi2 g=new girdi2("fa"," "); String s=g.vericiktisi(); try{ g.finalize(); } catch(Throwable e1) {System.err.println("girdi hatası.");} return s; } public static String createfunction(String function) { functiongenerator g=new functiongenerator("fa",function); String s=g.createfunction(); try{ g.finalize();} catch(Throwable e1) {System.err.println("girdi hatası.");} return s; } public static String create3Dfunction() { girdi3 g=new girdi3("fb"," "); String s=g.vericiktisi(); try{g.finalize();} catch(Throwable e1) {System.err.println("girdi hatası.");} return s; } public static String create3Dfunction(String fonksiyon) { functiongenerator3D g=new functiongenerator3D(fonksiyon); String s=g.createfunction(); try{ g.finalize(); } catch(Throwable e1) {System.err.println("girdi hatası.");} return s; } public static double[][] readDouble_TextArea() { String s1=JOptionPane.showInputDialog("n(satır) ve m(sütun) boyutlarını veriniz :" ); StringTokenizer token=new StringTokenizer(s1); Integer ax=new Integer(token.nextToken()); int n=ax.intValue(); ax=new Integer(token.nextToken()); int m=ax.intValue(); girdi g=new girdi(n,m); double a[][]=g.vericiktisi(); return a; } public static double[][] readDouble_Table(int n,int m) { girdi1 g=new girdi1(n,m); double a[][]=g.vericiktisi(); return a; } public static double[][] readDouble_Table() { String s1=JOptionPane.showInputDialog("n(satır) ve m(sütun) boyutlarını veriniz :" ); StringTokenizer token=new StringTokenizer(s1); Integer ax=new Integer(token.nextToken()); int n=ax.intValue(); ax=new Integer(token.nextToken()); int m=ax.intValue(); girdi1 g=new girdi1(n,m); double a[][]=g.vericiktisi(); return a; } public static double[][] T(double a[][]) { //Ters matris int n=a.length; int i,j; int m=a[0].length; double b[][]=new double[m][n]; for(i=0;i<n;i++) { for(j=0;j<m;j++) {b[j][i]=a[i][j];}} return b; } public static void print(double a[][],String baslik[]) {print(a,baslik,"data output(veri çıktısı) :");} public static void print(double b[],String baslik[],String bb) { double a[][]=new double[1][b.length]; a[0]=b; print(a,baslik,bb); } public static void print(double b[],String bb) { double a[][]=new double[1][b.length]; a[0]=b; print(a,bb); } public static void print(double b[]) { double a[][]=new double[1][b.length]; a[0]=b; print(a,"vektör çıktısı : "); } public static void printT(double b[],String bb) { double a[][]=new double[b.length][1]; for(int j=0;j<b.length;j++) a[j][0]=b[j]; print(a,bb); } public static void printT(double b[],String [] bb) { double a[][]=new double[b.length][1]; for(int j=0;j<b.length;j++) a[j][0]=b[j]; print(a,bb); } public static void printT(double b[],String [] bb,String cc) { double a[][]=new double[b.length][1]; for(int j=0;j<b.length;j++) a[j][0]=b[j]; print(a,bb,cc); } public static void printT(double b[]) { double a[][]=new double[b.length][1]; for(int j=0;j<b.length;j++) a[j][0]=b[j]; print(a,"vektör çıktısı"); } public static void print(double a[][],String baslik[],String bb) { JTable jt; int n=a.length; int m=a[0].length; genelModel gm=new genelModel(a,baslik); jt=new JTable(gm); //JOptionPane.showMessageDialog(null,jt); JFrame cerceve=new JFrame(bb); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(new JScrollPane(jt)); cerceve.pack(); cerceve.setVisible(true); } public static void print(double a[][],String baslik) { JTable jt; int n=a.length; int m=a[0].length; genelModel gm=new genelModel(a); jt=new JTable(gm); //JOptionPane.showMessageDialog(null,jt); JFrame cerceve=new JFrame(baslik); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(new JScrollPane(jt)); cerceve.pack(); cerceve.setVisible(true); } public static void print(double a[][]) {print(a,"data output(veri çıktısı) :");} public static void print(String dosyaadi,String genelbaslik) { genelModel gm=new genelModel(dosyaadi); JTable jt=new JTable(gm); //JOptionPane.showMessageDialog(null,jt); JFrame cerceve=new JFrame(genelbaslik); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(new JScrollPane(jt)); cerceve.pack(); cerceve.setVisible(true); } public static void print(String dosyaadi,String[] baslik,String genelbaslik) { genelModel gm=new genelModel(dosyaadi,baslik); JTable jt=new JTable(gm); //JOptionPane.showMessageDialog(null,jt); JFrame cerceve=new JFrame(genelbaslik); cerceve.addWindowListener(new BasicWindowMonitor()); cerceve.getContentPane().add(new JScrollPane(jt)); cerceve.pack(); cerceve.setVisible(true); } public static void print(String dosyaadi) {print(dosyaadi," "+dosyaadi+" :");} //========== //JComponent added versions of print statements // main program should include a JPanel definition public static void print(JComponent anapencere,double a[][],String baslik[]) {add(anapencere,a,baslik,"data output(veri çıktısı) :");} public static void add(JComponent anapencere,double a[][],String baslik[],String bb) { JButton B; B=new JButton(bb); JTable jt; int n=a.length; int m=a[0].length; genelModel gm=new genelModel(a,baslik); jt=new JTable(gm); JScrollPane sp=new JScrollPane(jt); JPanel cerceve=new JPanel(); cerceve.setLayout(new BorderLayout()); cerceve.add(B,BorderLayout.NORTH); cerceve.add(sp,BorderLayout.SOUTH); anapencere.add(cerceve); } public static void add(JComponent anapencere,double b[],String baslik[],String bb) { double a[][]=new double[1][b.length]; a[0]=b; add(anapencere,a,baslik,bb); } public static void addT(JComponent anapencere,double b[],String bb) { double a[][]=new double[b.length][1]; for(int j=0;j<b.length;j++) a[j][0]=b[j]; add(anapencere,a,bb);} public static void add(JComponent anapencere,double b[],String bb) { double a[][]=new double[1][b.length]; a[0]=b; add(anapencere,a,bb); } public static void addT(JComponent anapencere,double b[]) {addT(anapencere,b,"vektör :");} public static void add(JComponent anapencere,double b[]) { double a[][]=new double[1][b.length]; a[0]=b; add(anapencere,a,"vektör çıktısı"); } public static void add(JComponent anapencere,double a[][],String baslik) { JButton B; B=new JButton(baslik); JTable jt; int n=a.length; int m=a[0].length; genelModel gm=new genelModel(a); jt=new JTable(gm); JScrollPane sp=new JScrollPane(jt); JPanel cerceve=new JPanel(); cerceve.setLayout(new BorderLayout()); cerceve.add(B,BorderLayout.NORTH); cerceve.add(sp,BorderLayout.SOUTH); anapencere.add(cerceve); } public static void add(JComponent anapencere,double a[][]) {add(anapencere,a,"data output(veri çıktısı) :");} public static void add(JComponent anapencere,String dosyaadi,String baslik) { JButton B; B=new JButton(baslik); genelModel gm=new genelModel(dosyaadi); JTable jt=new JTable(gm); JScrollPane sp=new JScrollPane(jt); JPanel cerceve=new JPanel(); cerceve.setLayout(new BorderLayout()); cerceve.add(B,BorderLayout.NORTH); cerceve.add(sp,BorderLayout.SOUTH); anapencere.add(cerceve); } public static void print(JComponent anapencere,String genelbaslik) { Container c; JFrame cerceve=new JFrame(genelbaslik); cerceve.addWindowListener(new BasicWindowMonitor()); c=cerceve.getContentPane(); c.add(new JScrollPane(anapencere)); cerceve.pack(); cerceve.setVisible(true); } public static void add(JComponent anapencere,String dosyaadi) {add(anapencere,dosyaadi,""+dosyaadi+" :");} public static void printf(String dosyaadi,String s) throws IOException { BufferedWriter fout=new BufferedWriter(new FileWriter(dosyaadi)); fout.write(s,0,s.length()); fout.close();} public static void printf(String dosyaadi,double a) throws IOException { String s=""+a; BufferedWriter fout=new BufferedWriter(new FileWriter(dosyaadi)); fout.write(s,0,s.length()); fout.close();} } Program 1.8.4-13 GENELMODEL SINIFI import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import java.io.*; import java.util.*; class genelModel extends AbstractTableModel implements TableModelListener { Object[][] veri; String[] baslik; public genelModel(Object[][] verii,String basliki[]) { int n=veri.length; int m=veri[0].length; veri=new Object[n][m]; baslik=new String[m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=verii[i][j];} baslik[j]=basliki[j]; } addTableModelListener(this); } public genelModel(Object[][] verii) { int n=veri.length; int m=veri[0].length; veri=new Object[n][m]; baslik=new String[m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=verii[i][j];} baslik[j]=""+j; } } public genelModel(int n,int m) { veri=new Object[n][m]; baslik=new String[m]; /* for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=(Object)"";} } */ } public genelModel(double[][] verii) { int n=verii.length; int m=verii[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(verii); for(int j=0;j<m;j++) baslik[j]=""+j; } public genelModel(double[][] verii,String basliki[]) { int n=verii.length; int m=verii[0].length; int m1=basliki.length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(verii); if(m1>=m) { for(int j=0;j<m;j++) baslik[j]=basliki[j]; } else { for(int j=0;j<m1;j++) baslik[j]=basliki[j]; for(int j=m1;j<m;j++) baslik[j]=""+j; } } public genelModel(String filename) { double a[][]=readDouble(filename); int n=a.length; int m=a[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(a); for(int j=0;j<m;j++) baslik[j]=""+j; } public genelModel(String filename,String basliki[]) { double a[][]=readDouble(filename); int n=a.length; int m=a[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(a); for(int j=0;j<m;j++) baslik[j]=basliki[j]; } public static Double[][] doubletoDouble(double xi[][]) { int n=xi.length; int m=xi[0].length; Double X[][]=new Double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {X[i][j]=new Double(xi[i][j]);} } return X; } public static double[][] readDouble(String filename) { //veriyi oku bu metodun verisayısı sınırı yoktur //istediğimiz uzunluktaki veriyi okuyabilir Vector xi=new Vector(); int nn; int m=2; int i=0; BufferedReader fin; try{ fin=new BufferedReader(new FileReader(filename)); try { try{ try{ String s1=Text.readStringLine(fin); //System.out.println(s1); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; m=n+1; //m tokens boyutludeğişken kolon sayısı while(token.hasMoreTokens()) { String s2=token.nextToken(); xi.add(s2); } i=0; while(fin != null) { i++; String s11=Text.readStringLine(fin); //System.out.println(s11); if(s11=="") break; StringTokenizer token1=new StringTokenizer(s11); while(token1.hasMoreTokens()) { String s2=token1.nextToken(); xi.add(s2); } } } catch(ArrayIndexOutOfBoundsException e_eof) { } } catch(StringIndexOutOfBoundsException e_eof) { } } catch(EOFException e_eof) {System.out.println("end of file"); } } catch(IOException e_io) {System.out.println("file name is not existed"); } nn=i; //System.out.println("m="+m+"nn="+nn); double aa[][]=new double[nn][m]; Enumeration nx=xi.elements(); for(i=0;i<nn;i++) { for(int j=0;j<m;j++) { String s1=(String)nx.nextElement(); Double ax=new Double(s1); aa[i][j]=ax.doubleValue(); } } return aa; } public int getRowCount() {return veri.length;} public int getColumnCount() {return baslik.length;} public Object getValueAt(int satir,int sutun) {return veri[satir][sutun];} public String getColumnName(int c) {return baslik[c];} public void setValueAt(Object val, int row, int col) {veri[row][col] = val;} public void setValues(String filename) {veri=doubletoDouble(readDouble(filename));} public void tableChanged(TableModelEvent e) { } public double[][] todouble() { int n=veri.length; int m=veri[0].length; double x[][]=new double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {x[i][j]=Double.parseDouble((String)(veri[i][j]));} } return x; } public void setValues(double xi[][],String[] basliki) { int n=xi.length; int m=xi[0].length; Double X[][]=new Double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {X[i][j]=new Double(xi[i][j]);} baslik[j]=basliki[j]; } veri=X; } public Object[][] getValues(){return veri;} public boolean isCellEditable(int row, int col) {return true;} } Program 1.8.4-14 GIRDI SINIFI (JTEXTAREA VERİ GIRİŞİ) import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import java.io.*; import java.util.*; class genelModel extends AbstractTableModel implements TableModelListener { Object[][] veri; String[] baslik; public genelModel(Object[][] verii,String basliki[]) { int n=veri.length; int m=veri[0].length; veri=new Object[n][m]; baslik=new String[m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=verii[i][j];} baslik[j]=basliki[j]; } addTableModelListener(this); } public genelModel(Object[][] verii) { int n=veri.length; int m=veri[0].length; veri=new Object[n][m]; baslik=new String[m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=verii[i][j];} baslik[j]=""+j; } } public genelModel(int n,int m) { veri=new Object[n][m]; baslik=new String[m]; /* for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {veri[i][j]=(Object)"";} } */ } public genelModel(double[][] verii) { int n=verii.length; int m=verii[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(verii); for(int j=0;j<m;j++) baslik[j]=""+j; } public genelModel(double[][] verii,String basliki[]) { int n=verii.length; int m=verii[0].length; int m1=basliki.length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(verii); if(m1>=m) { for(int j=0;j<m;j++) baslik[j]=basliki[j]; } else { for(int j=0;j<m1;j++) baslik[j]=basliki[j]; for(int j=m1;j<m;j++) baslik[j]=""+j; } } public genelModel(String filename) { double a[][]=readDouble(filename); int n=a.length; int m=a[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(a); for(int j=0;j<m;j++) baslik[j]=""+j; } public genelModel(String filename,String basliki[]) { double a[][]=readDouble(filename); int n=a.length; int m=a[0].length; veri=new Object[n][m]; baslik=new String[m]; veri=doubletoDouble(a); for(int j=0;j<m;j++) baslik[j]=basliki[j]; } public static Double[][] doubletoDouble(double xi[][]) { int n=xi.length; int m=xi[0].length; Double X[][]=new Double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {X[i][j]=new Double(xi[i][j]);} } return X; } public static double[][] readDouble(String filename) { //veriyi oku bu metodun verisayısı sınırı yoktur //istediğimiz uzunluktaki veriyi okuyabilir Vector xi=new Vector(); int nn; int m=2; int i=0; BufferedReader fin; try{ fin=new BufferedReader(new FileReader(filename)); try { try{ try{ String s1=Text.readStringLine(fin); //System.out.println(s1); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; m=n+1; //m tokens boyutludeğişken kolon sayısı while(token.hasMoreTokens()) { String s2=token.nextToken(); xi.add(s2); } i=0; while(fin != null) { i++; String s11=Text.readStringLine(fin); //System.out.println(s11); if(s11=="") break; StringTokenizer token1=new StringTokenizer(s11); while(token1.hasMoreTokens()) { String s2=token1.nextToken(); xi.add(s2); } } } catch(ArrayIndexOutOfBoundsException e_eof) { } } catch(StringIndexOutOfBoundsException e_eof) { } } catch(EOFException e_eof) {System.out.println("end of file"); } } catch(IOException e_io) {System.out.println("file name is not existed"); } nn=i; //System.out.println("m="+m+"nn="+nn); double aa[][]=new double[nn][m]; Enumeration nx=xi.elements(); for(i=0;i<nn;i++) { for(int j=0;j<m;j++) { String s1=(String)nx.nextElement(); Double ax=new Double(s1); aa[i][j]=ax.doubleValue(); } } return aa; } public int getRowCount() {return veri.length;} public int getColumnCount() {return baslik.length;} public Object getValueAt(int satir,int sutun) {return veri[satir][sutun];} public String getColumnName(int c) {return baslik[c];} public void setValueAt(Object val, int row, int col) {veri[row][col] = val;} public void setValues(String filename) {veri=doubletoDouble(readDouble(filename));} public void tableChanged(TableModelEvent e) { } public double[][] todouble() { int n=veri.length; int m=veri[0].length; double x[][]=new double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {x[i][j]=Double.parseDouble((String)(veri[i][j]));} } return x; } public void setValues(double xi[][],String[] basliki) { int n=xi.length; int m=xi[0].length; Double X[][]=new Double[n][m]; for(int j=0;j<m;j++) {for(int i=0;i<n;i++) {X[i][j]=new Double(xi[i][j]);} baslik[j]=basliki[j]; } veri=X; } public Object[][] getValues(){return veri;} public boolean isCellEditable(int row, int col) {return true;} } Program 1.8.4-15 GIRDI1 SINIFI (JTABLE VERİ GIRİŞİ) import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import java.io.*; import java.util.*; public class girdi1 extends Thread implements ActionListener { Container c; String s[][]; genelModel gm; JTable jt; JButton bb; boolean basildi; double a[][]; int n,m; public girdi1(int ni,int mi) { n=ni; m=mi; gm=new genelModel(n,m); a=new double[n][m]; jt=new JTable(gm); bb=new JButton("veri girişi tamamlandığında basınız"); JScrollPane jsp=new JScrollPane(jt); JFrame cerceve=new JFrame("Matris girdi penceresi ("+n+" * "+m+") matris giriniz"); cerceve.addWindowListener(new BasicWindowMonitor()); c=cerceve.getContentPane(); c.setLayout(new BorderLayout()); c.add(jsp,BorderLayout.NORTH); c.add(bb,BorderLayout.SOUTH); bb.addActionListener(this); cerceve.pack(); cerceve.setVisible(true); basildi=false; } public double[][] vericiktisi() { while(!basildi) { try {Thread.sleep(100);} catch(InterruptedException e) {System.err.println(e.toString());} } return a; } protected void finalize() throws Throwable {super.finalize();} public void actionPerformed( ActionEvent e) { if(e.getSource()==bb) {double b[][]=gm.todouble(); for(int i=0;i<n;i++){for(int j=0;j<m;j++){a[i][j]=b[i][j];};} basildi=true; } } } Program 1.8.4-16 BASICWINDOWMONITOR SINIFI import java.awt.event.*; import java.awt.Window; public class BasicWindowMonitor extends WindowAdapter { public void windowClosing(WindowEvent e) { Window w=e.getWindow(); w.setVisible(false); w.dispose(); System.exit(0); } } 1.8.5 GRAFİK ORTAMDAN VERİ OKUNMASI Sayısal analiz kavramlarını incelerken sık sık karşımıza çıkabilecek bir problem de verinin grafik ortamdan direk olarak sağlanmasıdır. Bu işlem İngilizce de sayıya dönüştürme veya sayısallaştırma adı verilen digitizing kavramı ile verilir. Çeşitli proseslerde kullanacağımızdan dolayı bu işlemle ilgili bir örnek programı vermekte yarar görüyoruz. Program 1.8.5-1 scanP.java SINIFI import java.io.*; import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.table.*; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import java.awt.geom.*; import java.net.URL; import java.awt.image.*; import java.util.*; public class scanP extends JPanel implements MouseListener,MouseMotionListener,MouseWheelListener { int x1[],y1[]; public JLabel jp; public double a[][]; int n; boolean mousemoved; Rectangle2D l; Ellipse2D l1,l2; Color c; Image img; public PrintWriter fout; String dosya; //BufferedWriter fout; double xmin,xmax,ymin,ymax; int xcmin,xcmax,ycmin,ycmax; public scanP(String p1, String idosya,double ixmin,double ixmax,double iymin,double iymax) {super(); dosya=idosya; try {fout=new PrintWriter(new BufferedWriter(new FileWriter(dosya))); } catch(IOException e1) {System.err.println("girdi hatası.");} catch(NumberFormatException e2){} URL url = getClass().getResource(p1); img = getToolkit().getImage(url); xmin=ixmin; xmax=ixmax; ymin=iymin; ymax=iymax; jp=new JLabel(); xcmin=(int)xmin; ycmin=(int)ymin; xcmax=(int)xmax; ycmax=(int)ymax; x1=new int[1000]; y1=new int[1000]; a=new double[2][1000]; n=-2; addMouseListener(this); addMouseMotionListener(this); addMouseWheelListener(this); mousemoved=false; } public void setMinMax(double ixmin,double ixmax,double iymin,double iymax) { xmin=ixmin; xmax=ixmax; ymin=iymin; ymax=iymax; } public JLabel getLabel() { return jp; } public void setDosyaismi(String Di) { dosya=Di; try {fout=new PrintWriter(new BufferedWriter(new FileWriter(dosya))); } catch(IOException e1) {System.err.println("girdi hatası.");} catch(NumberFormatException e2){}} public void setResimismi(String Ci) { URL url = getClass().getResource(Ci); img = getToolkit().getImage(url);} public void setCizgi(int x1i,int y1i) {if(n==-2) {xcmin=x1i;ycmin=y1i;} else if(n==-1) {xcmax=x1i;ycmax=y1i;} else {x1[n]=x1i;y1[n]=y1i; a[0][n]=xmin+(xmax-xmin)/(xcmax-xcmin)*(x1i-xcmin); a[1][n]=ymin+(ymax-ymin)/(ycmax-ycmin)*(y1i-ycmin); System.out.println(a[0][n]+" "+a[1][n]); fout.println(a[0][n]+" "+a[1][n]); }} public void paintComponent(Graphics g) { //super.paintComponent(g); Graphics2D g2=(Graphics2D)g; g2.setFont(new Font("Serif",Font.BOLD,24)); g2.setColor(Color.blue); g2.setStroke(new BasicStroke(2.0f)); Dimension d=getSize(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); int dx = d.width; int dy = d.height; g2.drawImage(img, 0, 0,dx,dy, this); if(n>=-1) { l1=new Ellipse2D.Double(xcmin-2,ycmin-2,5,5); l2=new Ellipse2D.Double(xcmax-2,ycmax-2,5,5); g2.draw(l1); g2.draw(l2); } for(int i=0;i<n;i++) {l=new Rectangle2D.Double(x1[i]-1,y1[i]-1,3,3); g2.draw(l); } } //MouseListener (fare dinleyicisi) public void mouseClicked(MouseEvent e) {} public void mouseclose() {if(!mousemoved) {fout.close(); Text.print(dosya,"digitize çıktı verisi : "+dosya+"dosyası "); mousemoved=true; } } public void mousePressed(MouseEvent e) { if(e.isMetaDown()) {mouseclose();} //sağ tuş basıldığında else if(e.isAltDown()) //orta tuş basıldığında {} else { setCizgi(e.getX(),e.getY());n++;repaint();} //sol tuş basıldığında } public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} //MouseMotionListener (fare hareket dinleyicisi) metotlari public void mouseDragged(MouseEvent e) { } public void mouseMoved(MouseEvent e) { double x1,y1; x1=xmin+(xmax-xmin)/(xcmax-xcmin)*(e.getX()-xcmin); y1=ymin+(ymax-ymin)/(ycmax-ycmin)*(e.getY()-ycmin); jp.setText("x = "+x1+"y = "+y1); } public void mouseWheelMoved(MouseWheelEvent e) {} } Program 1.8.5-2 digitizerF.java SINIFI import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.filechooser.*; public class digitizerF extends JFrame implements ActionListener { private JButton B[]; private JLabel l[]; JLabel altbar; private JTextField t[]; private JTextArea ta; private String S[]={"girdi sayfası","grafik digitizer sayfası"}; private Container c; private JPanel J[]; scanP fp; double xmin,xmax,ymin,ymax; String resim,dosya; JTabbedPane jtp; public digitizerF(String s) { super(s); xmin=0.0; xmax=10.0; ymin=0.0; ymax=10.0; resim="kalp.JPG"; dosya="a.txt"; //super("verilen bir grafikteki verilerin digital değerlerini okur"); c=getContentPane(); c.setLayout(new BorderLayout(5,5)); B=new JButton[2]; l=new JLabel[8]; t=new JTextField[6]; altbar=new JLabel(); ta=new JTextArea(toString()); jtp=new JTabbedPane(); J=new JPanel[3]; J[0]=new JPanel(); J[0].setLayout(new GridLayout(4,4)); J[1]=new JPanel(); J[2]=new JPanel(); B[0]=new JButton("JFileChoser resim okuma"); B[1]=new JButton("JFileChoser çıktı dosya"); l[0]=new JLabel("minimum x"); l[1]=new JLabel("minimum y"); l[2]=new JLabel("maksimum x"); l[3]=new JLabel("maksimum y"); l[4]=new JLabel("grafik (girdi) dosyası"); l[5]=new JLabel("çıktı koordinat dosyası"); l[6]=new JLabel("grafik (girdi) dosyası"); l[7]=new JLabel("çıktı koordinat dosyası"); t[0]=new JTextField(""+xmin); t[1]=new JTextField(""+ymin); t[2]=new JTextField(""+xmax); t[3]=new JTextField(""+ymax); t[4]=new JTextField(resim); t[5]=new JTextField(dosya); for(int i=0;i<5;i++) t[i].addActionListener(this); for(int i=0;i<2;i++) B[i].addActionListener(this); J[0].add(l[0]); J[0].add(t[0]); J[0].add(l[1]); J[0].add(t[1]); J[0].add(l[2]); J[0].add(t[2]); J[0].add(l[3]); J[0].add(t[3]); J[0].add(l[4]); J[0].add(t[4]); J[0].add(l[5]); J[0].add(t[5]); J[0].add(l[6]); J[0].add(B[0]); J[0].add(l[7]); J[0].add(B[1]); J[1].add(J[0],BorderLayout.NORTH); J[1].add(ta,BorderLayout.CENTER); jtp.addTab(S[0],J[1]); fp=new scanP(resim,dosya,xmin,xmax,ymin,ymax); //fp.setSize(1000,600); //J[2].setLayout(new FlowLayout()); J[2].add(fp,BorderLayout.CENTER); //J[2].add(fp.jp,BorderLayout.SOUTH); jtp.addTab(S[1],fp); c.add(jtp); } public String toString() {String s; s=" Turhan ÇOBAN EGE Üniversitesi, Mühendislik Fak. Makina Müh.\n"; s+="=========================================================================================\n"; s+="Komut yapısı : fareye ilk iki basış sırası ile minimum ve maksimum noktayı tanımlar.\n"; s+="Bu işlemden sonra fare ile (sol düğme) basılan her nokta verilen xmin,xmax,ymin,ymax \n"; s+="değerlerine göre double değerlere dönüştürülür. Ekranın arka planına istenilen bir resim \n"; s+="yerleştirilir. Bu resimdeki verilerden yararlanılarak basılan noktaların gerçek değerlere \n"; s+="dönüştürülmüş eşdeğerleri hesaplanır ve bizim tarafımızdan verilen bir çıktı dosyasına \n"; s+="kaydedilir. farenin sağ düğmesine basıldığında program durur ve o ana kadar alınan veri dosyaya \n"; s+=" kaydedilir ve ekrana yansıtılır.\n"; s+="=========================================================================================\n"; return s; } public void actionPerformed(ActionEvent e) { if(e.getSource()==t[0]) { Double V0=new Double(t[0].getText()); xmin=V0.doubleValue(); } else if(e.getSource()==t[1]) { Double V0=new Double(t[1].getText()); ymin=V0.doubleValue(); } else if(e.getSource()==t[2]) { Double V0=new Double(t[2].getText()); xmax=V0.doubleValue(); } else if(e.getSource()==t[3]) { Double V0=new Double(t[3].getText()); ymax=V0.doubleValue(); } else if(e.getSource()==t[4]) { resim=t[4].getText(); fp.setResimismi(resim);} else if(e.getSource()==t[5]) { dosya=t[4].getText(); fp.setDosyaismi(dosya); } else if(e.getSource()==B[0]) { File file=new File("kalp.jpg"); JFileChooser fc=new JFileChooser(); if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {file = fc.getSelectedFile();resim=file.getName();} t[4].setText(resim); fp.setResimismi(resim); } else if(e.getSource()==B[1]) { File file=new File("a.txt"); JFileChooser fc=new JFileChooser(); if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {file = fc.getSelectedFile();dosya=file.getName();} t[5].setText(dosya); fp.setDosyaismi(dosya); } System.out.println("xmin = "+xmin+"xmax="+xmax+"ymin="+ymin+"ymax="+ymax); fp.setMinMax(xmin,xmax,ymin,ymax); repaint(); } public static void main(String s[]) { JFrame f = new digitizerF("digitiser çizim programı"); f.pack(); f.setSize(800,1000); f.setVisible(true); } } Bu programı çalıştırdığımızda ekranımıza arka planda istediğimiz bir grafiğin JPG formatında resmi olan bir ekran gelecektir. Ekranda önce minimum ve maksimum noktalarımızı işaretleyerek digitizer programımızı kalibre etmemiz gerekir. Ayrıca maksimum ve minumum noktalarının x ve y koordinat değerleri de programa girilmelidir. Bundan sonra her fareye basışımızda(sol tuş) düzeltilmiş karteziyan koordinat sistemindeki veri alınarak bizim belirttiğimiz dosyaya (dosya belirtmediyseiz a.txt dosyasına) yazılacaktır. Farenin sağ tuşuna basıldığında program duracak ve kaydedilen tüm veriyi (üstte incelediğimiz Text sınıfı üzeriden) ekrana taşıyacaktır. Bu pencereden veriyi kopyeleyebiliriz veya kaydedilen dosya üzerinden herhangi bir program girdisi olarak okuyabiliriz. Şekil 1.8.5-1 digitizerF.java programı çıktısı (giriş sayfası) Şekil 1.8.5-2 digitizerF.java programı çıktısı (grafik digitizer sayfası) Şekil 1.8.5-3 digitizerF.java programı çıktısı (çıktı dosyası içeriğinin Text sınıfı ile gösterimi) 1.8.6 FONKSİYON TANIMINI PROGRAM İÇİNDE GİRDİ OLARAK TANIMLIYARAK KULLANMAK Sayısal yöntemleri kulanırken çeşitli fonksiyonların değerlendirilmesi söz konusu olacaktır. Bu tür fonksiyonları herhangi bir editöre yazarak ve sonra javac komutuyla derleyerek kullanabiliriz. Örneğin class fa extends f_x { public double func (double x) { double y=Math.cos(x) ; return y; } } Buradaki f_x sınıfı abstract bir sınıftır. abstract class f_x { //single function single independent variable // example f=x*x abstract double func(double x); } Bu yapı bize sayısal yöntemlerimizi abstract sınıf olan f_x cinsinden yazma olasılığını verir. Aynı abstract yapıyı fonksiyonların grafiklerini çizmek için girdi olarak ta kullanılabilir. Eğer daha önce yazılmış programları daha sonra yazılan fonksionlarla kullanmak istersek, bu tür abstract sınıf üzerinden yazılmış fonksiyonları kullanabiliriz. Örneğin : public class sayisal { public static double turev(f_x f,double x) { double h=0.00001; return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/(12.0*h);}} sınıfında verilen turev(f_x f,double x) metodunu f_x abstract sınıfından türeyen fa sınıfı fonksiyon için sayisal.turev(new fa(),1.0); şeklinde çağırabiliriz. Ancak yeni fonksiyon tanımını yaparken yeni program yazma gereği olması gerçek zamanda proğramı çalıştırırken yeni fonksiyon girdisi oluşturmamızı engelleyen bir yapıdır. Yeni bir fonsiyon oluştuğunda javac komutuyla derlenerek class dosyasının oluşturulması gerekir. Bu sorunun program içinde çözülmesi javax.tools.JavaCompiler ve javax.tools.ToolProvider sınıflarını kullanara çözülebilir. Bu iki sınıfı kullanarak programımızın içinde oluşan bir kodu derleyebiliriz. Bunun için String isim=”fa.java” JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int rc = javac.run(null, null, null,isim); komutlarını programımızın içinde kullanmamız yeterlidir. Bu komut fa.java dosyasını derleyecektir. fa.java dosyasını program içinde oluşturarak derleyebiliriz. Bunu oluşturacak bir örnek program listesi Program 1.8.6-1 2 boyutlu fonksiyon oluşturan functiongenerator sınıfı import java.io.*; import javax.swing.*; import javax.tools.*; import java.util.*; import java.lang.Math.*; class functiongenerator { String fonksiyon; String dosyaismi; public functiongenerator(String dosyaismi,String fonksiyon) { this.fonksiyon=fonksiyon; this.dosyaismi=dosyaismi; } public functiongenerator(String fonksiyon) {this.fonksiyon=fonksiyon; dosyaismi="fa"; } public void addfunction(String fonksiyon) {this.fonksiyon=fonksiyon;} public String toString() {return fonksiyon;} public functiongenerator() {fonksiyon="x*x-4.0"; dosyaismi="fa"; } public String createfunction() {String isim=dosyaismi+".java"; String s=""; try {PrintWriter fout=new PrintWriter(new BufferedWriter(new FileWriter(isim))); s+="class "+dosyaismi+" extends f_x\n"; s+=" {\n"; s+=" public double func (double x)\n"; s+="{ double y="+fonksiyon+";\n"; s+=" return y;\n"; s+="}\n"; s+="}\n"; fout.println(s); //System.out.println(s); fout.close(); } catch(IOException e1) {System.err.println("girdi hatası.");} catch(NumberFormatException e2){}; try{ JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int rc = javac.run(null, null, null,isim);} catch(NullPointerException e1) {System.err.println("NULL POıNTER");} return fonksiyon; } protected void finalize() throws Throwable {super.finalize();} } Burada oluşturduğumuz program kodunu dosyaya yazdıktan sonra JavaCompiler kulanarak derledi. Bu durumda yeni oluşan fonksiyon kodu direk olarak çalıştırılabilir. Alttaki örnekte interaktif fonksiyon girişi ile grafik çizen bir program gurubunu oluşturduk : Program 1.8.6-2 2 boyutlu fonksiyon için String girdisi oluşturan girdi2 sınıfı import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.event.*; import java.io.*; import java.util.*; public class girdi2 extends Thread implements ActionListener { Container c; String s=" "; String s1=""; functiongenerator fg; JTextArea jt; JButton bb; boolean basildi; public girdi2(String isim,String fonksiyon) { jt=new JTextArea(s,5,30); jt.setFont(new Font("SansSerif",Font.PLAIN,20)); fg=new functiongenerator(); bb=new JButton("fonksiyon yazıldığında basınız. değişken : x"); JScrollPane jsp=new JScrollPane(jt); JFrame cerceve=new JFrame("fonksiyon girdi penceresi örnek: Math.sin(x)-1/(x*x-1) "); cerceve.addWindowListener(new BasicWindowMonitor()); c=cerceve.getContentPane(); c.setLayout(new BorderLayout()); c.add(jsp,BorderLayout.NORTH); c.add(bb,BorderLayout.SOUTH); bb.addActionListener(this); cerceve.pack(); cerceve.setVisible(true); basildi=false; } public String vericiktisi() { while(!basildi) { try {Thread.sleep(100);} catch(InterruptedException e) {System.err.println(e.toString());} } return s1; } protected void finalize() throws Throwable {super.finalize();} public void actionPerformed( ActionEvent e) { if(e.getSource()==bb) {s=jt.getText();fg.addfunction(s);s1=fg.createfunction(); basildi=true; try{fg.finalize();finalize(); } catch(Throwable e1) {System.err.println("girdi hatası.");} } } } Program 1.8.6-3 2 boyutlu fonksiyon için String girdisi oluşturan girdi2 sınıfınını çağıran ce1.java sınıfı import java.io.*; import javax.swing.*; import javax.tools.*; import java.util.*; import java.lang.Integer; import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; import java.util.Locale; import java.text.*; import java.util.*; import javax.swing.table.*; import static java.lang.Math.*; class ce1 { String s; public ce1() {girdi2 g=new girdi2("fa"," "); s=g.vericiktisi(); try{ g.finalize();} catch(Throwable e1) {System.err.println("girdi hatası.");} } public ce1(String function) { functiongenerator g=new functiongenerator("fa",function); s=g.createfunction(); try{ g.finalize();} catch(Throwable e1) {System.err.println("girdi hatası.");} } public static void main(String arg[]) { //String s1=JOptionPane.showInputDialog(" Fonksiyonu giriniz : "); ce1 x0=new ce1(); double a[]=Text.readDoubleV("Fonksiyonun minimum ve maksimum değerlerini giriniz xmin xmax"); ce3 x1=new ce3(a[0],a[1],100,x0.s); //ce8 x2=new ce8(a[0],a[1],x0.s); } } Program 1.8.6-3 2 boyutlu fonksiyonu için çizmek için Plot sınıfını çağıran ce3 sınıfı import java.io.*; import javax.swing.*; import javax.tools.*; import java.util.*; import java.lang.Integer; import java.awt.*; import java.awt.event.*; import java.awt.font.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; import java.util.Locale; import java.text.*; import java.util.*; import javax.swing.table.*; class ce3 extends JApplet { public ce3(double x1,double x2,int n,String s) {Plot pp=new Plot(new fa(),x1,x2,n); pp.setPlabel("f(x)="+s); pp.plot(); } public ce3(double x1,double x2,int n) {Plot pp=new Plot(new fa(),x1,x2,n); pp.plot(); } public ce3(double x1,double x2) {Plot pp=new Plot(new fa(),x1,x2,50); pp.plot(); } } ce2 sınıfı çalıştırıldığında pencerelerinden fonksiyon ve grafik sınır şartlarını girdikten sonra 2 boyutlu grafik çıktısını elde edebiliriz. Görüldüğü gibi burada fonksiyon girdisi oluşturabildik. Burada program içinde program yazmanın bir örneği verilmiş oldu. Bu örneği genelleştirerek her türlü programlama işlemlerimiz için kullanabiliriz. İkinci bir örnek olarak 3boyutlu bir fonksiyon oluşturan functiongnerator3 sınıfını verelim import java.io.*; import javax.swing.*; import javax.tools.*; import java.util.*; class functiongenerator3D extends Thread { String fonksiyon; String dosyaismi; public functiongenerator3D(String dosyaismi,String fonksiyon) { this.fonksiyon=fonksiyon; this.dosyaismi=dosyaismi; } public functiongenerator3D(String fonksiyon) {this.fonksiyon=fonksiyon; dosyaismi="fb"; } public functiongenerator3D() {fonksiyon="x[0]*x[0]+x[1]*x[1]-4.0"; dosyaismi="fb"; } public void addfunction(String fonksiyon) {this.fonksiyon=fonksiyon; } public String toString() {return fonksiyon;} public String createfunction() {String isim=dosyaismi+".java"; String s=""; try {PrintWriter fout=new PrintWriter(new BufferedWriter(new FileWriter(isim))); s+="class "+dosyaismi+" extends f_xj\n"; s+="{\n"; s+="public double func(double w[])\n"; s+="{//çözümü istenen fonksiyon\n"; s+="double x=w[0];\n"; s+="double y=w[1];\n"; s+="double ff;\n"; s+="ff="+fonksiyon+";\n"; s+="return ff;\n"; s+="}\n"; s+="}\n"; fout.println(s); //System.out.println(s); fout.close(); } catch(IOException e1) {System.err.println("girdi hatası.");} catch(NumberFormatException e2){}; JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int rc = javac.run(null, null, null,isim); return s; } protected void finalize() throws Throwable {super.finalize();} } 1.8.7 RASLANTISAL ULAŞIM DOSYASI OKU (RANDOM ACCESS FILE) Rastlantısal Ulaşım Dosyasının (Random Access File) Ardışık Dosya sisteminden temel farkı, Teyp kaydıyla CD kaydı arasındaki fark gibidir. Ardışık dosyalar Teyp kaydı şeklinde birbiri ardı sıra gelen bilgilerden oluşur. Rastlantısal Ulaşım sisteminde ise CD gibi herhangi bir kayıta kayıt numarası kullanılarak doğrudan ulaşmak mümkündür. Rastlantısal Ulaşım dosyası işlemleri RandomAccessFile sınıfı üzerinden yapılır. Bu sınıfın tanımı : public class RandomAccessFile extends Object implements DataOutput, DataInput { public RandomAccessFile(String name,String mode) throws IOException public RandomAccessFile(File file,String mode) throws IOException public final FileDescriptor getFD() throws IOException public int read() throws IOException public int read(byte b[],int off,int len) throws IOException public int read(byte b[]) throws IOException public final void readFully(byte b[]) throws IOException public final void readFully(byte b[],int off,int len) throws IOException public int skipBytes(int n) throws IOException public void write(int b) throws IOException public void write(byte b[]) throws IOException public void write(byte b[],int off,int len) throws IOException; public long getFilePointer() throws IOException; public void seek(long pos) throws IOException; public void seek(long pos) throws IOException; public long length() throws IOException; public void close() throws IOException; public final byte readByte() throws IOException; public final int readUnsignedByte() throws IOException; public final short readShort() throws IOException; public final int readUnsignedShort() throws IOException; public final char readChar() throws IOException; public final int readInt() throws IOException; public final long readLong() throws IOException; public final float readFloat() throws IOException; public final double readDouble() throws IOException; public final String readLine() throws IOException; public final String readUTF() throws IOException; public final void writeBoolean(boolean v) throws IOException; public final void writeByte(int v) throws IOException; public final void writeShort(int v) throws IOException; public final void writeChar(int v) throws IOException; public final void writeInt(int v) throws IOException; public final void writeLong(long v) throws IOException; public final void writeFloat(float v) throws IOException; public final void writeDouble(double v) throws IOException; public final void writeBytes(String s) throws IOException; public final void writeChars(String s) throws IOException; public final void writeUTF(String str) throws IOException; } Burada tanımlanan metodların görevlerine kısaca bir bakacak olursak : getFD() : dosya (File) tanımını verir getFilePointer() : Dosyanın (File) o anda hangi dosya referansını gösterdiğini belirtir. length() : Dosyadaki toplam referans sayısını verir. read() : Byte (char değişkeni karşılığı) olarak dosyadan bilgiyi okur (bir byte). read(byte[]) : Byte (char değişkeni karşılığı) olarak dosyadan bilgiyi okur (byte[] değişkeninin boyu kadar) ve byte degişkenine aktarır. read(byte[], int baslangıç_indisi, int indis_boyutu) : Byte (char değişkeni karşılığı) olarak dosyadan bilgiyi okur (byte[] değişkeninin boyu kadar, başlangıç indisinden başlayarak, indis_boyutu uzunluğunda) ve byte degişkenine aktarır. readBoolean() : boolean değişken okur readByte() : dosyadan integer tipi byte değişken (işaretli 8-bit ) okur. readChar() : Dosyadan Unicode karekter (character) okur. readDouble() : Dosyadan double değişkeni okur. readFloat() : Dosyadan float değişkeni okur. readFully(byte[] b) : dosyadan byte olarak okur readFully(byte[] b, int baslangıç_indisi, int toplam_boy) : dosyadan bte olarak sadece byte boyutlu değişkeninin başlangıc_indisi’nden başlamak üzere taplam_boy kadar kısmını okur. readInt() : Dosyadan int değişkeni okur. readLine() : Dosyadan “\n” = yeni satır işaretini veya “\r” satırbaşı işaretini veya herikisini birden arka arkaya görene kadar yazılan her şeyi bütün bir satır olarak okur. readLong(): Dosyadan Long (Long integer) değişkeni okur. readShort(): Dosyadan Short (Short integer) değişkeni okur. readUnsignedByte(): İşaretsiz Byte değeri okur. readUnsignedShort(): İşaretsiz 16 bitlik Short integer değeri okur. readUTF(): UTF stringi okur seek(long) : indisi herhangi bir bilgi gurubu indisine ayarlar. skipBytes(int n) : n bit input değerini okumadan atlar Aşağıdaki tanımlar read tanımlarına parelel olan write terimleridir. write(byte[]) : byte boyutlu değişkenini yazar. write(byte[],int baslangıç_indisi, int toplam_boy) : dosyaya byte olarak sadece byte boyutlu değişkeninin başlangıc_indisi’nden başlamak üzere taplam_boy kadar kısmını yazar. write(int) : dosyaya byte boyutlu değişkenini yazar writeBoolean(boolean) : dosyaya boolean boyutlu değişkenini yazar writeByte(int) : dosyaya int girdisini byte olarak yazar writeBytes(String) : dosyaya String girdisini byte boyutlu değişkeni olarak yazar writeChar(int) : dosyaya int girdisini Char olarak yazar writeChars(String) : dosyaya string girdisini char boyutlu değişkeni olarak yazar writeDouble(double) : dosyaya double girdisini double olarak yazar. writeFloat(float) : dosyaya float girdisini float olarak yazar writeInt(int) : dosyaya int girdisini int olarak yazar. writeLong(long) : dosyaya long(integer) girdisini long(integer) olarak yazar writeShort(int) : dosyaya integer gidisini short(integer) olarak yazar. writeUTF(String) : dosyaya String girdisini UTF string olarak yazar. RandomAccessFile sınıfının tanımından da görüldüğü gibi b sınıf DataOutput ve DataInput sınıflarını implement eder. DataOutput ve DataInput sınıflarınını tanımı : public interface DataOutput { public abstract void write(int b) throws IOException public abstract void write(byte b[]) throws IOException public abstract void write(byte b[],int off,int len) throws IOException public abstract void writeBoolean(boolean v) throws IOException public abstract void writeByte(int v) throws IOException public abstract void writeShort(int v) throws IOException public abstract void writeChar(int v) throws IOException public abstract void writeInt(int v) throws IOException public abstract void writeLong(long v) throws IOException public abstract void writeFloat(float v) throws IOException public abstract void writeDouble(double v) throws IOException public abstract void writeBytes(String s) throws IOException public abstract void writeChars(String s) throws IOException public abstract void writeUTF(String str) throws IOException } public interface DataInput { public abstract void readFully(byte b[]) throws IOException public abstract void readFully(byte b[],int off,int len) throws IOException public abstract int skipBytes(int n) throws IOException public abstract boolean readBoolean() throws IOException public abstract byte readByte() throws IOException public abstract int readUnsignedByte() throws IOException public abstract short readShort() throws IOException public abstract int readUnsignedShort() throws IOException public abstract int readInt() throws IOException public abstract long readLong() throws IOException public abstract float readFloat() throws IOException public abstract double readDouble() throws IOException public abstract String readLine() throws IOException public abstract String readUTF() throws IOException } RandomAccessFile Çok daha çabuk ulaşım olanakları yaratır. Raslantısal Ulaşım dosyası örneği olarak aşağıdaki paketi veriyoruz. Kayit sınıfı tek bir kayıtın yazılıp okunabilmesi için gerekli olan bilgileri içeriyor. Kayıtların hesap numarası, isim, soyisim ve hesaptaki paradan oluştuğunu kabul ediyoruz. Bütün bu kayıtları bir arada yapmak için oku ve yaz metotları bu sınıfın içindr tanımlanmıştır. Raslantısal ulaşım kanalının dosyaya açılması için : try{ girdi=new RandomAccessFile("musteri1.dat","rw"); } catch(IOException e) { System.err.println("Dosya acma hatasi\n"+e.toString()); System.exit(1); } yapısı kullanbilir. Buradaki “rw” yapısı dosyaya hem yazı yazılıp hem okunabileceğini belirtir. “r” sadece okumak için “w” sadece yazmak için kullanılır. RandomAccessFile içinde yer alan close() metodu RandomAccessFile (Raslantısal Ulaşım Dosyası) kanalını ve ilgili tüm sınıfları kapatır. örnek olarak : private void closeFile() { try{ girdi.close(); System.exit(0); } catch(IOException e) { System.err.println("Error closing filr\n"+e.toString()); System.exit(1); } } metotu verilebilir. Şimdi de örnek programın listelerini verelim: Program 1.8.7-1 Kayit.java raslantısal ulaşım dosyası kayıt programı import java.io.*; public class Kayit { private int hesap; private String soyIsim; private String Isim; private double hesaptakiPara; public void oku(RandomAccessFile dosya) throws IOException { //RandomAccessFile = Raslantisal Ulasim dosyasi hesap=dosya.readInt(); char first[]=new char[15]; for(int i=0;i<first.length;i++) { first[i]=dosya.readChar(); } Isim=new String(first); char last[]=new char[15]; for(int i=0;i<first.length;i++) { last[i]=dosya.readChar(); } soyIsim=new String(last); hesaptakiPara=dosya.readDouble(); } public void yaz(RandomAccessFile dosya) throws IOException { StringBuffer buf; dosya.writeInt(hesap); if(Isim!=null) buf=new StringBuffer(Isim); else buf=new StringBuffer(15); buf.setLength(15); dosya.writeChars(buf.toString()); if(soyIsim!=null) buf=new StringBuffer(soyIsim); else buf=new StringBuffer(15); buf.setLength(15); dosya.writeChars(buf.toString()); dosya.writeDouble(hesaptakiPara); } public void yazhesap(int a) {hesap = a;} public int okuhesap() {return hesap;} public void yazIsim(String f){Isim=f;} public String okuIsim() {return Isim;} public void yazsoyIsim(String f){soyIsim=f;} public String okusoyIsim() {return soyIsim;} public void yazhesaptakiPara(double b) {hesaptakiPara=b;} public double okuhesaptakiPara() {return hesaptakiPara;} public static int boyut() {return 72;} } Program 1.8.7-2 RaslantisalUlasimDosyasiYarat.java programı import java.io.*; import java.awt.*; import java.awt.event.*; import Kayit; public class RaslantisalUlasimDosyasiYarat { private Kayit hesapDosyasi; private RandomAccessFile girdi; public RaslantisalUlasimDosyasiYarat() { hesapDosyasi = new Kayit(); try{ girdi = new RandomAccessFile("musteri1.dat","rw"); for(int i=0;i<100;i++) { hesapDosyasi.yaz(girdi); } } catch(IOException e) { System.err.println("Dosya acma hatasi\n"+e.toString()); System.exit(1); } } public static void main(String args[]) { RaslantisalUlasimDosyasiYarat H= new RaslantisalUlasimDosyasiYarat(); } } Program 1.8.7-3 RaslantisalUlasimDosyasiYaz.java programı import java.io.*; import java.awt.*; import java.awt.event.*; import Kayit; public class RaslantisalUlasimDosyasiYaz extends Frame implements ActionListener { private TextField hesapAlani,isimAlani,soyisimAlani,hesaptakiParaAlani; private Button birsonraki,kapat; private RandomAccessFile girdi; private Kayit hesapDosyasi; public RaslantisalUlasimDosyasiYaz() { super("Tesadufi ulasim dosyasina yaz"); hesapDosyasi=new Kayit(); try{ girdi=new RandomAccessFile("musteri1.dat","rw"); } catch(IOException e) { System.err.println("Dosya acma hatasi\n"+e.toString()); System.exit(1); } setSize(300,150); setLayout(new GridLayout(5,2)); add(new Label("Hesap numarasi:")); hesapAlani=new TextField(); add(hesapAlani); add(new Label("isim : ")); isimAlani=new TextField(20); add(isimAlani); add(new Label("Soyisim : ")); soyisimAlani=new TextField(20); add(soyisimAlani); add(new Label("Hesaptaki para : ")); hesaptakiParaAlani=new TextField(20); add(hesaptakiParaAlani); birsonraki=new Button("Gir"); birsonraki.addActionListener(this); add(birsonraki); kapat=new Button("cikis"); kapat.addActionListener(this); add(kapat); setVisible(true); } public void addKayit() { int accountNumber=0; Double d; if(!hesapAlani.getText().equals("")) { try{ accountNumber=Integer.parseInt(hesapAlani.getText()); if(accountNumber0 && accountNumber <=100) { hesapDosyasi.yazhesap(accountNumber); hesapDosyasi.yazIsim(isimAlani.getText()); hesapDosyasi.yazsoyIsim(soyisimAlani.getText()); d=new Double(hesaptakiParaAlani.getText()); hesapDosyasi.yazhesaptakiPara(d.doubleValue()); girdi.seek((long)(accountNumber-1)*Kayit.boyut()); hesapDosyasi.yaz(girdi); } hesapAlani.setText(""); isimAlani.setText(""); soyisimAlani.setText(""); hesaptakiParaAlani.setText(""); } catch(NumberFormatException nfe) { System.err.println("Hesap numarasi tamsayi degisken olamalidir"); } catch(IOException io) { System.err.println("Dosyaya yazarken hata olustu\n"+io.toString()); System.exit(1); } } } public void actionPerformed(ActionEvent e) { addKayit(); if(e.getSource()==kapat) { try{ girdi.close();} catch(IOException io) { System.err.println("Dosya kapatilamadi\n"+io.toString()); } System.exit(0); } } public static void main(String args[]) { new RaslantisalUlasimDosyasiYaz(); } } Program 1.8.7-4 RaslantisalUlasimDosyasiOku.java programı import java.io.*; import java.awt.*; import java.awt.event.*; import Kayit; public class RaslantisalUlasimDosyasiOku extends Frame implements ActionListener { private TextField hesapAlani,isimAlani,soyisimAlani,hesaptakiParaAlani; private Button birsonraki,kapat; private RandomAccessFile girdi; private Kayit hesapDosyasi; public RaslantisalUlasimDosyasiOku() { super("Musteri dosyasini oku"); try{ girdi=new RandomAccessFile("musteri1.dat","r"); } catch(IOException e) { System.err.println("Dosya acilamadi\n"+e.toString()); System.exit(1); } hesapDosyasi=new Kayit(); setSize(300,150); setLayout(new GridLayout(5,2)); add(new Label("Hesap numarasi :")); hesapAlani=new TextField(); add(hesapAlani); add(new Label("isim : ")); isimAlani=new TextField(20); add(isimAlani); add(new Label("soyisim : ")); soyisimAlani=new TextField(20); add(soyisimAlani); add(new Label("Hesaptaki para : ")); hesaptakiParaAlani=new TextField(20); add(hesaptakiParaAlani); birsonraki=new Button("bir sonraki hesap"); birsonraki.addActionListener(this); add(birsonraki); kapat=new Button("cikis"); kapat.addActionListener(this); add(kapat); setVisible(true); } public void okuKayit() { int hesap; String ilk,son; double balance; { try{ do{ hesapDosyasi.oku(girdi); } while(hesapDosyasi.okuhesap()==0); hesapAlani.setText(String.valueOf(hesapDosyasi.okuhesap())); isimAlani.setText(String.valueOf(hesapDosyasi.okuIsim())); soyisimAlani.setText(String.valueOf(hesapDosyasi.okusoyIsim())); hesaptakiParaAlani.setText(String.valueOf(hesapDosyasi.okuhesaptakiPara())); } catch(EOFException eof) { closeFile(); } catch(IOException io) { System.err.println("Dosyayı okurken hata olustu\n"+io.toString()); System.exit(1); } } } public void actionPerformed(ActionEvent e) { if(e.getSource()==birsonraki) okuKayit(); else closeFile(); } private void closeFile() { try{ girdi.close(); System.exit(0); } catch(IOException e) { System.err.println("Error closing filr\n"+e.toString()); System.exit(1); } } public static void main(String args[]) { new RaslantisalUlasimDosyasiOku(); } } Şekil 1.8.7-1 RaslantisalUlasimDosyasiYaz.java Frame çıktısı Yukarıdaki programın ilginç bir yönü de Frame sınıfını kullanmış olmasıdır. Frame ve swing eşiti JFrame konsol ortamında kullanılabilen grafik ortamı programlamasıdır. Temel olarak applet yapılarında kullanılan her yerde Frame de kullanılabilir. Frame main programdan başlatılır. Html dosyasından başlatılmaz. 1.8.8 DOSYA SIKIŞTIRILMASI (GZIP,GUNZIP,ZIP,UNZIP) java.util.zip paketi veri sıkıştırmaya yarayan dosyaları içerir. Günümüz bilgisayar kullanımında GZIP ve ZIP adı verilen bu yapılar ZLIB sıkıştırma algoritmasında tanımlanmıştır. Bu algoritm RFC 1950,RFC 1951 ve RFC 1952 dokümanlarında tanımlanmıştır. Bu dokümanlara http://www.faqs.org/rfcs adresinden ulaşılabilir. Kullanma açısından bu dokümanlara ihtiyacınız yoktur. Gerekli programlar java zip paketinde bulunmaktadır. GZIP tek bir dosyayı sıkıştırarak isim.gz ismiyle sıkıştırılmış dosya oluşturur. Bunun için GZIPOutputStream dosyasına bir FileOutptStream açmamız kafidir. Program 1.8.4 den de görüleceği gibi GZIPOutputStream zipout; try { FileOutputStream out = new FileOutputStream(zipname); zipout = new GZIPOutputStream(out); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya oluşturma hatası : " + zipname + "."); return; } deyimi dosyanın gzip olarak yazılması için gerekli kanalı oluşturur. Program 1.8.8-1 Gzip.java dosya sıkıştırma programı //dosya: GZip.java import java.io.*; import java.util.zip.*; import javax.swing.JOptionPane; public class GZip { public static int sChunk = 8192; public static void main(String[] args) { if (args.length != 1) { JOptionPane.showInputDialog(null,"KULLANIM: java GZip girisdosyasi"); return; } // çıktı doyası oluştur. String zipname = args[0] + ".gz"; GZIPOutputStream zipout; try { FileOutputStream out = new FileOutputStream(zipname); zipout = new GZIPOutputStream(out); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya oluşturma hatası : " + zipname + "."); return; } byte[] buffer = new byte[sChunk]; // dosyayı sıkıştır try { FileInputStream in = new FileInputStream(args[0]); int length; while ((length = in.read(buffer, 0, sChunk)) != -1) zipout.write(buffer, 0, length); in.close( ); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya sıkıştırma hatası : " + args[0] + "."); } try { zipout.close( ); } catch (IOException e) {} } } GZIP işleminin tersini yapmak içinse parelel olarak : GZIPInputStream zipin; try { FileInputStream in = new FileInputStream(zipname); zipin = new GZIPInputStream(in); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya açma hatası : " + zipname + "."); return; } yapısı kullanılır. Programların çalışması için java isim deyiminden sonra dostya ismini vermek kafidir. C:\co\java\prog>java Gzip a.dat veya C:\co\java\prog >java Gunzip a.dat.gz gibi. Program 1.8.8-2 GUnzip.java dosya sıkıştırılmış dosyayı açma programı //dosya : GUnzip.java import java.io.*; import java.util.zip.*; import javax.swing.JOptionPane; public class GUnzip { public static int sChunk = 8192; public static void main(String[] args) { if (args.length != 1) { JOptionPane.showInputDialog(null,"KULLANIM: java GUnzip girisdosyasi"); return; } // girdi dosyasını incele String zipname, source; if (args[0].endsWith(".gz")) { zipname = args[0]; source = args[0].substring(0, args[0].length( ) - 3); } else { zipname = args[0] + ".gz"; source = args[0]; } GZIPInputStream zipin; try { FileInputStream in = new FileInputStream(zipname); zipin = new GZIPInputStream(in); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya açma hatası : " + zipname + "."); return; } byte[] buffer = new byte[sChunk]; // dosyayı aç (decompress) try { FileOutputStream out = new FileOutputStream(source); int length; while ((length = zipin.read(buffer, 0, sChunk)) != -1) out.write(buffer, 0, length); out.close( ); } catch (IOException e) { JOptionPane.showInputDialog(null,"Dosya sıkıştırılması açılma hatası : " + args[0] + "."); } try { zipin.close( ); } catch (IOException e) {} } } ZIP ve UNZIP biraz daha kompleks bir yapıya sahiptir. Çünki bu proseste direktory içindeki dosyaların açılma işlemi söz konusudur. Prosesi izah etmek için önce ZIP işlemi yapan bir programa göz atalım : Program 1.8.8-3 zip.java dosya sıkıştırma programı // dosya : zip.java // Turhan Çoban 24.2.2001 import java.io.*; import java.util.*; import java.util.zip.*; import javax.swing.JOptionPane; public class zip { public static int sChunk = 8192; public static String[] dosyalistesi(String p) { File path=new File(p); if(path.isDirectory()) { Vector x=new Vector(); File files[]; files=path.listFiles(); int n=files.length; int n1=0; for(int i=0;i<n;i++) { if(!files[i].isDirectory()) { x.addElement(files[i].toString()); n1++; } } String s1[]; s1=new String[n1]; Enumeration nn=x.elements(); int k=0; while(nn.hasMoreElements()) { s1[k++]=(String)nn.nextElement(); } return s1; } else { String[] s1 = new String[1]; s1[0]=p; return s1; } } public static void main(String[] args) { String str=""; FileOutputStream out; ZipOutputStream zout; String zipname, source; String s="KULLANIM: \n"+ "java zip zipdosyası dosya(veyadirectory)ismi1 dosya(veyadirectory)ismi1...\n"+ " zip dosyası yarat ve dosya(veya directorylerdeki dosyaları) sıkıştır "+ " alt direktoryler atlanmaktadır tekrar tanımla"; // anahtarı kontrol et if(args.length<1 ) { String s1="zipdosyası isim.zip tanımlanmadı lütfen argümanları giriniz\n"+s; JOptionPane.showMessageDialog(null,s1); System.exit(0); return; } // girdi dosyasını incele else if(args.length<2) { String s1="sıkıştırılacak dosya(veya direktory) isimleri tanımlanmadı\n"+ " lütfen argümanları giriniz\n"+s; JOptionPane.showMessageDialog(null,s1); System.exit(0); return; } if (args[0].endsWith(".zip")) { zipname = args[0]; source = args[0].substring(0, args[0].length( ) - 3); } else { zipname = args[0] + ".zip"; source = args[0]; } //zip kanalını tanımla try { out = new FileOutputStream(zipname); zout=new ZipOutputStream(out); } catch (IOException e) { JOptionPane.showMessageDialog(null,"Dosya oluşturma hatası : " + zipname + "."); return; } int k=1; while(k<args.length) { try { String ss[]; ss=dosyalistesi(args[k]); int j=0; byte[] buffer=new byte[sChunk]; while(j<ss.length) { ZipEntry giris=new ZipEntry(ss[j]); zout.putNextEntry(giris); try { FileInputStream in=new FileInputStream(ss[j]); int length; while((length=in.read(buffer,0,sChunk))!=-1) zout.write(buffer,0,length); in.close(); } //try sonu catch (IOException e) { JOptionPane.showMessageDialog(null,"Dosya sıkıştırma hatası : " +ss[j] ); } //catch sonu } str+="ss["+j+"] = "+ss[j]+" "+giris+" iceri girdi\n"; j++; }//while sonu } //try sonu catch(IOException io) {} k++; } //while(k< sonu try{ zout.close(); out.close(); } catch(IOException e){} JOptionPane.showMessageDialog(null,str); System.exit(0); } } örnek program girdisi : java zip zip1.zip c:\co\java\prog\a d.dat c:\co\java\prog\a\b Şekil 1.8.8-1 zip.java programını çıktısı şimdi de ZIP yapılmış bir dosyayı açan Unzip.java programına bir göz atalım : Program 1.8.8-3 Unzip.java dosya sıkıştırılmış dosyayı açma programı //dosya : Unzip.java import java.io.*; import java.util.zip.*; import javax.swing.JOptionPane; public class Unzip { public static int sChunk = 8192; public static void main(String[] args) { String zipname, source; String s=""; if (args.length != 1) { JOptionPane.showMessageDialog(null,"KULLANIM: java Unzip girisdosyasi"); System.exit(0); return; } // girdi dosyasını incele if (args[0].endsWith(".zip")) { zipname = args[0]; source = args[0].substring(0, args[0].length( ) - 3); } else { zipname = args[0] + ".zip"; source = args[0]; } s+="zip dosyası : "+zipname+" içideki sıkıştırılmış \n"; try { FileInputStream in = new FileInputStream(zipname); ZipInputStream zin=new ZipInputStream(in); byte[] buffer = new byte[sChunk]; // dosyayı aç (decompress try{ ZipEntry z; do { z=zin.getNextEntry(); try { FileOutputStream out = new FileOutputStream(z.getName()); int length; while ((length = zin.read(buffer, 0, sChunk)) != -1) out.write(buffer, 0, length); out.close( ); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Dosya sıkıştırma hatası : " + args[0] + "."); System.exit(0); } s+=" "+z.getName()+" \n"; }while(z!=null); } catch(NullPointerException npe) { s+="dosyaları açıldı";JOptionPane.showMessageDialog(null,s); System.exit(0); } try { zin.close(); } catch (IOException e) {} } catch(IOException e) { JOptionPane.showMessageDialog(null,"Dosya açılma hatası : " + zipname); System.exit(0); } } } programı java unzip zip1.zip komutu kullanarak çalıştırırsak : Şekil 1.8.7-2 unzip.java programını çıktısı Çıktısını elde ederiz. Burada zip dosyasına ulaşmak için : FileInputStream in = new FileInputStream(zipname); ZipInputStream zin=new ZipInputStream(in); Deyimini kullandık. Zipli dosyayı okumak için ise : ZipEntry z; do { z=zin.getNextEntry(); try { FileOutputStream out = new FileOutputStream(z.getName()); int length; while ((length = zin.read(buffer, 0, sChunk)) != -1) out.write(buffer, 0, length); out.close( ); } gurubunu kullandık. Burada temel olarak iki yeni sınıf kullanıldı. Bunlardan birincisi ZipInputStream, diğeri ise ZipEntry sınıfları idi. Şimdi bu iki sınıfın tanımlarına göz atalım : public class ZipInputStream extends InflaterInputStream implements ZipConstants { private ZipEntry entry; private CRC32 crc; private long remaining; private byte[] tmpbuf ; private static final int STORED; private static final int DEFLATED; private boolean closed ; private boolean entryEOF; private void ensureOpen() throws IOException; public ZipInputStream(InputStream in) ; public ZipEntry getNextEntry() throws IOException; public void closeEntry() throws IOException; public int available() throws IOException ; public int read(byte[] b, int off, int len) throws IOException; public long skip(long n) throws IOException ; public void close() throws IOException; private ZipEntry readLOC() throws IOException; private static String getUTF8String(byte[] b, int off, int len) throws IOException; protected ZipEntry createZipEntry(String name) throws IOException; private void readEnd(ZipEntry e) throws IOException; private void readFully(byte[] b, int off, int len) throws IOException; private static final int get16(byte b[], int off); private static final long get32(byte b[], int off); } ZipOutputStream’in tanımı ise : public class ZipOutputStream extends DeflaterOutputStream implements ZipConstants { private ZipEntry entry; private Vector entries; private Hashtable names ; private CRC32 crc; private long written; private long locoff ; private String comment; private int method ; private boolean finished; private boolean closed = false; private void ensureOpen() throws IOException public static final int STORED ; public static final int DEFLATED; public ZipOutputStream(OutputStream out) public void setComment(String comment) public void setMethod(int method public void setLevel(int level) public void putNextEntry(ZipEntry e) throws IOException public void closeEntry() throws IOException public void close() throws private void writeLOC(ZipEntry e) throws IOException private void writeEXT(ZipEntry e) throws IOException private void writeCEN(ZipEntry e) throws IOException private void writeEND(long off, long len) throws IOException private void writeShort(int v) throws IOException private void writeInt(long v) throws IOException private void writeBytes(byte[] b, int off, int len) throws IOException private static byte[] getUTF8Bytes(String s) } şeklindedir. Ayrıca zip dosyasının içindeki elemanlar ZipEntry sınıfında tanımlanmaktadır. ZipEntry sınıfı : public class ZipEntry implements ZipConstants, Cloneable { String name; long time; long crc ; long size; long csize; int method; byte[] extra; String comment; int flag; int version; long offset; public static final int STORED ; public static final int DEFLATED; private static native void initIDs(); public ZipEntry(String name) public ZipEntry(ZipEntry e ZipEntry(String name, long jzentry ZipEntry(long jzentry) public String getName() public void setTime(long time) public long getTime() public void setSize(long size) public long getSize() public long getCompressedSize() public void setCompressedSize(long csize) public void setCrc(long crc) public long getCrc() public void setMethod(int method) public int getMethod() public void setExtra(byte[] extra) public byte[] getExtra() public void setComment(String comment) public String getComment() public boolean isDirectory() public String toString() private static long dosToJavaTime(long dtime) private static long javaToDosTime(long time) public int hashCode() public Object clone() } şeklinde tanımlanmıştır. Burada şu ana kadar verdiğimiz sınıf tanımları ile ilgili şunu söyliyelim. Tanımlamalar sadece sınıf ve değişken adlarını vermektedir, gerçek programı açtığınızda göreceğiniz koda benzemezler sadece metod isimlerini taşırlar. BÖLÜM 1.9 GELİŞMİŞ JAVA BİLGİ İŞLEME YAPILARI 1.9.0 GİRİŞ Bu bölümde çeşitli ileri bilgi işleme ve boyut oluşturma kavramlarına göz atacağız. 1.9.1 STRINGTOKENIZER SINIFI Biz bir cümle okuduğumuzda beynimiz cümleyi otomatik olarak kelimelerine ayırır. Java Dilinde bu görevi StringTokenizer sınıfı yerine getirir. StringTokenizer sınıfının yapısı : Public class StringTokenizer implements Enumeration { private int currentPosition; private int maxPosition; private String str; private String delimiters; private boolean retTokens; public StringTokenizer(String str, String delim, boolean returnTokens) public StringTokenizer(String str, String delim) public StringTokenizer(String str) private void skipDelimiters() public boolean hasMoreTokens() public String nextToken() public String nextToken(String delim) public boolean hasMoreElements() public Object nextElement() public int countTokens() } StringTokenizer sıfını açıklamak için önce küçük bir program verelim : Program 1.9.1 : StringTokenizerTest.java programı import java.io.*; import java.util.*; public class StringTokenizerTest { public static void main(String arg[]) { String s="Ali veli 49 elli"; System.out.println("cumle : "+s); StringTokenizer t=new StringTokenizer(s); System.out.println("kelime sayisi : "+t.countTokens()); int i=0; while(t.hasMoreTokens()) { System.out.println("kelime indeksi : "+(i++)+" kelime : "+t.nextToken()); } } } Programdan da görüleceği gibi StringTokenizer sınıfı StringTokenizer t=new StringTokenizer(s); deyimiyle tanımlanmıştır. Ayrıca string’in içindeki cümle sayısı t.countTokens(); metoduyla çağırılmış, t.hasMoreTokens() sınıfı ise daha fazla kelime kalıp kalmadığının boolean kontrolü metodu olarak çağırılmıştır. t.nextToken() metodu o andaki kelimeyi dışarıya (String cinsinden) aktarırken indeksi de (currentPosition) bir sonraki kelimeye kaydırır. Program çıktısı : cümle : Ali veli 49 elli kelime sayısı : 4 kelime indeksi : 0 kelime : Ali kelime indeksi : 1 kelime : veli kelime indeksi : 2 kelime : 49 kelime indeksi : 3 kelime : elli olacaktır. StringTokenizer sınıfının alt değişkenleri : nval : eğer seçilmiş olan token bir sayı ise nval bu sayının değerini içerir. sval eğer seçilmiş olan token bir kelime(String) ise sval bu String değişkenini içerir TT_EOF girdi stringinin sonuna ulaşıldığını gösterir TT_EOL satır sonu okunduğunu bildirir TT_NUMBER bir sayi tokeni okunduğunu bildirir TT_WORD bir kelime(String) token'i okunduğunu bildirir.. ttype nextToken metotu çağrıldıkrtan sonra bu değişken en son okunan token (kelimenin) türünü bildiri StringTokenizer sınıfının metotları : kurucu metot : StreamTokenizer(Reader) eolIsSignificant(boolean) satır sonu kumutunun yeni kelime tanımlayıp tanımlamadığını belirler. lineno() satır sayısını verir. lowerCaseMode(boolean) kelimelerin otomatik olarak küçük harfe çevrilip çevrilmeyeceğini tanımlar nextToken() giriş Stringinin içindeki bir sonraki kelimeyi bulur. ordinaryChar(int) Tokanizer'in normalde kontrol için kullandığı coşluk,satır sonu gibi özel kontrol karakterlerinin normal karakter olarak okunmasını sağlar parseNumbers() Direk olarak bir sayı dizininin geldiğini haber verir pushBack() bir sonraki nextToken çağırılmasında kelimenin şu andaki kelime olarak kalmasını sağlar. quoteChar(int) eğer " karecteri varsa bunun içindeki karakterleri bir String değişkeni olarak algılar. slashSlashComments(boolean) Tokenizer'in C++-tipi (//.....)comment deyimlerini comment olarak tanıyım tanımıyacağını belirler. slashStarComments(boolean) Tokenizer'in C-tipi comment (/*...*/) deyimlerini comment olarak tanıyıp tanımıyacağını belirler. toString() o anda seçilmiş olan klimeyi (token) gönderir. whitespaceChars(int, int) birinciinteger <= c <= ikinciinteger arasındaki karekterleri boşluk olarak tanımlar wordChars(int, int) birinciinteger <= c <= ikinciinteger arasındaki karekterleri tek kelime olarak tanımlar 1.9.2 STRİNG BUFFER SINIFI Yeri gelmişken String sınıfının kardeş sınıfı, StringBuffer sınıfından da bahsedelim. StringBuffer genel olarak String sınıfının aynıdır, fakat genellikle dinamik olarak program içinde değeri sıkça değişen String’ler için kullanılır. String ise genellikle statik olarak verilen String değişkenleri içindir. StringBuffer sınıfına Append metoduyla dinamik olarak ilave yapabiliriz. StringBuffer sınıfının metot yapısı şöyledir : package java.lang; public final class StringBuffer implements java.io.Serializable { private int count; private boolean shared; static final long serialVersionUID = 3388685877147921107L; public StringBuffer public StringBuffer(int length) public StringBuffer(String str) public int length() public int capacity() private final void copy() public synchronized void ensureCapacity(int minimumCapacity) private void expandCapacity(int minimumCapacity) public synchronized void setLength(int newLength) public synchronized char charAt(int index) public synchronized void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) public synchronized void setCharAt(int index, char ch) public synchronized StringBuffer append(Object obj) public synchronized StringBuffer append(String str) public synchronized StringBuffer append(char str[]) public synchronized StringBuffer append(char str[], int offset, int len) public StringBuffer append(boolean b) public synchronized StringBuffer append(char c) String) public StringBuffer append(int i) public StringBuffer append(long l) public StringBuffer append(float f) public StringBuffer append(double d) public synchronized StringBuffer delete(int start, int end) public synchronized StringBuffer deleteCharAt(int index) public synchronized StringBuffer replace(int start, int end, String str) public String substring(int start) public synchronized String substring(int start, int end) public synchronized StringBuffer insert(int index, char str[], int offset, int len) public synchronized StringBuffer insert(int offset, Object obj) public synchronized StringBuffer insert(int offset, char str[]) public StringBuffer insert(int offset, boolean b) public synchronized StringBuffer insert(int offset, char c) public StringBuffer insert(int offset, int i) public StringBuffer insert(int offset, long l) public StringBuffer insert(int offset, float f) public StringBuffer insert(int offset, double d) public synchronized StringBuffer reverse() public String toString private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException } Şimdi küçük bir test programında StringBuffer sınıfını kullanalım : Program 1.9.4 TestString.java, giren String değişkenini tersine çevirir. class TersString { public static String reverseIt(String source) { int i, len = source.length(); StringBuffer dest = new StringBuffer(len); for (i = (len - 1); i = 0; i--) { dest.append(source.charAt(i)); } return dest.toString(); } } diğer bir StringBuffer metotu insert metotudur. Bu metot i inci elementten sonra verilen yeni parçayı ilave edecektir. Program 1.9.5 javaKahvesi.java, StringBuffer, insert metodu örneği import java.io.*; class javaKahvesi { public static void main (String args[]) { StringBuffer sb = new StringBuffer("Java kahvesi ic!"); sb.insert(12, "ni sicak"); System.out.println(sb.toString()); } } bu programı çalıştırdığımızda Java kahvesini sicak iç! mesajını verecektir. 1.9.3 VECTOR SINIFI Daha önce boyutlu değişkenleri görmüştük. Boyutlu değişkenlerin boyutları bilgisayar belleğinde oluşturulurken birbiri ardına sırayla oluşturulur. Örneğin double b[]=new double[3]; Deyimi bilgisayar belleğinde Tablo 1.9.1 boyutlu değişkenlerin bilgisayar belleğinde yerleşimi 1023400 b[0] 1023464 b[1] 1023528 b[2] yerlerini birbirini izleyen adreslerde ayırır. Buradaki sorun eğer bilgisayar belleğindeki toplam yer değiştirilmek istenirse bunun zor olmasıdır. Aynı zamanda bilgisayar boyutlu değişkenin adreslerini bilgisayar hafızasında bir referans tablosu olarak tuttuğundan boyut değiştirme bilgisayar hafızasını da zorlayan bir işlemdir. Pratik olarak yapılan uygulama yeni bir boyutlu değişken oluşturup adresleri değiştirmektir. double c[]=new double[5]; for(int i=0,i<b.length;i++) { c[i]=b[i];} b=c; Daha gelişmiş bir bilgi yapısı olarak Vector sınıfını kullanabiliriz. Vector sınıfı java.util kütüphanesinde tanımlanmıştır. Vector sınıfında her bilgi elemanı aynı zamanda bir sonraki bilgi elemanının adresini taşır. Boylece istenildiğinde dizinin son elemanına yeni bir adres ilave edilerek kolayca yeni elemanlar ilave edilebilir. Dizinin arasından herhangibir elemanı da kalaylıkla sadece referans adresini değiştirerek silebiliriz. Vector sınıfının tanımı : public class Vector extends AbstractList implements List, Cloneable, java.io.Serializable { protected int elementCount; protected int capacityIncrement; private static final long serialVersionUID = -2767605614048989439L; public Vector(int initialCapacity, int capacityIncrement); public Vector(int initialCapacity); public Vector(); public Vector(Collection c); public synchronized void copyInto(Object anArray[]); public synchronized void trimToSize(); public synchronized void ensureCapacity(int minCapacity); private void ensureCapacityHelper(int minCapacity); public synchronized void setSize(int newSize); public int capacity(); public boolean isEmpty(); public Enumeration elements(); public boolean hasMoreElements(); public Object nextElement(); public boolean contains(Object elem); public int indexOf(Object elem); public synchronized int indexOf(Object elem, int index); public int lastIndexOf(Object elem); public synchronized int lastIndexOf(Object elem, int index) public synchronized Object elementAt(int index); public synchronized Object firstElement(); public synchronized Object lastElement(); public synchronized void setElementAt(Object obj, int index); public synchronized void removeElementAt(int index); public synchronized void insertElementAt(Object obj, int index); public synchronized void addElement(Object obj) ; public synchronized boolean removeElement(Object obj); public synchronized void removeAllElements(); public synchronized Object clone(); public synchronized Object[] toArray(); public synchronized Object[] toArray(Object a[]); public boolean remove(Object o); public void add(int index, Object element); public synchronized Object remove(int index); public void clear(); public synchronized boolean containsAll(Collection c); public synchronized boolean addAll(Collection c); public synchronized boolean removeAll(Collection c); public synchronized boolean retainAll(Collection c); public synchronized boolean addAll(int index, Collection c); public synchronized boolean equals(Object o); public synchronized int hashCode(); public synchronized String toString(); public List subList(int fromIndex, int toIndex); protected void removeRange(int fromIndex, int toIndex); } Vector sınıfında tanımlanan metotların bazılarının anlamları şunlardır : addElement(Object) Vektöre object türü (herhangi bir sınıf olabilir, vectörün hepsi bu sınfta tanımlanmış olmalıdır.) bir eleman ekler. capacity() vektörün toplam kapasitesini verir. clone() vectorun bir kopye vectörünü verir. contains(Object) Vectörün içinde sorgulanan elemanın olup olmadığını kontrol eder. copyInto(Object[]) vectorü boyutlu değişkene aktarır. elementAt(int indeks) Verilen indeksteki elemanı verir.. elements() Tüm vektörü enumeration sınıfına aktarır. ensureCapacity(int yeni_kapasite) eğer yeni_kapasite vector kapasitesinin üstündeyse vector yeni_kapasite’ye aktarılır. firstElement() Vectörün ilk elemanını verir. indexOf(Object) Object’in indeks değerini verir indexOf(Object, int indeks) Object’in indeks değerini verir, arama indeks değişkeninden başlayarak yapılır. insertElementAt(Object, int indeks) Vectörün ideks noktasına Object ilave edilir. isEmpty() Vectörün boş olup olmadığı kontrol edilir. lastElement() vectörün son elemanının indeksini verir. lastIndexOf(Object) Object’in vectördeki son tekrarının indeksini verir. lastIndexOf(Object, int indeks) indeks ten başlayarak geriye doğru Objectin ilk tekrarlandığı yeri bulur. removeAllElements() Vectördeki bütün elemanları siler. removeElement(Object) Vectördeki Object elemanını siler. removeElementAt(int indeks) indeksle verilen elemanı siler. setElementAt(Object, int indeks) Objectin ideksini indeks olarak belirler. setSize(int) Sets the size of this vector. size() Vectördeki toplam eleman sayısını verir. toString() Vectörün String eşitini verir. trimToSize() Vectörün boyutunu dolu olan elemanlarının boyutuna kısaltır. Aşağıda bu metotların önemlilerinden bazılarını kullanan bir örnek program verilmiştir. Program 1.9.6 : VectorTesti.java programı, vector sınıfının kullanımı import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; public class VectorTesti extends Applet implements ActionListener { private Vector v; private Label prompt; private TextField input; private Button addBtn, removeBtn, firstBtn, lastBtn, emptyBtn, containsBtn, locationBtn, trimBtn, statsBtn, displayBtn; Panel YaziPaneli; public void init() { setBackground(Color.lightGray); YaziPaneli=new Panel(); YaziPaneli.setFont(new Font("Serif",Font.BOLD,12)); YaziPaneli.setLayout( new GridLayout(5,2) ); v = new Vector(1); prompt= new Label("Bir String degiskeni giriniz "); input = new TextField(10); addBtn = new Button("Ekle"); removeBtn = new Button("Cikar"); firstBtn = new Button("Ilk"); lastBtn = new Button("Son"); emptyBtn = new Button("Bos mu ?"); containsBtn = new Button("Listede varmi?"); locationBtn = new Button("Adresi"); trimBtn = new Button("Kes"); statsBtn = new Button("Istatistikler"); displayBtn = new Button("Listeyi Goster"); add(prompt); add(input); addBtn.addActionListener(this); YaziPaneli.add(addBtn); removeBtn.addActionListener(this); YaziPaneli.add(removeBtn); firstBtn.addActionListener(this); YaziPaneli.add(firstBtn); lastBtn.addActionListener(this); YaziPaneli.add(lastBtn); emptyBtn.addActionListener(this); YaziPaneli.add(emptyBtn); containsBtn.addActionListener(this); YaziPaneli.add(containsBtn); locationBtn.addActionListener(this); YaziPaneli.add(locationBtn); trimBtn.addActionListener(this); YaziPaneli.add(trimBtn); statsBtn.addActionListener(this); YaziPaneli.add(statsBtn); displayBtn.addActionListener(this); YaziPaneli.add(displayBtn); add(YaziPaneli); } public void actionPerformed(ActionEvent e) { if(e.getSource()==addBtn) { v.addElement(input.getText()); showStatus("Listenin sonuna eklendi: "+input.getText()); } else if(e.getSource()==removeBtn) { if(v.removeElement(input.getText())) showStatus("Silindi :"+input.getText()); else showStatus(input.getText()+"not in vector"); } else if(e.getSource() == firstBtn) { try{ showStatus("Ilk eleman : "+v.firstElement()); } catch(NoSuchElementException exception) { showStatus(exception.toString() ); } } else if(e.getSource()==lastBtn) { try{ showStatus("Son eleman : "+v.lastElement()); } catch(NoSuchElementException exception) { showStatus(exception.toString() ); } } else if(e.getSource() == emptyBtn) { showStatus(v.isEmpty()? "Vector bos ":"vector dolu "); } else if(e.getSource()==containsBtn) { String searchKey = input.getText(); if(v.contains(searchKey) ) showStatus("Vektor elemanlar " +searchKey); else showStatus("Aranan eleman Vektorde bulunamadi "+searchKey); } else if(e.getSource()==locationBtn) { showStatus("Eleman "+v.indexOf(input.getText() )+" pozisyonunda bulundu"); } else if(e.getSource()==trimBtn) { v.trimToSize(); showStatus("Vector boyu eleman boyuna ksaltld"); } else if(e.getSource()== statsBtn) { showStatus("Boyut = "+v.size()+"; Toplam kapasite = "+v.capacity()); } else if(e.getSource()== displayBtn) { Enumeration enum=v.elements(); StringBuffer buf = new StringBuffer(); while(enum.hasMoreElements()) { buf.append(enum.nextElement() ); buf.append(" "); } showStatus(buf.toString() ); } input.setText(""); } } Bundan sonraki program iki kümenin bileşim ve kesişim kümelerini hesaplamaktadır. Kümelerin kaç elemandan oluştuğu tanımlanmamıştır. İşlemler vector sınıfını kullanarak yapılmaktadır. Ayrıca bu yapıda vector sınıfını bir döngü içinde kullanmak için vector sınıfı Enumeration sınıfına yüklenmektedir. Enumeration sınıfının görevi, StringTokenizer sınıfının görevini andırır. Vector yapısının içinden her vector elemanını ayrı ayrı çağırma ve indeksleme görevi görür. Enumeration interface’inin tanımı : public interface Enumeration { boolean hasMoreElements(); Object nextElement(); } şeklindedir. Enumeration n1=list1.elements(); Enumeration n2=list2.elements(); while(n1.hasMoreElements()) { s1=(String)n1.nextElement(); bilesimVectoru.addElement(s1); } kod parçacığında vector sınıfının elements metotu,Enumeration sınıfı ve Enumeration sınıfının hasMoreElements ve nextElement metotları kullanılarak nasıl döngü oluşturulduğu görülmektedir. Aşağıdaki örnekte setA sınıfı verilmiştir. Bu örnekte bir kümelerin bileşim ve kesişim kümelerinin vector metodunu kullanarak nasıl oluşturulabileceği gösterilmektedir. Program 1.9.7 setA.java setTest.java sınıfları, bir kümenin bileşim ve kesişim kümelerini hesaplar. // Bu program vector ve Enumeration siniflarını // Kullanmaktadır. Bilesim, kesisim kümelerini hesaplar // Ayni zamanda StringTokaniser sinifini kullanir. import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; class SetA { public Vector bilesim(Vector list1, Vector list2) { Vector bilesimVectoru = new Vector(); String s1,s2; Enumeration n1=list1.elements(); Enumeration n2=list2.elements(); while(n1.hasMoreElements()) { s1=(String)n1.nextElement(); bilesimVectoru.addElement(s1); } while(n2.hasMoreElements()) { s2=(String)n2.nextElement(); if(!bilesimVectoru.contains(s2)) bilesimVectoru.addElement(s2); } return bilesimVectoru; } public Vector kesisim(Vector list1,Vector list2) { Vector kesisimVectoru = new Vector(); String s; Enumeration n = list1.elements(); while(n.hasMoreElements()) { s=(String)n.nextElement(); if(list2.contains(s)) kesisimVectoru.addElement(s); } return kesisimVectoru; } } public class SetTest extends Applet implements ActionListener { SetA set = new SetA(); // SetA Label L1, P1, P2; TextField T1,T2; TextArea cikti; // dinamik boyutlu degisken sinifi Vector'u kullanarak // iki vector listesi yarat Vector list1 = new Vector(); Vector list2 = new Vector(); // Sonuclari yine vektor cinsinden degiskenler // kullanarak aktar Vector ansUn; Vector ansInt; public void init() { P1 = new Label("Birinci listeyi gir : "); T1 = new TextField(50); P2 = new Label("Ikinci listeyi gir : "); T2 = new TextField(50); // Sonuclarin yazildigi yazi alanini ac cikti = new TextArea(10,40); cikti.setEditable(false); cikti.setText(""); add(P1); add(T1); T1.addActionListener(this); add(P2); add(T2); T2.addActionListener(this); add(cikti); } public void girdiA(String string, Vector list) { // StringTokeniser sinifi String degiskenleri icin // Enumeration sinifinin yaptigina paralel gorev // gorur String'i siraya sokarak degerlerini sirayla verir StringTokenizer tokens = new StringTokenizer(string); while(tokens.hasMoreTokens()) { String test = tokens.nextToken(); list.addElement(test); } } public void ciktiA(Vector v) { Enumeration enum = v.elements(); while(enum.hasMoreElements()) { String ans = (String)enum.nextElement(); cikti.append(ans + "\n"); } } public void actionPerformed(ActionEvent e) { if(e.getSource()==T1) { String stringToTokenize = T1.getText(); girdiA(stringToTokenize,list1); } else if(e.getSource()==T2) { String stringToTokenize = T2.getText(); girdiA(stringToTokenize,list2); // Iki listenin bilesim ve kesisim kmelerini hesapla. ansUn = set.bilesim(list1,list2); ansInt = set.kesisim(list1,list2); // sonuclari cikti alanina gonder cikti.append("\nIki listenin bilesim kumesi : \n"); ciktiA(ansUn); cikti.append("\nIki listenin kesisim kumesi : \n"); ciktiA(ansInt); } } //actionPerformed metotunun sonu } Bu programda aynı zamanda StringTokaniser sınıfı kullanılmıştır. StringTokaniser String değişkenini bosluk kullanarak alt değişkenlere ayırmaya yarayan Enumeration türü bir sınıftır. Aynı programın Swing versiyonuSetTestSWF_2000.java aşağıda verilmiştir : // Bu program vector ve Enumeration siniflarını // Kullanmaktadır. Bileşim ve kesişim kümelerini hesaplar // Aynı zamanda StringTokeniser sınıfını kullanır. Program 1.9.8 setTestSWF_2000.java, bir kümenin bileşim ve kesişim kümelerini hesaplar. import java.util.*; import java.awt.*; import javax.swing.*; import java.awt.event.*; public class SetTestSWF_2000 extends JFrame implements ActionListener { SetA set = new SetA(); // SetA JLabel L1, P1, P2; JTextField T1,T2; JTextArea cikti; // dinamik boyutlu degisken sinifi Vector'u kullanarak // iki vector listesi yarat Vector list1 = new Vector(); Vector list2 = new Vector(); // Sonuclari yine vektor cinsinden de§iskenler // kullanarak aktar Vector ansUn; Vector ansInt; Container c; public SetTestSWF_2000() { super("küme testi bileşim ve kesişim kümeleri"); c=getContentPane(); c.setLayout(new FlowLayout()); P1 = new JLabel("Birinci listeyi giriniz : "); T1 = new JTextField(30); T1.setBackground(c.getBackground()); P2 = new JLabel("İkinci listeyi giriniz : "); T2 = new JTextField(30); T2.setBackground(c.getBackground()); // Sonuclarin yazildigi yazi alanini ac cikti = new JTextArea(); cikti.setEditable(false); cikti.setText(""); cikti.setBackground(c.getBackground()); c.add(P1); c.add(T1); T1.addActionListener(this); c.add(P2); c.add(T2); T2.addActionListener(this); JScrollPane jp=new JScrollPane(cikti); jp.setPreferredSize(new Dimension(320,200)); c.add(jp); } public void girdiA(String string, Vector list) { // StringTokeniser sinifi String degiskenleri icin // Enumeration sinifinin yaptigina paralel gorev // gorur String'i sraya sokarak degerlerini srayla verir StringTokenizer tokens = new StringTokenizer(string); while(tokens.hasMoreTokens()) { String test = tokens.nextToken(); list.addElement(test); } } public void ciktiA(Vector v) { Enumeration enum = v.elements(); while(enum.hasMoreElements()) { String ans = (String)enum.nextElement(); cikti.append(ans + " "); } cikti.append("\n"); } public void actionPerformed(ActionEvent e) { if(e.getSource()==T1) { String stringToTokenize = T1.getText(); girdiA(stringToTokenize,list1); } else if(e.getSource()==T2) { String stringToTokenize = T2.getText(); girdiA(stringToTokenize,list2); // Iki listenin bilesim ve kesisim kümelerini hesapla. ansUn = set.bilesim(list1,list2); ansInt = set.kesisim(list1,list2); // sonuclari cikti alanina gonder cikti.setText(""); cikti.append("İki listenin bileşim kümesi : \n"); ciktiA(ansUn); cikti.append("İki listenin kesişim kümesi : \n"); ciktiA(ansInt); } } //actionPerformed metodunun sonu public static void main(String[] args) { SetTestSWF_2000 pencere = new SetTestSWF_2000(); pencere.addWindowListener(new BasicWindowMonitor()); pencere.setSize(400,350); pencere.setVisible(true); } } Şekil 1.9.7 Vector sınıfını kullanarak iki kumenin bileşim ve kesişim kümelerini hesaplayan SetTestSWF_2000 programı JFrame çıktısı 1.9.4 LIST(LİSTE) SINIFI Yukarıdaki vektor sınıfında ilk defa dinamik hafıza kullanabilen (vektor boyutunu program çalışırken değiştirebilen) Vector sınıfını inceledik. Eğer vektor boyutları program çalışırken azalıyor veya çoğalıyorsa, boyutlu değişkenler yerine dinamik hafıza kullanımı toplam bilgisayar hafızası kullanımı açısında çok daha verimlidir. Dinamik data yapıları sadece vektorden ibaret değildir. List(liste), Stack(dizin) ve Queue (sıra) ve Tree(agaç) yapıları da oldukça sık kullanılar dinamik yapıları teşkil eder. Bunlardan List yapısının özellikleri şunlardır : Listenin ilk elemanından önce veya son elemanından sonra listeye dinamik eleman ilavesi yapılabilir. Listenin herhangibir ara noktasına yeni eleman ilave edilemez. Listenin ilk elemanı veya son elemanı listeden çekilebilir. Listenin herhangi bir ara noktasından eleman çekilemez. Burada List kavramının daha iyi anlaşılabilmesi için önce kendi List sınıfımız oluşturulmuş ve bir örnek problemde kullanlmıştır. Bu program örneklerine bir göz atalım. Program 1.9.9 List.java programı. Bu program List yapısını tanımlayan ListNode ve List sınıflarını içerir. class ListNode { Object data; ListNode next; ListNode(Object o) {this(o,null);} ListNode(Object o,ListNode nextNode) { data=o; next=nextNode; } Object getObject() {return data;} ListNode getnext() {return next;} } public class List { //Liste private ListNode firstNode; private ListNode lastNode; private String name; public List(String s) { name=s; firstNode=lastNode=null; } public List(){this("Liste");} public synchronized void insertAtFront(Object insertItem) { if( isEmpty() ) firstNode = lastNode = new ListNode(insertItem); else firstNode = new ListNode(insertItem,firstNode); } public synchronized void insertAtBack(Object insertItem) { if(isEmpty()) firstNode=lastNode=new ListNode(insertItem); else lastNode=lastNode.next=new ListNode(insertItem); } public synchronized Object removeFromFront() throws EmptyListException { Object removeItem=null; if(isEmpty()) throw new EmptyListException(name); removeItem=firstNode.data; if(firstNode.equals(lastNode)) firstNode=lastNode=null; else firstNode=firstNode.next; return removeItem; } public synchronized Object removeFromBack() throws EmptyListException { Object removeItem=null; if(isEmpty()) throw new EmptyListException(name); removeItem=lastNode.data; if(firstNode.equals(lastNode)) firstNode=lastNode=null; else { ListNode current=firstNode; while(current.next != lastNode) current=current.next; lastNode=current; current.next=null; } return removeItem; } public boolean isEmpty() {return firstNode==null; } //türkçe eşdeğer metodlar public boolean bosmu() {return isEmpty(); } public synchronized void oneEkle(Object o) {insertAtFront(o);} public synchronized void arkayaEkle(Object o) {insertAtBack(o);} public synchronized Object ondenCikar() {return removeFromFront();} public synchronized Object arkadanCikar() {return removeFromBack();} public void print() { if(bosmu()) { System.out.print(" Bos "+name); return; } System.out.print(" "+name+" : "); ListNode current=firstNode; while(current!=null) { System.out.print(current.data.toString()+" "); current=current.next; } System.out.println("\n"); } } Program 1.9.10 : EmptyListException sınıfının EmptyListException dosyasındaki tanımı public class EmptyListException extends RuntimeException { public EmptyListException(String name) { super(" "+name+" bos "); } } Program 1.9.11 : List yapısını kullanan örnek program ListTest.java import List; import EmptyListException; public class ListTest { public static void main(String args[]) { List objList=new List(); Boolean b=new Boolean(true); Character c=new Character('$'); Integer i=new Integer(34567); String s=new String("hello"); objList.insertAtFront(b); objList.print(); objList.insertAtFront(c); objList.print(); objList.insertAtFront(i); objList.print(); objList.insertAtFront(s); objList.print(); Object removedObj; try{ removedObj=objList.removeFromFront(); System.out.print(removedObj.toString()+" cikarildi"); objList.print(); removedObj=objList.removeFromFront(); System.out.print(removedObj.toString()+" cikarildi"); objList.print(); removedObj=objList.removeFromBack(); System.out.print(removedObj.toString()+" cikarildi"); objList.print(); removedObj=objList.removeFromBack(); System.out.print(removedObj.toString()+" cikarildi"); objList.print(); } catch(EmptyListException e) {System.out.println("\n"+e.toString());} } } ListTest programının sonucu : List yapısını kullanan örnek program ListTest.java nın çıktısı Liste : true Liste : $ true Liste : 34567 $ true Liste : hello 34567 $ true hello cikarildi Liste : 34567 $ true 34567 cikarildi Liste : $ true true cikarildi Liste : $ $ cikarildi Bos Liste Burada List sınıfının girdisinin Object sınıfı olduğun dikkatinizi çekelim. Object sınıfı yine dinamik object değişken yapıları olarak tanımlanan Double, Byte, String, Integer, Boolean, Float, Short, Long gibi değişken türleri için kullanılan sınıfların abstract sınıfını teşkil eder. Bu yüzden bu sınıfların hepsini temsil edebilir ve yerlerine kullanılabilir (genel bir sınıftır.). Bu sınıflar normal değişken türlerine dönüştürülebilirler. (daha önce de kullandığımız intValue(), doubleValue() gibi metotları kullanarak) Object sınıfının temel tanımı (metodtanımları olmadan) şu şekildedir. package java.lang; public class Object { private static native void registerNatives(); static { registerNatives(); } public final native Class getClass(); public native int hashCode(); public boolean equals(Object obj protected native Object clone() throws CloneNotSupportedException; public String toString() public final native void notify(); public final native void notifyAll(); public final native void wait(long timeout) throws InterruptedException; public final void wait(long timeout, int nanos) throws InterruptedException ; public final void wait() throws InterruptedException ; protected void finalize() throws Throwable; } burada geçen native sözcüğünün anlamak istiyorsanız, 14 üncü bölümü inceleyebilirsiniz. Bu terim metodun anadilde (native) yazıldığını belirtir. Java.util paketinde List sınıfı tanımlanmıştır. Yukarıda kendi tanımladığımız List ile yapabildiklerimizi ve daha fazlasını tanımlı List paketiyle a gerçekleştirebiliriz. package java.util; public interface List extends Collection { int size(); boolean isEmpty(); boolean contains(Object o); Iterator iterator(); Object[] toArray(); Object[] toArray(Object a[]); boolean add(Object o); boolean remove(Object o); boolean containsAll(Collection c); boolean addAll(Collection c); boolean addAll(int index, Collection c); boolean removeAll(Collection c); boolean retainAll(Collection c); void clear(); boolean equals(Object o); int hashCode(); Object get(int index); Object set(int index, Object element); void add(int index, Object element); Object remove(int index); int indexOf(Object o); int lastIndexOf(Object o); ListIterator listIterator(); ListIterator listIterator(int index); List subList(int fromIndex, int toIndex); } List sınıfıyla birlikte kullanılmak üzere ListIterator interface’i tanımlanmıştır. /* package java.util; public interface ListIterator extends Iterator { boolean hasNext(); Object next(); boolean hasPrevious(); Object previous(); int nextIndex(); int previousIndex(); void remove(); void set(Object o); void add(Object o); } Şimdi bu iki sınıfın kullanımını bir örnekle gösterelim. Program 1.9.12 : List yapısını kullanan örnek program MovingPlanets.java import java.util.List; import java.util.ListIterator; import java.util.Iterator; import java.util.ArrayList; import javax.swing.JOptionPane; public class MovingPlanets { public static void main (String args[]) { String names[] = {"Mercür", "Venüs", "Dünya", "Mars", "Jupiter", "Satürn", "Uranüs", "Neptün", "Pluto"}; int namesLen = names.length; List planets = new ArrayList(); for (int i=0; i < namesLen; i++) { planets.add (names[i]); } ListIterator lit = planets.listIterator(); String s; lit.next(); lit.next(); s = (String)lit.next(); lit.remove(); lit.next(); lit.next(); lit.next(); lit.add(s); lit.next(); lit.previous(); lit.previous(); s = (String)lit.previous(); lit.remove(); lit.next(); lit.next(); lit.add(s); Iterator it = planets.iterator(); String ss=""; while (it.hasNext()) {ss+=it.next()+"\n";} JOptionPane.showMessageDialog(null,ss); System.exit(0); } } Şekil 1.9.08 List sınıfı, MovingPlanets çıktısı List sınıfının bir alt sınıfı da LinkedList sınıfıdır. LinkedList sınıfı List sınıfında olmayan ilave metodlar tanımlamıştır. public class LinkedList extends AbstractSequentialList implements List, Cloneable, java.io.Serializable { private transient Entry header; private transient int size; public LinkedList() public LinkedList(Collection c) public Object getFirst() public Object getLast() public Object removeFirst() public Object removeLast() public void addFirst(Object o) public void addLast(Object o) public boolean contains(Object o) public int size() public boolean add(Object o) public boolean remove(Object o) public boolean addAll(Collection c) public boolean addAll(int index, Collection c) public void clear() public Object get(int index) public Object set(int index, Object element public void add(int index, Object element) public Object remove(int index) public int indexOf(Object o) public int lastIndexOf(Object o) */ public ListIterator listIterator(int index) } Bu sınıfı kullanan küçük bir örnek problemi inceleyelim : Program 1.9.13 : LinkedList yapısını kullanan örnek program MovingPlanets.java import java.util.List; import java.util.ListIterator; import java.util.Iterator; import java.util.ArrayList; import javax.swing.JOptionPane; public class GezegenlerVeaylarListesi { static class Gezegen { private String isim; private int aySayisi; Gezegen (String s, int aylar) { isim = s; aySayisi = aylar; } public String toString() { return getClass().getName() + "[" + isim + "-" + aySayisi + "]"; } public final String getName() { return isim; } public final int getaySayisi () { return aySayisi; } } public static void main (String args[]) { String names[] = {"Mercür", "Venüs", "Dünya", "Mars", "Jupiter", "Satürn", "Uranüs", "Neptün", "Pluto"}; int aylar[] = {0, 0, 1, 2, 16, 18, 17, 8, 1}; int namesLen = names.length; List Gezegens = new ArrayList (namesLen); for (int i=0; i < namesLen; i++) { Gezegens.add (new Gezegen (names[i], aylar[i])); } String ss=""; for (int i=Gezegens.size()-1; i >= 0; --i) { Gezegen p = (Gezegen)(Gezegens.get (i)); ss+=p.getName() + " : " + p.getaySayisi()+"\n"; } JOptionPane.showMessageDialog(null,ss); System.exit(0); } } Program çıktısı Şekil 1.9.09 Linkedlist sınıfı, GezegenlerVe aylarListesi çıktısı LinkList Bölüm 1.9.4’de incelediğimiz Stack(dizi) yapısı ve bölüm 1.9.5 de incelediğimiz queue(sıra) yapısı yerine kullanılabilir. 1.9.5 DİZİ (STACK) SINIFI Diziler veya ingilizce adıyla Stack aslında üstte tanımladığımız List sınıfının bir alt sınıfıdır. dizin listeye göre daha sınırlı olan şu koşullara sahiptir : Dizide son elemandan sonra listeye dinamik eleman ilavesi yapılabilir. Dizinin herhangibir ara noktasına yeni eleman ilave edilemez. Dizinin sadece son elemanı listeden çekilebilir. Listenin herhangi bir ara noktasından eleman çekilemez. Yukardaki kendi tanımladığımız List (Program 1.9.5,1.9.6) kullanarak oluşturduğumuz dizi programı ve diziyi kullnan bir test programı aşağıda verilmiştir. Program 1.9.14 : dizi sınıfının dizi.java dosyasındaki tanımları public class dizi extends List { public dizi() {super("dizi");} public synchronized void push(Object o) {insertAtFront(o);} public synchronized void ekle(Object o) {insertAtFront(o);} public synchronized Object pop() throws EmptyListException {return removeFromFront();} public synchronized Object cek() throws EmptyListException {return removeFromFront();} public boolean isEmpty() {return super.isEmpty();} public boolean bosmu() {return super.isEmpty();} public void print() {super.print();} } Program 1.9.15 : dizi sınıfının diziTesti.java dosyasındaki örnek kullanımı import bolum1.9.dizi; import bolum1.9.EmptyListException; public class diziTesti { public static void main(String args[]) { dizi d=new dizi(); Boolean b=new Boolean(true); Character c=new Character('$'); Integer i=new Integer(34567); String s=new String("hello"); d.ekle(b); d.print(); d.ekle(c); d.print(); d.ekle(i); d.print(); d.ekle(s); d.print(); Object cekilen; try { while(true) { cekilen=d.cek(); System.out.println(cekilen.toString()+" diziden cekildi"); d.print(); } } catch(EmptyListException e) {System.err.println("\n"+e.toString());} } } dizi yapısını kullanan örnek program diziTesti.java’nın çıktısı dizi : true dizi : $ true dizi : 34567 $ true dizi : hello 34567 $ true hello diziden cekildi dizi : 34567 $ true 34567 diziden cekildi dizi : $ true $ diziden cekildi dizi : true true diziden cekildi Bos dizi yukarıda tanımlanan LinkedList sınıfının addFirst()/removeFirst() metotlarını kullanarak da stack oluşturabiliriz. java.util paketinde vector sınıfının yanı sıra Stack sınıfı da tanımlanmıştır. Java Stack sınıfında push, pop ve peek metotları vardır. push ve pop dizin programını aynısıdır. peek ise listenin en sonundaki elemanın değerini bu elemanı listeden uzaklaştırmadan alır. (pop ile push beraber kullanılarak da aynı işi yapabilirler) Bu sınıfın tanımı : public class Stack extends Vector { public Stack(); public Boolean empty(); public synchronized Object peek(); public synchronized Object pop(); public synchronized Object push(Object obj); public synchronized int search(Object obj); } Stack sınıfının metotlarının ne olduğunu daha detaylı inceleyecek olursak: push public Object push(Object item) stack'in üstüne yeni eleman ilave eder pop public synchronized Object pop() Stakin en tepesindeki elemanı çeker (Stack dizisinden kaldırır ve değerini return eder) Stack'in boş olması halinde EmptyStackException gönderir. peek public synchronized Object peek() Stack'in en tepesindeki elemanın değerini okur(Stack dizisinden kaldırmaz ve sadece değerini Stack'in boş olması halinde EmptyStackException gönderir. empty public boolean empty() Stack'in boş olup olmadığını kontrol eder, boş ise true, dolu ise false değeri gönderir. Tests if this stack is empty. search public synchronized int search(Object o) Stack'in içindeki istenen Object'in yerini verir. Eğer object Stack'de yok ise -1 değeri verir return eder) Burada hemen Stack sınıfının Vector sınıfının alt sınıfı olduğunu ve Vector sınıfında mevcut olan tüm metotlar Stack metodunda da geçerli olduğunu da hatırlatalım. şimdi bir örnek problemde bu sınıfın nasıl kullanıldığına bakalım : Program 1.9.16 : java.util kütüphanesinde yer alan Stack yapısını kullanan örnek program StackTesti.java import java.util.*; public class StackTesti { public static void main(String args[]) { StackTesti st=new StackTesti(); Stack d=new Stack(); Boolean b=new Boolean(true); Character c=new Character('$'); Integer i=new Integer(34567); String s=new String("hello"); d.push(b); st.print(d); d.push(c); st.print(d); d.push(i); st.print(d); d.push(s); st.print(d); Object bakilan; Object cekilen; try { while(true) { bakilan=d.peek(); System.out.println(bakilan.toString()+" de§erine bakildi"); st.print(d); cekilen=d.pop(); System.out.println(cekilen.toString()+" de§eri listeden cekildi "); st.print(d); System.out.println("---------------------"); } } catch(EmptyStackException e) {System.err.println("\n"+e.toString());} } public void print(Stack di) { Enumeration enum=di.elements(); StringBuffer buf=new StringBuffer(); while(enum.hasMoreElements()) buf.append(enum.nextElement()).append(" "); System.out.println(buf.toString()); } } java.util kütüphanesinde yer alan Stack yapısını kullanan örnek program StackTesti.java nın çıktısı true true $ true $ 34567 true $ 34567 hello hello degerine bakildi true $ 34567 hello hello degeri listeden cekildi true $ 34567 --------------------34567 degerine bakildi true $ 34567 34567 degeri listeden cekildi true $ --------------------$ degerine bakildi true $ $ degeri listeden cekildi true --------------------true degerine bakildi true true degeri listeden cekildi --------------------- 1.9.6 SIRA (QUEUE) SINIFI Sıra veya ingilizce adıyla queue aslında üstte tanımladığımız List sınıfının bir alt sınıfıdır. sıra listeye göre daha sınırlı olan şu koşullara sahiptir : Sırada son elemandan sonra listeye dinamik eleman ilavesi yapılabilir. Sıranın herhangibir ara noktasına yeni eleman ilave edilemez. Sıranın sadece ilk elemanı listeden çekilebilir. Sıranın herhangi bir ara noktasından eleman çekilemez. Sıra kavramının oldukça yaygın olarak kullanıldığı ülkemizde oldukça yararlı olabilecek bir sınıfı değilmi? Yukardaki List tanımını kullanarak oluşturduğumuz sıra programı ve sırayı kullanan bir test programı aşağıda verilmiştir. Program 1.9.17 : sira sınıfının sira.java dosyasındaki tanımları public class sira extends List { public sira() {super("sira");} public synchronized void sirayagir(Object o) {arkayaEkle(o);} public synchronized Object siranGeldi() throws EmptyListException {return ondenCikar();} public boolean isEmpty() {return super.isEmpty();} public boolean bosmu() {return super.isEmpty();} public void print() {super.print();} } Program 1.9.18 : sira sınıfının siraTesti.java dosyasındaki test programı import sira; import EmptyListException; public class siraTesti { public static void main(String args[]) { sira s=new sira(); Boolean b=new Boolean(true); Character c=new Character('$'); Integer i=new Integer(34567); String st=new String(" merhaba "); s.sirayagir(b); s.print(); s.sirayagir(c); s.print(); s.sirayagir(i); s.print(); s.sirayagir(st); s.print(); Object cekilen; try { while(true) { cekilen=s.siranGeldi(); System.out.println(cekilen.toString()+" sirasi geldi ”nden cikti"); s.print(); } } catch(EmptyListException e) {System.err.println("\n"+e.toString());} } } sira sınıfını kullanan siraTesti.java dosyasının çıktısı sira : true sira : true $ sira : true $ 34567 sira : true $ 34567 merhaba true sirasi geldi onden cikti sira : $ 34567 merhaba $ sirasi geldi onden cikti sira : 34567 merhaba 34567 sirasi geldi onden cikti sira : merhaba merhaba sirasi geldi onden cikti Bos sira Queue sınıfı Java'da direk olarak tanımlanmamıştır, ancak üstteki sıra örneğinin bir benzeri Vector sınıfından bizim tarafımızdan rahatlıkla yazılabilir, veya yine LinkedList sınıfının addFirst()/removeLast() metotlarını kullanarak oluşturulabilir. 1.9.7 TREE(AGAÇ) SINIFI Elimizdeki bir gurup boyutlu değişkenin belli bir yapıda gruplandırılması veya aranması gerektiğinde bu standart boyut kavramında oldukça kompleks bir yapı arz eder. Bilgi gruplandırma işlemini çok daha basit bir şekilde yapabilmek için Tree yapıları öngörülmektedir. Tree temel olarak Vector gibi bir yapıdır. fakat burada her Tree noktası (Nod'u) iki değişik adrese işaret eder bu adreslerden birisi o noktadaki objenin kok değerindekinden daha küçük olduğu bir değeri, diğeri ise daha büyük olduğu bir değeri taşır. hiç bir değer taşımıyorsa da null değeriyle o Tree-ağaç dalı sona erer. Bu yapıyı kullanarak sayıları büyükten küçüğe veya küçükten büyüğe veya daha değişik mantıklarla direk olarak sıralamak mümkündür. Şekil 1.9.11 Binary search Tree (ikili arama ağacı) yapısının bir rakam setine uygulanmasının grafiksel gösterimi Şekil 1.9.10 de ikili arama ağacı yapısının seti görülmektedir. Şekil 1.9.11 de ise sayısal bir örnekle yapı gösterilmiştir. Her bir dal kökü kendinden sonra gelen rakamı küçükse sol dala büyükse sağ dala göndermektedir. ve her yeni veri yeni bir dallanma oluşturmaktadır. Şimdi Tree yapısını oluşturacak bir örnek sınıfı ve onun kullanıldığı bir örnek problem sınıfını oluşturarak kavramı biraz daha açmaya çalışalım : Program 1.9.19 : Binary search Tree (ikili arama ağacı) yapısının programlandığı TreeNode ve Tree sınıflarının yer aldığı Tree.java programı class TreeNode { TreeNode sol; int data; TreeNode sag; public TreeNode(int d) { data=d; sol=sag=null; } public synchronized void gir(int d) { // not ayni deger iki kere girilmeye calisilirsa // ikinci giris dikkate alinmiyacaktir if(d<data) { if(sol==null) {sol=new TreeNode(d);} else {sol.gir(d);} } else if(ddata) { if(sag==null) {sag=new TreeNode(d);} else {sag.gir(d);} } } } public class Tree { private TreeNode kok; public Tree() {kok=null;} public synchronized void gir(int d) { if(kok==null) kok=new TreeNode(d); else kok.gir(d); } public void node_soldal_sagdal_sirala(){node_soldal_sagdal_siralayici(kok);} public void soldal_node_sagdal_sirala(){soldal_node_sagdal_siralayici(kok);} public void soldal_sagdal_node_sirala(){soldal_sagdal_node_siralayici(kok);} public void node_sagdal_soldal_sirala(){node_sagdal_soldal_siralayici(kok);} public void sagdal_node_soldal_sirala(){sagdal_node_soldal_siralayici(kok);} public void sagdal_soldal_node_sirala(){sagdal_soldal_node_siralayici(kok);} public void node_soldal_sagdal_siralayici(TreeNode node) { if(node==null) return; System.out.print(node.data+" "); node_soldal_sagdal_siralayici(node.sol); node_soldal_sagdal_siralayici(node.sag); } public void node_sagdal_soldal_siralayici(TreeNode node) { if(node==null) return; System.out.print(node.data+" "); node_sagdal_soldal_siralayici(node.sag); node_sagdal_soldal_siralayici(node.sol); } public void soldal_node_sagdal_siralayici(TreeNode node) { if(node==null) return; soldal_node_sagdal_siralayici(node.sol); System.out.print(node.data+" "); soldal_node_sagdal_siralayici(node.sag); } public void sagdal_node_soldal_siralayici(TreeNode node) { if(node==null) return; sagdal_node_soldal_siralayici(node.sag); System.out.print(node.data+" "); sagdal_node_soldal_siralayici(node.sol); } public void soldal_sagdal_node_siralayici(TreeNode node) { if(node==null) return; soldal_node_sagdal_siralayici(node.sol); soldal_node_sagdal_siralayici(node.sag); System.out.print(node.data+" "); } public void sagdal_soldal_node_siralayici(TreeNode node) { if(node==null) return; sagdal_node_soldal_siralayici(node.sag); sagdal_node_soldal_siralayici(node.sol); System.out.print(node.data+" "); } } Program 1.9.20 : Binary search Tree (ikili arama ağacı) yapısının programlandığı TreeNode ve Tree sınıflarının kullanılmasını örnekleyen TreeTest.java programı import Tree; public class TreeTest { public static void main(String args[]) { Tree agac=new Tree(); int sayi; System.out.println("orijinal olarak Tree'ye girilen sayi dizini"); for(int i=0;i<=6;i++) { sayi=(int)(Math.random()*45)+1; System.out.print(sayi+" "); agac.gir(sayi); } System.out.println("\nSol dal - kok - sag dal siralama : "); agac.soldal_node_sagdal_sirala(); System.out.println("\nkok -Sol dal - sag dal siralama : "); agac.node_soldal_sagdal_sirala(); System.out.println("\nSol dal - sag dal - kok siralama : "); agac.soldal_sagdal_node_sirala(); System.out.println("\nSag dal - kok - sol dal siralama : "); agac.sagdal_node_soldal_sirala(); System.out.println("\nkok -Sag dal - sol dal siralama : "); agac.node_sagdal_soldal_sirala(); System.out.println("\nSag dal - sol dal - kok siralama : "); agac.sagdal_soldal_node_sirala(); } } Program 1.9.17 : Binary search Tree (ikili arama ağacı) yapısının programlandığı TreeNode ve Tree sınıflarının kullanılmasını örnekleyen TreeTest.java programının sonuçları. renkli olarak işaretlenen satırların sayı dizisini küçükten büyüğe ve büyükten küçüğe sıraladığına dikkat ediniz. orijinal olarak Tree'ye girilen sayi dizini 13 11 25 34 21 26 14 Sol dal - kok - sag dal siralama : 11 13 14 21 25 26 34 kok -Sol dal - sag dal siralama : 13 11 25 21 14 34 26 Sol dal - sag dal - kok siralama : 11 14 21 25 26 34 13 Sag dal - kok - sol dal siralama : 34 26 25 21 14 13 11 kok -Sag dal - sol dal siralama : 13 25 34 26 21 14 11 Sag dal - sol dal - kok siralama : 34 26 25 21 14 11 13 1.9.8 DICTIONARY ve HASHTABLE SINIFLARI Şu ana kadar bu konuda gördüğümüz elemanlarda belli bir bağlantı kuralı kullanarak elemanları birbirine bağlamıştık. Bu hafıza açısından yoğun bir işlemdir. Her seferinde hafıza pozisyonunun araştırılmasını gerektirir. Java anahtar referans sağlayan daha değişik bir yapıyı da içerir. Burada her elemanın kendimiz tarafından verilen bir referans değeri mevcuttur ve elemanı bulmak için bu referansı kullanabiliriz. Bu gurubun abstract sınıfı Dictionary sınıfıdır. Dictionary sınıfının altında Hashtable sınıfı yer alır. Dictionary sınıfının tanımı : package java.util; public abstract class Dictionary { public Dictionary() abstract public int size(); abstract public boolean isEmpty(); abstract public Enumeration keys(); abstract public Enumeration elements(); abstract public Object get(Object key); abstract public Object put(Object key, Object value); abstract public Object remove(Object key); } HashTable sınıfının tanımı : public class Hashtable extends Dictionary implements Map, Cloneable, java.io.Serializable { private transient Entry table[]; private transient int count; private int threshold; private float loadFactor; private transient int modCount = 0; private static final long serialVersionUID = 1421746759512286392L; public Hashtable(int initialCapacity, float loadFactor) public Hashtable(int initialCapacity) public Hashtable(Map t) public int size() public boolean isEmpty() public synchronized Enumeration keys() public synchronized Enumeration elements() public synchronized boolean contains(Object value) public boolean containsValue(Object value) public synchronized boolean containsKey(Object key) public synchronized boolean equals(Object key) public synchronized Object get(Object key) protected void rehash() public synchronized Object put(Object key, Object value) public synchronized Object remove(Object key) public synchronized void putAll(Map t) public synchronized void clear() public synchronized Object clone() public synchronized String toString() public Set entySet() public Set keySet() public Collection Values() public synchronized int hashCode() } Hashtables sınıfı temel olarak Dictionary ve Map sınıflarından türetilmiştir. Map sınıfı tanımı package java.util; public interface Map { int size(); boolean isEmpty(); boolean containsKey(Object key); boolean containsValue(Object value); Object get(Object key); Object put(Object key, Object value); Object remove(Object key); void putAll(Map t); void clear(); public Set keySet(); public Collection values(); public Set entrySet(); boolean equals(Object o); int hashCode(); public interface Entry { Object getKey(); Object getValue(); Object setValue(Object value); boolean equals(Object o); int hashCode(); } } şeklindedir. En çok kullanacağımız Hashtable metotlarının anlamlarına bir göz atalım : Bir referans çifti girmek için : put(Object anahtar, Object değer) Anahtarı vererek referans değerini çağırmak için : get(Object anahtar) Bir elemanı silmek için : remove((Object anahtar) Boyutu kontrol için : size() Boş olup olmadığının kontrolu için empty() Tüm anahtarların listesini almak için : keys() veya keySet() Tüm değerlerin listesini almak için : elements() veya entrySet() Program 1.9.21 : Hashtable yapısının programlandığı GezegenCaplari.java programı import java.util.Enumeration; import java.util.Hashtable; import javax.swing.JOptionPane; public class GezegenCaplari { public static void main (String args[]) { String names[] = {"Merkür", "Venüs", "Dünya", "Mars", "Jüpiter", "Satürn", "Uranüs", "Neptün", "Pluton"}; float diameters[] = {4800f, 12103.6f, 12756.3f, 6794f, 142984f, 120536f, 51118f, 49532f, 2274f}; Hashtable hash = new Hashtable(); for (int i=0, n=names.length; i < n; i++) { hash.put (names[i], new Float (diameters[i])); } Enumeration enum = hash.keys(); Object obj; String ss=""; while (enum.hasMoreElements()) { obj = enum.nextElement(); ss+=obj + ": " + hash.get(obj)+"\n"; } JOptionPane.showMessageDialog(null,ss); System.exit(0); } } Şekil 1.9.12 HashTable sınıfını kullanan GezegenCaplari programı Programdan da görüldüğü gibi çıktı hiçbir mantıksal sıralama düzeni içermemektedir, fakat burada önemli olan gezegenlerin ve çaplarının birbirleriyle olan ilişkilerinin listelenmesidir. Hashtable bu tür işlevleri en iyi bir şekilde yerine getirir. 1.9.9 ARRAYS SINIFI VE SIRALAMA Arrays sınıfı boyutlu değişkenleri sıralamaya yarıyan bir java sınfıdır. Metodları: public static List asList(object array[]); b değerinin a değerinin hangi elemanında olduğunu bulan : public static int binarySearch(<değişkentürü> a[],<değişkentürü>b); <değişkentürü> char,double,float,int,Object,long,short değerleri alabilir, elbette Object üzerinden Objectin alt sınıfları olan String, Double, Integer gibi sınıfları da kabul eder. İki boyutlu değişkenin birbirine eşit olup olmadığını denetleyen : public static boolean equals(<değişkentürü> a[],<değişkentürü>b[]); boyutlu değişkenin tüm değerlerini veya tanımlanan bir bölümünü bir bölümünü aynı tür bir değişken atayan public static void fill(<değişkentürü> a[],<değişkentürü>b); public static void fill(<değişkentürü> a[],int başlangıçindisi,int bitişindisi,<değişkentürü>b); boyutlu değişkeni sıraya sokan : public static void sort(<değişkentürü> a[]); public static void sort(Object a[],Comparator comp); listeden de görüldüğü gibi tüm metodlar static metodlardır. Program 1.9.22 : Arrays yapısının kullanıldığı Gezegensirasi.java programı import java.util.*; import javax.swing.JOptionPane; public class Gezegensirasi { static class InsensitiveComp implements Comparator { public int compare (Object a1, Object a2) { String s1 = a1.toString().toLowerCase(); String s2 = a2.toString().toLowerCase(); return s1.compareTo (s2); } } public static void main (String args[]) { String names[] = {"Mercür", "Venüs", "Dünya", "Mars", "Jüpiter", "Satürn", "Uranüs", "Neptün", "Pluto", "mercür", "venüs", "dünya", "mars", "jüpiter", "satürn", "uranüs", "neptün", "pluto" }; Arrays.sort(names); int namesLen = names.length; String ss=""; for (int i=0; i<namesLen; i++) { ss+=names[i] + " "; } ss+="\n"; Arrays.sort(names, new InsensitiveComp()); for (int i=0; i<namesLen; i++) { ss+=names[i] + " "; } ss+="\n"; JOptionPane.showMessageDialog(null,ss); System.exit(0); } } Şekil 1.9.13 Arrays sınıfını kullanan Gezegensirasi programı programda liste ikinci kere Comparator sınıfı InsensitiveComp() kullanarak büyük ve küçük harfi göz önüne almadan sıraya sokulmuştur. BÖLÜM 2 DOĞRUSAL DENKLEM SİSTEMLERİ 2.1 DOĞRUSAL DENKLEM SİSTEMLERİ, GENEL En genel formunda Doğrusal denklem sistemleri : a11 X1 + a12 X2 + a13 X3 + … + a1n X3 = b1 a21 X1 + a22 X2 + a23 X3 + … + a2n X3 = b2 a31 X1 + a32 X2 + a33 X3 + … + a3n X3 = b3 ………. an1 X1 + an2 X2 + an3 X3 + … + ann X3 = bn Şeklinde yazılabilir. Bu denklem matris formunda [A]{X}={B} veya Ax B şeklinde yazılabilir. Matris formunu açık yazarsak : a11 a12 a 21 a 22 .... .... a n1 a n 2 .... a1n X 1 b1 ..... a 2 n X 2 b2 .... .... ... .... .... a nn X n bn Bazı kaynaklarda da bu denklem sistemi kısaltılmış formda a11 a12 ..... a1n a21 a22 ..... a2 n .... .... .... .... an1 an 2 ..... ann b1 a11 a b2 21 veya ..... .... bn an1 a12 a22 ..... an 2 ..... ..... ..... ..... a1n b1 a2 n b2 ..... ..... ann bn şeklinde de gösterilebilir. Bu denklem sisteminde A ve B değerleri bilinen değerler X değerleri bilinmeyenlerdir. X değerlerinin saptanması problemini doğrusal denklem sistemi çözümü olarak adlandıracağız. Matrislerle ilgili sayısal işlemleri gelecek bölümümüzde inceleyeceğiz, ancak matris işlemlerinin de temelini oluşturan doğrusal denklem sistemi çözümü problemine ilk konu olarak bakmakta yarar görüyoruz. Burada yöntem bazında tanımlamalara gideceğiz, her verilen yöntemi örnek bir java programı ile destekleyeceğiz ve çeşitli örneklerin çözüm sonuçlarını da vereceğiz 2.2 GAUSS ELEME METODU Gauss eleme yöntemi en basit formunda matrislerin temel özelliklerine dayanan bir işlemdir. Matrislerin satırlarını değiştirmek, matrisin bir satırını belli bir çarpanla çarpmak veya satırları birbiriyle toplamak(veya çıkarmak) doğrusal denklem sistemindeki bilinmeyenlerin değerini etkilemez. Bu yüzden doğrusal denklem sisteminde (i numaralı satır)- Sabit * (j numaralı satır) gibi bir işlemi denklem sisteminin değerini değiştirmeden oluşturabiliriz. Gauss eleme metodunda bu manipülasyonu yapmaktaki gayemiz üst üçgen matris dediğimiz matrisin diyagonalinin altının tamamen sıfıra eşitlendiği eşdeğer formunu elde etmektir. Örneğin n=5 için a'11 a'12 0 a' 22 0 0 0 0 0 0 a'13 a' 23 a'33 0 0 a'14 a' 24 a'34 a' 44 0 a'15 X 1 b'1 a' 25 X 2 b' 2 a'35 X 3 b'3 a' 45 X 4 b' 4 a'55 X 5 b'5 şekline getirmemiz gerekir. Bunu yapabilmek için sistematik bir eleme uygulayabiliriz. Örneğin a21 elemanını 0 a dönüştürmek için a’21 = 0 = a 21 – C1 * a 11 işleminde sabitin değeri C1=(a 21/a 11) olacaktır. İkinci satırın her elemanı için C1 çarpanı kullanılarak yeni değerine çevrilir. Örneğin a’ 22 = a 22 – C1*a 12 a’ 23 = a 23 – C1*a 13 ………………………….. a’ 25 = a 25 – C1*a15 b’2=b2 – C1*b1 Bu işlemin sonunda a’21 elemanı sıfırlanmış olur. Aynı işlem önce a11 in altındaki tüm satırlara uygulanarak birinci sütundaki 0 değerleri oluşturulur. Daha sonra aynı işlem a22 nin altındaki kolon için yinelenir. Bu işlemi aynı değişkenlerle java döngüsü olarak yazarsak for(k=0;k<(n-1);k++) { for(i=k+1;i<n;i++) { C[k]=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-= C[k]*a[k][j]; } b[i] =b[i] - C[k]*b[k]; } } Lineer denklem sistemi üst üçgen matris şekline dönüştürüldükten sonra tersten itibaren çözme yöntemiyle bilinmeyenler çözülür. Yukarıda verilen beşli sistemin çözüm seti : X5 = b’5 / a’55 X4 = (b’4 – a’45*X5)/a’44 X3 = (b’3 – a’34*X4 – a’35*X5)/a’33 X2 = (b’2 – a’23*X3 – a’24*X3 – a’25*X5)/a’22 X1 = (b’1 – a’12*X2 – a’13*X3 – a’14*X4 – a’15*X5)/a’11 Şeklindedir. Bu işlemi n*n matris için java kodu olarak yazacak olursak : x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } Doğrusal denklem sisteminin çıktılarını anlaşılır bir şekilde oluşturabilmek için bir String çıktı sınıfı olan matriscikti.java programını oluşturduk. Program kodu aşağıda verilmiştir. Program 2.2-1 matris cikti.java doğrusal denklem sistemi formatlama sınıfı import java.io.*; import java.text.*; import java.util.Locale; public class matriscikti { public static String toString(double left, int w, int d) // double değişkenini verilen boyutta(w) ve noktadan sonra uzaklığında(d) // string değişkenine çevirir { NumberFormat df=NumberFormat.getInstance(Locale.US); df.setMaximumFractionDigits(d); df.setMinimumFractionDigits(d); df.setGroupingUsed(false); String s = df.format(left); while (s.length() < w) s = " " + s; if (s.length() > w) { s = ""; for (int i=0; i<w; i++) s = s + "-"; } return s; } public static String toString(double left) {// double değişkenini sabit boyutta(25) ve noktadan sonra uzaklığında(15) // string değişkenine çevirir return toString(left,25,15);} public static String toString(double[][] left,int w,int d) { //matrisin string eşdeğerini oluşturur int n,m; String b; b=""; n=left.length; m=left[0].length; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { b=b+toString(left[i][j],w,d); } b=b+"\n"; } return b; } public static String toString(double[][] a,double b[],int w,int d) {//doğrusal denklem sisteminin string eşdeğerini oluşrurur int n,m; String s; s=""; n=a.length; m=a[0].length; for(int i=0;i<n;i++) { s+=" |"; for(int j=0;j<m;j++) { s+=toString(a[i][j],w,d); } s+="| "+toString(b[i],w,d)+"| \n"; } return s; } public static String toString(double[][] a,double b[]) {//doğrusal denklem sisteminin string eşdeğerini oluşrurur return toString(a,b,25,15); } public static String toStringT(double[][] left,int w,int d) { return toString(Matrix.Transpose(left),w,d);} public static String toStringT(double[][] left) { return toString(Matrix.Transpose(left),15,10);} public static String toStringT(double[] left) { // returns a vertical string representation // of a double vector int n,m; String b; b=""; n=left.length; for(int i=0;i<n;i++) { b=b+toString(left[i])+"\n"; } return b; } public static String toString(double[] left) { // returns a horizontal string representation // of a double vector int n,m; String b; b=""; n=left.length; for(int i=0;i<n;i++) { b=b+toString(left[i])+"\t "; } b=b+"\n"; return b; }} Şimdi Gauss eleme işlemine bir bütün program olarak bakalım : Program 2.2-2 Gauss Eleme yöntemi import java.io.*; class SCO10A { public static double[] gauss(double a[][],double b[]) { int n=a.length; double x[]=new double[n]; double carpan=0; double toplam=0; //gauss eleme int i,j,k; String s=""; s="Orijinal doğrusal denklem sistemi :\n"+matriscikti.toString(a,b); for(k=0;k<(n-1);k++) { for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0;//bu deyim sadece elimine matrisin doğru değerlerini hesaplamak için konulmuştur for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } s+="elimine matris : k="+k+"\n";; s+=matriscikti.toString(a,b); } System.out.println(s); //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static void main(String args[]) throws IOException { double a[][]={{1,2,5},{2,1,2},{3,1,1}}; double b[]={1,1,2}; System.out.println("çözüm vektörü : \n"+matriscikti.toStringT(gauss(a,b))); } } Çıktı 2.2-1 Gauss Eleme yöntemi ---------- Capture Output ---------> "C:\co\java\bin\java.exe" SCO10A Orijinal doğrusal denklem sistemi : | 1.000000000000000 2.000000000000000 | 2.000000000000000 1.000000000000000 | 3.000000000000000 1.000000000000000 elimine matris : k=0 | 1.000000000000000 2.000000000000000 | 0.000000000000000 -3.000000000000000 | 0.000000000000000 -5.000000000000000 elimine matris : k=1 | 1.000000000000000 2.000000000000000 | 0.000000000000000 -3.000000000000000 | 0.000000000000000 0.000000000000000 5.000000000000000| 2.000000000000000| 1.000000000000000| 1.000000000000000| 1.000000000000000| 2.000000000000000| 5.000000000000000| -8.000000000000000| -14.000000000000000| 1.000000000000000| -1.000000000000000| -1.000000000000000| 5.000000000000000| -8.000000000000000| -0.666666666666666| 1.000000000000000| -1.000000000000000| 0.666666666666667| çözüm vektörü : -0.000000000000001 3.000000000000003 -1.000000000000001 > Terminated with exit code 0. Buradaki örnek doğrusal denklem sistemi : 1 2 5 X 0 1 2 1 2 X 1 1 3 1 1 X 2 2 Çıktının gerçek çözümleri 0,3 ve -1 değerleri olmalıdır, görüldüğü gibi denklem sistemimizin çözümünde ufak ta olsa bir hata mevcuttur. Buradaki elimine işlemlerini daha iyi anlamak için bir de açık hesap olarak yapalım Sıfır’ıncı kolon(kolon numarası 0 dan başlıyor), birinci satır(satır numarası sıfırdan başlıyor) k=0 çarpan C1=a10/a00 = 2/1=2 a10 = a10 - C1 * a00 = a10 - (a10/a00 )* a00 = 2 - 2*1 = 0 sıfırıncı kolon elimine prosesi tamamlandı birinci kolon,ikinci satır k=1 çarpan C3=a21/a11 = -5/-3=(5/3) a21 = a21 – C3 * a11 = a21 - (a21/a11 )* a11 = -5 – (5/3)*(-3) = 0 a22 = a22 - C3 * a12 = a11 - (a21/a11 )* a01 = -14 – (5/3)*(-8) = -0.6666666666666 b2 = b2 - C3 * b1 = b2 - (a21/a11 )* b1 = -1 – (5/3)*(-1) = 0.6666666666666 5 1 1 2 X 0 0 3 8 1 X1 0 0 0.666666666 X 2 0.666666666 Geriye koyma işlemi : X2 = b2/a22 = 0.6666666666/(-0.6666666666) = -1 X1 = (b1 - a12*X2)/a11 = (-1 - (-8)*(-1))/(-3) =(-9)/(-3)=3 X0 = (b0 - a01*X1 - a02*X2 )/a00 = (1 – 2*3-5*(-1))/1=0 X0 0 X 3 1 X 2 1 2.3 KISMİ PİVOT İŞLEMİ, KISMİ PİVOTLU GAUSS ELEME METODU Yukardaki basit örnekte de görüldüğü gibi sonuçta belli bir hata oluşmuştur. Gauss eleme prosesi tek başına kullanıldığında bazı denklem sistemlerinde bu hata büyük boyutlara ulaşabilir. Bu durumun oluşmasındaki temel neden Gauss elimine prosesindeki çarpandaki bölüm teriminin üst tarafta kalan terime göre küçük olması ve bunun sonucunda çarpım teriminin yuvarlatma hatası verecek kadar büyük değerlere ulaşmasıdır. Hatta bölünen sayı sıfıra eşit olursa çarpan sonsuza da gidebilir. Bunu engellemenin bir yolu eleme prosesi yapılan kolon için bölünen değerin en büyük değer olacağı şekilde satırların yerlerinin değiştirilmesidir. Bu işleme kısmi pivotlama adı veriyoruz. Eleme prosesinin yapıdığı satır ve sütunları tarıyarak maksimum olan değerleri diagonal terimin üzerinde de toplayabiliriz, ancak sütunların yer değiştirilmesi durumunda değişkenlerin sıraları da değişeceğinden çok daha kompleks bir indeksleme sistemine ihtiyacımız olacaktır. Bu yüzden tam pivotlama daha seyrek olarak kullanılan bir prosestir. Şimdi kısmi pivotlamayı bir önceki aynı örnekle anlatalım, örnek problemimiz : 1 2 5 X 0 1 2 1 2 X 1 1 3 1 1 X 2 2 Şeklindeydi. Burada gauss eliminasyonu uygulamadan önce her kolon için eleme elemanını alttaki elemanlarla karşılaştırarak alttakiler arasında daha büyük mutlak değere sahip olan varsa eleme elemanıyla bu satır değiştirilecektir. Örneğimizin sıfırıncı sütünunda olan kritik eleman a 00 1 e eşittir. Bu değer a10 (2) ve a20 (3) ile karşılaştırıldığında a20 değerinin en büyük olduğu görülecektir. Bu yüzden 2. satır ve 0. satır yer değiştirir ve sistem 3 1 1 X 0 2 2 1 2 X 1 1 1 2 5 X 2 1 Şeklini alır. Bu işleme java program parçacığı olarak bakarsak : double buyuk, dummy; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } } Şeklinde gerçekleştirdiğimizi görürüz. Burada satırları değiştirmek için bir ek değişkene ihtiyaç duyulduğunu not etmede yarar görüyoruz. Kısmi pivotlama işleminden sonra gauss eleme işlemini bölüm 2.1 de anlattığımız gibi gerçekleştiririz. Program 2.3-1 Pivotlu Gauss Eleme yöntemi import java.io.*; class SCO10B { public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; String s="Orijinal Matris :\n"+matriscikti.toString(a,b); for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } s+="pivotlu Matris : k="+k+"\n"+matriscikti.toString(a,b); //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } s+="elimine prosesi bitmiş matris : k="+k+"\n"+matriscikti.toString(a,b); //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } System.out.println(s); return x; } public static void main(String args[]) throws IOException { double a[][]={{1,2,5},{2,1,2},{3,1,1}}; double b[]={1,1,2}; System.out.println("sonuç vektörü : \n"+matriscikti.toStringT(pivotlugauss(a,b))); } } Çıktı 2.3-1 kısmi pivotlu gauss eleme yöntemi ---------- Capture Output ---------> "C:\co\java\bin\java.exe" SCO10B Orijinal Matris : | 1.000000000000000 2.000000000000000 | 2.000000000000000 1.000000000000000 | 3.000000000000000 1.000000000000000 pivotlu Matris : k=0 | 3.000000000000000 1.000000000000000 | 2.000000000000000 1.000000000000000 | 1.000000000000000 2.000000000000000 pivotlu Matris : k=1 | 3.000000000000000 1.000000000000000 | 0.000000000000000 1.666666666666667 | 0.000000000000000 0.333333333333333 elimine prosesi bitmiş matris : k=2 | 3.000000000000000 1.000000000000000 | 0.000000000000000 1.666666666666667 | 0.000000000000000 0.000000000000000 5.000000000000000| 2.000000000000000| 1.000000000000000| 1.000000000000000| 1.000000000000000| 2.000000000000000| 1.000000000000000| 2.000000000000000| 5.000000000000000| 2.000000000000000| 1.000000000000000| 1.000000000000000| 1.000000000000000| 4.666666666666667| 1.333333333333334| 2.000000000000000| 0.333333333333333| -0.333333333333333| 1.000000000000000| 4.666666666666667| 0.400000000000000| 2.000000000000000| 0.333333333333333| -0.400000000000000| sonuç vektörü : 0.000000000000000 3.000000000000000 -1.000000000000000 Sonuçtan da görüldüğü gibi sonuç vektöründe bir önce görülen hata burada yok olmuştur. Küçük matris sistemlerinin çözümünde gauss eleme yöntemi ideal bir çözümdür, ancak matris boyutu büyüdüğünde toplam hesap miktarı çok fazlalaştığından pratik avantajını yitirir. 2.4 GAUSS-JORDAN METODU 2.5 Gauss Jordan metodu temel olarak gauss metoduna benzer. Temel ayrılığı pivot elemanı dediğimiz elemenin yapılmasında kullanılan temel elemanın bulunduğu satırın elemeden önce pivot elemanına bölünerek normalize edilmesi ve eleme prosesinin sadece pivot elemanının altındaki satırlara değil pivot elemanı satırı haricindeki tüm satırlar için uygulanmasıdır. Program 2.4-1 de Gauss-Jordan elemesi java programı olarak verilmiştir. Burada çıktı olarak java programlama bölümünde detaylarını verdiğimiz Text sınıfı grafik çıktısı kullanılmıştır. Girdinin çeşitli şekillerde girilebilmesi için de public static double[][] C(double a[][],double b[]) ve public static double[][] C(double a[][],double b[][]) metodları tanımlanmıştır. Program 2.4-1 Gauss_Jordan Eleme yöntemi import java.io.*; class SCO10C { public static double[] gaussjordan(double a[][],double b[]) { //pivotsuz int n=b.length; int np1=n+1; double C[][]=new double[n][np1]; double x[]=new double[n]; double carpan=0; int i,j,k; for(i=0;i<n;i++) {for(j=0;j<n;j++){C[i][j]=a[i][j];};C[i][n]=b[i];} for(k=0;k<n;k++) { //gauss jordan eleme for(j=k+1;j<np1;j++) { C[k][j]/=C[k][k]; } for(i=0;i<n;i++) { if(i!=k) { carpan=C[i][k]; C[i][k]=0; for(j=k+1;j<np1;j++) { C[i][j]-=carpan*C[k][j]; } } } } for(i=0;i<n;i++) {x[i]=C[i][n];} return x; } public static void main(String args[]) throws IOException { double a[][]={{1,2,5},{2,1,2},{3,1,1}}; double b[]={1,1,2}; double x[]=gaussjordan(a,b); Text.print(x,"Gauss Jordan Metodu çözümü"); } } Çıktı 2.4-1 Gauss_Jordan Eleme yöntemi çözüm seti ikinci bir örnek olarak : 3 1 1 X 0 2 1 4 1 X 12 1 2 1 2 X 2 10 bu örneği programa girmek için veri satırını double a[][]={{3,1,-1},{1,4,1},{2,1,2}}; double b[]={2,12,10}; Olarak değiştirmemiz kafidir. Çözüm seti : Çıktı 2.4-2 Gauss_Jordan Eleme yöntemi çözüm seti Olacaktır. Bu denklem sistemini Gauss-Jordan eleme kullanarak elle çözelim 1 0.3333 0.3333 X 0 0.6667 1 4 1 X 1 12 2 1 2 X 2 10 ikinci satırdan birinci satırı çıkaralım 1 0.3333 0.3333 X 0 0.6667 0 3.6667 1.3333 X 11.3333 a 1 2 1 2 X 2 10 birinci satırı 2 ile çarpıp üçüncü satırdan çıkaralım 1 0.3333 0.3333 X 0 0.6667 0 3.6667 1.3333 X 11.3333 1 0 0.3333 2.6667 X 2 8.6667 Şimdi ikinci sütuna geçiyoruz. İkinci sütundakipivot elemanı 3.6667 dir. Tüm ikinci satırı bu değere bölerek normalize edelim 1 0.3333 0.3333 X 0 0.6667 0 1 0.3636 X 1 3.0909 0 0.3333 2.6667 X 2 8.6667 birinci satırı sıfırlayalım (ikinci satırı 0.333 ile çarpıp birinci satırdan çıkaralım): 0 0.4545 X 0 0.3636 1 0 1 0.3636 X 1 3.0909 0 0.3333 2.6667 X 2 8.6667 üçüncü satırı sıfırlayalım (ikinci satırı 0.333 ile çarpıp üçüncü satırdan çıkaralım): 1 0 0.4545 X 0 0.3636 0 1 0.3636 X 3.0909 1 0 0 2.5455 X 2 7.6365 üçüncü satırı 2.5455 e bölelim 1 0 0.4545 X 0 0.3636 0 1 0.3636 X 3.0909 1 0 0 1 X 2 3.0000 birinci satırı sıfırlayalım (üçüncü satırı -0.4545 ile çarpıp birinci satırla toplayalım) 0 X 0 1.0000 1 0 0 1 0.3636 X 3.0909 1 0 0 1 X 2 3.0000 ikinci satırı sıfırlayalım (üçüncü satırı 0.3636 ile çarpıp ikinci satırdan çıkaralım ) 1 0 0 X 0 1.0000 0 1 0 X 2.0001 1 0 0 1 X 2 3.0000 çözüm vektörü X 0 1.0000 X 2.0001 1 X 2 3.0000 gerçek çözüm : X 0 1.0000 X 2.0000 1 X 2 3.0000 değerleridir. 2.6 KISMİ PİVOTLU GAUSS-JORDAN METODU Gauss metodundaki gibi Gauss-Jordan metodunda da çözüm her zaman doğru olarak oluşmıyabilir. Doğru çözüme ulaşmamız pivotlama dediğimiz ek işlemi gerektirir. Kısmi pivotlama işleminde satırlar arasında en büyük mutlak değere sahip olan satırla pivot satırı yer değiştirilir. Program 2.5-1 Kısmi Pivotlu Gauss_Jordan Eleme yöntemi import java.io.*; class SCO10C3 { public static double[][] C(double a[][],double b[]) {int n=a.length;int m=a[0].length;double c[][]=new double[n][m+1]; for(int i=0;i<n;i++){for(int j=0;j<m;j++){c[i][j]=a[i][j];};c[i][m]=b[i];} return c; } public static double[][] C(double a[][],double b[][]) {int n=a.length;int o=b[0].length;int m=n+o;double c[][]=new double[n][m]; for(int i=0;i<n;i++) {for(int j=0;j<n;j++){c[i][j]=a[i][j];}; for(int j=n;j<m;j++){c[i][j]=b[i][j];} } return c; } public static double[][] pivotlugaussjordan(double a[][]) { //pivotlu int n=a.length; int m=a[0].length; int o=m-n; double x[][]=new double[n][o]; double carpan=0; double toplam=0; double buyuk; double dummy=0; int i,j,k,p,ii,jj; i=0; for(k=0;k<n;k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=0;ii<n;ii++) { if(i!=k) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } } if(p!=k) { for(jj=k;jj<m;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } } //gauss jordan elemeyi çözme for(j=k+1;j<m;j++) { a[k][j]/=a[k][k]; } a[k][k]=1.0; for(i=0;i<n;i++) { if(i!=k) { carpan=a[i][k]; a[i][k]=0; for(j=k+1;j<m;j++) {a[i][j]-=carpan*a[k][j]; } } } } for(jj=0;jj<o;jj++) {for(i=0;i<n;i++) {x[i][jj]=a[i][n+jj];}} return x; } public static void main(String args[]) throws IOException { double a[][]={{3,0,2,8},{0,0,2,-7},{6,2,8,26}}; //double a[][]=Text.readDouble_Table(); double x[][]=pivotlugaussjordan(a); System.out.println(Matrix.toString(x)); Text.print(x,"Şekil 2.5-1 Pivotlu Gauss Jordan Metodu çözümü"); } } Çıktı 2.5-1 Kısmi pivotlu Gauss_Jordan Eleme yöntemi çözüm seti 2.7 LU-ALT-ÜST ÜÇGEN MATRİS- GAUSS (DOLİTTLE) METODU Gauss ve Gauss-Jordan eleme metodlarında sol taraftaki matris ile sağ taraftaki vektör aynı anda işleme girmektedir. Bu durumda yeni bir sol taraf vektörü değerlendirmeye alınacağı zaman sağ tarafın tekrar işleme alınması gerekmektedir. Bunu engellemek için sol taraf matrisinin üst üçgen matrisi(U) ve alt üçgen matrisi(L) olmak üzere iki matrisin çarpımı şekline getirilmesi, sonra bu iki alt matris vektörünün çözülmesine gidilebilir. Örneğin N=5 için 1 0 0 0 l 21 1 0 0 [ L] l31 l32 1 0 l41 l42 l43 1 l51 l52 l53 l54 u11 u12 u13 0 u u23 22 [U ] 0 0 u33 0 0 0 0 0 0 u14 u24 u34 u44 0 0 0 0 0 1 u15 u25 u35 u45 u55 şeklindedir. Çözüm için : [A]=[L][U] [A]{X}={B} [L][U]{X}={B} [L]{D}={B} [U]{X}={D} Temel matris çarpım işlemleri dizisinden yararlanılır. Buradaki U matrisini Gauss eleme prosesinden sonraki üst üçgen matris olarak hesaplayabiliriz. L matrisi Gauss eleme prosesindeki çarpanlardan oluşur. L matrisinin diagonal elemanları 1 değerine eşit olduğundan L ve U matrisleri giriş A matrisinin aynı yerine yerleştirilebilir, ek bilgisayar alanı kullanılması gerekmez. Program 2.6.1 de Pivot kullanılmadan uygulanan Dolittle metodu verilmiştir. Program 2.6.2 de LU işlemi pivotlama işlemi ile birlikte uygulanmıştır. Pivotlu versiyonumuzda LU ayrıştırma prosesi ve denklem sistemi çözme prosesi ayrı ayrı uygulandığından matris satır değiştirme işlemi bir referans değeri üzerinden taşınmakta ve denklem sistemi çözümünde b matrisi aynı referansa göre yeniden düzenlenmektedir. Program 2.6-1 Gauss (Dolittle) Eleme yöntemi import java.io.*; import javax.swing.*; class SCO10D1 { public static double[][] gaussLU(double ai[][]) { int n=ai.length; double x[]=new double[n]; double a[][]=new double[n][n]; double carpan=0; double toplam=0; //gauss eleme int i,j,k; for(i=0;i<n;i++) for(j=0;j<n;j++){a[i][j]=ai[i][j];}; for(k=0;k<(n-1);k++) { for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=carpan;///L elemanı for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } } } return a; } public static double[] yerine_koyma(double ai[][],double bi[]) { //gauss LU çözümüyle LU indirgenmesi yapılmış Matris kullanarak lineer //denklem sistemi kökleri int n=ai.length; double toplam; double x[]=new double[n]; double a[][]=new double[n][n]; double b[]=new double[n]; int i,j; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};b[i]=bi[i];} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(i=1;i<n;i++) {toplam=b[i];for(j=0;j<i;j++){toplam-=a[i][j]*b[j];};b[i]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1]=b[n-1]/a[n-1][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[i][j]*x[j];}; x[i]=(b[i]-toplam)/a[i][i]; } //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double[][] yerine_koyma(double ai[][],double bi[][]) { int n=ai.length; int m=bi[0].length; double toplam; double x[][]=new double[n][m]; double a[][]=new double[n][n]; double b[][]=new double[n][m]; int i,j,k; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};for(k=0;k<m;k++) {b[i][k]=bi[i][k];}} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(k=0;k<m;k++) { for(i=1;i<n;i++) {toplam=b[i][k];for(j=0;j<i;j++){toplam-=a[i][j]*b[j][k];};b[i][k]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1][k]=b[n-1][k]/a[n-1][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[i][j]*x[j][k];}; x[i][k]=(b[i][k]-toplam)/a[i][i]; } }//kin sonu //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double [] AXB(double a[][],double b[]) { //denklem sistemi çözümü b vektörü için int n=a.length; double c[][]=gaussLU(a); double s[]=yerine_koyma(c,b); return s; } public static double [][] AXB(double a[][],double b[][]) {//denklem sistemi çözümü b matrisi için int n=a.length; double c[][]=gaussLU(a); double s[][]=yerine_koyma(c,b); return s; } public static void main(String args[]) throws IOException { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; JPanel y=new JPanel(); Text.add(y,a,"a matrisi"); double b[]={7.85,-19.3,71.4}; Text.addT(y,b,"b matrisi"); double x[]=AXB(a,b); Text.addT(y,x,"çözüm matrisi"); Text.print(y,"Gauss LU ayrıştırma ve yerine koyma metodu çözümü"); } } Program 2.6-2 Kısmi Pivotlu LU Gauss (Dolittle) Eleme yöntemi import java.io.*; import javax.swing.*; class SCO10D { public static void pivot(double a[][],int o[],double s[],int k) {// GaussLU için pivot metodu int n=a.length; int dummy1=0; double buyuk; double dummy=0; //pivotlama int p=k; buyuk=Math.abs(a[o[k]][k]); for(int ii=k+1;ii<n;ii++) { dummy=Math.abs(a[o[ii]][k]/s[o[ii]]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } dummy1=o[p]; o[p]=o[k]; o[k]=dummy1; } public static int[] sirali_indeks(int n) { // sıralı rakamları taşıyan bir referans vektörü oluşturur int o[]=new int[n]; for(int i=0;i<n;i++) {o[i]=i;} return o; } public static double[][] gaussLU(double ai[][],int o[]) { //kısmi pivotlu gauss eleme yöntemi int n=ai.length; double a[][]=new double[n][n]; double s[]=new double[n]; double carpan=0; double toplam=0; double absaij; //gauss eleme int i,j,k,p,ii,jj; //System.out.println("Orijinal Matris :\n"+Matrix.toString(ai)); for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];}} for(i=0;i<n;i++) { o[i]=i;s[i]=Math.abs(a[i][0]); for(j=1;j<n;j++) { absaij=Math.abs(a[i][j]); if(absaij>s[i]) {s[i]=absaij;} } } for(k=0;k<(n-1);k++) { pivot(a,o,s,k); //pivot referansını değiştir //System.out.println("pivotlu Matris : k="+k+"\n"+Matrix.toString(a)); //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[o[i]][k]/a[o[k]][k]; a[o[i]][k]=carpan; for(j=k+1;j<n;j++) { a[o[i]][j]-=carpan*a[o[k]][j]; } } } return a; } public static double[] yerine_koyma(double ai[][],double bi[]) { int n=ai.length; return yerine_koyma(ai,bi,sirali_indeks(n)); } public static double[][] yerine_koyma(double ai[][],double bi[][]) { int n=ai.length; return yerine_koyma(ai,bi,sirali_indeks(n)); } public static double[] yerine_koyma(double ai[][],double bi[],int o[]) { //gauss LU çözümüyle LU indirgenmesi yapılmış Matris kullanarak lineer //denklem sistemi kökleri int n=ai.length; double toplam; double x[]=new double[n]; double a[][]=new double[n][n]; double b[]=new double[n]; int i,j; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};b[i]=bi[i];} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(i=1;i<n;i++) {toplam=b[o[i]];for(j=0;j<i;j++){toplam-=a[o[i]][j]*b[o[j]];};b[o[i]]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1]=b[o[n-1]]/a[o[n-1]][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[o[i]][j]*x[j];}; x[i]=(b[o[i]]-toplam)/a[o[i]][i]; } //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double[][] yerine_koyma(double ai[][],double bi[][],int o[]) { int n=ai.length; int m=bi[0].length; double toplam; double x[][]=new double[n][m]; double a[][]=new double[n][n]; double b[][]=new double[n][m]; int i,j,k; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};for(k=0;k<m;k++) {b[i][k]=bi[i][k];}} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(k=0;k<m;k++) { for(i=1;i<n;i++) {toplam=b[o[i]][k];for(j=0;j<i;j++){toplam-=a[o[i]][j]*b[o[j]][k];};b[o[i]][k]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1][k]=b[o[n-1]][k]/a[o[n-1]][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[o[i]][j]*x[j][k];}; x[i][k]=(b[o[i]][k]-toplam)/a[o[i]][i]; } }//kin sonu //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double [] AXB(double a[][],double b[]) { //denklem sistemi çözümü b vektörü için int n=a.length; int q[]=new int[n]; double c[][]=gaussLU(a,q); double s[]=yerine_koyma(c,b,q); return s; } public static double [][] AXB(double a[][],double b[][]) {//denklem sistemi çözümü b matrisi için int n=a.length; int q[]=new int[n]; double c[][]=gaussLU(a,q); double s[][]=yerine_koyma(c,b,q); return s; } public static void main(String args[]) throws IOException { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; JPanel y=new JPanel(); Text.add(y,a,"a matrisi"); double b[]={7.85,-19.3,71.4}; Text.addT(y,b,"b matrisi"); double x[]=AXB(a,b); Text.addT(y,x,"çözüm matrisi"); Text.print(y,"Gauss LU ayrıştırma ve yerine koyma metodu çözümü"); } } Çıktı 2.6-1 Kısmi Pivotlu LU Gauss (Dolittle) Eleme yöntemi 2.8 CRAUT LU METODU Gauss (Dolittle) LU ayrıştırmasında L matrisinin köşegen elemanları 1 idi. Craut ayrıştırmasının temel farkı U matrisinin köşegen elemanlarının 1 olmasıdır. Örneğin N=5 için l11 l 21 [ L] l31 l41 l51 0 0 0 0 l22 0 0 0 l32 l33 0 0 l42 l43 l44 0 l52 l53 l54 l55 1 u12 u13 u14 0 1 u u24 23 [U ] 0 0 1 u34 0 1 0 0 0 0 0 0 şeklindedir. Çözüm için yine : [A]=[L][U] u15 u25 u35 u45 1 [A]{X}={B} [L][U]{X}={B} [L]{D}={B} [U]{X}={D} Temel matris çarpım işlemleri dizisinden yararlanılabilir. Craut algoritması işlemleri yaparken sırası ile kolon ve satır taramaları yaparak hesaplama işlemini gerçekleştirir. İşlem steplerini şu şekilde sıralayabiliriz : döngü i=1,2,….,n li,1 = ai,1 u1, j a1, j döngü i=2,3,….,n l11 döngü j=2,3,….,n – 1 j 1 li , j ai , j li ,k uk , j döngü k=j,j+2,….,n k 1 j 1 ui , j a j ,k l j ,i ui ,k i 1 l jj döngü k=j+1,j+2,….,n döngü sonu n 1 l n ,n an ,n l n ,k u k ,n k 1 Algoritmayı Alttaki örnek programda verelim : Program 2.7-1 LU Craut yöntemi import java.io.*; class SCO10F { //LU decomposition method public static double[][] LU(double c[][],int indx[],int d[]) { //LU ayrıştırması ve index indx değerlerini verir double a[][]; int n=c.length; a=new double[n][n]; double vv[]; vv=new double[n]; double sum,dum,big,temp; int i,j,k; int imax; int nmax=100; double tiny=1.0e-40; imax=0; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) a[i-1][j-1]=c[i-1][j-1]; } d[0]=1; for(i=1;i<=n;i++) { big=0.0; for(j=1;j<=n;j++) { if(Math.abs(a[i-1][j-1])>big) big=Math.abs(a[i-1][j-1]); } if(big==0) {System.out.println("tekil matris");return a;} vv[i-1]=1.0/big; } for(j=1;j<=n;j++) { for(i=1;i<j;i++) { sum=a[i-1][j-1]; for(k=1;k<i;k++) { sum-=a[i-1][k-1]*a[k-1][j-1]; } a[i-1][j-1]=sum; } big=0; for(i=j;i<=n;i++) { sum=a[i-1][j-1]; for(k=1;k<j;k++) { sum-=a[i-1][k-1]*a[k-1][j-1]; } a[i-1][j-1]=sum; dum=vv[i-1]*Math.abs(sum); if(dum>=big) { imax=i; big=dum; } } //end of i=0 if(j != imax) { for(k=1;k<=n;k++) { dum=a[imax-1][k-1]; a[imax-1][k-1]=a[j-1][k-1]; a[j-1][k-1]=dum; } d[0]=-d[0]; vv[imax-1]=vv[j-1]; } //end of if indx[j-1]=imax; if(a[j-1][j-1]==0) a[j-1][j-1]=tiny; if(j!=n) { dum=1.0/a[j-1][j-1]; for(i=j+1;i<=n;i++) a[i-1][j-1]*=dum; }//endif } //end for j= return a; } public static double[] LUaxb(double a[][],double x[],int indx[]) { int ii=0; int i,j,ll=0; double sum=0; int n=a.length; double b[]; b=new double[n]; for(i=1;i<=n;i++) { b[i-1]=x[i-1]; } for(i=1;i<=n;i++) { ll=indx[i-1]; sum=b[ll-1]; b[ll-1]=b[i-1]; if(ii!=0) { for(j=ii;j<=(i-1);j++) { sum-=a[i-1][j-1]*b[j-1]; } } else if(sum!=0) ii=i; b[i-1]=sum; } for(i=n;i>=1;i--) { sum=b[i-1]; if(i<n) { for(j=(i+1);j<=n;j++) { sum-=a[i-1][j-1]*b[j-1]; } } b[i-1]=sum/a[i-1][i-1]; } return b; } public static double[] AXB(double a[][],double b[]) { //craut LU methodu int n=a.length; double c[]=new double[n]; int d[]={1}; int indx[]=new int[n]; double e[][]=new double[n][n]; e=Matrix.LU(a,indx,d); c=Matrix.LUaxb(e,b,indx); return c; } //end of AXB public static double[][] AXB(double a[][],double b[][]){ if(a.length!=b.length) { System.out.println("Boyut hatası Matrix.AxB 471"); System.exit(1); } double[] bin=new double[b.length]; double[][] bout=new double[b.length][1]; for(int i=0;i<bin.length;i++) bin[i]=b[i][0]; double[] c=AXB(a,bin); for(int i=0;i<bin.length;i++) bout[i][0]=c[i]; return bout; } public static void main(String args[]) throws IOException { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; double b[]={7.85,-19.3,71.4}; double x[]=AXB(a,b); //System.out.println("x=\n "+Matrix.toStringT(x)); Text.print(x,"craut LU ayrıştırma ve yerine koyma metodu çözümü"); } } 2.9 JACOBİ, GAUSS-SEİDEL VE RAHATLAMALI İNTERPOLASYON İTERATİF METODLARI İteratif methodlar bilhassa büyük matrislerin çözülmesinde çok önemli olabilir. Gauss eleme metodu ve LU metodu toplam olarak n3/3, Gauss-Jordan metodu n3/2 işleme gerek duyar n çok büyüdüğünde toplam işlem sayısı da çok büyür. İterativ metodlar eleme işlemi yapmadan bir önceki çözüm setini kullanarak, bir sonraki iterativ çözüme ulaşır. Çözüm sabit hale geldiğinde sonuç elde edilmiş olur. İteratif yöntemlerin en basiti Jacobi metodudur. Burada her denklem için bir x değeri seçilerek değerlendirilir. Diğer x değerleri bir önceki iterasyondan alınır. xik 1 1 (bi Aij x kj ) Aij j i , 1 i n Bu denklemin daha çabuk bir şekilde çözüme ulaşması için tüm değerleri bir önceki iterasyondan almak yerine hesaplanan tüm değerler formüle koyulur. Bu iteratif yönteme Gauss-Seidel metodu adı verilir. xik 1 i 1 n 1 (bi Aij x kj 1 Aij x kj ), Aij j 1 j i 1 1 i n İterativ yöntemin dönüşmesini biraz daha çabuklaştırmanın yolu eski iterasyonla yeni iterasyon arasında rahatlama katsayısı ismi verilen gibi bir ağırlık katsayısıyla hesaplamaya gitmektir. xik 1 (1 ) xik Aij i 1 n j 1 j i 1 (bi Aij x kj 1 Aij x kj ), 1 i n birden büyük veya küçük olabilir. Bu yönteme rahatlamalı interpolasyon (relaxation) adı verilir. bire eşit olduğunda yöntem normal Gauss-Seidel formülüne dönüşür. Aşağıda bu metodun java dilinde yazılmış programı görülmektedir. Program 2.7-1 Gauss_seidel rahatlamalı interpolasyon formülü import java.io.*; class SCO10E { public static double [] gauss_seidel(double a[][],double b[]) { double lambda=1.2; int n=a.length; //ilk x tahmin değerleri 0 olarak alındı double x[]=new double[n]; return gauss_seidel(a,b,x,lambda); } public static double [] gauss_seidel(double a[][],double b[],double x[],double lambda) { //denklem sistemi çözümü b iteratif gauss_seidel metodu metodu //yakınsama faktörü lambda ile birlikte verilmiş formül int n=a.length; int imax=300; double es=1.0e-20; double dummy=0; double ea=1e-1; double sum=0; double old=0; int iter=0; int sentinel=0; for(int i=0;i<n;i++) { dummy=a[i][i]; for(int j=0;j<n;j++) {a[i][j]/=dummy;} b[i]/=dummy; } for(int i=0;i<n;i++) { sum=b[i]; for(int j=0;j<n;j++) {if(i!=j)sum-=a[i][j]*x[j];} x[i]=sum; } iter=0; do { sentinel=1; for(int i=0;i<n;i++) { old=x[i]; sum=b[i]; for(int j=0;j<n;j++) {if(i!=j) sum-=a[i][j]*x[j];} x[i]=lambda*sum+(1.0-lambda)*old; if(sentinel==1 && x[i]!=0.0 ) {ea=Math.abs((x[i]-old)/x[i])*100.0;} if(ea<es) sentinel=0; } iter++; }while(sentinel==1 && iter<imax); if(iter>=imax) System.out.println("Maksimum iterasyon sayısı aşıldı sonuç geçerli olmayabilir iter = "+iter); return x; } public static void main(String args[]) throws IOException { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; double b[]={7.85,-19.3,71.4}; Text.print(gauss_seidel(a,b),"Rahatlamalı Gauss Seidel Metodu çözümü"); } } Çıktı 2.7-1 Gauss_seidel rahatlamalı interpolasyon formülü 2.10 CHOLESKY SİMETRİK MATRİS LU METODU Cholesky simetrik matris LU metodu temel olarak Dolittle LU metoduna benzer ancak matris simetrik olduğundan ayrıştırma alt üçgen matris ve alt üçgen matrisin transpozu(üst üçgen matris) şeklinde ayrılabilir. [A]=[L][L]T Ayrıştırma işlemini i 1 lki aki lij lkj j 1 lii k 1,2,......,k 1 ve lkk akk lkj2 şeklinde gerçekleştirebiliriz. Cholesky programı altta verilmiştir. Program 2.8-1 Cholesky simetrik matris LU formülü import java.io.*; class SCO10I { public static double[][] choleskyLU(double c[][]) { //cholesky LU //sadece simetrik matrisler içindir double factor=0; double buyuk; int i,j,k,p,ii,jj; int n=c.length; double d[][]=new double[n][n]; double dummy; double toplam; for(i=0;i<n;i++) {for(j=0;j<n;j++) d[i][j]=c[i][j];} for(k=1;k<=n;k++) { for(i=1;i<=(k-1);i++) {toplam=0;; for(j=1;j<=(i-1);j++) { toplam+=d[i-1][j-1]*d[k-1][j-1]; } d[k-1][i-1]=(d[k-1][i-1]-toplam)/d[i-1][i-1]; } toplam=0.0; for(j=1;j<=(k-1);j++) { toplam+=d[k-1][j-1]*d[k-1][j-1]; } d[k-1][k-1]=Math.sqrt((d[k-1][k-1]-toplam)); for(j=k+1;j<=n;j++) d[k-1][j-1]=0.0; } return d; } public static double[] substitutecholesky(double c[][],double b[]) { //ileriye doğru yerine koyma cholesky simetrik LU metoduyla //indirgenmiş olmalıdır int i,j; double U[][]=T(c); double L[][]=c; System.out.println("L*L(T) = "+Matrix.toString(Matrix.multiply(L,U))); int n=b.length; double toplam=0; double x[]=new double[n]; for(i=1;i<n;i++) {toplam=b[i]; for(j=0;j<i;j++) {toplam-=U[i][j]*b[j];} b[i]=toplam/L[i][i];; } //geriye yerine koyma x[n-1]=b[n-1]/L[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=(i+1);j<n;j++) { toplam+=U[i][j]*x[j];} x[i]=(b[i]-toplam)/U[i][i]; } return x; } public static double[][] T(double [][] left) { //transpose matrix (if A=a(i,j) T(A)=a(j,i) int i,j; int n=left.length; int m=left[0].length; double b[][]; b=new double[m][n]; for(i=0;i<n;i++) { for(j=0;j<m;j++) { b[j][i]=left[i][j]; } } return b; } public static void main(String args[]) throws IOException { double a[][]={{6,15,55},{15,55,225},{55,225,979}}; double b[]={1,1,1}; double L[][]=choleskyLU(a); System.out.println("Matris L : \n"+Matrix.toString(L)); double x[]=substitutecholesky(L,b); System.out.println("Cholesky : \n"+Matrix.toStringT(x)); } } Program 2.8-1 Cholesky simetrik matris LU formülü Matris L : 2.449489742783178 6.123724356957946 22.453655975512470 0.000000000000000 4.183300132670377 20.916500663351886 0.000000000000000 0.000000000000000 6.110100926607781 L*L(T) = 5.999999999999999 15.000000000000000 15.000000000000000 55.000000000000000 55.000000000000000 225.000000000000000 55.000000000000000 225.000000000000000 979.000000000000000 Cholesky : 0.354676861892435 -0.076785714285715 0.026785714285714 2.11 3LÜ VE 5Lİ BANT MATRİS Üçlü köşegen sistem – yani bant genişliği 3 olan sistem genel olarak f1 e 2 g1 f2 e3 g2 f3 e4 g3 f4 e5 g4 f5 . g5 . en1 . f n1 en x1 r1 x r 2 2 x3 r3 x4 r4 x5 r5 . . g n1 xn1 rn1 f n xn rn şeklide ifade edilebilir. Tüm LU işlemlernde olduğu gibi ayrıştırma, yerine koyma ve geriye doğru yerine koyma proseslerinden oluşur. Ayrıştırma : for(int k=1;k<n;k++) {e[k]=e[k]/f[k-1]; f[k]=f[k]-e[k]*g[k-1]; } İleriye doğru yerine koyma : for(int k=1;k<n;k++) {r[k]=r[k]-e[k]*r[k-1]; } Geriye doğru yerine koyma : x[n-1]=r[n-1]/f[n-1]; for(int k=(n-2);k>=0;k--) {x[k]=(r[k]-g[k]*x[k+1])/f[k];} Tüm işlem java programı olarak alttaki programda tanımlanmıştır. Program 2.9-1 3-lü bant matris için Thomas algoritması import java.io.*; class SCO10H { public static double [] thomas(double a[][],double r[]) { // int n=a.length; double f[]=new double[n]; double e[]=new double[n]; double g[]=new double[n]; double x[]=new double[n]; for(int i=0;i<n;i++) {f[i]=a[i][i];} for(int i=0;i<(n-1);i++) {g[i]=a[i][i+1];} for(int i=0;i<(n-1);i++) {e[i+1]=a[i+1][i];} for(int k=1;k<n;k++) {e[k]=e[k]/f[k-1]; f[k]=f[k]-e[k]*g[k-1]; } for(int k=1;k<n;k++) {r[k]=r[k]-e[k]*r[k-1]; } x[n-1]=r[n-1]/f[n-1]; for(int k=(n-2);k>=0;k--) {x[k]=(r[k]-g[k]*x[k+1])/f[k];} return x; } public static double [] thomas(double f[],double e[],double g[],double r[]) { int n=f.length; double x[]=new double[n]; for(int k=1;k<n;k++) {e[k]=e[k]/f[k-1]; f[k]=f[k]-e[k]*g[k-1]; } for(int k=1;k<n;k++) {r[k]=r[k]-e[k]*r[k-1]; } x[n-1]=r[n-1]/f[n-1]; for(int k=(n-2);k>=0;k--) {x[k]=(r[k]-g[k]*x[k+1])/f[k];} return x; } public static void main(String args[]) throws IOException { double f[]={2.04,2.04,2.04,2.04}; double g[]={-1,-1,-1,0}; double e[]={0,-1,-1,-1}; double b[]={40.8,0.8,0.8,200.8}; System.out.println("thomas : \n"+Matrix.toStringT(thomas(f,e,g,b))); double a[][]={{2.04,-1,0,0},{-1,2.04,-1,0 },{0,-1,2.04,-1},{0,0,-1,2.04}}; double d[]={40.8,0.8,0.8,200.8}; System.out.println("thomas : \n"+Matrix.toStringT(thomas(a,d))); } } Çıktı 2.9-1 3-lü bant matris için Thomas algoritması thomas : 65.969834366776620 93.778462108224330 124.538228334001000 159.479523693137740 thomas : 65.969834366776620 93.778462108224330 124.538228334001000 159.479523693137740 Beşli köşegen sistem – yani bant genişliği 5 olan sistemi şu şekilde yazarsak : d1 a 1 e1 c1 d2 a2 e2 f1 c2 d3 a3 e3 f2 c3 d4 a4 . f3 c4 d5 . en3 f4 c5 . an 2 en2 f5 . d n1 an1 x1 b1 x b 2 2 x3 b3 x4 b4 x5 b5 f n2 . . cn1 xn1 bn1 d n xn bn buradaki LU ayrıştırma ve yerine koyma prosesi program 2.9.2 de görüldüğü gibi oluşturulur. Program 2.9-2 5-lü bant matris için band algoritması import java.io.*; class SCO10J { public static double [] besliband(double A[][],double b[]) { // int n=A.length; double f[]=new double[n-1]; double c[]=new double[n-1]; double d[]=new double[n]; double a[]=new double[n-1]; double e[]=new double[n-2]; double x[]=new double[n]; for(int i=0;i<n;i++) {d[i]=A[i][i];} for(int i=0;i<(n-1);i++) {c[i]=A[i][i+1];} for(int i=0;i<(n-1);i++) {a[i]=A[i+1][i];} for(int i=0;i<(n-2);i++) {f[i]=A[i][i+2];} for(int i=0;i<(n-2);i++) {e[i]=A[i+2][i];} int i; double xmult; for(i=1;i<(n-1);i++) {xmult=a[i-1]/d[i-1]; d[i]+=-xmult*c[i-1]; c[i]+=-xmult*f[i-1]; b[i]+=-xmult*b[i-1]; xmult=e[i-1]/d[i-1]; a[i]+=-xmult*c[i-1]; d[i+1]+=-xmult*f[i-1]; b[i+1]+=-xmult*b[i-1]; //System.out.println(i+"d="+d[i]+"c="+c[i]+"b="+b[i]); } xmult=a[n-2]/d[n-2]; d[n-1]+=-xmult*c[n-2]; x[n-1]=(b[n-1]-xmult*b[n-2])/d[n-1]; x[n-2]=(b[n-2]-c[n-2]*x[n-1])/d[n-2]; for(i=n-3;i>=0;i--) {x[i]=(b[i]-f[i]*x[i+2]-c[i]*x[i+1])/d[i];} return x; } public static double [] besliband(double f[],double c[],double d[],double a[],double e[],double b[]) { int n=d.length; double x[]=new double[n]; int i; double xmult; for(i=1;i<(n-1);i++) {xmult=a[i-1]/d[i-1]; d[i]+=-xmult*c[i-1]; c[i]+=-xmult*f[i-1]; b[i]+=-xmult*b[i-1]; xmult=e[i-1]/d[i-1]; a[i]+=-xmult*c[i-1]; d[i+1]+=-xmult*f[i-1]; b[i+1]+=-xmult*b[i-1]; //System.out.println(i+"d="+d[i]+"c="+c[i]+"b="+b[i]); } xmult=a[n-2]/d[n-2]; d[n-1]+=-xmult*c[n-2]; x[n-1]=(b[n-1]-xmult*b[n-2])/d[n-1]; x[n-2]=(b[n-2]-c[n-2]*x[n-1])/d[n-2]; for(i=n-3;i>=0;i--) {x[i]=(b[i]-f[i]*x[i+2]-c[i]*x[i+1])/d[i];} return x; } public static void main(String args[]) throws IOException { double a[][]={{2.04,-1,0,0},{-1,2.04,-1,0 },{0,-1,2.04,-1},{0,0,-1,2.04}}; double b[]={40.8,0.8,0.8,200.8}; double x[]=besliband(a,b); Text.print(x,"beşli bant matris metodu çözümü"); } } Program 2.9-3 5-lü bant matris için band algoritması örnek problem çözümü ana programı burada örnek problem olarak 3 lü band matriste aldığımız matrisi çözdük, aynı sonucu görmüş olduk. İkinci bir örnekte 5li band matris çözelim : matrisini alalım. Programın metodlarında bir değişiklik olmayacağından sadece ana program listesini veriyoruz. Bu örnekte tüm A matrisini vermek yerine bantları verdik. Bu şekilde giriş çok büyük boyuttaki matrisler için oldukça önemli bir hafıza kazanımı sağlar. Program 2.9-3 5-lü bant matris için band algoritması örnek problem çözümü ana programı public static void main(String args[]) throws IOException { double d[]={6,6,6,6,6,6,6,6,6,7}; double c[]={-4,-4,-4,-4,-4,-4,-4,-4,-4}; double f[]={1,1,1,1,1,1,1,1}; double a[]={-4,-4,-4,-4,-4,-4,-4,-4,-4}; double e[]={1,1,1,1,1,1,1,1}; double b[]={3,0,0,0,0,0,0,0,0,4}; double x[]=besliband(f,c,d,a,e,b); Text.printT(x,"beşli bant matris metodu çözümü"); } Program 2.9-4 5-lü bant matris için band algoritması örnek problem çözümü ana programı 2.12 KONJUGE GRADYAN METODU Vektör x* pozitif ve tanımlı Ax = b denklem sisteminin çözüm seti ise, bu çözüm setinin geçerli olması için x* vektörünün g ( x) x T A x 2bT x fonksiyonunu minimum yapması gerekir. x vektörünü çözüm x* vektöründen farklı bir vektör olarak tanımlıyalım. Ek olarak 0 dan farklı bir v vektörü ve gerçek bir sayı olan t sayısını tanımlayalım. g(x+tv)=g(x)+2t [vT (Ax-b)] + t2 [vT(Av)] şeklinde yazılabilir. Bu denklem için x ve v vektörleri bilindiğinde t nin hangi değeri için fonksiyonun minimum olacağını irdeleyelim(değişken boyutunu bir boyuta indirgeyelim). Bu fonksiyonun sadece t’nin fonksiyonu olduğunu kabul edersek : h(t)=g(x+tv) yazabiliriz ve minimum h fonksiyonunun t’ye göre türevinde oluşacaktır. h’(t)= 2[vT (Ax-b)]-2t [vT(Av)] = 0 . Bu denklemden t v T ( Ax b) olduğu görülebilir. Bu özellikten yararlanarak çözüme gitmek için önce v T Av r = b – A x tanımını yapalım. Bu tanımı bir önceki t tanımında yerine koyarsak : vT r tanım, şeklini alır. t T v Av t ye iteratif proses açısında baktığımızda iteratif olarak değişen xk=xk-1 + tkvk ve rk = b - xk için tk değeri v Tk rk tk T vk Av k şeklinde yazılabilir. Yeni bulunan xk vektörü d A xk = b denklemini sağlamalıdır. Çözüme ulaştığımızda A xk = A(xk-1 + tkvk ) = b olacağını da biliyoruz. Ancak arama yönü vk i hala bilmiyoruz. vk yönü olarak en dik yamaç yönü seçilebilir. Bu yön g ( x) 2( Ax b) 2r olur. Bu durumda vk 1 g ( xk ) rk olarak seçilebilir. bu yön g(xk) deki en büyük negatif değişimi verir. Bu metoda en dik yamaç metodu adı verilir. Alternatif bir seçim ise şöyle yapılabilir : 0 dan farklı öyle v vektörleri seçebilirizki bu vektörler için viT A v j 0 i j olur. Bu tür vektörlere ortogonal vektör adını veriyoruz. Eğer ortagonal v vektörleri bulabilirsek, bu bizim çözümümüzü oldukça basitleştirecektir (sette i ve j nin eşit olmadığı terimler yok olacağından matris çözümleri yerlerini çarpma ve bölme işlemlerine bırakacaktır.). Hestenes ve Stiefel’in önerdiği Ortoganal set rT r s k Tk k rk 1 rk 1 vk+1= rk + skvk şeklinde bir önceki v vektör değeri kullanılarak türetilir. Özet olarak metodu şu şekilde uygulayabiliriz : r0= b – A x0 ve v0= r0 (en dik yamaç medodu değeri) alınır. sonra k=1 den n e kadar rkT1 rk tk T vk Av k xk=xk-1 + tkvk rk = b - xk rT r s k Tk k rk 1 rk 1 vk+1= rk + skvk şeklinde iteratif proses oluşturulur. Görüldüğü gibi yöntem uzun bir yöntemdir, ve küçük matrisler için kullanımı Gauss yöntemi gibi direk metodlara göre daha zordur. Ancak denklem sistemi çok büyük boyutlara ulaştığında tercih edilen bir yöntem haline gelir. Program 2.11-1 konjuge gradyen metodu ile matris sistemi çözümü import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; import java.io.*; public class conjugate_gradient1 { public static double VT_V(double [] left) { //multiplies a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double[] multiply(double[] left,double[][] right) { //multiplication of one vector with one matrix int ii,jj,i,j,k; int m2=right[0].length; int n2=right.length; int m1=left.length; double[] b; b=new double[m1]; if(n2 != m1) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n2;ii++) { b[ii]=0; } return b; } for(i=0;i<m2;i++) { b[i]=0; for(k=0;k<m1;k++) b[i]+=right[i][k]*left[k]; } return b; //end of multiply of a vector and a matrix } public static double[] multiply(double[][] left,double[] right) { //multiplication of one matrix with one vector int ii,jj,i,j,k; int m1=left[0].length; int n1=left.length; int m2=right.length; double[] b; b=new double[m2]; if(n1 != m2) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n1;ii++) { b[ii]=0; } return b; } for(i=0;i<m1;i++) { b[i]=0; for(k=0;k<n1;k++) b[i]+=left[i][k]*right[k]; } return b; //end of multiply of a matrix and a vector } public static double[] multiply(double left,double[] right) { //multiplying a vector with a constant int i; int n=right.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=left*right[i]; } return b; } public static double[] substract(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]-right[i]; } return b; //end of vector substraction method } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] equals(double[] left) { //addition of two vectors int n1=left.length; double b[]; b=new double[n1]; for(int i=0;i<n1;i++) { b[i]=left[i]; } return b; //end of vector equal method } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double VT_G_V(double V[],double G[][]) { double x1[]=multiply(V,G); return VT_X(V,x1); } public static double[] conjugate_gradient(double A[][],double b[]) {int n=A.length; double x[]=new double[n]; return conjugate_gradient(x,A,b); } public static double[] conjugate_gradient(double x[],double A[][],double b[]) { // iterative system of equation solution double eps=1.0e-15; int maxiter=500; int n=x.length; double r[]=new double[n]; double re[]=new double[n]; double v[]=new double[n]; double t; double s; r=substract(b,multiply(A,x)); v=equals(r); int k=0; do { re=equals(r); t=VT_V(re)/VT_G_V(v,A); x=add(x,multiply(t,v)); r=substract(r,multiply(multiply(t,v),A)); s=VT_V(r)/VT_V(re); v=add(r,multiply(s,v)); k++; }while(norm(r)>eps && k<maxiter); System.out.println("k = "+k+" norm(r)="+norm(r)); return x; } public static void main(String args[]) throws IOException { double A[][]={{0.2,0.1,1,1,0},{0.1,4,-1,1,-1},{1,-1,60,0,-2},{1,1,0,8,4},{0,-1,-2,4,700}}; double b[]={1,2,3,4,5}; double x[]=conjugate_gradient(A,b); System.out.println("Konjuge gradyan metodu : \n"+Matrix.toStringT(x)); } } Program 2.11-1 konjuge gradyen metodu ile matris sistemi çözümü ---------- Capture Output ---------> "C:\co\java\bin\java.exe" conjugate_gradient1 k = 9 norm(r)=5.161554370481792E-18 Konjuge gradyan metodu : 7.859713075445860 0.422926408295008 -0.073592239024046 -0.540643016894627 0.010626162854036 > Terminated with exit code 0. Konunun başında konjuge gradyan yönteminin başarıyle uygulanabilmesi için denklem sisteminin pozitif ve tanımlı olması gerektiğini belirtmiştik. Pozitif ve tanımlı olmıyan denklem sistemlerinin çözümleri normal olarak iteratif yöntemlerle yapılamaz, ancak denklem sistemi ön şartlandırması veya iyileştirmesi diyebileceğimiz bir yöntem kullanarak, matris sistemini pozitif tanımlı şekle dönüştürebiliriz. Pozitif ve tanımlı bir C matrisi alalım. Bu matrisi kullanarak A*= C-1A C-1 x*= C-1x ve b*= C-1b tanımlarını yaparak denklem sistemimizi daha kararlı olan A* x* = b* formuna dönüştürebiliriz. Bu dönüşümden sonra Konjuge gardyan yöntemini kullanarak çözüme ulaşabiliriz. Pozitif ve Tanımlı C matrisi olarak örneğin A matrisinin diagonal elemanlarının kare köklerinin alındığı, diğer elemanların 0 olduğu bir matris seçilebilir. Ters matris alınması işlemi de sayıların 1 e bölünmesiyle oluşturulabilir. Eğer bu programı kullanarak şartlandırılmamış konjuge gradyan metodu kullanmak istersek C değerini I birim matrise eşit almalıyız. Bu metodun prosedurunu verirsek : Girdi : A matrisi ,b ve x vektörleri, C-1 pozitif ve tanımlı matrisi Adım 1 : r0 = b – A x w0 = C-1r0 v0 = C-1 w0 n 0 w2j j 1 Adım 2 : k=1 Adım 3 : while(k<=N) do adım 4-5 Adım 4 : u=Avk tk k 1 n v u j 1 j j xk=xk-1 + tkvk rk=rk-1 + tkuk wk = C-1rk n k w2j j 1 Adım 5 : sk= kk vk+1 = C-1 wk + skvk k = k k=k+1 ön şartlandırmalı konjuge gradyan programımızın bu şekilde oluşturulmuş bir versiyonu aşağıda verilmiştir. Program 2.11-2 şartlandırılmış konjuge gradyen metodu ile matris sistemi çözümü import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; import java.io.*; public class conjugate_gradient2 { public static double VT_V(double [] left) { //multiplies a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double[][] multiply(double left,double[][] right) { //multiplying a matrix with a constant int i,j; int n=right.length; int m=right[0].length; double b[][]; b=new double[n][m]; for(i=0;i<n;i++) { for(j=0;j<m;j++) b[i][j]=right[i][j]*left; } return b; //end of multiplying a matrix with a constant double } public static double[] multiply(double[] left,double[][] right) { //multiplication of one vector with one matrix int ii,jj,i,j,k; int m2=right[0].length; int n2=right.length; int m1=left.length; double[] b; b=new double[m1]; if(n2 != m1) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n2;ii++) { b[ii]=0; } return b; } for(i=0;i<m2;i++) { b[i]=0; for(k=0;k<m1;k++) b[i]+=right[i][k]*left[k]; } return b; //end of multiply of a vector and a matrix } public static double[] multiply(double[][] left,double[] right) { //multiplication of one matrix with one vector int ii,jj,i,j,k; int m1=left[0].length; int n1=left.length; int m2=right.length; double[] b; b=new double[m2]; if(n1 != m2) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n1;ii++) { b[ii]=0; } return b; } for(i=0;i<m1;i++) { b[i]=0; for(k=0;k<n1;k++) b[i]+=left[i][k]*right[k]; } return b; //end of multiply of a matrix and a vector } public static double[] multiply(double left,double[] right) { //multiplying a vector with a constant int i; int n=right.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=left*right[i]; } return b; } public static double[] substract(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]-right[i]; } return b; //end of vector substraction method } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] equals(double[] left) { //addition of two vectors int n1=left.length; double b[]; b=new double[n1]; for(int i=0;i<n1;i++) { b[i]=left[i]; } return b; //end of vector equal method } public static double norm(double v[]) {return Math.sqrt(normkare(v));} public static double normkare(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return total; } public static double VT_G_V(double V[],double G[][]) { double x1[]=multiply(V,G); return VT_X(V,x1); } public static double[][] I(int n) { //unit matrix double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=1.0; return b; } public static double[][] D(double A[][]) { //Diagonal elements of matrix int n=A.length; double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=A[i][i]; return b; } public static double[][] invsqrtD(double A[][]) { //square root of Diagonal elements of a matrix int n=A.length; double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=1.0/Math.sqrt(A[i][i]); return b; } public static double[] conjugate_gradient(double x[],double A[][],double b[]) { int n=A.length; double C[][]=new double[n][n]; C=invsqrtD(A); return conjugate_gradient(x,A,b,C); } public static double[] conjugate_gradient(double A[][],double b[]) { int n=A.length; double C[][]=new double[n][n]; C=invsqrtD(A); double x[]=new double[n]; //başlangıç x değerleri 0 olarak alındı return conjugate_gradient(x,A,b,C); } public static double[] conjugate_gradient(double x[],double A[][],double b[],double C[][]) { // iterative system of equation solution double eps=1.0e-15; int maxiter=500; int n=x.length; double r[]=new double[n]; double re[]=new double[n]; double v[]=new double[n]; double w[]=new double[n]; double u[]=new double[n]; double t; double alfa,beta,s; int k=0; r=substract(b,multiply(A,x)); w=multiply(C,r); v=multiply(C,w); alfa=normkare(w); do { k++; if(norm(v)<eps) return x; re=equals(r); u=multiply(A,v); t=alfa/VT_X(v,u); x=add(x,multiply(t,v)); r=substract(r,multiply(t,u)); w=multiply(C,r); beta=normkare(w); if(beta<eps) {if(norm(r)<eps) return x;} s=beta/alfa; v=add(multiply(C,w),multiply(s,v)); alfa=beta; }while(norm(r)>eps && beta>eps && k<maxiter ); System.out.println("k="+k); return x; } public static void main(String args[]) throws IOException { double A[][]={{0.2,0.1,1,1,0},{0.1,4,-1,1,-1},{1,-1,60,0,-2},{1,1,0,8,4},{0,-1,-2,4,700}}; double b[]={1,2,3,4,5}; double x[]=conjugate_gradient(A,b); System.out.println("Konjuge gradyan metodu : \n"+Matrix.toStringT(x)); } } Çıktı 2.11-2 şartlandırılmış konjuge gradyen metodu ile matris sistemi çözümü ---------- Capture Output ---------> "C:\co\java\bin\java.exe" conjugate_gradient2 k=5 Konjuge gradyan metodu : 7.859713075445862 0.422926408295008 -0.073592239024046 -0.540643016894627 0.010626162854036 > Terminated with exit code 0. 2.13 PROBLEMLER PROBLEM 1 7 1 2 X 0 47 1 4 1 X 19 1 3 15 20 X 2 87 Denklem sistemini çözünüz. PROBLEM 2 1.1348 0.5301 3.4129 1.2371 3.8326 1.1651 1.7875 2.5330 4.9317 8.7643 4.9998 10.6721 3.4017 X 0 9.5342 1.5435 X 1 6.3941 1.3142 X 2 18.4231 0.0147 X 3 16.9237 X 0 1 X 1 1 denklemini çözünüz. Tam çözüm : X 2 1 X 3 1 PROBLEM 3 4 3 1 X 0 6 7 2 3 X 9 1 5 18 13 X 2 3 denklem sistemini çözünüz. PROBLEM 4 1 1 / 2 1 / 3 1 / 4 1 / 5 1/ 2 1/ 3 1/ 4 1/ 4 1/ 6 1/ 3 1/ 4 1/ 5 1/ 6 1/ 7 1/ 4 1/ 5 1/ 6 1/ 7 1/ 8 1 / 5 X 0 137 / 60 1 / 6 X 1 87 / 60 1 / 7 X 2 459 / 60 1 / 8 X 3 743 / 840 1 / 9 X 4 1879 / 2520 denklem sistemini çözünüz. PROBLEM 5 8 2 3 X 0 30 1 9 2 X 1 1 2 3 6 X 2 31 denklem sistemini Gauss-Seidel iteratif yöntemini kullanarak çözünüz PROBLEM 6 20 X 0 18 3 5 47 11 16 17 10 X 1 26 56 22 11 18 X 2 34 17 66 12 7 X 3 82 denklem sistemini rahatlamalı gauss seidel veya diğer iteratif yöntemleri kullanarak çözünüz. PROBLEM 7 2 1 X 0 0.5 1 2 1 X 1.5 1 X 2 1.5 1 2 1 ... ... X 7 1.5 1 2 1 1 2 1 X 8 1.5 1 2 X 9 0.5 denklem sistemini Thomas algoritması (3’lü bant matris yöntemi) kullanarak çözünüz. PROBLEM 8 4 1 X 0 27 1 4 1 X 15 1 X 2 15 1 4 1 ... ... X 7 15 1 4 1 1 4 1 X 8 15 1 4 X 9 15 denklem sistemini Thomas algoritması kullanarak çözünüz. PROBLEM 9 4 2 3 8 X 0 47 3 5 6 1 1 9 15 1 9 2 X 1 17 2 1 7 5 1 6 11 X 2 24 3 2 7 1 2 X 3 8 1 1 4 3 1 7 2 1 1 X 4 13 9 8 11 1 4 1 X 5 10 2 7 2 1 2 7 1 9 X 6 34 denklem sistemini çözünüz. PROBLEM 10 5 7 8 X 0 12 1 1 2 3 9 1 1 8 1 X 1 8 1 1 9 9 2 3 X 2 22 7 2 3 1 4 X 3 41 1 7 1 2 4 1 1 X 4 15 3 9 12 2 7 X 5 50 2 denklem sistemini çözünüz. PROBLEM 11 denklem sistemini çözünüz. PROBLEM 12 Şekilde görülen sistemdeki yük dengesi şeklinde yazılabilir. Burada c=cos(s=sin(dır. =60o için yük dağılımını bulunuz. PROBLEM 13 Şekilde görülen devre için Voltaj akım şiddeti denklemleri şeklinde yazılabilir. R=10 için akım şiddeti, i (Amper), değerlerini hesaplayınız. PROBLEM 14 -x1 + 3x2 + 5x3 + x4 = 8 x1 +9x2 + 3x3 + 4x4 = 10 x2 +x4 = 2 3x1 + x2 +x3 - x4 = -4 doğrusal denklem sistemini uygun bir yöntem ile çözümleyiniz. PROBLEM 15 3 5 1 2 1 3 0 0 2 2 6 3 7 x1 1 5 x 2 2 5 x3 3 1 x 4 4 doğrusal denklem sistemini LU çarpanlara ayırma ( Doolittle) yöntemi ile çözünüz. PROBLEM 16 3x1 + 5x2 + 4x3 + 2x4 = 11 6x1 +14x2 + 11x3 + 6x4 = 26 9x1 + 11x2 +16x3 + 5x4 = 68 3x1 + 13x2 +17x3 + 12x4 = 43 doğrusal denklem sistemini LU çarpanlara ayırma yöntemi ile çözümleyiniz. PROBLEM 17 x1 3x2 x3 5 x4 4 2 x1 x2 3x4 5 4 x1 2 x2 2 x3 x4 11 3x1 x2 3x3 2 x4 3 denklem sistemini, a) Gauss yoketme yöntemi ile b) Gauss-seidel yöntemi ile c) Konuge granyan yöntemi ile çözünüz. PROBLEM 18 x1 + x2 – x3 = -3 6x1 +2x2+2x3=2 -3x1+4x2+x3=1 denklem sistemini kısmi pivotlamalı gauss eleme yöntemi ile çözün. BÖLÜM 3.0 VEKTÖR VE MATRİS İŞLEMLERİ 3.0 MATRİS TEMEL İŞLEMLERİ TOPLAMA VE ÇARPMA TANIMLARI Matrislerin temel işlemlerinin yapıldığı Matrix.java programı matrislerle ilgili tüm işlemleri barındıran bir kütüphanedir. Bu kitabın ekinde de bütün olarak listelenecektir. Bu bölümde matrisle ilgilili işlemleri alt bölümler olarak aldığımızdan Matrix kütüphanesinden alınmış temel işlemler küçük program parçacıkları halinde (ilgili bölümün programları şeklinde) verilecektir. Bu alt bölümde matrisin toplanması ve çarpmasını tanımlıyalım. Matris çıktısını almak için formatlı çıktı metodları da programımıza eklenmiştir. Matris toplama işlemi : cij = aij + bij şeklinde özetlenebilir matris çarpma işlemi ise : şeklinde gerçekleştirilir. Program 3.1-1 matris toplama ve çarpma işlemleri algoritması import javax.swing.*; import java.text.*; import java.util.Locale; public class matris1 { public static String toString(double left, int w, int d) // converts a double to a string with given width and decimals. { NumberFormat df=NumberFormat.getInstance(Locale.US); df.setMaximumFractionDigits(d); df.setMinimumFractionDigits(d); df.setGroupingUsed(false); String s = df.format(left); while (s.length() < w) s = " " + s; if (s.length() > w) { s = ""; for (int i=0; i<w; i++) s = s + "-"; } return s; } public static String toString(double[][] left) { //return a string representation of a matrix return toString(left,25,15); } public static String toString(double[][] left,int w,int d) { //return a string representation of a matrix int n,m; String b; b=""; n=left.length; m=left[0].length; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { b=b+toString(left[i][j],w,d); } b=b+"\n"; } return b; } public static double[][] carp(double[][] left,double[][] right) { //multiplication of two matrices int ii,jj,i,j,k; int m1=left[0].length; int n1=left.length; int m2=right[0].length; int n2=right.length; double[][] b; b=new double[m1][n2]; if(n1 != m2) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n1;ii++) { for(jj=0;jj<m2;jj++) b[ii][jj]=0; } return b; } for(i=0;i<m1;i++) { for(j=0;j<n2;j++) { for(k=0;k<n1;k++) b[i][j]+=left[i][k]*right[k][j]; } } return b; //iki matrisin çarpımı } public static double[][] topla(double[][] left,double[][] right) { //addition of two matrices int n1=left.length; int m1=left[0].length; int n2=right.length; int m2=right[0].length; int nMax,mMax; int i,j; if(m1>=m2) mMax=m1; else mMax=m2; if(n1>=n2) nMax=n1; else nMax=n2; double b[][]; b=new double[nMax][mMax]; for(i=0;i<n1;i++) { for(j=0;j<m1;j++) { b[i][j]=b[i][j]+left[i][j]; } } for(i=0;i<n2;i++) { for(j=0;j<m2;j++) { b[i][j]=b[i][j]+right[i][j]; } } return b; //end of matrix addition method } public static void main(String args[]) { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; double b[][]={{3,0,2},{1,2,-7},{6,8,26}}; double c[][]=carp(a,b); double d[][]=topla(a,b); String s="a=\n"+toString(a); s+="b=\n"+toString(b); s+="a*b=\n"+toString(b); s+="a+b=\n"+toString(b); String s1="matris çarpma ve toplama işlemleri"; JOptionPane.showMessageDialog(null,s,s1,JOptionPane.PLAIN_MESSAGE); } } Çıktı 3.1-1 matris toplama ve çarpma işlemleri algoritması 3.1 NORM TANIMI Normlar sayısal metodlar kullanılırken matrisleri değerlendirmek için önemli araçlardır. Çeşitli norm tanımları mevcuttur. Genel tanımlamaları burada verelim : Sonsuz normu : n n i 1 j 1 A maksimum ( aij ) norm A n n j 1 i 1 maksimum( a ij ) Öklit normu Ae n n a i 1 j 1 2 ij m normu n n A m m aijm i 1 j 1 aynı tür tanımlar vektörler için de uyarlanabilir. Temel norm tanımları program 3.2 de verilmiştir. Program 3.2 Matris norm tanımlama metodları public class norm { //*************norm methods definition**************** public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double norm(double v[],int p) { //p vector norm if(p==0) p=1; double total=0; double x,y; for(int i=0;i<v.length;i++) { x=Math.abs(v[i]); total+=Math.pow(x,p); } return Math.pow(total,(1.0/p)); } public static double norminf(double v[]) { //infinite vector norm double x; double max=0; for(int i=0;i<v.length;i++) { x=Math.abs(v[i]); if(x>max) max=x; } return max; } public static double[] vek(double mat[][],int n) { double a[]=new double[mat.length]; for(int i=0;i<mat.length;i++) {a[i]=mat[i][n];} return a; } public static double norminf(double a[][]) { //infinite matrix norm double x; double max = 0; double total; int i,j; int n=a.length; for(i=0;i<n;i++) { total=0; for(j=0;j<n;j++) {total+=Math.abs(a[i][j]);} x=total; if(x>max) max=x; } return max; } public static double norm(double a[][]) { //matrix norm double x; double max = 0; double total; int i,j; int n=a.length; for(j=0;j<n;i++) { total=0; for(i=0;i<n;j++) {total+=Math.abs(a[i][j]);} x=total; if(x>max) max=x; } return max; } public static double normE(double a[][]) { //Euclidian matrix norm double x; double total; int i,j; total=0; int n=a.length; for(j=0;j<n;i++) {for(i=0;i<n;j++) {total+=a[i][j]*a[i][j];}} return Math.sqrt(total); } } 3.2 BİRİM MATRİS, TRANSPOSE MATRİS VE TERS MATRİS Birim matris diagonal elemanları 1 diğer elemanları 0 olan matristir. aii 1 aij , i j 0 örneğin n=4 için 1 0 [I ] 0 0 0 1 0 0 0 0 1 0 0 0 0 1 Transpose matris satır ve sütunlarının yer değiştirdiği matristir. Genelde matris işaretinin üzerinde bir T simbolü ile gösterilir. Java dilinde matrisin transposunu almak için: public static double[][] Transpose(double [][] left) { //transpose matrix (if A=a(i,j) Transpose(A)=a(j,i) int i,j; int n=left.length; int m=left[0].length; double b[][]; b=new double[m][n]; for(i=0;i<n;i++) { for(j=0;j<m;j++) { b[j][i]=left[i][j]; } } return b; } şeklinde bir metod kullanılabilir. Ters matris matrisin kendi değeri ile çarpıldığında birim matrise eşit olan matristir. Matrisin bölme işlemi olarakta düşünebiliriz. [A][A]-1.= [I] Ters matrisleri bir önceki bölümde gördüğümüz lineer denklem sistemi çözüm yöntemlerini kullanarak elde edebiliriz. Program 3.3-1 Ters matris programı(kısmi pivotlu gauss LU metodu kullanarak hesaplar import java.io.*; class SCO10G { public static void pivot(double a[][],int o[],double s[],int k) {// GaussLU için pivot metodu int n=a.length; int dummy1=0; double buyuk; double dummy=0; //pivotlama int p=k; buyuk=Math.abs(a[o[k]][k]); for(int ii=k+1;ii<n;ii++) { dummy=Math.abs(a[o[ii]][k]/s[o[ii]]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } dummy1=o[p]; o[p]=o[k]; o[k]=dummy1; } public static int[] sirali_indeks(int n) { // sıralı rakamları taşıyan bir vektör oluşturur int o[]=new int[n]; for(int i=0;i<n;i++) {o[i]=i;} return o; } public static double[][] gaussLU(double ai[][],int o[]) { //kısmi pivotlu gauss eleme yöntemi int n=ai.length; double a[][]=new double[n][n]; double s[]=new double[n]; double carpan=0; double toplam=0; double absaij; //gauss eleme int i,j,k,p,ii,jj; //System.out.println("Orijinal Matris :\n"+Matrix.toString(ai)); for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];}} for(i=0;i<n;i++) { o[i]=i;s[i]=Math.abs(a[i][0]); for(j=1;j<n;j++) { absaij=Math.abs(a[i][j]); if(absaij>s[i]) {s[i]=absaij;} } } for(k=0;k<(n-1);k++) { pivot(a,o,s,k); //pivot referansını değiştir //System.out.println("pivotlu Matris : k="+k+"\n"+Matrix.toString(a)); //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[o[i]][k]/a[o[k]][k]; a[o[i]][k]=carpan; for(j=k+1;j<n;j++) { a[o[i]][j]-=carpan*a[o[k]][j]; } } } return a; } public static double[] yerine_koyma(double ai[][],double bi[]) { int n=ai.length; return yerine_koyma(ai,bi,sirali_indeks(n)); } public static double[][] yerine_koyma(double ai[][],double bi[][]) { int n=ai.length; return yerine_koyma(ai,bi,sirali_indeks(n)); } public static double[] yerine_koyma(double ai[][],double bi[],int o[]) { //gauss LU çözümüyle LU indirgenmesi yapılmış Matris kullanarak lineer //denklem sistemi kökleri int n=ai.length; double toplam; double x[]=new double[n]; double a[][]=new double[n][n]; double b[]=new double[n]; int i,j; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};b[i]=bi[i];} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(i=1;i<n;i++) {toplam=b[o[i]];for(j=0;j<i;j++){toplam-=a[o[i]][j]*b[o[j]];};b[o[i]]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1]=b[o[n-1]]/a[o[n-1]][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[o[i]][j]*x[j];}; x[i]=(b[o[i]]-toplam)/a[o[i]][i]; } //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double[][] yerine_koyma(double ai[][],double bi[][],int o[]) { int n=ai.length; int m=bi[0].length; double toplam; double x[][]=new double[n][m]; double a[][]=new double[n][n]; double b[][]=new double[n][m]; int i,j,k; for(i=0;i<n;i++) {for(j=0;j<n;j++){a[i][j]=ai[i][j];};for(k=0;k<m;k++) {b[i][k]=bi[i][k];}} //System.out.println("a=\n "+Matrix.toString(a)); //System.out.println("b=\n "+Matrix.toStringT(b)); for(k=0;k<m;k++) { for(i=1;i<n;i++) {toplam=b[o[i]][k];for(j=0;j<i;j++){toplam-=a[o[i]][j]*b[o[j]][k];};b[o[i]][k]=toplam;} //System.out.println("d=\n "+Matrix.toStringT(b)); x[n-1][k]=b[o[n-1]][k]/a[o[n-1]][n-1]; for(i=(n-2);i>=0;i--) {toplam=0; for(j=i+1;j<n;j++) {toplam+=a[o[i]][j]*x[j][k];}; x[i][k]=(b[o[i]][k]-toplam)/a[o[i]][i]; } }//kin sonu //System.out.println("d=\n "+Matrix.toStringT(x)); return x; } public static double [] AXB(double a[][],double b[]) { //denklem sistemi çözümü b vektörü için int n=a.length; int q[]=new int[n]; double c[][]=gaussLU(a,q); double s[]=yerine_koyma(c,b,q); return s; } public static double [][] AXB(double a[][],double b[][]) {//denklem sistemi çözümü b matrisi için int n=a.length; int q[]=new int[n]; double c[][]=gaussLU(a,q); double s[][]=yerine_koyma(c,b,q); return s; } public static double[][] I(int n) { //birim matris double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=1.0; return b; } public static double[][] inverse(double a[][]) { int n=a.length; int q[]=new int[n]; double c[][]=gaussLU(a,q); double s[][]=yerine_koyma(c,I(n),q); return s; } public static void main(String args[]) throws IOException { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; System.out.println("Matris a : \n"+Matrix.toString(a)); System.out.println("Ters Matris a : \n"+Matrix.toString(inverse(a))); } } Çıktı 3.3-1 Ters matris çıktısı Matris a : 3.000000000000000 0.100000000000000 0.300000000000000 -0.100000000000000 7.000000000000000 -0.200000000000000 -0.200000000000000 -0.300000000000000 1.10.000000000000000 Ters Matris a : 0.332488721339843 -0.005181765888768 -0.010078296957971 0.004944070205797 0.142902644602169 0.002709730785869 0.006798096532971 0.004183444020290 0.099879725984417 Program 3.3-2 Tam pivotlu Gauss eleme kullanan ters matris metodu public class tersmatris { public static double[][] inv(double[][] a) { // INVERSION OF A MATRIX // inversion by using gaussian elimination // with full pivoting int n=a.length; int m=a[0].length; double b[][]; b=new double[n][n]; int indxc[]; int indxr[]; double ipiv[]; indxc=new int[n]; indxr=new int[n]; ipiv=new double[n]; int i,j,k,l,ll,ii,jj; int icol=0; int irow=0; double big,dum,pivinv,temp; if(n!=m) { System.out.println("Matrix must be square "); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j]=a[i][j]; for(i=0;i<n;i++) { big=0.0; for(j=0;j<n;j++) { if(ipiv[j] != 1) for(k=0;k<n;k++) { if(ipiv[k] == 0) { if(Math.abs(b[j][k]) >= big) { big=Math.abs(b[j][k]); irow=j; icol=k; } } else if(ipiv[k] > 1 ) { System.out.println("error : inverse of the matrix : singular matrix-1"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } } } ++ ipiv[icol]; if(irow != icol) for(l=0;l<n;l++) { temp=b[irow][l]; b[irow][l]=b[icol][l]; b[icol][l]=temp; } indxr[i]=irow; indxc[i]=icol; if(b[icol][icol] == 0.0) { System.out.println("error : inverse of the matrix : singular matrix-2"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } pivinv=1.0/b[icol][icol]; b[icol][icol]=1.0; for(l=0;l<n;l++) b[icol][l] *=pivinv; for(ll=0;ll<n;ll++) if(ll != icol) { dum=b[ll][icol]; b[ll][icol]=0.0; for(l=0;l<n;l++) b[ll][l]-= b[icol][l]*dum; } } for(l=n-1;l>=0;l--) { if(indxr[l] != indxc[l]) for(k=0;k<n;k++) { temp=b[k][indxc[l]]; b[k][indxc[l]]=b[k][indxr[l]]; b[k][indxr[l]]=temp; } } return b; } public static void main(String args[]) { double a[][]={{3,-0.1,-0.2},{0.1,7,-0.3},{0.3,-0.2,10}}; System.out.println("Matris a : \n"+Matrix.toString(a)); System.out.println("Ters Matris a : \n"+Matrix.toString(inv(a))); } } Çıktı 3.3-2 Tam pivotlu gauss eliminasyon kullanan inv metodu çıktısı ---------- Capture Output ---------> "C:\co\java\bin\java.exe" tersmatris Matris a : 3.000000000000000 -0.100000000000000 0.100000000000000 7.000000000000000 0.300000000000000 -0.200000000000000 -0.200000000000000 -0.300000000000000 10.000000000000000 Ters Matris a : 0.332488721339843 -0.005181765888768 -0.010078296957971 0.006798096532971 0.004183444020290 0.099879725984417 0.004944070205797 0.142902644602169 0.002709730785869 > Terminated with exit code 0. 3.3 PROBLEMLER PROBLEM 1 7 1 2 1 4 1 3 15 20 matrisinin sonsuz normunu, ters normunu ve m=3 normunu bulunuz. PROBLEM 2 1.1348 3.8326 1.1651 3.4017 0.5301 1.7875 2.5330 1.5435 3.4129 4.9317 8.7643 1.3142 1.2371 4.9998 10.6721 0.0147 matrisinin ters matrisini bulunuz. PROBLEM 3 4 3 1 7 2 3 5 18 13 matrisinin ters matrisini bulunuz. PROBLEM 4 1 1 / 2 1 / 3 1 / 4 1 / 5 1 / 2 1 / 3 1 / 4 1 / 5 1 / 6 1 / 3 1 / 4 1 / 5 1 / 6 1 / 7 1 / 4 1 / 4 1 / 6 1 / 7 1 / 8 1 / 5 1 / 6 1 / 7 1 / 8 1 / 9 matrisinin norm değerini ve ters matrisini bulunuz. PROBLEM 5 8 2 3 1 9 2 2 3 6 matrisinin norm değerini ve ters matrisini bulunuz. PROBLEM 6 20 3 5 47 11 16 17 10 56 22 11 18 17 66 12 7 matrisinin norm değerini ve ters matrisini bulunuz. PROBLEM 7 2 1 1 2 1 1 2 1 ... 1 2 1 1 2 1 1 2 matrisinin ters matrisini bulunuz. BÖLÜM 4 LİNEER OLMAYAN DENKLEM VE DENKLEM SİSTEMLERİNİN KÖKLERİ Kök bulma işlemi mühendislikte oldukça yoğun olarak kullanılan yöntemlerden biridir. Matematiksel olarak bir bilinmiyenli fonksiyonlar için f(x)= 0 denklemini sağlayan x değerinin bulunması olarak özetlenebilir. Eğer denklem çok bilnmiyenli ise fi(x1,x2,x3,….,xn)=0 , i=1..n denklemlerini sağlayan x1,x2,x3,….,xn değerlerini bulmak işlemidir. Bu bölümde kök bulma işlemlerinin bazılarını detaylı olarak inceleyeceğiz. 4.1 İKİYE BÖLME YÖNTEMİ (BİSECTİON) İkiye bölme yönteminde f(x) fonksiyonunun a <= x <= b bölgesinde kökü aranır. Eğer bu bölgede bir kök mevcutsa f(a)*f(b) < 0 olacaktır. Bu şart gerçekleşmiyor ise bu bölgede bir kök olmadığını varsayabiliriz. Eğer Bu bölgede bir kök mevcut ise bölgeyi iki eşit parçaya böleriz a-b bölgesinin orta noktası p=(a+b)/2 ise fonksiyonu p noktasında değerlendiririz. Eğer f(a)*f(p) < 0 ise kökün a-p aralığında olduğunu söyleyebiliriz. Eğer f(a)*f(p) > 0 ise kök p-b bölgesindedir. Tesadüfen f(a)*f(p)=0 oluşabilir, bu kök değerinin p ye tam olarak eşit olduğu anlamına gelir ama bu çok küçük bir olasılıktır. Bulduğumuz yeni kök bölgesini bir sonraki iteasyon için kullanırız. İteratif prosesi durdurmak için (b a) (b a) gibi bir durdurma kriterinden yararlanabiliriz. Şekil 4.1-1 ikiye bölme yönteminin uygulanmasının grafik gösterimi Altta ikiye bölme yöntemini hesaplayan SCO1 sınıfı verilmiştir. Döngüyü durdurmak için iteratif yöntemde durdurma kriterinin yanında maksimum iterasyon sayısı kriteri uygulanmıştır. Program 4.1-1 İkiye bölme yöntemi ///Bilgisayar programlama II ve Sayısal Çözümleme //ÖDEV 1 // f(x)=ln(x)-0.7 fonksiyonunun a=0.5 ile b=3 arasındaki // kökünü bulmak için yarıya bölme yönteminikullanarak bir // program geliştiriniz, kök değerini hesaplatınız import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x*x*x+3.6*x*x-36.4;} } //=========================================================== public class FSCO1 { public static double ikiyebolme(f_x f,double a,double b) { //ikiye bölme yöntemi a ile b arsında kök değerini // her seferinde sayıyı ikiye bölerek arar. double test; double p=0; double es,ea; double fa,fp; int maxit=500,iter=0; es=0.0000001; ea=1.1*es; while((ea>es)&&(iter<maxit)) { p=(a+b)/2.0; iter++; if((a+b)!=0) { ea=Math.abs((b-a)/(a+b))*100;} fa= f.func(a); fp= f.func(p); test= fa*fp; if(test==0.0) ea=0; else if(test<0.0) b=p; else {a=p;} } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return p; } public static void main (String args[]) { fb f=new fb(); double a,b; a=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz a : ")); b=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz b : ")); double r; r= ikiyebolme(f,a,b); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "ikiye bölme yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 4.2 YER DEĞİŞTİRME YÖNTEMİ (FALSE POSİTİON) İkiye bölme yönteminde yaklaşma göreceli olarak yavaş ilerler. Yaklaşma hızını arttırmanın bir yolu a ve b noktalarını bir doğru ile birleştirmek ve doğrunun x eksenini kesim noktasını bir sonraki kök olarak kullanmaktır. p noktasını p b f (b) ( a b) ( f (a) f (b) formülüyle bulabiliriz. Kök testi için ikiye bölme yönteminde kullandığımız aynı yöntemi kullanırız. Şekil 4.2-1 yer değiştirme yöntemi Program 4.2-1 Yer değiştirme yöntemi ile kök bulma ///Bilgisayar programlama II ve Sayısal Çözümleme //ÖDEV 3 // f(x)=x^3-13x-12 fonksiyonunun x0=5 ilktahminini kulanarak // yer değiştirme yöntemi ile kökünü bulmak için bir // program geliştiriniz, kök değerini hesaplatınız import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x*x-0.5;} } //=========================================================== public class FSCO3 { public static double yerdegistirme(f_x f,double xa,double xu) { //Düzeltmeli yer değiştirme (Modified False position) yöntemi ile kök bulma // xa ve xu bölgesinde kök bulur double test; double p=0; double es,ea; double fa,fp,fu; int maxit=100,iter=0; es=0.000001; ea=1.1*es; double xold; int ia=0,iu=0; fa=f.func(xa); fu=f.func(xu); p=xu; double xpold; while(iter<maxit && ea>es) { xpold=p; p=xu-fu*(xa-xu)/(fa-fu); fp=f.func(p); iter++; if(p!=0) ea=Math.abs((p-xpold)/p)*100.0; test=fa*fp; if(test<0) {xu=p;fu=f.func(xu);iu=0;ia++;if(ia>=2) fa/=2.0;} else if(test>0) {xa=p;fa=f.func(xa);ia=0;iu+=1;if(iu>=2)fu/=2.0;} else ea=0; } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return p; } public static void main (String args[]) { fb f=new fb(); double xa,xu; xa=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz xa : ")); xu=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz xu : ")); double r= yerdegistirme(f,xa,xu); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "yer değiştirme : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.2-1 Yer değiştirme yöntemi ile kök bulma 4.3 MÜLLER YÖNTEMİ Yer değiştirme yönteminde iki noktadan bir doğru geçmesi prensibinden yararlanarak yeni kök değeri tahmini geliştirmiştik. Aynı kavramı ikinci dereceden polinom kullanarakta yapabiliriz, ancak ikinci dereceden polinom tanımlamak için üç noktaya ihtiyacımız olacaktır. x0, x1, x2 noktalarının giriş değerleri olarak verildiğini varsayalım (x3 değeri x0 ve x1 değeri arasında olsun). Fonksiyonumuz f(x) olsun. Bu üç noktanın y değerleri olarak f(x0), f(x1) ve f(x2) değerlerini alalım bu üç noktadan ikinci derece bir polinom geçirir isek bu polinomun kökü f(x0)-f(x2)=a(x0-x2)2+b(x0-x2) f(x1)-f(x2)=a(x1-x2)2+b(x1-x2) h0= x1 – x0 h1= x2 – x1 d0 d1 f ( x1 ) f ( x0 ) h0 f ( x2 ) f ( x1 ) h1 Şekil 4.3-1 Müller yönteminin grafik olarak gösterilmesi bu ifadeler ana denklemlerde yerine konulursa (h0+h1)b - (h0+h1)2a = h0d0 + h1d1 h1 b h12 a = h1d1 elde edilir buradan da a ve b çözülebilir. d d0 a 1 h1 h0 b = a*h1 + d1 c=f(x2) kökü bulmak için : b 2 4ac eğer b b eb b b eb xr x2 2c e x2 değerinin yerine xr değerini koyarak yeni iterasyonumuza başlayabiliriz. Program 4.3-1 de müler yöntemi gerçek köklerin değerini bulma yöntemi olarak verilmiştir. Bu yöntem sanal köklerin bulunması için de kullanılabilir. Program 4.3-1 Müller yöntemi ile kök bulma programı ///Bilgisayar programlama II ve Sayısal Çözümleme // Muller yöntemi ile kök bulma import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x*x-0.5;} } //=========================================================== public class FSCO2 { public static double muller(f_x f,double xr,double h) { //Müller yöntemi ile kök bulma (gerçek kökler) //orta xr noktasından +/- h kadar giderek diğer 2 noktaya ulaşıyoruz. int maxit=50; double x2=xr; double x1=xr*(1+h); double x0=xr*(1-h); int iter=0; double es1=0.001; double es=es1; double ea=1.1*es; double h0,h1; double d0,d1; double a,b,c; double fx0,fx1,fx2; double determinant; double den; double dxr; while(iter<maxit && ea>es) { fx0=f.func(x0); fx1=f.func(x1); fx2=f.func(x2); h0=x1-x0; h1=x2-x1; d0=(fx1-fx0)/h0; d1=(fx2-fx1)/h1; a=(d1-d0)/(h1+h0); b=a*h1+d1; c=fx2; determinant=b*b-4.0*a*c; if(determinant<=0) determinant=0;//we do not want to calculate complex roots here else determinant=Math.sqrt(determinant); if(Math.abs(b+determinant)>Math.abs(b-determinant)) {den=b+determinant;;} else {den=b-determinant;} dxr=-2*c/den; xr=x2+dxr; ea=Math.abs((xr-x2)/xr)*100; iter++; x0=x1; x1=x2; x2=xr; } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return xr; } public static void main (String args[]) { fb f=new fb(); double xr,h; xr=Double.parseDouble(JOptionPane.showInputDialog(" kök tahmini xr : ")); //h=Double.parseDouble(JOptionPane.showInputDialog(" h=(küçük bir rakam örneğin 0.1")); h=0.1; double r; r= muller(f,xr,h); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "müller yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.3-1 Müller yöntemi ile kök bulma 4.4 NEWTON-RAPHSON YÖNTEMİ Taylor formülü f(xn+1) = f(xn) + f’(xn)( xn+1- xn) + f ”(xn) ( xn+1- xn)2/2! + f (3)(xn) ( xn+1- xn)3/3! + f (4)(xn) ( xn+1- xn)4/4! + f (5)(xn) ( xn+1- xn)5/5!+…. Şeklindedir. f(xn+1)=0 olmasını istediğimizden bu değeri denkleme koyar ve birinci dereceden yüksek terimlerin 0 a gittiğini kabul eder isek 0 = f(xn) + f’(xn)( xn+1- xn) olur bu denklemden xn+1 çekilirse xn+1 = xn - f(xn) /f’(xn) denklemi elde edilir Bu denkleme Newton-Raphson kök bulma denklemi ismi verilir. x0 ilk tahmininden (tek değer) başlayarak kök değerine iteratif olarak ulaşabiliriz. Newton formülü ilk tahmin gerçek köke göreceli olarak yakınsadığında çok hızlı yaklaşım verir, ancak ilk tahmin kökten uzak ise köke ulaşması uzun sürebilir veya hiç ulaşamayabilir. Newton raphson denkleminin tek zorluğu türevleri bilme zorunluluğudur. Şekil 4.4-1 newton yönteminin yakınsaması Program 4.4-1 Newton-Raphson kök bulma programı // // // Newton-Raphson yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } class dfb extends f_x { public double func (double x) { return 2.0/x;} } //=========================================================== public class FSCO4A { public static double newton(f_x f,f_x df,double x) { int nmax=500; double tolerance=1.0e-15; double fx,dfx; for(int i=0;i<nmax;i++) { fx=f.func(x); dfx=df.func(x); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); dfb df=new dfb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton(f,df,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton-Raphson yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.4-1 Newton-Raphson kök bulma Newton- Raphson yöntemi aynı zamanda kompleks köklerin bulunmasında da kullanılabilir. Kompleks Newtonraphson metodu program 4.4-2 de verilmiştir. Bu programda kullanılan kompleks değişken hesabını yapan complex sınıfı da program 4.4-3 de verilmiştir. Program 4.4-2 Newton-Raphson metoduyla kompleks kök bulma programı // // // kompleks Newton-Raphson yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; abstract class cf_cx { abstract complex func(complex x); complex dfunc(complex x) {//complex sayısal türev fonksiyonu double hh=0.001; complex h=new complex(hh,hh); complex he=new complex(-hh,-hh); complex h2=new complex(2.0*hh,2.0*hh); complex he2=new complex(-2.0*hh,-2.0*hh); complex xah=complex.add(x,h); complex xa2h=complex.add(x,h2); complex xeh=complex.add(x,he); complex xe2h=complex.add(x,he2); complex fe2h=complex.multiply(func(xe2h),(1.0/12.0)); complex feh=complex.multiply(func(xeh),(-8.0/12.0)); complex fah=complex.multiply(func(xah),(8.0/12.0)); complex fa2h=complex.multiply(func(xa2h),(-1.0/12.0)); complex df=complex.add(fe2h,complex.add(feh,complex.add(fah,fa2h))); df=complex.divide(df,h); return df; } } class fa extends cf_cx { //tek fonksiyon, tek bağımsız değişken // örnek f=x*x*x-1 complex func(complex x) { complex f=complex.add(complex.multiply(x,complex.multiply(x,x)),-1.0); return f; } } public class SCO4G { public static complex newton(cf_cx f,complex x) { int nmax=50; double tolerance=1.0e-8; complex fx,dfx; for(int i=0;i<nmax;i++) { fx=f.func(x); dfx=f.dfunc(x); //x=complex.add(x,complex.multiply(complex.divide(fx,dfx),-1.0)); x=complex.substract(x,complex.divide(fx,dfx)); if(complex.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fa f=new fa(); double x0[]=verigir(" Fonksiyon değeri için ilk tahmin : "); complex x=new complex(x0[0],x0[1]); complex r= newton(f,x); complex ff=f.func(r); JOptionPane.showMessageDialog(null," kök değeri : "+r.toString()+"\nFonksiyon değeri : "+ff.toString(), "Newton-Raphson yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.4-2 Newton-Raphson metoduyla kompleks kök bulma :örnek fonksiyon f(x)=x*x+1 Kompleks kök bulma prosesinde gerekli olan kompleks değişken yapısını kendi geliştirdiğimiz bir java sınıfı olan complex sınıfı üzerinden oluşturduk. Bu sınıfın listesi aşağıda verilmiştir. Bu sınıf genel kullanım için hazırlandığından kod oldukça detaylı olarak hazırlanmıştır. Program 4.4-3 kompleks Newton-Raphson programında kullanılan complex sınıfı import java.io.*; import java.text.*; import java.util.Locale; import java.util.*; import javax.swing.*; // giriş çıkış // class complex // complex number abstraction // class complex { // constructors public complex() { nreal=0; nimag=0; } public complex(double nre,double nim) { nreal=nre; nimag=nim; } public complex(int nre,int nim) { nreal=(double)nre; nimag=(double)nim; } public complex(double numer) { nreal=numer; nimag=0; } public complex(complex value ) { nreal=value.real(); nimag=value.imaginary(); } // accessor functions public double real() { //return real part of the complex number return nreal; } public double imaginary() { //return imaginary part of the complex number return nimag; } public double R() { // Return radius of polar coordinate equivalent of complex number return Math.sqrt(nreal*nreal+nimag*nimag); } public double theta() { // Return angle of polar coordinate equivalent of complex number in radian return Math.atan2(nimag,nreal); } public double dtheta() { // Return angle of polar coordinate equivalent of complex number in degree return Math.atan2(nimag,nreal)*180.0/Math.PI; } // assignments public void assign(complex right) { nreal=right.real(); nimag=right.imaginary(); } public void add(complex right) { nimag = nimag + right.imaginary(); nreal = nreal + right.real(); } public void substract(complex right) { nimag = nimag - right.imaginary(); nreal = nreal - right.real(); } public void multiply(complex right ) { nreal = nreal*right.real() - nimag*right.imaginary(); nimag = nreal*right.imaginary() + nimag*right.real(); } public void divide(complex right ) { double a=nreal*nreal+nimag*nimag; nreal = ( nreal*right.real() + nimag*right.imaginary())/a; nimag = (-nreal*right.imaginary() + nimag*right.real())/a; } public static complex add(complex left, complex right) { // return sum of two complex numbers double r1=(left.real() + right.real()); double i1=(left.imaginary() + right.imaginary()); complex result; result=new complex(r1,i1); return result; } public static complex add(complex left, double right) { // return sum of two complex numbers double r1=(left.real() + right); double i1=left.imaginary(); complex result; result=new complex(r1,i1); return result; } public static complex conjugate(complex z) {complex z1=new complex(z.real(),-z.imaginary()); return z1; } public static complex substract(complex left, complex right) { // return substraction of two complex numbers complex result; result=new complex((left.real() - right.real()), (left.imaginary() - right.imaginary())); return result; } public static complex multiply(complex left, complex right) { // return multiplication of two complex numbers complex result; result=new complex ((left.real()*right.real() - left.imaginary()*right.imaginary()), (left.real()*right.imaginary() + left.imaginary()*right.real())); return result; } public static complex multiply(complex left, double right) {complex result; result=new complex((left.real()*right),(left.imaginary()*right)); return result; } public static complex divide(complex left, complex right) { // return division of two complex numbers double a=right.real()*right.real()+right.imaginary()*right.imaginary(); complex result; result=new complex ((left.real()*right.real() + left.imaginary()*right.imaginary())/a, (-left.real()*right.imaginary() + left.imaginary()*right.real())/a); return result; } public static complex divide(complex left, double right) { // return division of a complex number to a real number complex result; result=new complex((left.real()/right),(left.imaginary()/right)); return result; } public static complex pow(complex left, double right) { // return sum of two complex numbers double Rad,th; Rad=Math.pow(left.R(),right); th=right*left.theta(); complex result; result =new complex((Rad*Math.cos(th) ), (Rad*Math.sin(th) ) ); return result; } public static complex exp(complex left) { // exp(x+i*y) complex result; result =new complex((Math.exp(left.real())*Math.cos(left.imaginary()) ), (Math.exp(left.real())*Math.sin(left.imaginary()) )); return result; } public static complex exp(double left) { // exp(i*left) imaginary exponent complex result; result =new complex(Math.cos(left), Math.sin(left) ); return result; } public static complex sqrt(complex left) { return pow(left,0.5); } public static double abs(complex left) { return left.R(); } public boolean smaller(complex left,complex right) { // less then comparison of two complex numbers return (left.R() < right.R()); } public boolean smaller_equal(complex left,complex right) { // less then and equal comparison of two complex numbers return (left.R() <= right.R()); } public boolean greater(complex left,complex right) { // greater then comparison of two complex numbers return left.R() > right.R(); } public boolean greater_equal(complex left,complex right) { // greater then and equal comparison of two complex numbers return left.R() >= right.R(); } public boolean equal(complex left,complex right) { // equal comparison of two complex numbers return left.R() == right.R(); } public boolean not_equal(complex left,complex right) { // not equal comparison of two complex numbers return left.R() != right.R(); } public static String toString(double left, int w, int d) // converts a double to a string with given width and decimals. { NumberFormat df=NumberFormat.getInstance(Locale.US); df.setMaximumFractionDigits(d); df.setMinimumFractionDigits(d); df.setGroupingUsed(false); String s = df.format(left); while (s.length() < w) s = " " + s; if (s.length() > w) { s = ""; for (int i=0; i<w; i++) s = s + "-"; } return s; } public static String toString(double left) {// converts a double to a string with a constant width and constant decimals. return toString(left,15,10);} public static String toString(complex value) { String b=""; if(Math.abs(value.imaginary())!=1) { if(value.imaginary() >= 0) b=b+"("+toString(value.real())+" + "+toString(value.imaginary())+"i )"; else b=b+"("+toString(value.real())+" - "+toString(-value.imaginary())+"i )"; } else { if(value.imaginary() >= 0) b=b+"("+toString(value.real())+" + i )"; else b=b+"("+toString(value.real())+" - i )"; } return b; } public String toString() { String b=""; if(Math.abs(imaginary())!=1) { if(imaginary() >= 0) b=b+"("+toString(real())+" + "+toString(imaginary())+"i )"; else b=b+"("+toString(real())+" - "+toString(-imaginary())+"i )"; } else { if(imaginary() >= 0) b=b+"("+toString(real())+" + i )"; else b=b+"("+toString(real())+" - i )"; } return b; } public static complex toComplex(String s) { //bu metod compleks sayıyı ekrandan okur. //StringTokanizer kütüphane sınıfı bir stringi cümlelere ayırır String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } complex b=new complex(a[0],a[1]); return b; } // data areas public double nreal; public double nimag; }; 4.5 KİRİŞ YÖNTEMİ (SECANT) Newton yönteminin bir problemi türev fonksiyonu kulanma gereğidir. Bu türev fonksiyonunu fark denklemiyle değiştirirsek (türevdeki teğet yerine teğete yakın bir kiriş kullanırsak) kiriş yöntemi oluşur Eğer fark denklemi olarak xn1 xn f ' ( xn ) f ( xn ) f ( xn1 ) formülü kullanılırsa ( xn xn1 ) f ( xn )( xn xn1 ) f ( xn ) f ( xn1 ) Bu yöntemde iterasyona başlamak için iki noktanın verilmiş olması gerekmektedir. İlk tahmin olarak f ( x0 ) ve f ( x1 ) olmak üzere iki başlangıç değerinin verilmesi gerekir. Bunun yerine tek bir başlangıç noktası için de decant yöntemi denklemini oluşturabiliriz. Çok küçük bir x aralığı üzerinden fark denklemi f ' ( xn ) f ( xn x) f ( xn x) 2x şeklinde tanımlanacak olursa (merkezi fark denklemini kullanacak olursak), kiriş denklemi xn1 xn 2 f ( xn )x f ( xn x) f ( xn x) şeklini alır. Hatanın az olması için x değerinin göreceli olarak küçük olması gereklidir. Hata (x)2 ile orantılı olacaktır. Şekil 4.5-1 Kiriş yöntemi yakınsamasının grafiksel gösterimi Program 4.5-1 Kiriş yöntemi(iki nokta verilmiş) ///Bilgisayar programlama II ve Sayısal Çözümleme // // // Sekant yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x*x-2.0;} } public class FSCO4D { public static double sekant(f_x f,double x0,double x1) { int nmax=500; double tolerance=1.0e-10; double fx0,fx1; double x; fx0=f.func(x0); for(int i=0;i<nmax;i++) { fx1=f.func(x1); x=x1-fx1*(x1-x0)/(fx1-fx0); x0=x1; fx0=fx1; x1=x; if(Math.abs(fx1)<tolerance) { return x1;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x1; } public static void main (String args[]) { fb f=new fb(); double x0,x1; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); x1=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ikinci tahmin : ")); double r= sekant(f,x0,x1); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Sekant yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); }} Çıktı 4.5-1 Kiriş yöntemi Program 4.5-2 Kiriş yöntemi(tek nokta verilmiş) // Bilgisayar programlama II ve Sayısal Çözümleme // // // Sekant yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return 7.0*Math.sin(x)*Math.exp(x)-1.0;} } public class FSCO4 { public static double sekant(f_x f,double x) { int nmax=500; double tolerance=1.0e-10; double fx,dfx; double dx=0.001; for(int i=0;i<nmax;i++) { fx=f.func(x); dfx=(f.func(x+dx)-f.func(x-dx))/(2.0*dx); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= sekant(f,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Sekant yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.5-2 Kiriş yöntemi (Tek nokta verilmiş) Türev denklemi yerine fark denklemi kullanmayı bir adım daha ileri götürebiliriz. Gerçek türeve yaklaşımı çok daha fazla olacak bir fark denklemini kullanabiliriz. Örneğin fark denklemi olarak f ' ( xn ) f ( xn 2x) 8 f ( xn x) 8 f ( xn x) f ( xn 2x) 12x formülünü kullanarak hata miktarını (x)2 den (x)4 seviyesine düşürebiliriz. // // // Newton-Raphson yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } //=========================================================== public class FSCO4A1 { public static double df(f_x f,double x,double h) { //Türev hesabı double hh=1.0/h; return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh; } public static double newton(f_x f,double x) { int nmax=500; double tolerance=1.0e-15; double fx,dfx; for(int i=0;i<nmax;i++) { fx=f.func(x); dfx=df(f,x,0.00001); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton(f,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton-Raphson yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 4.6 AİTKEN EXTRAPOLASYON DÜZELTMELİ NEWTON-RAPHSON YÖNTEMİ Aitken extrapolasyonu Newton raphson hesaplamasındaki hataları azaltarak kök bulma olasılığını artıran bir hata azaltma yöntemidir. Temel olarak k çok büyük bir değer olduğunda xk 2 a xk 1 a xk 1 a xk a k 1 bu bağıntıdan dördüncü bir noktanın değerini bulmak istersek xe xk xk 2 xk21 xk 2 xk 1 xk 2 3 önceki nokta bilindiğinde 4üncü noktayı tahmin edebiliriz. xk = xk+1 - xk xk = xk+2 - 2xk+1 + xk xe xk (xk ) 2 2 xk Şimdi bu formülü Newton metodundan elde ettiğimiz ilk yaklaşımları daha iyileştirmek için kullanabiliriz. Program 4.6-1 Aitken ekstrapolasyonlu Newton yöntemi ///Optimizasyon // // // Newton-Raphson_Aitken yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } class dfb extends f_x { public double func (double x) { return 2.0/x;} } //=========================================================== public class FSCO4B { public static double newton_aitken(f_x f,f_x df,double x) { // newton metodu aitken extrapolasyonuyla birlikte int nmax=500; double tolerance=1.0e-10; double fx,dfx; double xm1,xm2; xm1=x; xm2=x; int j=0;; //Newton stebi for(int i=0;i<3;i++) { if(i==0) xm2=x; else if(i==1) xm1=x; fx=f.func(x); dfx=df.func(x); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x;} } //Aitken stebi for(int i=3;i<nmax;i++) { x=(xm2*x-xm1*xm1)/(xm2-2.0*xm1+x); //extrapolasyon fx=f.func(x); if(Math.abs(fx)<tolerance) { return x;} xm2=xm1; xm1=x; dfx=df.func(x); x-=fx/dfx; fx=f.func(x); if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); dfb df=new dfb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton_aitken(f,df,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton-Raphson-Aitken ektrapolasyon yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Program 4.6-2 Aitken ekstrapolasyonlu Newton yöntemi, türev yerine fark denklemi kullanılmış hali ///Optimizasyon // // // Newton-Raphson_Aitken yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } public class FSCO4B1 { public static double df(f_x f,double x,double h) { //türev double hh=1.0/h; return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh; } public static double newton_aitken(f_x f,double x) { // newton metodu aitken extrapolasyonuyla birlikte int nmax=500; double tolerance=1.0e-10; double fx,dfx; double xm1,xm2; double dx=0.00001; xm1=x; xm2=x; int j=0;; for(int i=0;i<3;i++) { if(i==0) xm2=x; else if(i==1) xm1=x; fx=f.func(x); dfx=df(f,x,dx); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x;} } for(int i=3;i<nmax;i++) { x=(xm2*x-xm1*xm1)/(xm2-2.0*xm1+x); //extrapolasyon fx=f.func(x); if(Math.abs(fx)<tolerance) { return x;} xm2=xm1; xm1=x; dfx=df(f,x,dx); x-=fx/dfx; fx=f.func(x); if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton_aitken(f,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton-Raphson-Aitken ektrapolasyon yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 4.7 AİTKEN EKSTRAPOLASYON DÜZELTMELİ DİREK YERİNE KOYMA : STEFFENSEN METODU Kök bulmada yakınsamada zorluklar olabilmesi sebebiyle çok fazla kullanılmayan bir metod da direk yerine koyma metodudur. Bu metodda f(x) fonksiyonundan bir x değeri çekilerek f(x)=0 fonksiyonu, x=g(x) fonksiyonuna dönüştürülür. Buna sabit nokta iterasyonu veya direk yerine koyma iterasyonu ismi verilir. Şekil 4.7-1 direk yerine koyma metodunun grafik gösterimi Aitken interpolasyon prosesinden yararlanarak direk yerine koyma metodu iyileştirilebilir. Metod ilk olarak Steffensen tarafından önerilmiştir. p0(0) ilk tahmin değeri verildiğinde, p1(0)=g(p0(0)) ve , p2(0)=g(p1(0)) normal direk yerine koyma adımı olarak hesaplanır, sonra bir Aitken interpolasyon stepi kullanılır. p0(1) = p0(0) - (p1(0) - p2(0))2/( p2(0) - 2 p1(0) + p1(0)) bundan sonra yine p1(1)=g(p0(1)) ve , p2(1)=g(p1(1)) stepleriyle devam edilir. Program 4.7-1 Stephensen kök bulma metodu (Aitken ekstrapolasyonlu direk yerine koyma metodu) ///Bilgisayar programlama II ve Sayısal Çözümleme // Stephensen metodu x=g(x) verildiğinde x değerini bulur. import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { //x = g(x) fonksiyonu public double func (double x) { return Math.sqrt(10.0/(x+4.0));} } //=========================================================== public class FSCO3A { public static double stephensen(f_x f,double x0) { //Stephensen kök bulma metodu double es,ea; int maxit=100,iter=0; es=0.000001; ea=1.1*es; double x,x1,x2; x=0; while(iter<maxit && ea>es) { x1=f.func(x0); x2=f.func(x1); x=x0-(x1-x0)*(x1-x0)/(x2-2*x1+x0); ea=Math.abs(x-x0)*100.0; x0=x; iter++; } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb g=new fb(); double xa,xu; xa=Double.parseDouble(JOptionPane.showInputDialog(" ilk tahmin değerini giriniz : ")); double r= stephensen(g,xa); double fr=g.func(r); String s=" kök değeri : "+r+"\ng(x) = "+fr+"\nf(x)=g(x)-x = "+(fr-r); JOptionPane.showMessageDialog(null,s, "Stephensen kök bulma metodu : ",JOptionPane.PLAIN_MESSAGE); } } Çıktı 4.7-1 Stephensen kök bulma metodu (Aitken ekstrapolasyonlu direk yerine koyma metodu) 4.8 İKİNCİ TÜREVLİ NEWTON RAPHSON YÖNTEMİ Newton iterasyon formülüne Taylor serisinin ikinci teriminin çözümünü de ilave edebiliriz. İkinci türevler genelde birinci türev ve fonksiyondan sayısal olarak hesaplanabilir. İkinci türevi Newton-Raphson interpolasyon formülü : xn1 xn f ( xn ) * f ' ( xn ) f ' ( xn ) * f ' ( xn ) f ( xn ) * f " ( xn ) şeklindedir. Bu formül katlı kökler dediğimiz aynı noktada birden fazla kök olması durumunda da bize iyi bir dönüşüm hızı sağlayacaktır. Program 4.8-1 İkinci türev düzeltmeli newton-raphson formülü, birinci türev tanımlanmış // // ikinci türev düzeltmeli Newton-Raphson yöntemi // fonksiyon ve birinci türev tanımlanması gereklidir // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x*x*x+3.6*x-36.4;} } class dfb extends f_x { public double func (double x) { return 3.0*x*x+3.6;} } //=========================================================== public class FSCO4C { public static double newton1(f_x f,f_x df,double x) { int nmax=500; double dx=1.0e-3; double tolerance=1.0e-8; double fx,dfx,fxm,dfxm,d2fx; for(int i=0;i<nmax;i++) { fx=f.func(x); fxm=f.func(x-dx); dfx=df.func(x); dfxm=df.func(x-dx); d2fx=-6.0/dx/dx*(fx-fxm)+2.0/dx*(2.0*dfx+dfxm); x-=fx*dfx/(dfx*dfx-fx*d2fx); if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); dfb df=new dfb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton1(f,df,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "ikinci türev düzeltmeli Newton-Raphson yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.8-1 İkinci türev düzeltmeli Newton-Raphson formülü, birinci türev tanımlanmış Program 4.8.1 de türev fonksiyonu verilmişti. Türev fonksiyonunu sayısal olarak hesaplayan ikinci bir programı Program 4.8.2 de veriyoruz. Program 4.8-2 İkinci türev düzeltmeli Newton-Raphson formülü, birinci türev sayısal olarak hesaplanmış // // // ikinci türev düzeltmeli Newton-Raphson yöntemi // fonksiyon tanımlanması gereklidir // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class fb extends f_x { public double func (double x) { return x*x*x+3.6*x-36.4;} } public class FSCO4C1 { public static double newton1(f_x f,double x) { int nmax=500; double h=1.0e-3; double hh=1.0/h; double tolerance=1.0e-8; double fx,dfx,fxm,dfxm,d2fx; for(int i=0;i<nmax;i++) { fx=f.func(x); fxm=f.func(x-h); dfx=(-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh; d2fx=(-f.func(x+2.0*h)+16.0*f.func(x+h)-30.0*f.func(x)+16.0*f.func(x-h)-f.func(x-2.0*h))/(12.0)*hh*hh; x-=fx*dfx/(dfx*dfx-fx*d2fx); if(Math.abs(fx)<tolerance) { return x;} } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static void main (String args[]) { fb f=new fb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için ilk tahmin : ")); double r= newton1(f,x0); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "ikinci türev düzeltmeli Newton-Raphson yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 4.9 NEWTON-RAPHSON VE İKİYE BÖLME METODLARININ BİRLİKTE KULLANILMASI İkiye bölme metodunun bizim için en önemli avantajı, eğer tanımlanan bölgede bir kök mevcutsa ona muhakkak ulaşabilmesidir, ancak kök değerine ulaşması çok fazla iterasyon stepi gerektirir. Öte yandan Newton-raphson metodu eğer köke yakın olduğunda az bir iterasyon sayısıyla köke ulaşırke, kökten uzak bir ilk tahmin verildiğinde kökü hiç bulamayabilir veya çok uzun step sayısıyla köke doğru hareket eder. Bu ikimetodu birleştirerek her metodun avantajlı kısmını bir arada kullanabiliriz, İkiye bölme stepleriyle iterasyona başlayıp, kök değerine yaklaştığımızda Newton-Raphson steplerine geçebiliriz. Alttaki örnek programda Newton metodundaki türev değerleri de sayısal şekle dönüştürülerek sadece fonksiyonun girdi olarak alındığı bir formata dönüştürülmüştür. Bu şekilde oldukça etkin çalışabilen bir kök bulma sistemi oluşmuştur. Program 4.9-1 Newton-Raphson-İkiye bölme kombine formülü, birinci türev sayısal olarak hesaplanmış // // // Newton-Raphson-ikiye bölme kombine yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } //=========================================================== public class FSCO4A2 { public static double dfx(f_x f,double x,double h) { //Türev hesabı double hh=1.0/h; return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh; } public static double newton_bisection(f_x fx, double x1, double x2) { double xacc=1.0e-10; //iterasyonlar arasındaki fark, bu rakamdan // küçük olduğunda çözüme ulaştığımızı kabul edeceğiz double h=0.0001; //türev step büyüklüğü int MAXIT=100; //Maksimum iterasyon sayısı int j; double dfr,dx,dxold,fr,fh,fl; double temp,b,a,r; fl=fx.func(x1); fh=fx.func(x2); //Bölgemizde kök değeri varmı kontrol et if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0)) System.out.println("verilen sınırlar içinde kök değeri yok"); if (fl == 0.0) return x1; if (fh == 0.0) return x2; if (fl < 0.0) { a=x1;b=x2;} else { b=x1;a=x2;} r=0.5*(x1+x2); //orta nokta değeri dxold=Math.abs(x2-x1); dx=dxold; fr=fx.func(r); //fonksiyonun r noktasındaki değeri dfr=dfx(fx,r,h); //fonksiyonun türevinin r noktasındaki değeri for (j=1;j<=MAXIT;j++) { if ((((r-b)*dfr-fr)*((r-a)*dfr-fr) > 0.0) || (Math.abs(2.0*fr) > Math.abs(dxold*dfr))) { //ikiye bölme dxold=dx; dx=0.5*(b-a); r=a+dx; if (a == r) return r; //çözüm!!!! } else{ //Newton-Raphson dxold=dx; dx=fr/dfr; temp=r; r -= dx; if (temp == r) return r; //çözüm!!!!! } if (Math.abs(dx) < xacc) return r; //çözüm!!!!! fr=fx.func(r); dfr=dfx(fx,r,h); if (fr < 0.0) a=r; else b=r; } System.out.println("Maksimum iterasyon sayısı aşıldı"); return 0.0; //program buraya gelmemeli } public static void main (String args[]) { fb f=new fb(); double x0,x1; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için alt tahmin sınırı : ")); x1=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyon değeri için üst tahmin sınırı : ")); double r= newton_bisection(f,x0,x1); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton-Raphson - ikiye bölme kombine yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.9-1 Newton-Raphson-İkiye bölme kombine formülü, birinci türev sayısal olarak hesaplanmış İkinci bir örnek problemi ısı transferinden tanımlayalım. Düz bir duvarın sıcaklığı denklemiyle verilmektedir. Bu denklem zamana bağlı bir boyutlu taşınım ısı transferini tanımlar. Buradaki T sıcaklık(derece Kelvin), x mesafe, t zaman (saniye) değişkenidir. ısıl yayılım olarak tanımlanır ve formüldeki k ısıl iletim katsayısı (W/mK), yoğunluk (kg/m3), C ısıl iletim katsayısıdır (W/kgK). h ısı taşınım katsayısı adını alır. (W/m2K). Diferansiyel denklemin çözüm seti şeklinde yazılabilir. Bu denklemi boyutsuz formda yazarsak : sınır şartları bu diferansiyel denklemi çözersek : formunda bir çözüme ulaşırız. Buradaki Bi Biot sayısıdır. olarak tanımlanır. Bu denklemin çözümü şeklindedir. Burada ve şeklinde verilebilir. Bu denklemin çözülebilmesi denklemin kökünü bulma anlamına gelir. Denklemi çözmek için önce kökü buluruz, sonra Cn katsayılarını çözdükten sonra denklem çözülür. Bu işlemleri yapan ve çözümü veren program altta verilmiştir. Program 4.9-2 Newton-Raphson-İkiye bölme kombine formülü, ile zamana bağlı duvar probleminin çözümü import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class HT_duvar { public static double fx(double lambda,double Bi) {return lambda*Math.tan(lambda)-Bi;} public static double dfx(double x,double h,double Bi) { //Türev hesabı return (-fx((x+2.0*h),Bi)+8.0*fx((x+h),Bi)-8.0*fx((x-h),Bi)+fx((x-2.0*h),Bi))/(12.0*h); } public static double Cn(double ln,double Bi) { return 4.0*Math.sin(ln)/(2.0*ln+Math.sin(2.0*ln)); } public static double lambda(double n,double Bi) { //lineer olmayan denklemin kökü : ikiyebölme-Newton Raphson metodu //lambda*tan(lambda)-Bi=0 denkleminin köklerini bulur double x1=(n-1)*Math.PI; double x2= x1+Math.PI/2-0.000001; double xacc=1.0e-10; //iterasyonlar arasındaki fark, bu rakamdan // küçük olduğunda çözüme ulaştığımızı kabul edeceğiz double h=0.0001; //türev step büyüklüğü int MAXIT=100; //Maksimum iterasyon sayısı int j; double dfr,dx,dxold,fr,fh,fl; double temp,b,a,r; fl=fx(x1,Bi); fh=fx(x2,Bi); //System.out.println("x1 ="+x1+"fl="+fl+"x2="+x2+"fh="+fh); //Bölgemizde kök değeri varmı kontrol et if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0)) System.out.println("n = "+n+"x1="+x1+"x2="+x2+"verilen sınırlar içinde kök değeri yok"); if (fl == 0.0) return x1; if (fh == 0.0) return x2; if (fl < 0.0) { a=x1;b=x2;} else { b=x1;a=x2;} r=0.5*(x1+x2); //orta nokta değeri dxold=Math.abs(x2-x1); dx=dxold; fr=fx(r,Bi); //fonksiyonun r noktasındaki değeri dfr=dfx(r,h,Bi); //fonksiyonun türevinin r noktasındaki değeri for (j=1;j<=MAXIT;j++) { if ((((r-b)*dfr-fr)*((r-a)*dfr-fr) > 0.0) || (Math.abs(2.0*fr) > Math.abs(dxold*dfr))) { //ikiye bölme dxold=dx; dx=0.5*(b-a); r=a+dx; if (a == r) return r; //çözüm!!!! } else{ //Newton-Raphson dxold=dx; dx=fr/dfr; temp=r; r -= dx; if (temp == r) return r; //çözüm!!!!! } if (Math.abs(dx) < xacc) return r; //çözüm!!!!! fr=fx(r,Bi); dfr=dfx(r,h,Bi); if (fr < 0.0) a=r; else b=r; } System.out.println("Maksimum iterasyon sayısı aşıldı"); return 0.0; //program buraya gelmemeli } public static double teta(double Fo,double Bi,double x) {double tt=0;double ln=0; for(int n=1;n<20;n++) {ln=lambda(n,Bi);tt+=Cn(ln,Bi)*Math.exp(-ln*ln*Fo)*Math.cos(ln*x);} return tt; } public static void main (String args[]) { fb f=new fb(); double Bi,Fo,x; Fo=Double.parseDouble(JOptionPane.showInputDialog(" Forier sayısı Fo : ")); Bi=Double.parseDouble(JOptionPane.showInputDialog(" Biot sayısı Bi : ")); x=Double.parseDouble(JOptionPane.showInputDialog(" x* = x/L : ")); JOptionPane.showMessageDialog(null," teta = "+teta(Fo,Bi,x), "duvarda zamana bağlı ısı transferi : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } silindir için benzer denklem silindirik koordinat sisteminde çözülürse sonuç denklemleriyle verilebilir. Buradaki J0(n), J1(n) birinci tip Bessel fonksiyonlarıdır. Program 4.9-3 Newton-Raphson-İkiye bölme kombine formülü, ile zamana bağlı silindir probleminin çözümü import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class HT_silindir { double x0,x1,x2; int ix; public HT_silindir() { ix=0; x1=0.0; } public static double fx(double lambda,double Bi) {return lambda*Mathd.J(1,lambda)/Mathd.J(0,lambda)-Bi;} public static double dfx(double x,double h,double Bi) { //Türev hesabı return (-fx((x+2.0*h),Bi)+8.0*fx((x+h),Bi)-8.0*fx((x-h),Bi)+fx((x-2.0*h),Bi))/(12.0*h); } public double Cn(double lambda) { double J1=Mathd.J(1,lambda); double J0=Mathd.J(0,lambda); return 2.0/lambda*J1/(J0*J0+J1*J1); } public void genislet(double Bi) { //kök olan bir bölge bulana kadar verilen sınırı genişletir x0=x1; x2=x1+0.00001; int NTRY=200; double a[]=new double[2]; double FACTOR=1.01; int j; double f1,f2; if (x1 == x2) System.out.println("Giriş değerleri yanlış verildi"); f1=fx(x1,Bi); f2=fx(x2,Bi); for (j=1;j<=NTRY;j++) { if (f1*f2 < 0.0) {ix++;break;} else {f2=fx(x2 += FACTOR*(x2-x1),Bi);} } } // x1 ve x2 nin yeni değerleri geldi public double lambda(double Bi) { //lineer olmayan denklemin kökü : ikiyebölme-Newton Raphson metodu genislet(Bi); //kök sınırlarını saptar double xacc=1.0e-10; //iterasyonlar arasındaki fark, bu rakamdan // küçük olduğunda çözüme ulaştığımızı kabul edeceğiz double EPS=1.0e-10; double h=0.0001; //türev step büyüklüğü int MAXIT=100; //Maksimum iterasyon sayısı int j; double dfr,dx,dxold,fr,fh,fl; double temp,b,a,r; fl=fx(x1,Bi); fh=fx(x2,Bi); //System.out.println("x1 ="+x1+"fl="+fl+"x2="+x2+"fh="+fh); //Bölgemizde kök değeri varmı kontrol et if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0)) System.out.println("n = "+ix+"x1="+x0+"x2="+x2+"verilen sınırlar içinde kök değeri yok"); if (fl == 0.0) return x1; if (fh == 0.0) return x2; if (fl < 0.0) { a=x1;b=x2;} else { b=x1;a=x2;} r=0.5*(x1+x2); //orta nokta değeri dxold=Math.abs(x2-x1); dx=dxold; fr=fx(r,Bi); //fonksiyonun r noktasındaki değeri dfr=dfx(r,h,Bi); //fonksiyonun türevinin r noktasındaki değeri for (j=1;j<=MAXIT;j++) { if ((((r-b)*dfr-fr)*((r-a)*dfr-fr) > 0.0) || (Math.abs(2.0*fr) > Math.abs(dxold*dfr))) { //ikiye bölme dxold=dx; dx=0.5*(b-a); r=a+dx; if ( a == r && fr>EPS) {x1=r+0.001;return r;} //çözüm!!!! } else{ //Newton-Raphson dxold=dx; dx=fr/dfr; temp=r; r -= dx; if ((temp == r) && fr<EPS) {x1=r+0.001;return r;} //çözüm!!!!! } if ((Math.abs(dx) < xacc)&& fr<EPS) {x1=r+0.001;return r;} //çözüm!!!!! fr=fx(r,Bi); dfr=dfx(r,h,Bi); if (fr < 0.0) a=r; else b=r; } System.out.println("Maksimum iterasyon sayısı aşıldı"); return 0.0; //program buraya gelmemeli } public double teta(double Fo,double Bi,double x) {double tt=0;double ln=0; for(int n=0;n<20;n++) {ln=lambda(Bi); double ffx=fx(ln,Bi); double cn; if(Math.abs(ffx)<1.0e-4) { cn=Cn(ln); System.out.println("ln ="+ln+"Cn = "+cn+" ix="+ix+" x1="+x0+"x2="+x2+"fx="+ffx); tt+=cn*Math.exp(-ln*ln*Fo)*Mathd.J(0,ln*x); } } return tt; } public static void main (String args[]) { HT_silindir hts=new HT_silindir(); double Bi,Fo,x; Fo=Double.parseDouble(JOptionPane.showInputDialog(" Forier sayısı Fo : ")); Bi=Double.parseDouble(JOptionPane.showInputDialog(" Biot sayısı Bi : ")); x=Double.parseDouble(JOptionPane.showInputDialog(" x* = x/L : ")); JOptionPane.showMessageDialog(null," teta = "+hts.teta(Fo,Bi,x), "silindirde zamana bağlı ısı transferi : ",JOptionPane.PLAIN_MESSAGE); } } Buradaki Bessel fonksiyonu ayrıca düzenlenmiş olan Mathd sınıfında hesaplanmıştır bu sınıfın listesi de ayrıca veriyoruz. Program 4.9-3A Mathd sınıfı listesi import static java.lang.Math.*; public class Mathd { public static double PI=Math.PI; public static double E=Math.E; public static double C=0.577215664901532860606512090082402431; public static double abs(double a) {return Math.abs(a);} public static float abs(float a) {return Math.abs(a);} public static int abs(int a) {return Math.abs(a);} public static double sin(double a) {return Math.sin(a);} public static double sinh(double a) {return Math.sinh(a);} public static double cosh(double a) {return Math.cosh(a);} public static double tanh(double a) {return Math.tanh(a);} public static double cos(double a) {return Math.cos(a);} public static double tan(double a) {return Math.tan(a);} public static double asin(double a) {return Math.asin(a);} public static double acos(double a) {return Math.asin(a);} public static double atan(double a) {return Math.atan(a);} public static double atan2(double a,double b) {return Math.atan2(a,b);} public static double sqrt(double a) {return Math.sqrt(a);} public static double cbrt(double a) {return Math.cbrt(a);} public static double ln(double a) {return Math.log(a);} public static double log(double a) {return Math.log(a);} public static double log10(double a) {return Math.log10(a);} public static double log1p(double a) {return Math.log1p(a);} public static double hypot(double a,double b) {return Math.hypot(a,b);} public static double max(double a,double b) {return Math.max(a,b);} public static float max(float a,float b) {return Math.max(a,b);} public static int max(int a,int b) {return Math.max(a,b);} public static long max(long a,long b) {return Math.max(a,b);} public static double exp(double a) {return Math.exp(a);} public static double pow(double a,double b) {return Math.pow(a,b);} public static double us(double a,double b) {return Math.pow(a,b);} public static double toRadians(double a) {return Math.toRadians(a);} public static double toDegrees(double a) {return Math.toDegrees(a);} public static double radyanacevir(double a) {return Math.toRadians(a);} public static double dereceyecevir(double a) {return Math.toDegrees(a);} public static double sind(double a) { double r=(a/180.0)*PI; return Math.sin(r); } public static double cosd(double a) { double r=(a/180.0)*PI; return Math.cos(r); } public static double tand(double a) { double r=(a/180.0)*PI; return Math.tan(r); } public static double asind(double b) { return Math.asin(b)*180.0/PI; } public static double acosd(double b) { return Math.acos(b)*180/PI; } public static double atand(double b) { return Math.atan(b)*180/PI; } public static double atan2d(double a,double b) { return Math.atan2(a,b)*180.0/PI; } public static double gamma(double xx) {return Math.exp(gammln(xx));} public static double C(long n) { double cc=0; for(double i=1;i<=n;i++) {cc+=1.0/i;} cc-=Math.log(n); return cc; } public static double gammln(double xx) { //gamma function double x,y,tmp,ser; double cof[]={76.18009172947146,-86.50532032941677, 24.01409824083091,-1.231739572450155, 0.1208650973866179e-2,-0.5395239384953e-5}; int j; y=x=xx; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.000000000190015; for (j=0;j<=5;j++) ser += cof[j]/++y; return -tmp+log(2.5066282746310005*ser/x); } public static double factrl(int n) { // n! of an integer number int ntop=4; double a[]=new double[50]; a[0]=1.0; a[1]=1.0; a[2]=2.0; a[3]=6.0; int j; if (n < 0) System.out.println("Negative factorial in routine FACTRL"); if (n > 50) return Math.exp(gammln(n+1.0)); while (ntop<=n) { j=ntop-1; a[ntop]=a[j]*ntop; ntop++; } return a[n]; } public static double factln(int n) { //Math.log(factorial) of an integer number double a[]=new double[100]; int ntop=4; a[0]=1.0; a[1]=1.0; a[2]=2.0; a[3]=6.0; int j; if (n < 0) System.out.println("Negative factorial in routine FACTLN"); if (n <= 1) return 0.0; if (n > 30) return gammln(n+1.0); while (ntop<=n) { j=ntop-1; a[ntop]=a[j]*ntop; ntop++; } return Math.log(a[n]); } public static double PI() { //Ramanujan formülü double p=0,pi=0.0; double c3=2.0*Math.sqrt(2.0)/9801.0; double c,c1,c2; for(int n=0;n<5;n++) {c1=factln(n);c=factln(4*n)-c1*c1*c1*c1+Math.log(1103.0+26390.0*n)-4.*n*Math.log(396);c2=c3*Math.exp(c); p+=c2; pi=1.0/p; System.out.println("c="+c+"c2="+c2+"pi="+pi); } return pi; } public static double bico(int n,int k) { //binomial coefficients return Math.floor(0.5+Math.exp(factln(n)-factln(k)-factln(n-k))); } public static double beta(double z,double w) { //gamma(z)*gamma(w)/gamma(z+w); return Math.exp(gammln(z)+gammln(w)-gammln(z+w)); } public static double gammp(double a,double x) { //incomplete gamma function P(a,x) double gamser,gammcf; if (x < 0.0 || a <= 0.0) System.out.println("Invalid arguments in routine GAMMP"); if (x < (a+1.0)) { gamser=gser(a,x); return gamser; } else { gammcf=gcf(a,x); return 1.0-gammcf; } } public static double gammq(double a,double x) { //incomplete gamma function Q(a,x)=1-P(a,x); double gamser,gammcf; if (x < 0.0 || a <= 0.0) System.out.println("Invalid arguments in routine GAMMQ"); if (x < (a+1.0)) { gamser=gser(a,x); return 1.0-gamser; } else { gammcf=gcf(a,x); return gammcf; } } public static double gser(double a,double x) { int ITMAX=100; double EPS=3.0e-7; int n; double sum,del,ap; double gln=gammln(a); double gamser=0; if (x <= 0.0) { if (x < 0.0) System.out.println("x less than 0 in routine GSER"); gamser=0.0; return gamser; } else { ap=a; del=sum=1.0/a; for (n=1;n<=ITMAX;n++) { ap += 1.0; del *= x/ap; sum += del; if (Math.abs(del) < Math.abs(sum)*EPS) { gamser=sum*Math.exp(-x+a*Math.log(x)-(gln)); return gamser; } } System.out.println("a too large, ITMAX too small in routine GSER"); return gamser; } } public static double gcf(double a,double x) { int ITMAX=100; double EPS=3.0e-7; int n; double gln; double gammcf=0; double gold=0.0,g,fac=1.0,b1=1.0; double b0=0.0,anf,ana,an,a1,a0=1.0; gln=gammln(a); a1=x; for (n=1;n<=ITMAX;n++) { an=(double) n; ana=an-a; a0=(a1+a0*ana)*fac; b0=(b1+b0*ana)*fac; anf=an*fac; a1=x*a0+anf*a1; b1=x*b0+anf*b1; if (a1!=0) { fac=1.0/a1; g=b1*fac; if (Math.abs((g-gold)/g) < EPS) { gammcf=Math.exp(-x+a*Math.log(x)-gln)*g; return gammcf; } gold=g; } } System.out.println("a too large, ITMAX too small in routine GCF"); return gammcf; } public static double erf(double x) { //error function return x < 0.0 ? -gammp(0.5,x*x) : gammp(0.5,x*x); } public static double erfc(double x) { //complimentary error function return x < 0.0 ? 1.0+gammp(0.5,x*x) : gammq(0.5,x*x); } public static double erfcc(double x) { double t,z,ans; z=Math.abs(x); t=1.0/(1.0+0.5*z); ans=t*Math.exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+ t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+ t*(-0.82215223+t*0.17087277))))))))); return x >= 0.0 ? ans : 2.0-ans; } public static double betacf(double a,double b,double x) { int ITMAX=100; double EPS=3.0e-7; double qap,qam,qab,em,tem,d; double bz,bm=1.0,bp,bpp; double az=1.0,am=1.0,ap,app,aold; int m; qab=a+b; qap=a+1.0; qam=a-1.0; bz=1.0-qab*x/qap; for (m=1;m<=ITMAX;m++) { em=(double) m; tem=em+em; d=em*(b-em)*x/((qam+tem)*(a+tem)); ap=az+d*am; bp=bz+d*bm; d = -(a+em)*(qab+em)*x/((qap+tem)*(a+tem)); app=ap+d*az; bpp=bp+d*bz; aold=az; am=ap/bpp; bm=bp/bpp; az=app/bpp; bz=1.0; if (Math.abs(az-aold) < (EPS*Math.abs(az))) return az; } System.out.println("a or b too big, or ITMAX too small in BETACF"); return az; } public static double betai(double a,double b,double x) { //incomplete beta function double bt; if (x < 0.0 || x > 1.0) System.out.println("Bad x in routine BETAI"); if (x == 0.0 || x == 1.0) bt=0.0; else bt=Math.exp(gammln(a+b)-gammln(a)-gammln(b)+a*Math.log(x)+b*Math.log(1.0-x)); if (x < (a+1.0)/(a+b+2.0)) return bt*betacf(a,b,x)/a; else return 1.0-bt*betacf(b,a,1.0-x)/b; } public static double J(double v,double x) {double JJ=0;double a=1.0;int fact=1;double b; double x1,x2,x3,x4; int x5=1; for(int k=0;k<50;k++) { x1=v*Math.log(0.5*x); x2=Math.log(a); x3=factln(k); x4=gammln(v+k+1); b=x1+x2-x3-x4; b=x5*Math.exp(b); fact*=(k+1); a*=(0.25*x*x); x5*=-1; JJ+=b; } if(v==0 && x==0) JJ=1; //if(v==1 && x==0) JJ=0; return JJ; } } 4.10 İKİNCİ DERECE TERS LAGRANGE İNTERPOLASYON YÖNTEMİ Lagrange interpolasyonunu interpolasyon ve eğri uydurma bölümünde göreceğiz. İkinci dereceden Lagrange interpolasyonu x=f(y) şeklinde (ters interpolasyon olarak) yazılırsa x [ y f ( x1 )][ y f ( x2 )] x3 [ y f ( x2 )][ y f ( x3 )] x1 [ y f ( x3 )][ y f ( x1 )] x2 [ f ( x3 ) f ( x1 )][ f ( x3 ) f ( x2 )] [ f ( x1 ) f ( x2 )][ f ( x1 ) f ( x3 )] [ f ( x2 ) f ( x3 )][ f ( x2 ) f ( x1 )] bu intrepolasyon denkleminde y=0 alındığında x değeri bize y=f(x)=0 denkleminin köklerini verecektir. x f ( x1 ) f ( x2 ) x3 f ( x2 ) f ( x3 ) x1 f ( x3 ) f ( x1 ) x2 [ f ( x3 ) f ( x1 )][ f ( x3 ) f ( x2 )] [ f ( x1 ) f ( x2 )][ f ( x1 ) f ( x3 )] [ f ( x2 ) f ( x3 )][ f ( x2 ) f ( x1 )] [ f ( x1 ) f ( x2 )] f ( x1 ) f ( x2 ) x3 [ f ( x3 ) f ( x2 )] f ( x2 ) f ( x3 ) x [ f ( x3 ) f ( x1 )] f ( x3 ) f ( x1 ) x2 [ f ( x3 ) f ( x1 )][ f ( x3 ) f ( x2 )][ f ( x1 ) f ( x3 )] Denklemimiz hesap kolaylığı açısından x R f ( x2 ) f ( x3 ) S f ( x2 ) f ( x1 ) T f ( x1 ) f ( x3 ) P = S[T(R-T)(x3 – x2) – (1-R)(x2 – x1)] Q = (T - 1)(R – 1)(S – 1) Formunda da yazılabilir. Kök değeri x = x2 + P Q olacaktır. Yeni kök bulunduktan sonra bulunan köke komşu olan bölgeler bırakılır ve bu bölgenin dışında olan bölge elimine edilir. Şekil 4.10-1 İkinci derece ters lagrange interpolasyon yönteminde bölge seçimi Şekil 4.10-1 de bu seçim işlemi görülmektedir. Bu mtodun uygulaması Program 4.10-1 de verilmiştir. Program 4.10.1 ikinci derece ters Lagrange interpolasyon formülü kullanarak kök bulma programı import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fc extends f_x { public double func(double x) {return x*x-2;} } //=========================================================== public class FSCO1A { public static double tersinter2Dkok(f_x f,double x1,double x2,double x3) { // brent metodu ile kök değerini bulur double test; double p=0; double es,ea; double f1,f2,f3,fp; int maxit=500,iter=0; double tol=1.0e-15; es=0.0000001; ea=1.1*es; f1=f.func(x1); f2=f.func(x2); f3=f.func(x3); if(f1==0) return x1; else if(f2==0) return x2; else if(f3==0) return x3; if(f1*f3>0) System.out.println("verilen bölgede kök yok"); while((ea>es)&&(iter<maxit)) { p=-(f2*f3*x1*(f2-f3)+f3*f1*x2*(f3-f1)+f1*f2*x3*(f1-f2))/((f1-f2)*(f2-f3)*(f3-f1)); fp=f.func(p); ea=Math.abs(x3-p); if(Math.abs(f3)<tol) return x3; if(p>x3) {x1=x3;f1=f3;x3=p;f3=fp;} else if(p<x3) {x2=x3;f2=f3;x3=p;f3=fp;} iter++; } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return p; } public static void main (String args[]) { fc f=new fc(); double x1,x2,x3; x1=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz x1 : ")); x2=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun ortaki bir değerini giriniz x3 : ")); x3=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz x2 : ")); double r; r= tersinter2Dkok(f,x1,x2,x3); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "ikinci derece ters interpolasyon yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.10.1 ikinci derece ters Lagrange interpolasyon formülü kullanarak kök bulma programı çıktısı 4.11 BRENT KÖK BULMA YÖNTEMİ Yukarda Newton-Raphson metodu ile ikiye bölme metodunun integrasyonunun çok daha verimli ve emniyetli bir metod oluşturduğundan bahsetmiştik. Aynı şekilde ikinci dereceden ters Lagrange interpolasyon kök bulma yöntemi de ikiye bölme yöntemi ile integre edilerek oldukça yararlı bir yöntem oluşturulabilir. Bu yöntem Brent yöntemi adını alır. Bu yöntemde ikinci dereceden ters Lagrange interpolasyon kök bulma yönteminden farklı olarak sadece iki sınır değeri tanımlanır. Birinci step olarak ikiye böme formülü uygulanır ve ikinci dereceden interpolasyonun üçüncü noktası olarak bu noktadan yararlanılır. İkinci dereceden ters Lagrange interpolasyon kök formülü kullanılarak yeni bir çözüm noktası saptanır ve bu çözüm bölgesine göre bölge küçültülür. Eğer çözüm seçilen değer x1 – x2 bölgesine düşmüyorsa yeni bir ikiye bölme stebi uygulanır. Denklemin bölündüğü değerinin çok küçük olduğu sıfıra yaklaştığı değerlerde metod yine yanlış değer verebilir. Bu durumda yine ikiye bölme yöntemine dönülür. Bu bölümde Brent yönteminin iki versiyonu örnek program olarak düzenlenmiştir. Birinci program üstteki bölümde oluşturduğumuz programı değiştirerek oluşturulmuştur. Program 4.11-1 Brent yöntemi ile kök bulma import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fc extends f_x { public double func(double x) {return x*x-2;} } //=========================================================== public class FSCO1B { public static double brent(f_x f,double a,double b) { // brent metodu ile kök değerini bulur double test; double p=0; double es,ea; double f1,f2,f3,fp; int maxit=500,iter=0; double tol=1.0e-15; es=0.0000001; double x1=a;f1=f.func(x1); double x2=b;f2=f.func(x2); double x3=(x1+x2)/2.0;f3=f.func(x3); if(f1==0) return x1; else if(f2==0) return x2; else if(f3==0) return x3; if(f1*f2>0) System.out.println("verilen bölgede kök yok"); p=-(f2*f3*x1*(f2-f3)+f3*f1*x2*(f3-f1)+f1*f2*x3*(f1-f2))/((f1-f2)*(f2-f3)*(f3-f1)); fp=f.func(p); ea=Math.abs(x3-p); while((ea>es)&&(iter<maxit)) { if(Math.abs(f3)<tol) return x3; if((p<x1) && (p>x2)) {p=(x1+x2)/2.0; if(p>x3) {x1=x3;f1=f3;x3=p;f3=fp;} else if(p<x3) {x2=x3;f2=f3;x3=p;f3=fp;} } else { if(p>x3) {x1=x3;f1=f3;x3=p;f3=fp;} else if(p<x3) {x2=x3;f2=f3;x3=p;f3=fp;} p=-(f2*f3*x1*(f2-f3)+f3*f1*x2*(f3-f1)+f1*f2*x3*(f1-f2))/((f1-f2)*(f2-f3)*(f3-f1)); fp=f.func(p); ea=Math.abs(x3-p); } iter++; } if(iter>=maxit) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return p; } public static void main (String args[]) { fc f=new fc(); double x1,x2,x3; x1=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz x1 : ")); x2=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun ortaki bir değerini giriniz x3 : ")); double r; r= brent(f,x1,x2); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "ikinci derece ters interpolasyon yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.11-1 Brent yöntemi ile kök bulma Program 4.11-2 Brent yöntemi ile kök bulma (ikinci versiyon) ///Bilgisayar programlama II ve Sayısal Çözümleme // // // Brent yöntemi ile kök bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class SCO7 { public static double f(double x) { return Math.log(x*x)-0.7;} public static double brent(double x1,double x2) { //lineer olmayan denklemin kökü : brent metodu //referans : Numerical Recipes in C, second edition, William H. Press, //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery //cambridge university press double ITMAX=100; double EPS=3.0e-8; int iter; double a=x1,b=x2,c,d,e,min1,min2; double tol=1.0e-5; c=0; d=0; e=0; double fa=f(a),fb=f(b),fc,p,q,r,s,tol1,xm; if (fb*fa > 0.0) JOptionPane.showMessageDialog(null,"Kök sınırları doğru olarak seçilmemiş \n sonuç hatalı olabilir" ,"KÖK SINIRLARI SEÇİM UYARISI",JOptionPane.WARNING_MESSAGE); fc=fb; for (iter=1;iter<=ITMAX;iter++) { if (fb*fc > 0.0) { c=a; fc=fa; e=d=b-a; } if (Math.abs(fc) < Math.abs(fb)) { a=b; b=c; c=a; fa=fb; fb=fc; fc=fa; } tol1=2.0*EPS*Math.abs(b)+0.5*tol; xm=0.5*(c-b); if (Math.abs(xm) <= tol1 || fb == 0.0) return b; if (Math.abs(e) >= tol1 && Math.abs(fa) > Math.abs(fb)) { s=fb/fa; if (a == c) { p=2.0*xm*s; q=1.0-s; } else { q=fa/fc; r=fb/fc; p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0)); q=(q-1.0)*(r-1.0)*(s-1.0); } if (p > 0.0) q = -q; p=Math.abs(p); min1=3.0*xm*q-Math.abs(tol1*q); min2=Math.abs(e*q); if (2.0*p < (min1 < min2 ? min1 : min2)) { e=d; d=p/q; } else { d=xm; e=d; } } else { d=xm; e=d; } a=b; fa=fb; if (Math.abs(d) > tol1) b += d; else b += (xm > 0.0 ? Math.abs(tol1) : -Math.abs(tol1)); fb=f(b); } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return b; } public static void main (String args[]) { double a,b; a=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz a : ")); b=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz b : ")); double r; r= brent(a,b); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f(r), "brent yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.11-2 Brent yöntemi ile kök bulma 4.12 KÖK SINIRLARININ SAPTANMASI Bir değişkenli fonksiyonlar için (a,b) bölgesinde en az bir kök vardır diyebilmemiz için üç noktadaki fonksiyon değerlerinin ters işaretli olması gerekir. Bu kural üniversal olarak her tür fonksiyon için geçerli olmasa da sürekli fonsiyon ailesinin çoğu üyesi için geçerlidir. O zaman verilen bir alanı daha küçük steplerle tarayarak kök sınırlarının bulunduğu bölgeyi daraltabiliriz, veya belli bir noktadan veya birbirine yakın iki noktadan başlayarak ve her seferinde bölgeyi birden büyük bir katsayısıyla kökün bulunduğunu tahmin ettiğimiz tarafa doğru genişleterek kökün olduğu bir bölge sapayabiliriz. Bu amaçla genişlet ve koksınırınısapta metodları geliştirilmiş ve alttaki programda brent metoduyla birlikte kullanılmıştır. Program 4.12-1 Kök sınırlarını saptayan ve brent metoduyla kökü bulan FSCO6.java programı ///Bilgisayar programlama II ve Sayısal Çözümleme // // // Brent yöntemi ile kök bulmak // ve kökün sınırlarını saptamak // Dr. M. Turhan Çoban import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class SCO6 { public static double f(double x) { return x*x*x-6.0*x*x+11.0*x-6.0;} //üç gerçek kök 1 2 3 public static double[] genislet(double x1) {return genislet(x1,(x1+0.1));} public static double[] genislet(double x1,double x2) { //kök olan bir bölge bulana kadar verilen sınırı genişletir int NTRY=50; double a[]=new double[2]; double FACTOR=1.6; int j; double f1,f2; if (x1 == x2) System.out.println("Bad initial range in ZBRAC"); f1=f(x1); f2=f(x2); for (j=1;j<=NTRY;j++) { if (f1*f2 < 0.0) {a[0]=x1;a[1]=x2;return a;} if (Math.abs(f1) < Math.abs(f2)) f1=f(x1 += FACTOR*(x1-x2)); else f2=f(x2 += FACTOR*(x2-x1)); } {a[0]=x1;a[1]=x2;return a;} } public static double[][] koksinirisapta(double x1,double x2,int n,int nbb) { // koklerin yer aldığı alt bölgeleri saptar // n : verilen bölgeyi böldüğümüz alt bölge sayısı // x1,x2 : sınır değerleri // nbb = aranan bölgedeki köksayısı // int nb; int i; double x,fp,fc,dx; double xb[][]=new double[2][nbb]; nb=0; dx=(x2-x1)/n; x=x1; fp=f(x1); for (i=1;i<=n;i++) { x+=dx; fc=f(x); // eğer kök olan bölge bulunduysa..... if (fc*fp < 0.0 || fp==0) { xb[0][nb]=x-dx; xb[1][nb]=x; nb++; } fp=fc; if (nbb == nb) return xb; } if( nb == 0) JOptionPane.showMessageDialog(null,"arama tamamlandı kök olan bölge bulunamadı " ,"ARAMA SONUÇLARI UYARISI",JOptionPane.WARNING_MESSAGE); else if(nb<nbb) { JOptionPane.showMessageDialog(null,"arama tamamlandı sadece "+nb+" adet kök bulundu \n"+ "siz "+nbb+" adet kök için arama yaptırdınız","ARAMA SONUÇLARI UYARISI",JOptionPane.WARNING_MESSAGE); double xc[][]=new double[2][nb]; for (i=0;i<nb;i++) {xc[0][i]=xb[0][i];xc[1][i]=xb[1][i];} return xc; } return xb; } public static double brent(double x1,double x2) { //lineer olmayan denklemin kökü : brent metodu //referans : Numerical Recipes in C, second edition, William H. Press, //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery //cambridge university press double ITMAX=200; double EPS=3.0e-10; int iter; double a=x1,b=x2,c,d,e,min1,min2; double tol=1.0e-5; c=0; d=0; e=0; double fa=f(a),fb=f(b),fc,p,q,r,s,tol1,xm; if (fb*fa > 0.0) JOptionPane.showMessageDialog(null,"Kök sınırları doğru olarak seçilmemiş \n sonuç hatalı olabilir" ,"KÖK SINIRLARI SEÇİM UYARISI",JOptionPane.WARNING_MESSAGE); fc=fb; for (iter=1;iter<=ITMAX;iter++) { if (fb*fc > 0.0) { c=a; fc=fa; e=d=b-a; } if (Math.abs(fc) < Math.abs(fb)) { a=b; b=c; c=a; fa=fb; fb=fc; fc=fa; } tol1=2.0*EPS*Math.abs(b)+0.5*tol; xm=0.5*(c-b); if (Math.abs(xm) <= tol1 || fb == 0.0) return b; if (Math.abs(e) >= tol1 && Math.abs(fa) > Math.abs(fb)) { s=fb/fa; if (a == c) { p=2.0*xm*s; q=1.0-s; } else { q=fa/fc; r=fb/fc; p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0)); q=(q-1.0)*(r-1.0)*(s-1.0); } if (p > 0.0) q = -q; p=Math.abs(p); min1=3.0*xm*q-Math.abs(tol1*q); min2=Math.abs(e*q); if (2.0*p < (min1 < min2 ? min1 : min2)) { e=d; d=p/q; } else { d=xm; e=d; } } else { d=xm; e=d; } a=b; fa=fb; if (Math.abs(d) > tol1) b += d; else b += (xm > 0.0 ? Math.abs(tol1) : -Math.abs(tol1)); fb=f(b); } JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return b; } public static void main (String args[]) { double a[],x0,r; double dx=0.1; a=genislet(Double.parseDouble(JOptionPane.showInputDialog(" ilk tahmin değeri x0 : "))); r= brent(a[0],a[1]); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f(r)+"\nsınırlar: a="+a[0]+" b="+a[1], "brent yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); double b[][]=koksinirisapta(0.0,10.0,10,4); System.out.println(Matrix.toString(b)); b=koksinirisapta(b[0][0],b[1][0],10,4); System.out.println(Matrix.toString(b)); System.exit(0); } } Çıktı 4.12-1 Kök sınırlarını saptayan ve brent metoduyla kökü bulan FSCO6.java programı çıktısı 4.13 RIDDER METODU Daha önce Yer değiştirme (False position – Regula-falsi) metodunu incelemiştik. Ridder metodu bu metodun değiştirilmiş bir versiyonu olarak kabul edilebilir. x1 ve x2 noktaları arasında bir kök mevcut ise Ridder metodu önce orta noktada fonksiyonu değerlendirir. x3=(x1+x2)/2 daha sonra fonksiyonu lineer fonksiyona dönüştüren özel bir faktörü eQ faktörünü çözer. Daha açık yazacak olur isek f(x1)-2f(x3) eQ + f(x2) e2Q = 0 fonksiyonundan eQ faktörünü çözer. İkinci dereceden bir fonksiyon olan bu fonksiyonun kökleri f ( x3 ) sign[ f ( x2 )] f ( x3 ) 2 f ( x1 ) f ( x2 ) e f ( x2 ) Q şeklinde hesaplanır. Buradaki sign(x) fonksiyonu x in işaretini verecektir. Eğer x sıfırdan büyükse +1, eğer sıfırdan küçükse -1 değerini verecektir. Şimdi yer değiştirme metodu f(x1), f(x3) ve f(x2) fonksiyonlarını kullanarak değil f(x1), f(x3) eQ ve f(x2) e2Q fonksiyonlarına uygulanarak x4 kök değeri bulunur. sign[ f ( x1 ) f ( x2 )] f ( x3 ) x4 x3 ( x3 x1 ) f ( x3 ) 2 f ( x1 ) f ( x2 ) Denklem ikinci dereceden olduğundan ikinci derece yaklaşım sağlar . Aynı zamanda bulunan kök her zaman x1 ve x2 arasında yer alacaktır. Program 4.13-1 Ridder metoduyla kökü bulan FSCO7.java programı ///Bilgisayar programlama II ve Sayısal Çözümleme //ÖDEV 8 // f(x)=ln(x^2)-0.7 fonksiyonunun x0=0 x1=4 ilktahminini kulanarak // ridder yöntemi ile kökünü bulmak için bir // program geliştiriniz, kök değerini hesaplatınız import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return Math.log(x*x)-0.7;} } public class FSCO8 { // Ridder Metodu ile lineer olmıyan denklemlerin köklerinin bulunması //referans : Numerical Recipes in C, second edition, William H. Press, //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery //cambridge university press public static double SIGN(double a,double b) { return Math.abs(a)*b/Math.abs(b); } public static double ridder(f_x f, double x1, double x2) {double xacc=1.0e-9; return ridder(f, x1,x2,xacc); } public static double ridder(f_x f, double x1, double x2, double xacc) { int NRANSI; int MAXIT=64; double UNUSED=-1.11e30; int j; double ans,fh,fl,fm,fnew,s,xh,xl,xm,xnew; fl=f.func(x1); fh=f.func(x2); if ((fl > 0.0 && fh < 0.0) || (fl < 0.0 && fh > 0.0)) { xl=x1; xh=x2; ans=UNUSED; for (j=0;j<MAXIT;j++) { xm=0.5*(xl+xh); fm=f.func(xm); s=Math.sqrt(fm*fm-fl*fh); if (s == 0.0) return ans; xnew=xm+(xm-xl)*((fl >= fh ? 1.0 : -1.0)*fm/s); if (Math.abs(xnew-ans) <= xacc) return ans; ans=xnew; fnew=f.func(ans); if (fnew == 0.0) return ans; if (SIGN(fm,fnew) != fm) { xl=xm; fl=fm; xh=ans; fh=fnew; } else if (SIGN(fl,fnew) != fl) { xh=ans; fh=fnew; } else if (SIGN(fh,fnew) != fh) { xl=ans; fl=fnew; } else System.out.println("bu noktaya asla ulaşamayız."); if (Math.abs(xh-xl) <= xacc) return ans; } System.out.println("ridder metodu maksimum iterasyon sayısını aştı"); } else { if (fl == 0.0) return x1; if (fh == 0.0) return x2; System.out.println("ridderde verilen sınırlar arasında kök mevcut değil"); } return 0.0; } public static void main (String args[]) { fb f=new fb(); double a,b; a=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz a : ")); b=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz b : ")); double r; r= ridder(f,a,b); JOptionPane.showMessageDialog(null," kök değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Ridder yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.13-1 Ridder metoduyla kökü bulan FSCO7.java programı çıktısı 4.14 ÜÇÜNCÜ DERECEDEN POLİNOMUN KÖKLERİ İkinci dereceden polinomun köklerini bulma denklemini hepimiz biliriz. Üçüncü dereceden polinomun köklerini paralel, fakat biraz daha karışık olan bir denklem sistemi kullanarak bulabiliriz. Sınır değer problemi çözümünde ninci dereceden polinomun köklerini bulmayı da irdeleyeceğiz. Program 4.14-1 Üçüncü dereceden polinomun köklerini bulan program import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; import java.io.*; import java.text.*; import java.util.Locale; //import Numeric; class SCO13H { public static double[][] cubic_roots(double d[]) { // roots of a degree 3 polynomial // P(x)=d[3]*x^3+d[2]*x^2+d[1]*x+d[0]=0; // assuming d is all real; // if value of d will be entered bigger than d[3] // remaining terms will be ignored double x[][]=new double[2][3]; double a,b,c; a=d[2]/d[3]; b=d[1]/d[3]; c=d[0]/d[3]; //System.out.println("a="+a+"b="+b+"c="+c); double Q,R,theta; Q=(a*a-3.0*b)/9.0; double x1,x2,x3,x4; x1=2.0*a*a*a; x2=-9*a*b; x3=27*c; x4=x1+x2+x3; R=x4/54.0; //System.out.println("Q="+Q+"R="+R+"x1="+x1+"x2="+x2+"x3="+x3+"x4="+x4); double Q3=Q*Q*Q; double R2=R*R; double qq; //System.out.println("Q3="+Q3+"R2="+R2+(R2<Q3)); double A,B; if(R2<Q3) { qq=-2.0*Math.sqrt(Q); theta=Math.acos(R/Math.sqrt(Q3)); x[0][0]=qq*Math.cos(theta/3.0)-a/3.0; x[0][1]=qq*Math.cos((theta-2.0*Math.PI)/3.0)-a/3.0; x[0][2]=qq*Math.cos((theta+2.0*Math.PI)/3.0)-a/3.0; } else { A=-Math.pow((R+Math.sqrt(R2-Q3)),(1.0/3.0)); if(A==0) B=0; else B=Q/A; x[0][0]=(A+B)-a/3.0; x[0][1]=-0.5*(A+B)-a/3; x[1][1]=Math.sqrt(3.0)/2.0*(A-B); x[0][2]=-0.5*(A+B)-a/3; x[1][2]=-Math.sqrt(3.0)/2.0*(A-B); } return x; } public static complex[] cubic_rootsC(double c[]) { // roots of a degree 3 polynomial //return 3 complex roots double a[][]=new double[2][3]; a=cubic_roots(c); complex e[]=new complex[3]; for(int i=0;i<3;i++) e[i]=new complex(a[0][i],a[1][i]); return e; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main(String args[]) throws IOException { String s="üçüncü dereceden denklemin dört katsayısını aralarında boşluk bırakarak giriniz: "; double [] x0=verigir(s); complex z[]=cubic_rootsC(x0); String s1=""; for(int i=0;i<3;i++) {s1+=complex.toString(z[i])+"\n";} JOptionPane.showMessageDialog(null,s1, "üçüncü dereceden denklemin kökleri : ",JOptionPane.PLAIN_MESSAGE); } } Bu programda kullanılan kompleks değişken hesabını yapan complex sınıfı da program 4.4-3 de verilmiştir. Çıktı 4.14-1 Üçüncü dereceden polinomun köklerini bulan program 4.15 LE GUERRE METODU İLE POLİNOMLARIN KOMPLEKS KÖKLERİNİ BULMA Leguerre iteratif metodu n inci dereceden polinomun köklerini bulmak için aşağıdaki denklemleri kullanır. g ( x) [ f ' ( x)]2 xk 1 xk buradaki n f ( x) f " ( x) n 1 n f ( xk ) f ( xk ) (n 1) g ( xk ) ' g ( xk ) terimi kompleks olabilir.dolayısıyla bu metodu kompleks olarak yazmak daha doğrudur. Program 4.15-1 Leguerre yöntemi ile polinom köklerinin hesaplanması // // // kompleks Lequerre yöntemi ile polinomun kökünü bulmak // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class SCO4H { static complex func(double a[],complex x) { //complex polynomial int n=a.length; complex y=new complex(a[n-1]); for(int i=n-2;i>=0;i--) {y=complex.add(complex.multiply(y,x),a[i]);} return y; } static complex dfunc(double a[],complex x) {//complex numeric derivative of a polynomial double hh=0.001; complex h=new complex(hh,0.0); complex he=new complex(-hh,0.0); complex h2=new complex(2.0*hh,0.0); complex he2=new complex(-2.0*hh,0.0); complex xah=complex.add(x,h); complex xa2h=complex.add(x,h2); complex xeh=complex.add(x,he); complex xe2h=complex.add(x,he2); complex fe2h=complex.multiply(func(a,xe2h),(1.0/12.0)); complex feh=complex.multiply(func(a,xeh),(-8.0/12.0)); complex fah=complex.multiply(func(a,xah),(8.0/12.0)); complex fa2h=complex.multiply(func(a,xa2h),(-1.0/12.0)); complex df=complex.add(fe2h,complex.add(feh,complex.add(fah,fa2h))); df=complex.divide(df,h); return df; } static complex d2func(double a[],complex x) {//complex second numeric derivative of a polynomial double hh=0.001; complex h=new complex(hh,hh); complex hkare=complex.pow(h,2); complex he=new complex(-hh,-hh); complex h2=new complex(2.0*hh,2.0*hh); complex he2=new complex(-2.0*hh,-2.0*hh); complex xah=complex.add(x,h); complex xa2h=complex.add(x,h2); complex xeh=complex.add(x,he); complex xe2h=complex.add(x,he2); complex fe2h=complex.multiply(func(a,xe2h),(-1.0/12.0)); complex feh=complex.multiply(func(a,xeh),(4.0/3.0)); complex ff=complex.multiply(func(a,x),(-5.0/2.0)); complex fah=complex.multiply(func(a,xah),(4.0/3.0)); complex fa2h=complex.multiply(func(a,xa2h),(-1.0/12.0)); complex d2f=complex.add(fe2h,complex.add(feh,complex.add(ff,complex.add(fah,fa2h)))); d2f=complex.divide(d2f,hkare); return d2f; } public static complex Leguerre(double a[],complex x) { int n=a.length-1; double eps=1.0e-8; int m=50; int k=0; complex f0=func(a,x); complex f1=new complex(); complex f2=new complex(); complex g=new complex(); complex d1=new complex(); complex d2=new complex(); complex x0=x; complex x1=new complex((-a[0]/a[1]),0.0); do{ f1=dfunc(a,x0); f2=d2func(a,x0); g=complex.add(complex.multiply(f1,f1),complex.multiply(complex.multiply(f0,f2),(-(double)n/(double)(n-1)))); d1=complex.add(f1,complex.multiply(complex.pow(g,0.5),(double)(n-1))); d2=complex.add(f1,complex.multiply(complex.pow(g,0.5),(double)(1-n))); if(complex.abs(d1)>=complex.abs(d2)) x1=complex.add(x0,complex.multiply(complex.divide(f0,d1),(double)(-n))); else x1=complex.add(x0,complex.multiply(complex.divide(f0,d2),(double)(-n))); x0=complex.add(x1,0.0); f0=func(a,x0); k++; }while(complex.abs(f0)>eps && k<m); if(complex.abs(f0)<eps) { return x1;} JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x1; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { double a[]={-75,-5,4,-4,-1,1}; int n=a.length-1; double x0[]=verigir(" Fonksiyon değeri için ilk tahmin : "); complex x=new complex(x0[0],x0[1]); complex r=Leguerre(a,x); complex ff=func(a,r); String s="kök = "+r.toString()+"\n"+"Fonksiyon = "+ff.toString(); JOptionPane.showMessageDialog(null,s, "Leguerre yöntemiyle kök hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.15-1 Leguerre yöntemi ile polinom köklerinin hesaplanması Programda kullanılan complex sınıfı Program 4.4-3 olarak tanımlanmıştır. Bu bölüme kadar lineer olmıyan bir bilinmiyenli f(x) denkleminin çeşitli çözüm yöntemlerini irdeledik. Eğer birden fazla bilinmiyen varsa, bu bilinmeyenlerin köklerini bulmak için kök sayısı kadar denkleme ihtiyacımız vardır. Bu durumda lineer olmıyan bir denklem sisyeminin çözmekten veya köklerini bulmaktan bahsedebiliriz. Bölümümüzün bundan sonraki alt konularında çeşitli lineer olmayan denklem sistemi çözüm yöntemleri irdelenecektir. 4.16 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – NEWTON - RAPHSON YÖNTEMİ Bir boyutlu Newton-Raphson formülünde xn+1 = xn - f(xn) /f’(xn) formülüne ulaşmıştık. Bu formülü biraz değiştirirsek aynı formül xn+1 = xn+1 - xn = - f(xn) /f’(xn) f’(xn)*xn+1 = - f(xn) formunda yazılabilir. Şimdi aynı işlemi çok boyutlu bir denklem sisteminin köklerini bulma problemi olarak düşününelim. Türev denklemi: f1 x 1 f 2 x1 [f ] f 3 x1 ... f n x 1 f1 x2 f 2 x2 f 3 x2 ... f n x2 f1 x3 f 2 x3 f 3 x3 ... f n x3 ... ... ... ... ... f1 xn f 2 xn f 3 xn ... f n xn x1 f1 x f 2 2 {x} x3 { f } f 3 ... ... xn f n şeklinde verilebilir. Bu durumda Newton-raphson denklemi [f ] {x} = - { f } şeklini alır. Görüldüğü gibi denklemimiz bir lineer denklem sistemidir ve bir önceki bölümde gördüğümüz tekniklerle çözülebilir. Her çözümde {x} in yeni değerlerini elde edeceğimizden, bunlardan da yeni x değerlerini buluruz. Program 4.16-1 Çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) // SCO5 Newton Raphson metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; public class SCO5 { // Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak public static double[] f(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[2]; ff[0]=x[0]*x[0]+x[0]*x[1]-10.0; ff[1]=x[1]+3.0*x[0]*x[1]*x[1]-57.0; return ff; } public static double[][] df(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double a[][]=new double[2][2]; a[0][0]=4.0*x[0]+x[1]; a[0][1]=x[0]; a[1][0]=3.0*x[1]*x[1]; a[1][1]=1.0+6.0*x[0]*x[1]; return a; } public static double[] multiply(double[] left,double right) { //multiplying a vector with a constant int i; int n=left.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=right*left[i]; } return b; } public static double abs(double[] left) { // absolute value of a vector int i; int n=left.length; double b=0; for(i=0;i<n;i++) { b=b+Math.abs(left[i]); } return b; } public static double[] divide(double[] left,double[][] right) { return pivotlugauss(right,left); } //en kucuk kareler metodu public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] newton(double x[]) { // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi de tanımlanacaktır // Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü double ti=1.0; int i; int nmax=400; double tolerance=1.0e-20; int n=x.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=1.0; } i=0; while( i++ < nmax && abs(b) > tolerance ) { b=multiply(divide(f(x),df(x)),-ti); x=add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); System.out.println(); return x; } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { double [] x0=verigir(); double [] r= newton(x0); String s=" kök değerleri : \n"+Matrix.toStringT(r); String s1="çok değişkenli Newton-Raphson metodu ile kök bulma : "; JOptionPane.showMessageDialog(null,s,s1,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.16-1 Çok boyutlu lineer olmayan denklem çözümü(köklerini bulma) Newton-Raphson denkleminde en önemli problemlerden biri türevlerin değerlerinin gerekmesidir. Bu zorluğu türevleri sayısal yöntemlerle (fark denklemleri olarak) hesaplamaktır. Program 4.16-2 Çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) Türev matrisi sayısal olarak hesaplanıyor // SCO5 Newton Raphson metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fi_xi { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0] and f[1] // as a two dimensional vector abstract double[] func(double x[]); } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları //çözümü istenen fonksiyon double ff[]=new double[2]; ff[0]=x[0]*x[0]+x[0]*x[1]-10.0; ff[1]=x[1]+3.0*x[0]*x[1]*x[1]-57.0; return ff; } } public class FSCO5A { // Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak // Bu metod denklem sistemi çözümü için Matrix.java programını // kullanmaktadır. public static double[] newtond( fi_xi f,double x[]) { // lineer olmayan denklem siteminin kökleri // fj(xi)=0 lineer olmayan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi turev alt programıyla hesaplanır. // Newton-Raphson metodu ile lineer olmayan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-15; int n=x.length; double b[]; b=new double[n]; double dy[][]; dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { for(ii=0;ii<n;ii++) { for(jj=0;jj<n;jj++) { dy[ii][jj]=turev(f,x,ii,jj); } } b=Matrix.multiply(Matrix.divide(f.func(x),dy),-ti); x=Matrix.add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double turev(fi_xi f,double x[],int denklem_ref,int x_ref) { // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref} değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.0256; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //derivative of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; f1=f.func(x1); f2=f.func(x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fa f =new fa(); double [] x0=verigir(); String s2="türev fonksiyonları sayısal hesaplanmış Newton-Raphson kök bulma : "; double [] r1= newtond(f,x0); String s=" kök değerleri : \n"+Matrix.toStringT(r1); JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 4.17 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – SHERMAN MORRISON FORMÜLLÜ BROYDEN KİRİŞ YÖNTEMİ f(x)=0 lineer olmıyan denklem sistemini çözmek istiyoruz. Burada x={x1, x1,…, xn-1, xn} çok boyutlu değişken setidir. Bu durumda kiriş metodunu uygulayarak türev fonksiyonunu yaklaşık değerini oluşturabiliriz. Hatırlanacağı gibi, Newton-Raphson denkleminde f1 x 1 f 2 x1 [f ] f 3 x1 ... f n x 1 f1 x2 f 2 x2 f 3 x2 ... f n x2 f1 x3 f 2 x3 f 3 x3 ... f n x3 ... ... ... ... ... f1 xn f 2 xn f 3 xn ... f n xn x1 f1 x f 2 2 {x} x3 { f } f 3 ... ... xn f n şeklinde verilebilir. Bu durumda Newton-raphson denklemi [f ] {x} = - { f } şeklini alır. Burada [f ] yerine yaklaşık türev formülünden yararlanmak istersek f j xk ( x (i ) ) f j ( x (i ) ek h) f j ( x (i ) ) h gibi bir formülle hesaplayabiliriz. Formüldeki h küçük bir sonlu değişim miktarı, ek ise k inci bileşeni 1 diğer bileşenleri 0 olan bir vektördür. Buradaki (i) iterasyon sayısını belirtir. Kiriş yöntemi uygulandığında Newton-raphson formülünün kök civarındaki hızlı yakınsaması yerini daha yavaş bir yakınsama hızına bırakır. Bu yüzden burada standart kiriş yöntemi yerine yakınsama hızı birim hesaplama başına daha etkin olan Broyden yöntemini inceleyeceğiz. Broyden yönteminde x(0) ilk iterasyonu verilmiş ise x(1) iterasyonunuNewton metodunu kullanarak hesaplayabiliriz. Bundan sonraki stepler için şu yaklaşımı kullanırız : [f ( x(0) )] {x(1) x( 0) } = - { f ( x( 0) } denklemi [ A1 ] {x(1) x( 0) } = { f ( x(1) f ( x(0) } şeklini alabilir. Bu denklemin geçerli olabilmesi için [ A1 ] vektörünün her z vektörü için [ A1 ] {z} = [f ( x( 0) )]z [ A1 ] formülünü oluşturabiliriz. [ A1 ] f ( x ) (0) buradaki {x(1) x( 0) }t z 0 tanımlarını gerçekleştirmesi gerekir. Bu temel tanımdan [{ f ( x (1) ) f ( x ( 0) )} f ( x ( 0) )( x (1) x ( 0) )] * ( x (1) x ( 0) )t x (1) x ( 0) x (1) x ( 0) 2 2 2 2 ifadesi 2 normudur. Norm tanımları 3. bölümümüzde verilmişdi. [ A1 ] değerini bulduktan sonra x vektörünün yeni değerini oluşturabiliriz. 1 x( 2) x(1) A1 f ( x(1) ) x ( 2) bulunduktan sonra bu değeri aynı yolla x (3) ü hesaplamak için kullanırız. Genel olarak formülümüz [ Ai ] [ Ai 1 ] x ( i 1) [{ f ( x (1) ) f ( x ( 0) )} [ Ai 1 ]( x (1) x ( 0) )] * ( x (1) x ( 0) )t x (1) x ( 0) 1 2 2 x Ai f ( x ) (i ) (i ) formunu alır. Bu formülde her seferinde A matrisinin ters matrisini çözme zorunluluğumuz mevcuttur. Bu işlemi Gauss eleme yöntemi gibi bir yöntem kullanarak gerçekleştirebiliriz. Ancak Gauss yöntemide oldukça yüksek hesaplama zamanına ihtiyaç gösterir. Daha iyi bir alternatif iteratif Sherman-Morrison formülünü kullanmaktır. Sherman_Morrison formülü Ai-1 değerini direk olarak Ai-1-1 değerinden hesaplıyabilmemizi sağlar. Bu formülü şu stepleri kullanarak oluştururuz: si {x(1) x(i 1) } yi { f ( x(i ) ) f ( x(i 1) )} ( A xy t )1 A1 A1 xy t A1 1 y t A1 x 1 yi Ai 1si t 1 Ai A si 2 si 2 1 yi Ai 1si t 1 Ai1 si Ai 1 2 si 2 1 Ai A1 sit t 1 yi Ai 1si t 1 si Ai 1 si 2 si 2 1 t 1 (s A y )s A 1 Ai A1 i t i 11i i i 1 si Ai 1 yi 1 bu denklem sadece matris çarpımlarını kapsadığından toplam işlem olarak yapılması çok daha kolaydır. Bu denklemleri kullanarak oluşturulmuş Broyden algoritması Program 4.16-1 de verilmiştir. Program 4.17-1 Çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) Broyden metodu // SCO5E Sherman-Morrison formülü destekli broyden sekant metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak // Metod Referansı : Numerical Analysis, 8th edition Richard L. Burden, J. Douglas Faires 3 // sayfa 617 import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fi_xi { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0] and f[1] // as a two dimensional vector abstract double[] func(double x[]); } abstract class fij_xi { // multifunction multi independent variable // for n independent variable n*n matrix of // dependent variables are returned // example f[0][0]=x[0]+Math.sin(x[1]) f[0][1]=x[0]-x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=Math.exp(x[0]+x[1]*x[1] // func(x) returns the value of f[0][0], f[0][1] // f[1][0], f[1][1] // as a two dimensional matrix abstract double[][] func(double x[]); } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } class fb extends fij_xi { fi_xi f; public fb(fi_xi fi) {f=fi;} public double[][] func(double x[]) { int n=x.length; double a[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { a[i][j]=turev(x,i,j); } } return a; } public double turev(double x[],int denklem_ref,int x_ref) { // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref} değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.0256; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //derivative of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; f1=f.func(x1); f2=f.func(x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } } public class FSCO5E { // SCO5E Sherman-Morrison formülü destekli broyden sekant metoduyla //denklem sistemlerinin köklerini (çözümünü) bulmak public static double[] multiply(double left,double[] right) { //multiplying a vector with a constant int i; int n=right.length; double b[]; b=new double[n]; for(i=0;i<n;i++) {b[i]=left*right[i];} return b; } public static double[] multiply(double[][] left,double[] right) { //multiplication of one matrix with one vector int ii,jj,i,j,k; int m1=left[0].length; int n1=left.length; int m2=right.length; double[] b; b=new double[m2]; if(n1 != m2) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n1;ii++) { b[ii]=0; } return b; } for(i=0;i<m1;i++) { b[i]=0; for(k=0;k<n1;k++) b[i]+=left[i][k]*right[k]; } return b; //end of multiply of a matrix and a vector } public static double[] multiply(double[] left,double[][] right) { //multiplication of one vector with one matrix int ii,jj,i,j,k; int m2=right[0].length; int n2=right.length; int m1=left.length; double[] b; b=new double[m1]; if(n2 != m1) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n2;ii++) { b[ii]=0; } return b; } for(i=0;i<m2;i++) { b[i]=0; for(k=0;k<m1;k++) b[i]+=right[i][k]*left[k]; } return b; //end of multiply of a vector and a matrix } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[][] multiply(double left,double[][] right) { //multiplying a matrix with a constant int i,j; int n=right.length; int m=right[0].length; double b[][]; b=new double[n][m]; for(i=0;i<n;i++) { for(j=0;j<m;j++) b[i][j]=right[i][j]*left; } return b; //end of multiplying a matrix with a constant double } public static double[][] add(double[][] left,double[][] right) { //addition of two matrices int n1=left.length; int m1=left[0].length; int n2=right.length; int m2=right[0].length; int nMax,mMax; int i,j; if(m1>=m2) mMax=m1; else mMax=m2; if(n1>=n2) nMax=n1; else nMax=n2; double b[][]; b=new double[nMax][mMax]; for(i=0;i<n1;i++) { for(j=0;j<m1;j++) { b[i][j]=b[i][j]+left[i][j]; } } for(i=0;i<n2;i++) { for(j=0;j<m2;j++) { b[i][j]=b[i][j]+right[i][j]; } } return b; //end of matrix addition method } public static double[] substract(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]-right[i]; } return b; //end of vector addition method } public static double[][] inv(double[][] a) { // INVERSION OF A MATRIX // inversion by using gaussian elimination // with full pivoting int n=a.length; int m=a[0].length; double b[][]; b=new double[n][n]; int indxc[]; int indxr[]; double ipiv[]; indxc=new int[n]; indxr=new int[n]; ipiv=new double[n]; int i,j,k,l,ll,ii,jj; int icol=0; int irow=0; double big,dum,pivinv,temp; if(n!=m) { System.out.println("Matrix must be square "); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j]=a[i][j]; for(i=0;i<n;i++) { big=0.0; for(j=0;j<n;j++) { if(ipiv[j] != 1) for(k=0;k<n;k++) { if(ipiv[k] == 0) { if(Math.abs(b[j][k]) >= big) { big=Math.abs(b[j][k]); irow=j; icol=k; } } else if(ipiv[k] > 1 ) { System.out.println("error : inverse of the matrix : singular matrix-1"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } } } ++ ipiv[icol]; if(irow != icol) for(l=0;l<n;l++) { temp=b[irow][l]; b[irow][l]=b[icol][l]; b[icol][l]=temp; } indxr[i]=irow; indxc[i]=icol; if(b[icol][icol] == 0.0) { System.out.println("error : inverse of the matrix : singular matrix-2"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } pivinv=1.0/b[icol][icol]; b[icol][icol]=1.0; for(l=0;l<n;l++) b[icol][l] *=pivinv; for(ll=0;ll<n;ll++) if(ll != icol) { dum=b[ll][icol]; b[ll][icol]=0.0; for(l=0;l<n;l++) b[ll][l]-= b[icol][l]*dum; } } for(l=n-1;l>=0;l--) { if(indxr[l] != indxc[l]) for(k=0;k<n;k++) { temp=b[k][indxc[l]]; b[k][indxc[l]]=b[k][indxr[l]]; b[k][indxr[l]]=temp; } } return b; } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double[][] multiply(double[] left,double[] right) { //multiplication of one vector with one matrix int ii,jj,i,j,k; int m2=left.length; int n2=right.length; int m1=left.length; double[][] b; b=new double[m2][n2]; for(i=0;i<m2;i++) { for(k=0;k<n2;k++) b[i][k]=left[i]*right[k]; } return b; //end of multiply of a vector and a matrix } public static double[] broyden(fi_xi f,double x[]) { //==================================================== // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi J de tanımlanacaktır // Sherman-Morrison formülü uygulanmış broyden (kiriş tipi) metodu // ile lineer olmıyan denklem sistemi çözümü fb J=new fb(f); int i; int nmax=400; double tolerance=1.0e-15; int n=x.length; double b[]=new double[n]; double v[]=new double[n]; double s[]=new double[n]; double w[]=new double[n]; double y[]=new double[n]; double z[]=new double[n]; double p; double ut[]=new double[n]; double x1[]=new double[n]; double A[][]=new double[n][n]; x1=x; A=J.func(x1); v=f.func(x1); A=inv(A); s=multiply(-1.0,multiply(A,v)); x=add(x,s); int k=1; while(k<nmax) { w=v; v=f.func(x); y=substract(v,w); z=multiply(-1.0,multiply(A,y)); p=-VT_X(s,z); ut=multiply(s,A); //********* A=add(A,multiply((1.0/p),multiply(add(s,z),ut))); s=multiply(-1.0,multiply(A,v)); x=add(x,s); if(norm(s)<tolerance) break; k++; } return x; } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fa f =new fa(); double [] x0=verigir(); double [] r= broyden(f,x0); String s=" kök değerleri broyden : \n"+Matrix.toStringT(r); String s1="çok değişkenli broyden metodu ile kök bulma : "; JOptionPane.showMessageDialog(null,s,s1,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.17-1 Çok boyutlu lineer olmayan denklem çözümü (köklerini bulma), Broyden metodu 4.18 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – SÜREKLİLİK YÖNTEMİ F(x)=0 lineer olmıyan denklem sistemini çözmek istiyoruz. Bulmak istediğimiz çözüm setine x* diyelim. Şimdi 0 ile 1 arasında bir değeri alan bir problem seti düşünelim. Bu sette =0 değeri x(0) çözümüne karşı gelsin ve =1 değeri x(1)= x* çözüm setine karşı gelsin. G(x) fonksiyonunu G(x) = F(x) + (1- F(x) - F(x(0)) ] olarak tanımlayacak olur isek, ve bu denklemden G(x) = 0 çözümünü elde etmek istersek, kök değerini veren çözümler için =0 olduğunda 0=G(x) = F(x) - F(x(0)) olur. =1 olduğunda ise 0=G(x) = F(x) olur. Bu yüzden x(1)=x* çözüm setine eşit olacaktır. Öyleyse bu özellikleri sağlayan bir G(x) fonksiyonu bulabilirsek bu fonksiyonu F(x) fonksiyonunun çözümü için kullanabiliriz. G fonksiyonuna geçiş veya süreklilik fonksiyonu adı veriyoruz(=0 dan =1 e geçiş) Böyle bir fonksiyonu oluşturabilmek için G(x)=0 alınır ve bu fonksiyonun ya göre kısmi türevi alınırsa. 0 G( , x) G( , x) ' x ( ) buradan x’() çekilirse x 1 G( , x( ) G( , x( )) ' x ( ) x ( ) x ' G(x) = F(x) + (1- F(x) - F(x(0)) ] değerini bu denklemde yerine koya isek : f1 ( x( )) x1 G ( , x( ) f 2 ( x( )) x x f ( x(1 )) 3 x1 f1 ( x( )) x 2 f 2 ( x( )) x 2 f 3 ( x( )) x 2 f1 ( x( )) x3 f 2 ( x( )) J ( x ( ) x3 f 3 ( x( )) x3 Jakobiyen matristir. Ve G( , x( ) F ( x(0)) x diferansiyel denklem x ' ( ) dx( ) 1 J ( x( )) F ( x(0)) d 0 1 formunu alır. Bu diferansiyel denklem x(0) başlangıç değeri için çözülürse, çözümden elde edilen x(1) değeri bize G(x) = 0 denkleminin çözümünü verecektir. Bunun için herhangi bir diferansiyel denklem çözüm yöntemini kullanabiliriz. Örneğin dx( ) f ( , x( )) denkleminin çözümünü veren Dördüncü dereceden Runge-Kutta yöntemi : d xi+1 = xi + (1/6)*( k1 + 2k2 +2k3+k4)h k1=f(i,xi) k2=f(i+0.5h,xi+0.5k1h) k3=f(i+0.5h,xi+0.5k2h) k4=f(i+h,xi +k3h) formüllerini kullanarak diferansiyel denklemi step step çözebilir. Buradaki h step boyutudur. Çözüm , x0(0) ilk değerini kullanarak hesaplamaya başlar, ve her stepte değerine h ekleyerek değerine kadar devam eder. x0(1) değeri çözüm setimizdir. Diferansiyel denklemlerin çözümü daha detaylı olarak diferansiyel denklemler konusunda görülecektir. Diferansiyel denklemin çözümü bize çözüm fonksiyonunu verdiği için aynı zamanda denklemin köklerini de bulmuş oluruz. Program 4.18-1 de süreklilik denklemini 4 dereceden ve 6ıncı dereceden Runge-Kutta formülleri yardımı ile çözen süreklilik lineer olmıyan denklem çözme programı verilmiştir. Program 4.18-1 Süreklilik yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) // SCO5C Süreklilik(Continuation-homotopy) metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak // Metod Referansı : Numerical Analysis, 8th edition Richard L. Burden, J. Douglas Faires 3 // sayfa 637 // bu versiyon fonksiyonların türevini sayısal olarak almaktadır. // kullanıcının türev fonksiyonu tanımlaması gerekmez // süreklilik denklemleri bir önceki SCO5 ile aynı formda kalmıştır. // kullanıcının sadece fa fonksiyonunu oluşturması gerekmektedir. import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fi_xi { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0] and f[1] // as a two dimensional vector abstract double[] func(double x[]); } abstract class fij_xi { // multifunction multi independent variable // for n independent variable n*n matrix of // dependent variables are returned // example f[0][0]=x[0]+Math.sin(x[1]) f[0][1]=x[0]-x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=Math.exp(x[0]+x[1]*x[1] // func(x) returns the value of f[0][0], f[0][1] // f[1][0], f[1][1] // as a two dimensional matrix abstract double[][] func(double x[]); } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } class fb extends fij_xi { fi_xi f; public fb(fi_xi fi) {f=fi;} public double[][] func(double x[]) { int n=x.length; double a[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { a[i][j]=turev(x,i,j); } } return a; } public double turev(double x[],int denklem_ref,int x_ref) { // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref} değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.0256; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //derivative of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; f1=f.func(x1); f2=f.func(x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } } public class FSCO5C { // Süreklilik(Continuity-homotopy) metodu kullanarak denklem sisteminin köklerini bulmak // Bu metod denklem sistemi çözümü için Matrix.java programını // kullanmaktadır. public static double[] multiply(double left,double[] right) { //multiplying a vector with a constant int i; int n=right.length; double b[]; b=new double[n]; for(i=0;i<n;i++) {b[i]=left*right[i];} return b; } public static double[] multiply(double[][] left,double[] right) { //multiplication of one matrix with one vector int ii,jj,i,j,k; int m1=left[0].length; int n1=left.length; int m2=right.length; double[] b; b=new double[m2]; if(n1 != m2) { System.out.println("inner matrix dimensions must agree"); for(ii=0;ii<n1;ii++) { b[ii]=0; } return b; } for(i=0;i<m1;i++) { b[i]=0; for(k=0;k<n1;k++) b[i]+=left[i][k]*right[k]; } return b; //end of multiply of a matrix and a vector } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[][] inv(double[][] a) { // INVERSION OF A MATRIX // inversion by using gaussian elimination // with full pivoting int n=a.length; int m=a[0].length; double b[][]; b=new double[n][n]; int indxc[]; int indxr[]; double ipiv[]; indxc=new int[n]; indxr=new int[n]; ipiv=new double[n]; int i,j,k,l,ll,ii,jj; int icol=0; int irow=0; double big,dum,pivinv,temp; if(n!=m) { System.out.println("Matrix must be square "); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j]=a[i][j]; for(i=0;i<n;i++) { big=0.0; for(j=0;j<n;j++) { if(ipiv[j] != 1) for(k=0;k<n;k++) { if(ipiv[k] == 0) { if(Math.abs(b[j][k]) >= big) { big=Math.abs(b[j][k]); irow=j; icol=k; } } else if(ipiv[k] > 1 ) { System.out.println("error : inverse of the matrix : singular matrix-1"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } } } ++ ipiv[icol]; if(irow != icol) for(l=0;l<n;l++) { temp=b[irow][l]; b[irow][l]=b[icol][l]; b[icol][l]=temp; } indxr[i]=irow; indxc[i]=icol; if(b[icol][icol] == 0.0) { System.out.println("error : inverse of the matrix : singular matrix-2"); for(ii=0;ii<n;ii++) for(jj=0;jj<n;jj++) b[ii][jj]=0.0; return b; } pivinv=1.0/b[icol][icol]; b[icol][icol]=1.0; for(l=0;l<n;l++) b[icol][l] *=pivinv; for(ll=0;ll<n;ll++) if(ll != icol) { dum=b[ll][icol]; b[ll][icol]=0.0; for(l=0;l<n;l++) b[ll][l]-= b[icol][l]*dum; } } for(l=n-1;l>=0;l--) { if(indxr[l] != indxc[l]) for(k=0;k<n;k++) { temp=b[k][indxc[l]]; b[k][indxc[l]]=b[k][indxr[l]]; b[k][indxr[l]]=temp; } } return b; } public static double[] continuationRK4(fi_xi f,fij_xi J,double x[],int N) { //==================================================== // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi J de tanımlanacaktır // Homotopy, continuation (devamlılık) metodu ile lineer olmıyan denklem sistemi çözümü // 4.derece Runge-Kutta denklemi ile // yi+1 = yi + (1/6)*( k1 + 2k2 +2k3+k4)h // k1=f(xi,yi) // k2=f(xi+0.5h,yi+0.5k1h) // k3=f(xi+0.5h,yi+0.5k2h) // k4=f(xi+h,yi +k3h) //=================================================== // x : bağımsız değişken vektörü // y : bağımlı değişken vektörü // dy : bağımlı değişkenin türev fonksiyonları vektörü // N : Runge-Kutta diferansiyel denklem noktasayısı int i; int nmax=400; double tolerance=1.0e-20; int n=x.length; double h=1.0/(double)N; double b[]=new double[n]; double x1[]=new double[n]; double k[][]=new double[4][n]; double A[][]=new double[n][n]; b=multiply(-h,f.func(x)); for(i=0;i<N;i++) { x1=x; A=J.func(x1); k[0]=multiply(inv(A),b); x1=add(x,multiply(0.5,k[0])); A=J.func(x1); k[1]=multiply(inv(A),b); x1=add(x,multiply(0.5,k[1])); A=J.func(x1); k[2]=multiply(inv(A),b); x1=add(x,k[2]); A=J.func(x1); k[3]=multiply(inv(A),b); for(int j=0;j<n;j++) {x[j]=x[j]+1.0/6.0*(k[0][j]+2.0*k[1][j]+2.0*k[2][j]+k[3][j]);} } return x; } public static double[] continuationRK6(fi_xi f,fij_xi J,double x[],int N) { //==================================================== // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi J de tanımlanacaktır // Homotopy, continuation (devamlılık) metodu ile lineer olmıyan denklem sistemi çözümü // 6. derece Runge-Kutta denklemi ile // yi+1 = yi + (1/90)*( 7k1 + 32k3 +12k4+32k5+7k6)h // k1=f(xi,yi) // k2=f(xi+0.25h , yi+0.25k1h) // k3=f(xi+0.25h , yi+0.125k1h+0.125k2h) // k4=f(xi+0.5h , yi - 0.5k2h+k3h) // k5=f(xi+0.75h , yi + (3/16)k1h+(9/16)k4h) // k6=f(xi+h , yi - (3/7)k1h+(2/7)k2h+(12/7)k3h - (12/7)k4h+(8/7)k5h) //=================================================== // x : bağımsız değişken vektörü // y : bağımlı değişken vektörü // dy : bağımlı değişkenin türev fonksiyonları vektörü // N : Runge-Kutta diferansiyel denklem noktasayısı int i; int nmax=400; double tolerance=1.0e-20; int n=x.length; double h=1.0/(double)N; double b[]=new double[n]; double x1[]=new double[n]; double k[][]=new double[6][n]; double A[][]=new double[n][n]; b=multiply(-h,f.func(x)); for(i=0;i<N;i++) { A=J.func(x); // k1=f(xi,yi) k[0]=multiply(inv(A),b); x1=add(x,multiply(0.25,k[0])); A=J.func(x1); // k2=f(xi+0.25h , yi+0.25k1h) k[1]=multiply(inv(A),b); x1=add(x,add(multiply(0.125,k[0]),multiply(0.125,k[1]))); A=J.func(x1); // k3=f(xi+0.25h , yi+0.125k1h+0.125k2h) k[2]=multiply(inv(A),b); x1=add(x,add(multiply(-0.5,k[1]),k[2])); A=J.func(x1); // k4=f(xi+0.5h , yi - 0.5k2h+k3h) k[3]=multiply(inv(A),b); x1=add(x,add(multiply((3.0/16.0),k[0]),multiply((9.0/16.0),k[3]))); A=J.func(x1); // k5=f(xi+0.75h , yi + (3/16)k1h+(9/16)k4h) k[4]=multiply(inv(A),b); x1=add(x, add(multiply((-3.0/7.0),k[0]),add(multiply((2.0/7.0),k[1]), add(multiply((12.0/7.0),k[2]), add(multiply((-12.0/7.0),k[3]),multiply((8.0/7.0),k[4])))))); A=J.func(x1); // k6=f(xi+h , yi - (3/7)k1h+(2/7)k2h+(12/7)k3h - (12/7)k4h+(8/7)k5h) k[5]=multiply(inv(A),b); // yi+1 = yi + (1/90)*( 7k1 + 32k3 +12k4+32k5+7k6)h for(int j=0;j<n;j++) {x[j]=x[j]+1.0/90.0*(7.0*k[0][j]+32.0*k[2][j]+12.0*k[3][j]+32.0*k[4][j]+7.0*k[5][j]);} } return x; } public static double[] newton_continuationRK4(fi_xi f,fij_xi df,double x[]) { // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi de tanımlanacaktır // Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü x=continuationRK4(f,df,x,4); double ti=1.0; int i; int nmax=400; double tolerance=1.0e-10; int n=x.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=1.0; } i=0; while( i++ < nmax && Matrix.abs(b) > tolerance ) { b=Matrix.multiply(Matrix.divide(f.func(x),df.func(x)),-ti); x=Matrix.add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); System.out.println(); return x; } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fa f =new fa(); fb df=new fb(f); double [] x0=verigir(); double [] r= continuationRK4(f,df,x0,4); double [] r1= continuationRK6(f,df,x0,4); double [] r2= newton_continuationRK4(f,df,x0); String s=" kök değerleri süreklilik RK4 : \n"+Matrix.toStringT(r); s+=" kök değerleri süreklilik RK6 : \n"+Matrix.toStringT(r1); s+=" kök değerleri newton-süreklilik RK4 : \n"+Matrix.toStringT(r2); String s1="çok değişkenli süreklilik metodu ile kök bulma : "; JOptionPane.showMessageDialog(null,s,s1,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.18-1 Süreklilik yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) Süreklilik denklem çözüm yöntemini Newton yöntemi gibi bir yöntem için ilk değer tayini için de kullanabiliriz. 4.19 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – OPTİMİZASYON YÖNTEMLERİ : NELDER-MEAD AMİP YÖNTEMİ Bir adaptasyon fonksiyonu kullanarak kök çözüm problemini optimizasyon problemi haline getirebiliriz, ve optimizasyon problemini çözerek köklere ulaşabiliriz. Bu alt bölümde temelde bu yöntemin çeşitli optimizasyon metodlarına adapte ederek uygulanmasını inceleyeceğiz. fi(xj)=0 denklem sistemini çözmek için g(x j ) n _ denklem f (x i 0 i j ) *fi (x j ) denkleminin minimum değeri bulunmuştur. Aslında bir çok non-lineer denklem sisteminin geometrik yöntemlerle optimizasyon probleminin çözümü ile kök bulma metodları iç içedir. Çünki optimizasyon(minimum veya maksimum bulma işlemi) fonksiyonun türevinin kökünü bulma işlemi ile aynıdır. Nelder-Mead ya da amip yöntemi detaylarıyla optimizasyon konusunda (bölüm 5.19) verilmiştir. Lütfen detayları için ilgili bölümümüze bakınız. Burada verilen program da Nelder mead programının sadece çıktı kısmını içermektedir. Program detayları için lütfen OPO7B.java programını inceleyiniz( Program 5.9-1) Program 4.19-1 Nelder-Mead optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) // Nelder mead metodu ile denklem sistemi çözümü // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj {//adaptör sınıfı //optimizasyon problemleri kullanarak lineer olmıyan denklem sistemi kökü çözer fi_xi ff1; public f1(fi_xi ffi) {ff1=ffi;} public double func(double x[]) { //çözümü istenen fonksiyon double ff=0.0; double fa[]=ff1.func(x); for(int i=0;i<fa.length;i++) ff+=fa[i]*fa[i]; return ff; } } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } public class OPO7BDS { public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=OPO7B.verigir(s); double [] dx0=new double[x0.length]; for(int i=0;i<x0.length;i++) dx0[i]=0.2*x0[i]; fa ff=new fa(); f1 f=new f1(ff); double [] r1= OPO7B.nelder(f,x0,dx0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Nelder-Mead metodu ile lineer olmıyan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.19-1 Nelder-Mead optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) 4.20 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – OPTİMİZASYON YÖNTEMLERİ : GENETİK ALGORİTMA YÖNTEMİ Genetik algoritmalar bir optimizasyon yöntemi olarak detaylı bir şekilde anlatılmıştır. Bu detayları bölüm 5.24 de bulabilirsiniz. Burada sadece bu yöntemin istatistik tabanlı bir yöntem olduğunu ve çözüm setinde istatistiksel sapmalar bekleyebileceğimizi belirtmekle yetineceğiz. Önceki bölümlerimizde kullandığımız aynı örnek problemi bu bölümde de kullandık, çözüm setinin (0.499502180107804, -0.000026702982723, -0.523405164356859) çok kötü olmadığını söyleyebiliriz. Orijinal fonksiyonu – ile çarpıp 10 ilave ettiğimize dikkatinizi çekeriz. Genetik algoritmalar fonksiyonun maksimimunu bulurlar ve fonksiyonun positif değerleri için sonuç verirler. Program 4.20-1 Genetik algoritma optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) import java.io.*; class f1 extends f_xj {//adaptör sınıfı //optimizasyon problemleri kullanarak lineer olmıyan denklem sistemi kökü çözer fi_xi ff1; public f1(fi_xi ffi) {ff1=ffi;} public double func(double x[]) { //çözümü istenen fonksiyon double ff=0.0; double fa[]=ff1.func(x); for(int i=0;i<fa.length;i++) ff+=fa[i]*fa[i]; return 10-ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } class OPO17DS { public static void main(String args[]) throws IOException { int N=18; int POPSIZE=500; int MAXGENS=500; int NVARS=3; double PXOVER=0.2; double PMUTATION=0.05; fa ff=new fa(); f1 f_x=new f1(ff); Genetic1 xx=new Genetic1(POPSIZE,MAXGENS,NVARS,N,PXOVER,PMUTATION); double low[]=new double[NVARS]; double high[]=new double[NVARS]; low[0]=-1.0;high[0]=1.0; low[1]=-1.0;high[1]=1.0; low[2]=-1.0;high[2]=1.0; xx.setPopulation(low,high,f_x); System.out.println("best=\n"+Matrix.toStringT(xx.calculate(f_x,false))); } } Çıktı 4.20-1 Genetik algoritma optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) ---------- Capture Output ---------> "C:\co\java\bin\javaw.exe" OPO17DS best= 0.499502180107804 -0.000026702982723 -0.523405164356859 9.999982661442765 > Terminated with exit code 0. 4.21 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ – OPTİMİZASYON YÖNTEMLERİ : EN DİK YAMAÇ METODU Optimizasyon metodlarından olan en dik yamaç metodunun detayları optimizasyon konusunda bölüm 5.20 de verilmiştir. Burada detaylarına girmeyeceğiz. Bir önceki bölümde de belirttiğimiz gibi bu metod da lineer olmıyan denklem sistemlerinin köklerini bulmada kullanılabilir. Program 4.21-1 en dik yamaç optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) import javax.swing.*; import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.io.*; class f1 extends f_xj {//adaptör sınıfı //optimizasyon problemleri kullanarak lineer olmıyan denklem sistemi kökü çözer fi_xi ff1; public f1(fi_xi ffi) {ff1=ffi;} public double func(double x[]) { //çözümü istenen fonksiyon double ff=0.0; double fa[]=ff1.func(x); for(int i=0;i<fa.length;i++) ff+=fa[i]*fa[i]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } class f1dim extends f_x { // iki boyutlu fonksiyonu tek boyutlu fonksiyona çeviren // pseudo fonksiyon f_xj ff1; double pc[]; double xc[]; double xt[]; int n; public f1dim(f_xj ff,double pi[],double xi[]) { n=pi.length; ff1=ff; pc=new double[n]; xc=new double[n]; xt=new double[n]; for(int i=0;i<n;i++) {pc[i]=pi[i];xc[i]=xi[i];} } public double func(double x) { for (int j=0;j<n;j++) xt[j]=pc[j]+x*xc[j]; return ff1.func(xt); } } public class OPO8DS { public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=OPO8.verigir(s); fa ff=new fa(); f1 f_x=new f1(ff); double [] r1= OPO8.endikyamac(f_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="En dik yamaç lineer olmıyan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.21-1 en dik yamaç optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) 4.22 LİNEER OLMAYAN DENKLEM SİSTEMLERİNİN ÇÖZÜMÜ –OPTİMİZASYON YÖNTEMLERİ : DAVİDON-FLETCHER-POWELL METODU Davidon-Fletcher-Powell metodu optimizasyon metodundan çok lineer olmıyan denklem sistemi çözüm metodu olarak düşünülebilir,ancak burada da tek boyutlu optimizasyondan yararlanıldığından bu metodu da bu bölümde guruplayabiliriz. Metod detaylarını bölüm 5.23 de bulabilirsiniz. Bu örnek problemde de Bu bölümdeki Program 5.23.1 deki OPO12F.java probleminden adapte edilmiştir. Burada okuyucu haklı olarak böyle bir bölümün optimizasyon bölümünden sonra sunulmasını talep edebilir, ancak aralarındaki zincirleme ilişki hangisinin daha temel olduğunu sınıflamada zorluk yaratmaktadır. Örneğin Newton lineer olmıyan kök bulma metodu bire bir Newton lineer olmıyan optimizasyon metodunun temelini oluşturmaktadır. Program 4.22-1 Davidon-Fletcher-Powell optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj {//adaptör sınıfı //optimizasyon problemleri kullanarak lineer olmıyan denklem sistemi kökü çözer fi_xi ff1; public f1(fi_xi ffi) {ff1=ffi;} public double func(double x[]) { //çözümü istenen fonksiyon double ff=0.0; double fa[]=ff1.func(x); for(int i=0;i<fa.length;i++) ff+=fa[i]*fa[i]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fa extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]=new double[3]; ff[0]=3.0*x[0]-Math.cos(x[1]*x[2])-0.5; ff[1]=x[0]*x[0]-81.0*(x[1]+0.1)*(x[1]+0.1)+Math.sin(x[2])+1.06; ff[2]=Math.exp(-x[0]*x[1])+20.0*x[2]+(10.0*Math.PI-3.0)/3.0; return ff; } } public class OPO12FDS { public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=OPO12F.verigir(s); fa ff=new fa(); f1 f_x=new f1(ff); double [] r1= OPO12F.davidon_fletcher_powell(f_x,x0); double [] r2= OPO12F.davidon_fletcher_powell_V1(f_x,x0); s=" çözüm seti DFP : \n"+Matrix.toStringT(r1); s+=" çözüm seti düzeltilmiş DFP : \n"+Matrix.toStringT(r2); String s2="Davidon - Fletcher - Powell çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 4.22-1 Davidon-Fletcher-Powell optimizasyon yöntemi kullanarak çok boyutlu lineer olmayan denklem çözümü (köklerini bulma) 4.23 PROBLEMLER PROBLEM 1 r yarıçapındaki küresel bir tankın içindeki sıvının V hacmi derinliğine V= h2(3r - h) / 3 Şeklinde bağlıdır. r = 1 m ve V= 0.5 m3 olarak verildiğine göre h yi bulunuz. Not : geometrinin(küre) gereği h nin değeri 0 dan küçük, d=2r den büyük olamaz. Kabın alabileceği maksimum sıvı miktarı 4.18879 m3 dür (bu veriye problemi çözmek için ihtiyacınız yok, fikir edinebilmeniz için verilmiştir.) . Kök bulma sayısal çözümleme metodu metodu size bırakılmıştır (ikiye bölme, yer değiştirme, newton, sekant, müller...). Kullandığınız metodu ve formülü açık olarak belirtiniz. Çözüme başlarken önce formülü f(h) = 0 formuna getiriniz. PROBLEM 2 f(x) = x2 - 0.9x - 8.5 fonksiyonunun köklerini ikiye bölme yöntemi kullanarak bulunuz. PROBLEM 3 7 değerini kök bulma yöntemlerinden birini kullanarak hesaplayınız. PROBLEM 4 f ( x) x 2 sin(x) 4 değerini kök bulma yöntemlerinden birini kullanarak hesaplayınız. PROBLEM 5 f ( x) cos( x) cosh( x) 1 değerini kök bulma yöntemlerinden birini kullanarak hesaplayınız. PROBLEM 6 f ( x) x 4 8.6 x 3 35.5x 2 464.4 x 998.46 değerini kök bulma yöntemlerinden birini kullanarak hesaplayınız. x0=4 ve 7 x 8 değerlerini deneyiniz PROBLEM 7 f ( x) x 2 2e x x e 2 x fonksiyonunun tek bir çoklu gerçek kök değeri mevcuttur. Newton yöntemini kullanarak hesaplayınız. x0=1 PROBLEM 8 f ( x) x 4 7.223x 3 13.447 x 2 0.672 x 10.223 fonksiyonunun tüm gerçek köklerini bulunuz. PROBLEM 9 f ( x) tan( x) 2 x fonksiyonunun köklerini bulunuz. PROBLEM 10 Boru içi akışta türbülanslı akış için (Re>2300) borudaki sürtünme kat sayısı boru yüzey pürüzlülüğünün fonksiyonu olarak Colebrook denklemiyle hesaplanır. Colebrook denklemi : / D 1 2.51 2.0 log10 f 3.7 Re f bu denklemden hesaplanacak sürtünme katsayısına ilk yaklaşım için (f0) Olujic-Jain denklemini alabiliriz. Bu denklem : 2 2.185 14.5 f 4.0 1.737 ln 0.269 ln(0.269 ) formundadır. D Re D Re Laminer akışta sürtünme katsayısı(dairesel boru profili için) f=64/Re eşitliğinden hesaplanabilir. Re sayısı ve /D (pürüzlülük katsayısı/boru çapı) ve yerel basınç düşümü katsayısı verildiğinde borudaki toplam basınç düşümünü hesaplayan bir program yazınız ve test ediniz. Borudaki toplam basınç düşümü : DP= (K+f*L/D)**U2/2 DP : basınç düşümü K : yerel basınç düşüm katsayısı f :sürtünme katsayısı L boru boyu D boru çapı sıvı yoğunluğu U sıvı hızı PROBLEM 11 Dairesel pürüzsüz borularda türbülanslı akış bölgesinde Fanning sürtünme katsayısının hesaplanması için önerilen denklemlerden biri de aşağıdaki gibidir: 1/ f 1,737 * ln (. Re * f ) 0,4 Bu denklem 4 * 103 < Re < 3 * 106 aralığında geçerlidir. Reynolds sayısının 5000 değeri için fannning sürtünme katsayısını (f) hesaplayınız. Not 1: Önce kökün(f) bulunduğu aralığı hesaplayınız. Kök değeri (f) 0,001 ile 0.01 arasında değişmektedir. Not 2: S = % 0,01 olana dek işlemi sürdürünüz. PROBLEM 12 Gazlar için van der Waals denklemi : RT a 2 şeklindedir. Burada vb v 27 R 2Tc2 a 64 Pc RTc b 8Pc P olarak verilebilir.Redlich ve Kwong Denklemi P RT a şeklindedir. Burada v b v(v b)T 1 / 2 R 2Tc5 / 2 Pc RT b 0.08664 c Pc a 0.42748 O2, oksijen için Pc=5.04 MPa Tc=154.6 K M=31.999 kg/kmol olarak verilmiştir. N2, azot için Pc=3.39 MPa Tc=126.2 K M=28.013 kg/kmol olarak verilmiştir. Benedict -Webb-Rubin (BWR) denklemi RT RTB0 A0 C0 / T 2 RTb a a c v2 P ( 1 )e v v6 v3T 2 v2 v3 v2 Gaz O2 N2 A0 1.49880 1.1925 B0 0.046524 0.0458 C0.10-6 0.0038617 0.0058891 A -0.040507 0.01490 B -0.00027963 0.00198154 c.10-6 -0.00020376 0.000548064 .103 0.008641 0.291545 Java programı geliştirerek (Örnek programlardan yararlanabilirsiniz)T ve v verildiğinde P’yi hesaplayabilen, P ve v verildiğinde T yi hesaplayabilen, P ve T verildiğinde v’yi hesaplayabilen bir program geliştiriniz. A) van der Waals denklemi : gaz : oksijen ve azot B) Redlich Kwong denklemi : gaz oksijen ve azot C) Benedict-webb rubin denklemi : gaz : oksijen D) Benedict-webb rubin denklemi : gaz : azot RT Bulunan değerleri ideal gaz denklemi ile karşılaştırınız P v PROBLEM 13 f(x)=x e-x/2 + x3 + 1 fonksiyonunun köklerini x1=-1, x2=0, x3=1 alarak müler yöntemi ile çözünüz. PROBLEM 14 f(x)=x4-20x3-25x2+100x+130 fonksiyonunun köklerini Leguerre yöntemi ile çözünüz. PROBLEM 15 f(x)=x2+1 fonksiyonunun köklerini bulunuz. PROBLEM 16 4x12-20x1+0.25x22+8=0 0.5x1x22+2x1+8=0 denklem sisteminin köklerini a) Newton raphson yöntemi b) Süreklilik yöntemi c) Nelder-Mead yöntemi d) en dik yamaç yöntemi e) Genetik algoritma yöntemlerini kullanarak bulunuz, sonuçları karşılaştırınız. .103 0.359 0.75 PROBLEM 17 3x12-cos(x2x2) - 0.5=0 4x12-6.25x22+2x3-1=0 ex1 x2 +20x3+(10-3)/3=0 denklem sisteminin köklerini a) Newton raphson yöntemi b) Broyden kiriş yöntemi c) Süreklilik yöntemi d) Nelder-Mead yöntemi e) en dik yamaç yöntem i f) Genetik algoritma yöntemlerini kullanarak bulunuz, sonuçları karşılaştırınız . PROBLEM 18 x1(1- x1) + 4x3 – 12 =0 (x1-2)2+(2x2-3)2-25 =0 lineer olmıyan denklem sisteminin köklerini a) Newton raphson yöntemi b) Süreklilik yöntemi c) Nelder-Mead yöntemi d) en dik yamaç yöntemi e) Genetik algoritma yöntemlerini kullanarak bulunuz, sonuçları karşılaştırınız . PROBLEM 19 sin(4x1x2)-2x2-x1=0 4 1 2 x1 2 (e e) 4ex2 2ex1 0 4 lineer olmıyan denklem sisteminin köklerini a) Newton raphson yöntemi b) Süreklilik yöntemi c) Nelder-Mead yöntemi d) en dik yamaç yöntemi e) Genetik algoritma yöntemlerini kullanarak bulunuz, sonuçları karşılaştırınız . PROBLEM 20 10x1-2x22+x2-2x3-5=0 8x22+4x32-9=0 8x2x3+4=0 lineer olmıyan denklem sisteminin köklerini a) Newton raphson yöntemi b) Süreklilik yöntemi c) Nelder-Mead yöntemi d) en dik yamaç yöntemi e) Genetik algoritma yöntemlerini kullanarak bulunuz, sonuçları karşılaştırınız . PROBLEM 21 Paralel akışklı bir ısı değiştiricinin verimlilik deneyleri sonucu transfer ünitesi sayısı NTU=1.989 ve etkinliği ε = 0.574 olarak bulunmuştur. Isı değiştirici etkinliği (ε) 1 exp NTU (1 C * ) (1 C * ) denklemi ile tanımlanmaktadır. A) Denklemi sağlayan C* değerinin bulunduğu aralığı belirleyiniz. Bunun için ilk değeri C*=0.1, artımları da 0.1 olarak alınız, B) Yer değiştirme yöntemini kullanarak C* değerini hesaplayınız. εa < % 0.1 olana dek işlemi sürdürünüz. PROBLEM 22 Uzunluğu 5 cm, kesiti (0.1 cm × 20 cm) olan bir levhanın iki ucu 80 °C ve 60 °C sıcaklıkta tutulmaktadır. Çubuğun bulunduğu ortam T∞ = 10 °C sıcaklıkta ve olup ısı taşınım katsatısı h=15 W/m2 °C’dır. Çubuk kesit alanı A=2×10-4 m2, çubuk çevresi P=0.402 m’dir. Yapılan deneyde çubuğun orta noktasının (x=0.025 m) sıcaklığı T=67.5 °C olarak bulunmuştur. Bu koşullarda çubuktaki sıcaklık dağılımı T T 68.7 e 0.025m 11.3 e 0.025m denklemi ile verilmektedir. Bu denklemde m ( h P k A) 0.5 olarak tanımlanmaktadır. A) Sıcaklık dağılımı denklemini sağlayan m değerinin bulunduğu aralığı belirleyiniz. Bunun için ilk değeri m=5, artımları da 5 olarak alınız. B) NewtonRaphson yöntemini kullanarak m değerini hesaplayınız. εa < % 1 olana dek işlemi sürdürünüz. C) Bulacağınız değeri kullanarak malzemenin ısı iletim katsayısını (k) hesaplayınız. PROBLEM 23 Bir ısı değiştiricinin maliyet fonksiyonu (M), ısı değiştiricinin boyu (L) ve gövde çapının (D) fonksiyonu olup, M=900 + 1100 D2,5 L + 320 D L eşitliği ile tanımlanmaktadır. Yapılan optimizasyon çalışması sonucu ısı değiştiricinin maliyeti 1900 YTL, boyu ise 1,3 m elde edilmiştir. Bu verilere göre gövde çapını hesaplayınız. A) Kökün bulunduğu aralığı (gövde çapını 0,1 m arttırarak) bulunuz. B) Gövde çapını(D), ikiye bölme yöntemi ile hesaplayınız. Yaklaşık bağıl yüzde hata(εa) % 2 değerinden küçük olana dek işleme devam ediniz. Her adımda yaklaşık bağıl yüzde hatayı hesaplayınız. PROBLEM 24 20.000.000. TL değerindeki bir cihazı hiç peşin ödemeden 6 yılda geri ödemek üzere yılda 4.000.000. TL taksitle satın alıyorsunuz. Borcunuza uygulanan faizin değerini Sekant yöntemini kullanarak hesaplayınız.? Bugünkü değer P, yıllık ödeme A, yıl sayısı n ve faiz oranı i arasındaki bağıntı aşağıda verilmiştir. İp ucu: Kökün bulunduğu aralığı 0.05 artımla belirleyiniz ve yaklaşık kök bulunması işlemine alt sınırdan başlayınız. Yaklaşık kök hesaplamasını üç adım yürütünüz ve yaklaşık bağıl yüzde hatayı bulunuz. A P {i (1 i) n / [(1 i) n 1]} PROBLEM 25 Redlich- Kwong hal denklemi P [ R T /(v b)] a / [v (v b) T ] şeklinde verilmiştir. Burada R, gaz sabiti, T mutlak sıcaklık (K), P mutlak basınç (kPa), v, bir kg gazın hacmi (özgül hacim) (m3/kg) olup a ve b parametreleri ise: a = 0,427(R 2 Tc / Pc) ve b = 0,0866 (T c/ Pc) bağıntılarıyla hesaplanabilir. Burada Pc = 4600 kPa, Tc = 191 K’dir. Elde mevcut bir tankın hacmi 3 m3 olup içine –40 °C sıcaklıkta ve 65000 kPa basınçta metan gazı depolanmaktadır. Metan gazı için gaz sabiti R=0,518 kJ/kgK dir. a) Kökün (v) bulunduğu aralığı, b) Yer değiştirme yöntemini kullanarak bir kg gazın hacmini (v), c) Depolanacak metan gazı kütlesini bulunuz. Not: İşlemi üç adım yürütünüz ve her adımda yaklaşık bağıl yüzde hatayı hesaplayınız. PROBLEM 26 Bir maddeyi belli bir sıcaklığa kadar ısıtmak için gerekli enerji Q = m * Cp * dT eşitliği ile bulunmaktadır. Sıcaklığı 30 °C, kütlesi 0,2 kg olan bir madde 80 °C’da bozunmaktadır. Bu maddenin özgül ısısının sıcaklıkla değişimi: Cp =10 + 0,4 * T + 18 *10-4 * T2 (kcal/kg K) olarak verilmektedir. Bu maddeye 733,16 kcal değerinde enerji verilmektedir. A) Ulaşılacak sıcaklığın (kökün) bulunduğu aralığı hesaplayınız. İlk değeri 283 K, artımları ise 5 olarak alınız. B) Son sıcaklığı (kök değerini) ikiye bölme yöntemi ile hesaplayınız. İşleme εa= %2 olana dek devam ediniz. PROBLEM 27 Bir ısı değiştirici için yazılan enerji dengesi ve ısı transfer hız denklemleri birlikte çözüldüğünde sistem f 1 exp ( 0,508 / w ) 0,341 / w denklemi ile tanımlanmaktadır. Burada w (kg/s) kütlesel debidir. Bu koşullarda a) f = f(w) denkleminde kütlesel debinin (w) bulunduğu aralığı hesaplayınız. Debi 0,4 kg/s’den büyüktür, b) Newton-Raphson yöntemi ile debinin (w) değerini hesaplayınız. Kök hesaplama işlemini yaklaşık bağıl yanlış %0,5 olana dek sürdürünüz. PROBLEM 28 Kurutma süreçlerinde, kurutma havasından, kurutulan malzemeye ısı transferi taşınım yanında radyasyon ve iletimle olduğunda malzeme yüzey sıcaklığı T S 0,622 f= [1,56*(TG-TS)] / QV – (1/CP)*[---------------------------------------- - YG] {P- exp(4288/TS - 10,93) – 1} eşitliği ile bulunur. Burada CP =1,005+1,884*YG ve QV = 2501- 2,44*(TS-273) olarak tanımlanmaktadır. Kurutma havası sıcaklığı TG=70°C, nemi YG =0,01066 ise a) 0 °C ile 100 °C arasında kökün bulunduğu aralığı (artımları en fazla 10 °C olarak alınız), b) malzeme sıcaklığını Bisection yöntemi ile hesaplayınız. PROBLEM 29 Doğal dolaşımlı güneş enerjili sıcak su sisteminde kütlesel debi m(kg/sn) aşağıdaki eşitlikle hesaplanabilir. m =- AC * UL * F’ ----------------------------------------------------------UL * (TO-Tİ) CP * ln [ 1 - -------------------------------] S – UL * (Tİ-TA) Yapılan bir deneyde toplayıcı yüzeyinde absorbe edilen ışınım şiddeti S= 780 W/m2, çevre sıcaklığı TA=15 °C, akışkanın toplayıcıya giriş sıcaklığı T İ = 30 °C ve çıkış sıcaklığı TO = 40 °C, toplayıcı alanı AC = 4 m2, toplayıcı verim faktörü F’ = 0,91, suyun kütlesel debisi m= 0,0604 kg/sn olarak belirlenmiştir. Bu verilere göre toplayıcı ısı kayıp katsayısı UL’nin değerini False Position yöntemi ile hesaplayınız. Kök bulma işlemine başlamadan önce kökün bulunduğu aralığı belirleyiniz. 0 < UL < 10 olarak düşününüz. PROBLEM 30 f(x) = x3-6x2+11x-6.1 fonksiyonunun en büyük gerçek kökünü Newton-Raphson yöntemi kullanarak belirleyin 5 OPTİMİZASYON(MİNİMİZASYON VE MAKSİMİZASYON) 5.0 OPTİMİZASYONUN TANIMLANMASI VE GRAFİK YÖNTEMLE TEK BOYUTLU OPTİMİZASYON Optimizasyon minimizasyon ve maksimizasyon işlemlerine verilen genel bir isimdir. Temel matematik olarak baktığımızda tek boyutlu f(x) fonksiyonu için df(x)/dx = 0 f(x) fonksiyonunun minimum veya maksimumunu tanımlar. Temel tanım olarak minimum veya maksimum arasında işlemsel olarak bir fark yoktur, çünki maksimum (f(x)) = minimum(-f(x)) olarak yazılabilir. Bu yüzden sadece fonksiyonu -1 ile çarparak maksimum veya minimum bulma işlemleri arasına yer değiştirmek mümkündür. Tek boyutlu minimizasyon işlemine ilk örnek olarak grafik çizme yöntemini verelim. Bir fonksiyonun grafiğini çizerek (sabit aralıklarla fonksiyon değerini hesaplayarak) minimumun yeri çizilen grafiknoktalarının arasındaki boşluk hassasiyeti ile saptanabilir. Minimum noktaya yaklaştığınızda yeni daha küçük bir aralık saptıyarak fonksiyonu tekrar bu aralık için tarayabiliriz. Program 5.0-1 2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c fonksiyonu maksimumu veya – (2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c) fonksiyonu minimumunun grafik yöntemle bulunması import java.io.*; class fa1 extends f_x { double func (double c) { return -(2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c)); } } class PlotT02 { public static void main (String args[]) throws IOException { fa1 ff1=new fa1(); Plot pp=new Plot(ff1,0.0,10.0,400,0); pp.plot(); } } Çıktı 5.0-1 2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c fonksiyonu maksimumu veya – (2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c) fonksiyonu minimumunun grafik yöntemle bulunması Çıktı 5.0-2 2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c fonksiyonu maksimumu veya – (2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c) fonksiyonu minimumunun grafik yöntemle bulunmasında detaya inilmesi Program 5.0-1 de -1 2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c) fonksiyonunun grafiği çizdirilmektedir. Grafik programımız farenin kaoordinatlarını da yansıttığından farereyi minimumun üzerine getirerek ekrandan değeri detaylı olarak okuyabiliriz. Grafik kontrol sayfasıdan x ve y eksenlerinin minumum ve maksimum değerlerini elle değiştirerek optimum noktası civarını daha detaylı çizdirerek noktayı okuma kolaylığı da elde edebiliriz. Grafik yöntemini çok daha büyük adımlarla bir tarama olarak kullanırsak optimumun olduğu bölgeyi saptamak için de kullanabiliriz. 5.1 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-ALTIN ORAN (FİBONACCHİ) ARAMA 0,1,1,2,3,5,8,13,21,34,… serisine fibonacci serisi ismi verilir. Genel yazılımı F(n)=F(n-1)+F(n-2) şeklindedir. F(0)=0, F(1)=1 şeklide tanımlanmıştır. Fibonacci serisinin büyük oranlarında R= lim n F (n 1) 5 1 0.618033989 F ( n) 2 Peki bu oranı optimizasyonda nasıl kullanacağız? Verilen bir (a,c) bölgesinin hangi tarafında bir minimum(veya maksimum) olduğunu kestirebilmek için bu bölgedeki iki ara noktayı değerlendirmemiz gerekir. Minimum arıyorsak iki ara nokta bölgeyi 3 parçaya böleceği için minimum değerin saptandığı noktanın iki tarafındaki bölgeler kalır diğer bölgeyi atarız. Ancak yeni değerlendirmede yine iki ara noktaya ihtiyaç duyulur. Kendimize daha önce hesaplanan ara noktalardan biri tekrar yeni hesapta kullanılamazmı sorusunu sorarsak yanıtımız ara noktaların seçiminde altın oran kullanımı olacaktır. Şekil 5.1-1 Altın oran minimum arama prensibi. Şekil 5.1-1 de görüldüğü gibi a ve c noktaları arasında minimum değeri veren noktayı bulmaya çalışalım bölgenin uzunluğu d0=(c – a) olacaktır. b1 noktasını b1=a+d0*R b2 noktasını b2 = c – d0*R = a + d0*R2 olarak alır isek ve minimumun b1 noktasında olduğunu kabul edersek (b2-c) aralığı iptal olacaktır. yeni aralığımız d1=d0*R olacağından b1 noktasını b1=a+d1*R=a+d0*R2 olarak alırız bu bir önceki b2 noktasının aynısıdır. b2 noktasını b2 = c – d1*R = a + d1*R2 = a + d0*R3 olarak alırız. Bir nokta aynı olduğundan yeni eleme için sadece bir fonksiyon değerlendirmesine ihtiyacımız olacaktır. ve her yeni elemede noktaların biri (sağ veya soldan elememize göre değişerek) daima aynı kalacaktır. Program 5.1-1 Altın oran arama programı (minimizasyon için) // OPTIMİZASYON // ÖDEV 1 import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class fb extends f_x { public double func (double c) { return -(2.0*c/(4.0+0.8*c+c*c+0.2*c*c*c));} } public class FOPO1 { public static double golden(f_x f,double a,double b,double epsilon) {return golden(f,a,b,epsilon,1.0e-10,0);} public static double golden(f_x f,double a,double b) {return golden(f,a,b,1.0e-10,1.0e-10,0);} public static double golden(f_x f,double a,double b,double epsilon,double delta,int print) { // fonksiyonunun minimumunu bulur // not maximum f(x) = minimum (-f(x)) double r1 = (Math.sqrt(5.0)-1.0)/2.0; // golden ratio double r2 = r1*r1; double h = b - a; double ya = f.func(a); double yb = f.func(b); double c = a + r2*h; double d = a + r1*h; double yc = f.func(c); double yd = f.func(d); int k = 1; double dp,dy,p,yp; while ((Math.abs(yb-ya)>epsilon) || (h>delta)) { k++; if (yc<yd) { b = d; yb = yd; d = c; yd = yc; h = b - a; c = a + r2 * h; yc = f.func(c); } else { a = c; ya = yc; c = d; yc = yd; h = b - a; d = a + r1 * h; yd = f.func(d); }//end of if }//end of while dp = Math.abs(b-a); dy = Math.abs(yb-ya); p = a; yp = ya; if (yb<ya) { p = b; yp = yb; } if(print==1) {System.out.println("x min = "+p+"ymin = "+yp+"error of x ="+dp+"error of y"+dy); } return p; } public static void main (String args[]) { fb f=new fb(); double a,b; a=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz a : ")); b=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz b : ")); double r; System.out.println("x=0.5"+f.func(0.5)); System.out.println("x=1.5"+f.func(1.5)); r= golden(f,a,b,1.0e-10,1.0e-5,0); JOptionPane.showMessageDialog(null," optimizasyon değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Fibonacchi optimizasyon : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.1-1 Fibonacci (altın oran ) minimizasyon programı Örnek fonksiyon Çıktı 5.0-1 deki aynı fonksiyondur. 5.2 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-İKİNCİ DERECE POLİNOM METODLARI Altın arama metodu lineer bir arama metodudur, her zaman işimize yarar ancak çözüme ulaşması göreceli olarak yavaştır. Çözüme ulaşma hızını arttırmak ister isek ikinci dereceden bir arama yöntemine başvurabiliriz. 3 noktadan ikinci dereceden bir polinom geçmesi kuralını kök bulma bölümünde de kullanmıştık. Benzer bir yaklaşımla verilen 3 noktadan (a b ve c noktaları olsun) geçen parabolün minimum(veya maksimum) noktasını parabol denkleminin çözümünden elde edebiliriz. Parabolün minimum noktası d b 0.5( (c b) 2 [ f (a) f (b)] (a b) 2 [ f (c) f (a)] (c b) [ f (a) f (b)] (a b) [ f (c) f (a)] denklemini kullanarak elde edilebilir. D nokasını bulduktan sonra b noktası yerine d noktasınıalarak yeni bir iterasyon için hesabımıza devam ederiz. Şekil 5.2-1 ikinci derece polinom metodu ile minimum bulunması Program 5.2-1 ikinci derece polinom optimizasyonu /// OPTIMİZASYON // 2 derece polinom interpolasyon kullanarak optimizasyon import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class fb extends f_x { public double func (double x) { return x*x-2.0*x;} } public class FOPO2 { public static double polinom2derece(f_x f,double x0,double x2) {double x1=(x0+x2)/2.0; return polinom2derece(f,x0,x1,x2); } public static double polinom2derece(f_x f,double x0,double x1,double x2) { double epsilon=1.0e-10; double delta=1.0e-5; int print=0; return polinom2derece(f,x0,x1,x2,epsilon,delta,print); } public static double polinom2derece(f_x f,double x0,double x1,double x2,double epsilon,double delta,int print) { int maxit=100; double f0 = f.func(x0); double f1 = f.func(x1); double f2 = f.func(x2); double f3 = f2; double x3 = 0; double h = x1 - x0; double k=1; double dd=Math.abs(f1-f0); while ((dd >epsilon) || (h>delta)) { k++; x3=(f0*(x1*x1-x2*x2)+f1*(x2*x2-x0*x0)+f2*(x0*x0-x1*x1))/ (2*f0*(x1-x2)+2.0*f1*(x2-x0)+2.0*f2*(x0-x1)); f3=f.func(x3); if(x3 >= x0 && x3<x1) {x2=x1;f2=f1;x1=x3;f1=f3;} else if(x3 >= x1 && x3 <x2) {x0=x1;f0=f1;x1=x3;f1=f3; } else if(x3 >x2) {x0=x1;f0=f1;x1=x2;f1=f2;x2=x3;f2=f3; } else if(x3 < x0) {x0=x3;f0=f3;x1=x0;f1=f0;x2=x1;f2=f1; } dd=Math.abs(f1-f0); h=Math.abs(x1-x0); if(k>maxit) break; }//end of while if(print==1) {System.out.println("x = "+x3+"f = "+f3+"hata x ="+h+"hata f(x)=y "+dd); } return x3; } public static void main (String args[]) { fb f=new fb(); double x0,x1,x2; x0=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun alt sınırını giriniz x0 : ")); x1=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun orta sınırını giriniz x1 : ")); x2=Double.parseDouble(JOptionPane.showInputDialog(" Fonksiyonun üst sınırını giriniz x2 : ")); double r; r= polinom2derece(f,x0,x1,x2,1.0e-10,1.0e-5,1); JOptionPane.showMessageDialog(null," optimizasyon değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Polinom 2 derece optimizasyon : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.2-1 ikinci derece polinom optimizasyonu 5.3 BİR BİLİNMİYENLİ-LİNEER OLMAYAN KÜBİK POLİNOM ARAMA YÖNTEMİ Fonksiyonumuza üçüncü dereceden bir polinom olarak yaklaşarak, bu polinomun köklerini bulma işlemini bir önceki bölümdekine benzer bir şekilde gerçekleştirebiliriz. Hermite kübik polinomu P(x)=a(x-x0)3+b(x-x0)2+c(x-x0)+d alınacak olursa, bu polinomun dönüş noktası (minimum maksimum veya ektremum noktası) [x0,x1] aralığı için : x x0 b b 2 4ac formülünden hesaplanabilir. İterasyon formülümüz, minimum sağlamak için 3a x* x0 b b 2 4ac şeklinde yazılabilir. Bu polinomun a b c d katsayılarını bilmiyoruz. Bu 3a katsayıları bulmak için p(x0)=d=f(x0) p’(x0)=c=f’(x0) a=(G-2H)/h h =x1 – x0 b=3H-G F=[f(x1) - f(x0)]/h G==[f’(x1) – f’(x0)]/h H=[F – f’(x0)]/h Formülleri ile hesaplanabilir. Bir önceki quadratik formülde olduğu gibi burada da her bulunan nokta yeni bir noktanın bulunması için kullanılabilir. Formüllerde fonksiyonu kendinin yanında türev değerlerinin de bulunması gerekmektedir. Bu değerler program 5.3-1 de sayısal türevler kullanılarak oluşturulmuştur. Sayısal türev kavramı için ilgili bölümümüzü inceleyebilirsiniz. Program 5.3-1 üçüncü derece polinom optimizasyonu // // // Kübik arama yöntemi ile OPTİMİZASYON // // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return x+25.0/(x*x);} } //=========================================================== public class FSCO4E { public static double df(f_x f,double x,double h) { //Türev hesabı double hh=1.0/h; return (-f.func(x+2.0*h)+8.0*f.func(x+h)-8.0*f.func(x-h)+f.func(x-2.0*h))/12.0*hh; } public static double cubic_search_opt(f_x f,double x0,double x1) { int nmax=500; double tolerance=1.0e-15; double f0,f1,df0,df1,fxs,dfxs; double h=0.00001; double xs; int k=0; double X,F,G,H,a,b,c; f0=f.func(x0); f1=f.func(x1); df0=df(f,x0,h); df1=df(f,x1,h); while(Math.abs(x0-x1)>tolerance && k<nmax) { k++; X=1.0/(x1-x0); F=X*(f1-f0); G=X*(df1-df0); H=X*(F-df0); a=X*(G-2.0*H); b=3.0*H-G; c=df0; xs=x0+(Math.sqrt(b*b-3.0*a*c)-b)/(3.0*a); fxs=f.func(xs); dfxs=df(f,xs,h); if(dfxs > 0 ) {x1=xs;f1=fxs;df1=dfxs;} else x0=xs;f0=fxs;df0=dfxs; } if(k>=nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return (x0+x1)/2.0; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fb f=new fb(); double x[]=verigir("arama bölge sınırlarını giriniz: xo x1"); double r= cubic_search_opt(f,x[0],x[1]); JOptionPane.showMessageDialog(null," minimum değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "kübik arama yöntemi ile minimizasyon hesabı : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.3-2 kübik polinom optimizasyonu 5.4 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NEWTON-RAPHSON METODU Kök bulma işlemleri sırasında Newton-raphson yöntemini incelemiştik. Optimizasyonun temel tanımına geri dönersek Minimum (veya maksimum) f(x) demek df(x)/dx=0 anlamına geliyordu. Öyleyse Newton-Raphson metodu ile fonksiyonun türevinin kökünü bulursak burada fonksiyonun bir maksimum veya minimum veya extremun (dönme noktası) bulunacağı anlamına gelir. Minimum f(x)=0 g ( x) df ( x ) 0 dx Newton raphson formülü df ( x) g ( x) f ' ( x) xn1 xn xn 2dx xn dg ( x) d f ( x) f " ( x) 2 dx dx şeklinde yazılabilir. Program 5.3-1 de Newton-Raphson optimizasyon programı verilmiştir. Bu programda ikinci türevler sayısal olarak (fark denklemleri ile) bulunmaktadır. Program 5.4-1 Newton-Raphson optimizasyon programı /// OPTIMİZASYON // Newton kök bulma yöntemi (ve türev ) kullanarak optimizasyon import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class fc { public double func(double x) { return -(2.0*Math.sin(x)-x*x/10.0);} } class fb extends f_x { public double func(double x) { return -(2.0*Math.cos(x)-x/5.0);} } public class FOPO3 { public static double derivative(f_x df,double x) { // türev alt programı // df fonksiyonunun türevini hesaplar double h0=0.256; int i,m; int n=7; //derivative of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { T[i][0]=( df.func(x + h[i]) - df.func( x - h[i]))/(2.0*h[i]); } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/ (h[i]*h[i]- h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double newton(f_x df,double x) { // df ile verilen türev fonksiyonunun köklerini bulur int nmax=500; double tolerance=1.0e-15; double fx,dfx; for(int i=0;i<nmax;i++) { fx=df.func(x); dfx=derivative(df,x); x-=fx/dfx; if(Math.abs(fx)<tolerance) { return x; } } return x; } public static double newton_2nd_derivative(f_x df,double x) { // df ile verilen türev fonksiyonunun köklerini bulur int nmax=500; double dx=1e-3; double x1m; double tolerance=1.0e-15; double fx,fxm,dfx,dfxm,d2fx; for(int i=0;i<nmax;i++) { fx=df.func(x); fxm=df.func(x-dx); dfx=derivative(df,x); dfxm=derivative(df,(x-dx)); d2fx=-6.0/dx/dx*(fx-fxm)+2.0/dx*(2.0*dfx+dfxm); x-=(fx/dfx+.5*fx*fx/(dfx*dfx*dfx)*d2fx); if(Math.abs(fx)<tolerance) { return x; } } return x; } public static void main (String args[]) { fc f=new fc(); fb df=new fb(); double x0; x0=Double.parseDouble(JOptionPane.showInputDialog(" optimum nokta tahmini giriniz x0 : ")); double r; r= newton(df,x0); JOptionPane.showMessageDialog(null," optimizasyon değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton optimizasyon : ",JOptionPane.PLAIN_MESSAGE); r= newton_2nd_derivative(df,x0); JOptionPane.showMessageDialog(null," optimizasyon değeri : "+r+"\nFonksiyon değeri : "+f.func(r), "Newton 2nci türev optimizasyon : ",JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.4-1 Newton-Raphson optimizasyon programı 5.5 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK BRENT METODU x b 0.5( (b a) 2 [ f (b) f (a)] (b c) 2 [ f (b) f (a)] (b a) [ f (b) f (a)] (b c) [ f (b) f (c)] parabolik formülünü kullanarak minimuma ulaşabileceğimizi görmüştük. Ancak bu formülün temel bir hatası bulunmaktadır. Minimuma ulaşacağı yerde maksimuma ulaşması da mümkündür. Daha emniyetli bir yol izlemek istersek fonksiyon köke yeterince yaklaşmadan önce altın oran gibi daha emniyetli bir metodla gittikten sonra fonksiyonun minimum değere yaklaştığını gördüğümüzde ikinci derece polinom yaklaşımına geçebiliriz. Brent metodu bu işlevi sağlamak için geliştirilmiştir. Brent metodu bir iterasyonda 6 nokta kullanır. Bu noktalara a,b,u,v,w ve x dersek, tanımları şu şekilde yapılabilir. A ve b minimumun içinde bulunduğu bölgeyi gösterir. x o ana kadar bulunan minimuma en yakın noktadır. w, x den sonra gelen minimuma en yakın noktadır ve v w’dan sonra gelen minimuma en yakın noktadır. ayrıca a b bölgesinin orta noktasını x m olarak tanımlayabiliriz, ancak bu noktada fonksiyon hesaplanmaz. Önce x v ve w noktalarından bir parabolik eğri geçiririz. Yeni değerin kabul edilebilmesi için önce a – b bölgesinin içine düşmesi şarttır. Eğer bu şart gerçekleşiyor ise eğer bu gerçekleşmiş ise yeni hesaplanan değerin o ana kadar bulunan en iyi minimum değerinin altına düşmüş olması şartı aranır. Bu ikinci şart iterasyonun minimuma yaklaştığı güvencesini sağlar. Eğer minimum nokta bu kriteri sağlıyor ama yine de yeterince minimuma yaklaşamıyorsa araya bir altın oran arama stepi yerleştirilir. Yalız tek bir kötü adım için bu yapılmaz algoritma ikinci adımda kendini toparlayabilir, bu yüzden altın arama stepine geçilmeden önce bir-kaç adım beklenir. Aynı zamanda değerlendirilen iki nokta arasındaki mesafe daha önceden verilen toleransın altına düşmemelidir. Program 5.5-1 de brent minimizasyon algoritması verilmiştir. Şekil 5-4-1 de bu programdaki örnek fonksiyonun grafiği görülmektedir. Program 5.5-1 Brent optimizasyon programı /// OPTIMİZASYON // bir boyutlu lineer olmayan fonksiyonlar // brent metodu // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return -(2.0*Math.sin(x)-x*x/10.0);} //- değeri maksimumunu elde etmek için verilmiştir } //=========================================================== public class OPO9 { public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bx ax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static void main (String args[]) { String s="üç adetkök tahmin değerini değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=opt.verigir(s); fb f=new fb(); double r1= brent(f,x0[0],x0[1],x0[2],1.0e-8); s=" çözüm seti : "+r1+"\n fonksiyon değeri : "+(-f.func(r1)); //fonksiyonun gerçek değerini elde etmek için -1 ile çarpılmıştır String s2="Brent metodu ile lineer olmayan bir değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); Plot pp=new Plot(f,0,2,100); pp.plot(); } } Çıktı 5.5-1 Brent optimizasyon programı Şekil 5.5-1 Brent optimizasyon programında kullanılan fonksiyonun grafiği 5.6 BİR BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-TÜREVLİ BRENT METODU Türevli Brent metodu brent metoduna benzer, temel farkı burada a,b,c gibi 3 nokta alınması ve her yeni noktada fonksiyon değerinin yanında türev değerinin de kontrol edilmesidir. a b intervalinin ortasında yer alan c noktasının türevi bize minimumun sol tarafa mı yoksa sağ tarafamı düştüğü hakında bilgi verir. Böylece bir sonraki arama bölgesinin a-c mi yoksa c-b mi olduğunu bilebiliriz. c noktasın türevi ve ikinci derece interpolasyonla bulunan en iyi noktanın türev değerleri kiriş(sekant) metodu kullanılarak interpole edilir. Eğer yeterli dönüşüm olmuyorsa tekrar altın arama metodunun uygulanmasına gidilir. Program 5.6-1 Türevli Brent optimizasyon programı /// OPTIMİZASYON // bir boyutlu lineer olmayan fonksiyonlar // türevli brent metodu // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return -(2.0*Math.sin(x)-x*x/10.0);} } //=========================================================== public class OPO10 { public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double df(f_x f,double x) { // türev alt programı // df fonksiyonunun türevini hesaplar double h0=0.0256; int i,m; int n=7; //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { T[i][0]=( f.func(x + h[i]) - f.func( x - h[i]))/(2.0*h[i]); } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/ (h[i]*h[i]- h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double dbrent(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; // MOV3(a,b,c, d,e,f) (a)=(d);(b)=(e);(c)=(f); // {a=d;b=e;c=f} int iter; boolean ok1,ok2; double a,b,d,d1,d2,du,dv,dw,dx,e=0.0; d=0.0; double fu,fv,fw,fx,olde,tol1,tol2,u,u1,u2,v,w,x,xm; double xmin=bx; a=(ax < cx ? ax : cx); b=(ax > cx ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); dw=dv=dx=df(f,x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol1=tol*Math.abs(x)+ZEPS; tol2=2.0*tol1; if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; return xmin; } if (Math.abs(e) > tol1) { d1=2.0*(b-a); d2=d1; if (dw != dx) d1=(w-x)*dx/(dx-dw); if (dv != dx) d2=(v-x)*dx/(dx-dv); u1=x+d1; u2=x+d2; ok1 = (a-u1)*(u1-b) > 0.0 && dx*d1 <= 0.0; ok2 = (a-u2)*(u2-b) > 0.0 && dx*d2 <= 0.0; olde=e; e=d; if (ok1 || ok2) { if (ok1 && ok2) d=(Math.abs(d1) < Math.abs(d2) ? d1 : d2); else if (ok1) d=d1; else d=d2; if (Math.abs(d) <= Math.abs(0.5*olde)) { u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } else { d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); } } else { d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); } } else { d=0.5*(e=(dx >= 0.0 ? a-x : b-x)); } if (Math.abs(d) >= tol1) { u=x+d; fu=f.func(u); } else { u=x+SIGN(tol1,d); fu=f.func(u); if (fu > fx) { xmin=x; return xmin; } } du=df(f,u); if (fu <= fx) { if (u >= x) a=x; else b=x; //MOV3(v,fv,dv, w,fw,dw) {v=w;fv=fw;dv=dw;} //MOV3(w,fw,dw, x,fx,dx) {w=x;fw=fx;dw=dx;} //MOV3(x,fx,dx, u,fu,du) {x=u;fx=fu;dx=du;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { //MOV3(v,fv,dv, w,fw,dw) {v=w;fv=fw;dv=dw;} //MOV3(w,fw,dw, u,fu,du) {w=u;fw=fu;dw=du;} } else if (fu < fv || v == x || v == w) { //MOV3(v,fv,dv, u,fu,du) {v=u;fv=fu;dv=du;} } } } System.out.println("DBRENT maximum iterasyon sayısını aştı sonuç geçerli olmıyabilir"); return xmin; } public static void main (String args[]) { String s="üç adetkök tahmin değerini değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=opt.verigir(s); fb f=new fb(); double r1= dbrent(f,x0[0],x0[1],x0[2],1.0e-8); s=" çözüm seti : "+r1; String s2="türevli Brent metodu ile lineer olmayan bir değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); } } Çıktı 5.6-1 Türevli Brent optimizasyon programı 5.7 OPTİMİZASYON SINIR TAHMİN DEĞERLERİNİN İYİLEŞTİRİLMESİ Optimizasyon değerlerini herhangi bir optimizasyon yöntemi ile aramaya başlamadan önce sınır değerlerinin iyileştirilmesi yapılabilir. Böylece daha yakın bir tahmin değerinden interpolasyon işlemine geçerken minimum olan bir alan seçilmiş olduğuna emin olabiliriz. Mnbrak metodu 3 noktayla verilen arama bölgesini içinde bir minimum değer bulunana kadar genişletir. Bu işle için altın oran arama tekniğini kullanır. Program 5.7-1 mnbrak optimizasyon braket tayin programı /// OPTIMİZASYON // bir boyutlu lineer olmayan fonksiyonlar // brent metodu // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ class fb extends f_x { public double func (double x) { return -(2.0*Math.sin(x)-x*x/10.0);} //- değeri maksimumunu elde etmek için verilmiştir } //=========================================================== public class OPO11 { // 5. minumumu brakete alma (sınırlarını bulma) arama metodu // altın oran araması kullanır public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } // // veri giriş çıkış metodu //________________________________________________________________ public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="bir veya üç adet maksimum arama sınır tahmin değerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); fb f=new fb(); double r1[]; if(x0.length==3) {r1= opt.mnbrak(f,x0[0],x0[1],x0[2]);} else if(x0.length==1) {r1= opt.mnbrak(f,x0[0]);} else{System.out.println("Yanlış maksimum raama sınır tahmin değeri verdiniz, ilk değer üzerinden hesap yapılacaktır"); r1= mnbrak(f,x0[0]);} s=" yeni kök tahmin değerleri : \n"+Matrix.toString(r1); //fonksiyonun gerçek değerini elde etmek için -1 ile çarpılmıştır String s2="bir boyutta içinde optimum olan bölgeyi sağlama :"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); } } Çıktı 5.7-1 mnbrak optimizasyon braket tayin programı 5.8 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NEWTON-RAPHSON METODU f(x1,x2,x3,…,xn) fonksiyon seti verildiğinde, birinci, ikinci türevler ve x değerleri iterasyon farkları 2 f f x 2 x m1 m 1 21 ( x1 x1 ) f f m1 m ( x x ) x x 2 x2 2 1 2 m1 m1 m ( x3 x3 ) ve [ H ] 2 f f f ve x x1 x3 ... 3 ... m1 m ... ( xn xn ) 2 f f xn x1 xn 2 f x1 x2 2 f x22 2 f x1 x2 ... 2 f x2 xn 2 f x1 x3 2 f x21x3 2 f x32 ... 2 f x3 xn ... ... ... ... ... 2 f x1 xn 2 f x2 xn 2 f x1 xn ... 2 f xn2 şeklinde verilebilir. (m+1) inci iterasyon için Newton-Raphson denklemi H { m m1 } {f m } şeklinde yazılabilir. Görüldüğü gibi lineer bir denklem sistemi oluşmuştur ve her iterasyonda bu denklem sisteminin çözülmesi gerekir. Sistem çözüldüğünde tüm x değerlerinin yeni iteratif değerleri bulunur . ikinci türev H hessian matrisi ismini alır. Birinci ve ikinci türevler sayısal metodlarla da hesaplanabilir, ancak bu durumda hata olasılıkları doğal olarak artar. Bu denklem 1 { m1} H m {f m } olarak ta yazılabilir. Burada H m 1 Hesian matrisinin ters (inverse) matrisidir. Program 5.8-1 Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı (Birinci ve ikinci türevler ayrı fonksiyonlar olarak verilmiş) // SCO5 Newton Raphson metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fij_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0][0]=x[0]+sin(x[1]) f[0][1]=x[0]*x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=x[0]+x[1]*x[0] // func(x) returns the value of f[0][0] and f[0][1] // f[0][1] and f[1][1] // as a two dimensional vector // abstract double[][] func(double x[]); } abstract class fi_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0][0] // f[0][1] // as a two dimensional vector // abstract double[] func(double x[]); } abstract class f_xj extends Mathd { // single function multi independent variable // a single value is returned indiced to equation_ref // example f=x[0]+sin(x[1]) // // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double x[]); } class fxa extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fxb extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[]=new double[2]; ff[0]=6.0*x[0]-4.0*x[1]-1.0; ff[1]=-4.0*x[0]+4.0*x[1]-1.0; return ff; } } class fxc extends fij_xi { public double[][] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[][]=new double[2][2]; ff[0][0]=6.0;ff[0][1]=-4.0; ff[1][0]=-4.0;ff[1][1]=4.0; return ff; } } public class FSCO5G { // Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak // Bu metod denklem sistemi çözümü için Matrix.java programını // kullanmaktadır. public static double[] newtond( fi_xi f,fij_xi f1,double x[]) { // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi turev alt programıyla hesaplanır. // Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-15; int n=x.length; double b[]; b=new double[n]; double dy[][]; dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { for(ii=0;ii<n;ii++) { for(jj=0;jj<n;jj++) { dy[ii][jj]=dfx(f,x,ii,jj); } } b=multiply(divide(dy(f,x),H(f1,x)),-ti); x=add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[][]H(fij_xi f,double x[]) { //Hessian matris int n=x.length; double dy[][]=f.func(x); System.out.println(Matrix.toString(dy)); return dy; } public static double[] dy(fi_xi f,double x[]) { //birinci türev int n=x.length; double deltay[]=f.func(x); System.out.println(Matrix.toStringT(deltay)); return deltay; } public static double dfx(fi_xi f,double x[],int denklem_ref,int x_ref) { // Türev hesabı double h=0.001; double hh=1.0/h; int i,m; int n=x.length; double f1[]; f1=new double[n]; double f2[]; f2=new double[n]; double f3[]; f3=new double[n]; double f4[]; f4=new double[n]; double x1[]; x1=new double[n]; double x2[]; x2=new double[n]; double x3[]; x3=new double[n]; double x4[]; x4=new double[n]; for(i=0;i<n;i++) { x1[i]=x[i]; x2[i]=x[i]; x3[i]=x[i]; x4[i]=x[i]; } x1[x_ref]+=2.0*h; x2[x_ref]+=h; x3[x_ref]-=h; x4[x_ref]-=2.0*h; f1=f.func(x1); f2=f.func(x2); f3=f.func(x3); f4=f.func(x4); double fx=(f1[denklem_ref]+8.0*f2[denklem_ref]-8.0*f3[denklem_ref]+f4[denklem_ref])/12.0*hh; //System.out.println("f("+x_ref+","+denklem_ref+") = "+fx); return fx; } public static double[] multiply(double[] left,double right) { //multiplying a vector with a constant int i; int n=left.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=right*left[i]; } return b; } public static double abs(double[] left) { // absolute value of a vector int i; int n=left.length; double b=0; for(i=0;i<n;i++) { b=b+Math.abs(left[i]); } return b; } public static double[] divide(double[] left,double[][] right) { return pivotlugauss(right,left); } //en kucuk kareler metodu public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fxa f1 =new fxa(); fxb f2 =new fxb(); fxc f3 =new fxc(); double [] x0=verigir(); String s2="Newton-Raphson kök bulma : "; double [] r1= newtond(f2,f3,x0); String s=" kök değerleri : \n"+Matrix.toStringT(r1); JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.8-1Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı Program 5.8-2 Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı , Hessian matrix H sayısal türev kullanılarak hesaplanmış. // FSCO5H Newton Raphson metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak // ve optimizasyon import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fij_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0][0]=x[0]+sin(x[1]) f[0][1]=x[0]*x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=x[0]+x[1]*x[0] // func(x) returns the value of f[0][0] and f[0][1] // f[0][1] and f[1][1] // as a two dimensional vector // abstract double[][] func(double x[]); } abstract class fi_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0][0] // f[0][1] // as a two dimensional vector // abstract double[] func(double x[]); } abstract class f_xj extends Mathd { // single function multi independent variable // a single value is returned indiced to equation_ref // example f=x[0]+sin(x[1]) // // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double x[]); } class fxa extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fxb extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[]=new double[2]; ff[0]=6.0*x[0]-4.0*x[1]-1.0; ff[1]=-4.0*x[0]+4.0*x[1]-1.0; return ff; } } public class FSCO5H { // Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak // Bu metod denklem sistemi çözümü için Matrix.java programını // kullanmaktadır. public static double[] newtond( fi_xi f,double x[]) { // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi turev alt programıyla hesaplanır. // Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-10; int n=x.length; double b[]; b=new double[n]; double dy[][]; dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { b=multiply(divide(dy(f,x),H(f,x)),-ti); x=add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double dfx(fi_xi f,double x[],int denklem_ref,int x_ref) { // Türev hesabı double h=0.001; double hh=1.0/h; int i,m; int n=x.length; double f1[]; f1=new double[n]; double f2[]; f2=new double[n]; double f3[]; f3=new double[n]; double f4[]; f4=new double[n]; double x1[]; x1=new double[n]; double x2[]; x2=new double[n]; double x3[]; x3=new double[n]; double x4[]; x4=new double[n]; for(i=0;i<n;i++) { x1[i]=x[i]; x2[i]=x[i]; x3[i]=x[i]; x4[i]=x[i]; } x1[x_ref]+=2.0*h; x2[x_ref]+=h; x3[x_ref]-=h; x4[x_ref]-=2.0*h; f1=f.func(x1); f2=f.func(x2); f3=f.func(x3); f4=f.func(x4); double fx=(-f1[denklem_ref]+8.0*f2[denklem_ref]-8.0*f3[denklem_ref]+f4[denklem_ref])/12.0*hh; return fx; } public static double[][] H(fi_xi f,double x[]) { int n=x.length; double dy[][]=new double[n][n];; for(int ii=0;ii<n;ii++) { for(int jj=0;jj<n;jj++) { //Hessian matrisi dy[ii][jj]=dfx(f,x,ii,jj); } } System.out.println(Matrix.toString(dy)); return dy; } public static double[] dy(fi_xi f,double x[]) { //birinci türev int n=x.length; double deltay[]=f.func(x); System.out.println(Matrix.toStringT(deltay)); return deltay; } public static double[] multiply(double[] left,double right) { //multiplying a vector with a constant int i; int n=left.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=right*left[i]; } return b; } public static double[] divide(double[] left,double[][] right) { return pivotlugauss(right,left); } //en kucuk kareler metodu public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fxa f1 =new fxa(); fxb f2 =new fxb(); double [] x0=verigir(); String s2="Newton-Raphson kök bulma : "; double [] r1= newtond(f2,x0); String s=" kök değerleri : \n"+Matrix.toStringT(r1); JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.8-2 Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı (ikinci türev-Hessian matrisi sayısal olarak hesaplanmış) Program 5.8-3 Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı (Birinci ve ikinci türevler sayısal olarak hesaplanmış) // FSCO5I Newton Raphson metoduyla // birden fazla değişkenli denklem sisteminin köklerini bulmak // ve optimizasyon Hessian matris H sayısal olarak hesaplanmış, birinci türev de sayısal olarak hesaplanmış import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; //============= Tanımı gereken fonksiyon ================ abstract class fij_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0][0]=x[0]+sin(x[1]) f[0][1]=x[0]*x[1] // f[1][0]=x[0]*x[0]-x[1] f[1][1]=x[0]+x[1]*x[0] // func(x) returns the value of f[0][0] and f[0][1] // f[0][1] and f[1][1] // as a two dimensional vector // abstract double[][] func(double x[]); } abstract class fi_xi extends Mathd { // multifunction multi independent variable // vector of dependent variables are returned // example f[0]=x[0]+sin(x[1]) // f[1]=x[0]*x[0]-x[1] // func(x) returns the value of f[0][0] // f[0][1] // as a two dimensional vector // abstract double[] func(double x[]); } abstract class f_xj extends Mathd { // single function multi independent variable // a single value is returned indiced to equation_ref // example f=x[0]+sin(x[1]) // // func(x,1) returns the value of f[1] // func(x,0) returns the value of f[0] abstract double func(double x[]); } class fxa extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fxb extends fi_xi { f_xj fxx; fxb(f_xj fxi) {fxx=fxi;} public double[] func(double x[]) { // Türev hesabı double h=0.0013421432165; double hh=1.0/h; int i,m; int n=x.length; double f1; double f2; double f3; double f4; double x1[]; x1=new double[n]; double x2[]; x2=new double[n]; double x3[]; x3=new double[n]; double x4[]; x4=new double[n]; double fx[]=new double[n]; for(int j=0;j<n;j++) { for(i=0;i<n;i++) { x1[i]=x[i]; x2[i]=x[i]; x3[i]=x[i]; x4[i]=x[i]; } x1[j]+=2.0*h; x2[j]+=h; x3[j]-=h; x4[j]-=2.0*h; f1=fxx.func(x1); f2=fxx.func(x2); f3=fxx.func(x3); f4=fxx.func(x4); fx[j]=(-f1+8.0*f2-8.0*f3+f4)/12.0*hh; } return fx; } } public class FSCO5I { // Newton Raphson Metodunu kullanarak denklem sisteminin köklerini bulmak // Bu metod denklem sistemi çözümü için Matrix.java programını // kullanmaktadır. public static double[] newtond( fi_xi f,double x[]) { // lineer olmıyan denklem siteminin kökleri // fj(xi)=0 lineer olmıyan denklem sistemi için çözüm matrisi // türev matrisi dfj/dxi turev alt programıyla hesaplanır. // Newton-Raphson metodu ile lineer olmıyan denklem sistemi çözümü //ti :önem katsayısı //x bağımsız değişken vektörü //y bağımlı değişken vektörü //dy bağımlı değişkenin türev fonksiyonları vektörü double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-15; int n=x.length; double b[]; b=new double[n]; double dy[][]; dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { for(ii=0;ii<n;ii++) { for(jj=0;jj<n;jj++) { dy[ii][jj]=dfx(f,x,ii,jj); } } b=multiply(divide(dy(f,x),H(f,x)),-ti); x=add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double dfx(fi_xi f,double x[],int denklem_ref,int x_ref) { // Türev hesabı double h=0.00014354523465; double hh=1.0/h; int i,m; int n=x.length; double f1[]; f1=new double[n]; double f2[]; f2=new double[n]; double f3[]; f3=new double[n]; double f4[]; f4=new double[n]; double x1[]; x1=new double[n]; double x2[]; x2=new double[n]; double x3[]; x3=new double[n]; double x4[]; x4=new double[n]; for(i=0;i<n;i++) { x1[i]=x[i]; x2[i]=x[i]; x3[i]=x[i]; x4[i]=x[i]; } x1[x_ref]+=2.0*h; x2[x_ref]+=h; x3[x_ref]-=h; x4[x_ref]-=2.0*h; f1=f.func(x1); f2=f.func(x2); f3=f.func(x3); f4=f.func(x4); double fx=(-f1[denklem_ref]+8.0*f2[denklem_ref]-8.0*f3[denklem_ref]+f4[denklem_ref])/12.0*hh; //System.out.println("f("+x_ref+","+denklem_ref+") = "+fx); return fx; } public static double[][] H(fi_xi f,double x[]) { int n=x.length; double dy[][]=new double[n][n];; for(int ii=0;ii<n;ii++) { for(int jj=0;jj<n;jj++) { //Hessian matrisi dy[ii][jj]=dfx(f,x,ii,jj); } } System.out.println(Matrix.toString(dy)); return dy; } public static double[] dy(fi_xi f,double x[]) { //birinci türev int n=x.length; double deltay[]=f.func(x); System.out.println(Matrix.toStringT(deltay)); return deltay; } public static double[] multiply(double[] left,double right) { //multiplying a vector with a constant int i; int n=left.length; double b[]; b=new double[n]; for(i=0;i<n;i++) { b[i]=right*left[i]; } return b; } public static double[] divide(double[] left,double[][] right) { return pivotlugauss(right,left); } //en kucuk kareler metodu public static double[] pivotlugauss(double a[][],double b[]) { //kısmi pivotlu gauss eleme yöntemi int n=b.length; double x[]=new double[n]; double carpan=0; double toplam=0; double buyuk; double dummy=0; //gauss eleme int i,j,k,p,ii,jj; for(k=0;k<(n-1);k++) { //pivotlama p=k; buyuk=Math.abs(a[k][k]); for(ii=k+1;ii<n;ii++) { dummy=Math.abs(a[ii][k]); if(dummy > buyuk) {buyuk=dummy;p=ii;} } if(p!=k) { for(jj=k;jj<n;jj++) { dummy=a[p][jj]; a[p][jj]=a[k][jj]; a[k][jj]=dummy; } dummy=b[p]; b[p]=b[k]; b[k]=dummy; } //gauss elemeyi çözme for(i=k+1;i<n;i++) { carpan=a[i][k]/a[k][k]; a[i][k]=0; for(j=k+1;j<n;j++) { a[i][j]-=carpan*a[k][j]; } b[i] =b[i] -carpan*b[k]; } } //geriye doğru yerine koyma x[n-1]=b[n-1]/a[n-1][n-1]; for(i=n-2;i>=0;i--) { toplam=0; for(j=i+1;j<n;j++) { toplam+=a[i][j]*x[j];} x[i]=(b[i]-toplam)/a[i][i]; } return x; } public static double[] add(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]+right[i]; } return b; //end of vector addition method } public static double[] verigir() { String s=JOptionPane.showInputDialog("kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "); StringTokenizer token=new StringTokenizer(s); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { fxa f1 =new fxa(); fxb f2 =new fxb(f1); double [] x0=verigir(); String s2="Newton-Raphson kök bulma : "; double [] r1= newtond(f2,x0); String s=" kök değerleri : \n"+Matrix.toStringT(r1); JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.8-3 Çok bilinmiyenli lineer olmayan geometrik Newton-Raphson optimizasyon programı (birinci ve ikinci türev-Hessian matrisi sayısal olarak hesaplanmış) ÖRNEK PROBLEM 5.8-1 f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulunuz. 6 x 4 x1 1 21 6 4 f 0 [H ] 4 4 4 x1 4 x0 1 15 0.5 0.5 [ H ]1 0.5 0.75 x1 2 3 1 { m1} 01 H m {f m } 0.75 x1 2 x01 1 1 x1 1.25 5.9 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-NELDER VE MEAD SİMPLEKS METODU Nelder ve Mead tarafından geliştirilen çok boyutlu simpleks metodu olarak adlandırabileceğimiz metod bir anlamda tek boyutta yaptığımız altın arama metodunu çok boyuta yansıtma prosesidir. Simpleks n boyutlu bir geometrik şekildir. N boyutta (N+1) nokta içerir. İki boyuttaki simpleks bir üçgenden oluşur. Üç boyutta bir üçgenler prizması halini alır (4 yüzeyli). Bir boyutlu minimizasyon prosesinde minimumun sınırlarını saptamak olasıdır. Ancak çok boyuta geçtiğimizde bu olasılık ortadan kalkar. N boyutta en iyi yapabileceğimiz arama prosesine başlamak için N+1 nokta vermektir. Bundan sonra program yüzey topolojisini inceleyerek minimuma doğru hareket etmeye başlar. Bu hareketlerin esası şu şekilde oluşur : program verilen tüm noktalarda fonksiyonu analiz ederek en yüksek ve en düşük değerleri bulur, diğer noktaları aynı bırakarak en yüksek değeri en yüksek ve en düşük elemanların üzerinde olduğu yüzeye göre yansıma noktasına taşır. Minimizasyon doğrultusunda yeterli değişim yok ise yansıtma 1 faktöründen daha büyük yada daha küçük bir faktör kullanılarak ta gerçekleştirilebilir. Minimum değere yaklaştığımızda simpleks daralma ile küçülür, bu daralma proseside bir seferde birden fazla nokta için uygulanabilir. Şekil 5.9-1 de bu prosesleri geometrik olarak 3 boyutlu uzay simpleksi için (4 nokta) görüyoruz. Şekil 5.9-1 Nelder-Mead simpleks amip hareketleri N+1 nokta vererek nelder mead iteratif araştırmasına başlamak yerine bir nokta vererek ve bu noktayı xi-1 = Pi +dxj denklemi ile N+1 noktaya genişleterek N+1 noktamızı elde edebiliriz. bu denklemde eğer i=j =1 eğer i j =0 değeri alır. Yani örneğin a da P b ve dx db ise c dc a a da a a x0 b x1 b x 2 b db x3 b olacaktır. Böylece simplekse girdi olarak N+1 vektör c c c dc c yerine 2 vektör vererek nelder mead iterasyonuna başlayabiliriz. İterasyon stepleri şu şekilde gerçekleşir : 1. verilen N+1 Nokta için maksimum (en büyük), maksimumdan sonraki en büyük ve minimum fonksiyon değerlerini veren noktalar bulunur. 2. (yansıtma) maksimum değeri veren nokta tüm diğer noktaların ortalama değeri üzerinden yansıtılarak 1 yeni bir nokta elde edilir. xortalama xyeni1 = xortalama - xmaksimum xi n i i maksimum 3. (genişlemeli yansıtma) eğer elde edilen yeni noktanın değeri minimum noktsındaki değerden küçük ise yansıtma doğru yönde bir ilerleme sağlamış demektir, daha büyük ikinci bir yansıtma (genişleme) uygulanabilir: eğer f(xyeni1) < f(xminimum) xyeni2 = xyeni1 – (1-)xortalama burada birden küçük bir sayıdır. a. eğer f(xyeni2) < f(xminimum) xmaksimum = xyeni2 xmaksimum yerine xyeni2 değeri alınır. b. Değilse ) xmaksimum = xyeni1 xmaksimum yerine xyeni1 değeri alınır. 4. Şart 3 daha iyi bir değer vermemiş ise yansıtma prosesi bize iyi bir değer vermeyecek demektir, ancak f(xyeni1) değeri f(xmaksimum) ve f(xmaksimumdan bir küçük) değerleri arasında ise yine a. xmaksimum = xyeni1 alınabilir. b. Aynı zamanda yeni bir nokta araması 1 den küçük bir genleşme sayısı (büzülme) kullanılarak gerçekleştirilebilir. xyeni2 =xmaksimum – (1-)xortalama. Eğer bu proses başarılı ise f(xyeni2) < f(xmaksimum) xmaksimum = xyeni2 xmaksimum yerine xyeni2 değeri alınır. 5. Eğer yukarıdaki şartların hiçbiri başarı sağlamamış ise tüm simpleks elemanları minimumun 1 olduğu noktaya doğru büzülür. xi = (xi + xminimum) 2 6. böylece bir çevrim prosesi bitirilmiş olur ve aynı işleme yeni bir çevrim için başlanılır. Şekil 5.9-2 Nelder-Mead simpleks amip hareket serisi Şekil 5.9.2 de Nelder ve mead amipinin maksimuma ne şekilde yaklaştığı görülmektedir. Program 5.9.1 de bu işlemin programlanmış formu verilmiştir. Program 5.9-1 Nelder ve Mead simpleks optimizasyon arama programı // Newton metodu ile optimizasyon // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=(x[0]-2.0)*(x[0]-2.0)*(x[0]-2.0)*(x[0]-2.0)+(x[1]-1.0)*(x[1]-1.0)+ 3.0*(x[2]-1.0)*(x[2]-1.0)*(x[2]-1.0)*(x[2]-1.0)*(x[2]-1.0)*(x[2]-1.0); return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } public class OPO7B { //2. Nelder ve Mead metodu (simpleks arama metodu) //________________________________________________________________ public static double[] nelder(f_xj fnelder,double a[],double da[],int maxiteration,double tolerance,int printlist) { int i,j; double x[][]=new double[a.length+1][a.length]; double p[][]=new double[a.length+1][a.length+1]; for(i=0;i<x.length;i++) {for(j=0;j<x[0].length;j++) {if(i==j){x[i][j]=a[j]+da[j];p[i][j]=x[i][j];} else {x[i][j]=a[j];p[i][j]=x[i][j]; } } p[i][j] = fnelder.func(p[i]); } //System.out.println("x=\n"+Matrix.toString(x)); // Nelder mead çok boyutlu simplex minimizasyon metodu // Nelder & Mead 1965 Computer J, v.7, 308-313. // Giriş değişkenleri tanımlaması // fnelder : abstract çok boyutlu fonksiyon f(x) // x : for n boyutlu n+1 simlex noktasını içerir bağımsız değişken seti // maxiteration : maximum iterasyon sayısı // tolerance : int NDIMS = x.length-1; int NPTS = x.length; int FUNC = NDIMS; int ncalls = 0; ////// başlangıç simplexini oluştur ////////////////// //double p[][]=new double[NPTS][NPTS]; // [row][col] = [whichvx][coord,FUNC] double z[]=new double[NDIMS]; double best = 1E99; //////////////// iilk fonksiyon değerlerini hesapla //////////////// /* for (int i=0; i<NPTS; i++) { for (int j=0; j<NDIMS; j++) {p[i][j] = x[i][j];} p[i][NDIMS] = fnelder.func(p[i]); System.out.println("i="+i+"p=\n"+Matrix.toString(p)); } */ int iter=0; for (iter=1; iter<maxiteration; iter++) { //System.out.println("iter="+iter+"p=\n"+Matrix.toString(p)); /////////// lo, nhi, hi noktalarını tanımla ////////////// int ilo=0, ihi=0, inhi = -1; // -1 means missing double flo = p[0][FUNC]; double fhi = flo; double pavg,sterr; for (i=1; i<NPTS; i++) { if (p[i][FUNC] < flo) {flo=p[i][FUNC]; ilo=i;} if (p[i][FUNC] > fhi) {fhi=p[i][FUNC]; ihi=i;} } double fnhi = flo; inhi = ilo; for (i=0; i<NPTS; i++) if ((i != ihi) && (p[i][FUNC] > fnhi)) {fnhi=p[i][FUNC]; inhi=i;} //System.out.println("büyük y i="+fhi+" "+ihi+" ikinci büyük y i="+fnhi+" "+inhi+" küçük y i="+flo+" "+ilo); ////////// çıkış kriteri ////////////// if ((iter % 4*NDIMS) == 0) { //yi nin standart hata kriteri set değerinden (tolerance) // küçük olmalı // ortalama değeri hesapla (en büyük değer de dahil olmak üzere) pavg=0; for(i=0;i<NPTS;i++) pavg+=p[i][FUNC]; pavg/=NPTS; double tot=0; if(printlist!=0) { System.out.print(iter); for (j=0; j<=NDIMS; j++) { System.out.print(p[ilo][j]+" ");} System.out.println(""); } for(i=0;i<NPTS;i++) { tot=(p[i][FUNC]-pavg)*(p[i][FUNC]-pavg);} sterr=Math.sqrt(tot/NPTS); //if(sterr < tolerance) { for (j=0; j<NDIMS; j++) { z[j]=p[ilo][j];} //break; } best = p[ilo][FUNC]; } ///// ave[] vektorünü en büyük değeri hariç tutarak hesapla ////// double ave[] = new double[NDIMS]; for (j=0; j<NDIMS; j++) ave[j] = 0; for (i=0; i<NPTS; i++) if (i != ihi) for (j=0; j<NDIMS; j++) ave[j] += p[i][j]; for (j=0; j<NDIMS; j++) ave[j] /= (NPTS-1); ///////// yansıt //////////////// double r[] = new double[NDIMS]; for (j=0; j<NDIMS; j++) r[j] = 2*ave[j] - p[ihi][j]; double fr = fnelder.func(r); if ((flo <= fr) && (fr < fnhi)) // in zone: accept { for (j=0; j<NDIMS; j++) p[ihi][j] = r[j]; p[ihi][FUNC] = fr; continue; } if (fr < flo) //// genişlet, else kabul et { double e[] = new double[NDIMS]; for (j=0; j<NDIMS; j++) e[j] = 3*ave[j] - 2*p[ihi][j]; double fe = fnelder.func(e); if (fe < fr) { for (j=0; j<NDIMS; j++) p[ihi][j] = e[j]; p[ihi][FUNC] = fe; continue; } else { for (j=0; j<NDIMS; j++) p[ihi][j] = r[j]; p[ihi][FUNC] = fr; continue; } } ///////////// daralt: if (fr < fhi) { double c[] = new double[NDIMS]; for (j=0; j<NDIMS; j++) c[j] = 1.5*ave[j] - 0.5*p[ihi][j]; double fc = fnelder.func(c); if (fc <= fr) { for (j=0; j<NDIMS; j++) p[ihi][j] = c[j]; p[ihi][FUNC] = fc; continue; } else /////// daralt { for (i=0; i<NPTS; i++) if (i != ilo) { for (j=0; j<NDIMS; j++) p[i][j] = 0.5*p[ilo][j] + 0.5*p[i][j]; p[i][FUNC] = fnelder.func(p[i]); } continue; } } if (fr >= fhi) /// { double cc[] = new double[NDIMS]; for (j=0; j<NDIMS; j++) cc[j] = 0.5*ave[j] + 0.5*p[ihi][j]; double fcc = fnelder.func(cc); if (fcc < fhi) { for (j=0; j<NDIMS; j++) p[ihi][j] = cc[j]; p[ihi][FUNC] = fcc; continue; } else ///////// { for (i=0; i<NPTS; i++) if (i != ilo) { for (j=0; j<NDIMS; j++) p[i][j] = 0.5*p[ilo][j] + 0.5*p[i][j]; p[i][FUNC] = fnelder.func(p[i]); } } } } return z; } public static double[] nelder(f_xj fnelder,double a[],double da[],double tolerance) {return nelder(fnelder,a,da,500,tolerance,0);} public static double[] nelder(f_xj fnelder,double a[],double da[]) {return nelder(fnelder,a,da,500,1.0e-10,0);} // veri giriş çıkış metodu //________________________________________________________________ public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); double [] dx0=new double[x0.length]; for(int i=0;i<x0.length;i++) dx0[i]=0.2*x0[i]; f1 f=new f1(); double [] r1= nelder(f,x0,dx0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Nelder-Mead metodu ile lineer olmıyan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.9-1 Nelder ve Mead simleks optimizasyon arama programı ÖRNEK PROBLEM Bir örnek olarak işlemin detaylarına bakacak olursak : f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulalım ilk 50 iterasyonun sonuçları nelder_mead_ornek_sonuc.txt dosyasında yer almaktadır. Çıktı 5.9-2 Nelder ve Mead simpleks optimizasyon arama örnek çıktısı iter=1p= -2.400000000000000 -2.000000000000000 -2.000000000000000 2.000000000000000 2.400000000000000 2.000000000000000 44.879999999999995 42.320000000000000 36.000000000000000 büyük y i=44.879999999999995 0 ikinci büyük y i=42.32 1 küçük y i=36.0 2 iter=2p= -1.200000000000000 2.600000000000000 28.920000000000005 -2.000000000000000 2.400000000000000 42.320000000000000 -2.000000000000000 2.000000000000000 36.000000000000000 büyük y i=42.32 1 ikinci büyük y i=36.0 2 küçük y i=28.920000000000005 0 iter=3p= -1.200000000000000 2.600000000000000 28.920000000000005 -0.800000000000001 2.100000000000000 16.160000000000014 -2.000000000000000 2.000000000000000 36.000000000000000 büyük y i=36.0 2 ikinci büyük y i=28.920000000000005 0 küçük y i=16.160000000000014 1 iter=4p= -1.200000000000000 2.600000000000000 28.920000000000005 -0.800000000000001 2.100000000000000 16.160000000000014 0.999999999999999 3.050000000000002 5.355000000000019 büyük y i=28.920000000000005 0 ikinci büyük y i=16.160000000000014 1 küçük y i=5.355000000000019 2 iter=5p= 1.399999999999998 2.550000000000002 0.655000000000011 -0.800000000000001 2.100000000000000 16.160000000000014 0.999999999999999 3.050000000000002 5.355000000000019 büyük y i=16.160000000000014 1 ikinci büyük y i=5.355000000000019 2 küçük y i=0.6550000000000114 0 iter=6p= 1.399999999999998 2.550000000000002 0.655000000000011 3.199999999999998 3.500000000000003 3.719999999999994 0.999999999999999 3.050000000000002 5.355000000000019 büyük y i=5.355000000000019 2 ikinci büyük y i=3.7199999999999944 1 küçük y i=0.6550000000000114 0 iter=7p= 1.399999999999998 2.550000000000002 0.655000000000011 3.199999999999998 3.500000000000003 3.719999999999994 1.649999999999998 3.037500000000002 1.885312500000012 büyük y i=3.7199999999999944 1 ikinci büyük y i=1.8853125000000115 2 küçük y i=0.6550000000000114 0 iter=8p= 1.399999999999998 2.550000000000002 0.655000000000011 2.362499999999998 3.146875000000002 1.302519531250004 1.649999999999998 3.037500000000002 1.885312500000012 büyük y i=1.8853125000000115 2 ikinci büyük y i=1.3025195312500042 1 küçük y i=0.6550000000000114 0 iter=9p= 1.399999999999998 2.550000000000002 0.655000000000011 2.362499999999998 3.146875000000002 1.302519531250004 2.112499999999998 2.659375000000002 0.288925781250000 büyük y i=1.3025195312500042 1 ikinci büyük y i=0.6550000000000114 0 küçük y i=0.2889257812500001 2 iter=10p= 1.399999999999998 2.550000000000002 0.655000000000011 1.149999999999998 2.062500000000001 -0.224687499999993 2.112499999999998 2.659375000000002 0.288925781250000 büyük y i=0.6550000000000114 0 ikinci büyük y i=0.2889257812500001 2 küçük y i=-0.22468749999999327 1 iter=11p= 1.862499999999998 2.171875000000001 -0.374042968750002 1.149999999999998 2.062500000000001 -0.224687499999993 2.112499999999998 2.659375000000002 0.288925781250000 büyük y i=0.2889257812500001 2 ikinci büyük y i=-0.22468749999999327 1 küçük y i=-0.3740429687500022 0 iter=12p= 1.862499999999998 1.149999999999998 0.899999999999998 2.171875000000001 2.062500000000001 1.575000000000000 -0.374042968750002 -0.224687499999993 -0.753749999999998 büyük y i=-0.22468749999999327 1 ikinci büyük y i=-0.3740429687500022 0 küçük y i=-0.7537499999999975 2 iter=13p= 1.862499999999998 2.171875000000001 -0.374042968750002 1.612499999999998 1.684375000000000 -0.686386718750004 0.899999999999998 1.575000000000000 -0.753749999999998 büyük y i=-0.3740429687500022 0 ikinci büyük y i=-0.6863867187500037 1 küçük y i=-0.7537499999999975 2 iter=14p= 0.649999999999998 1.087499999999999 -0.932187499999998 1.612499999999998 1.684375000000000 -0.686386718750004 0.899999999999998 1.575000000000000 -0.753749999999998 büyük y i=-0.6863867187500037 1 ikinci büyük y i=-0.7537499999999975 2 küçük y i=-0.9321874999999984 0 iter=15p= 0.649999999999998 1.087499999999999 -0.932187499999998 1.193749999999998 1.507812500000000 -1.079252929687500 0.899999999999998 1.575000000000000 -0.753749999999998 büyük y i=-0.7537499999999975 2 ikinci büyük y i=-0.9321874999999984 0 küçük y i=-1.0792529296874995 1 iter=16p= 0.649999999999998 1.087499999999999 -0.932187499999998 1.193749999999998 1.507812500000000 -1.079252929687500 0.943749999999998 1.020312499999998 -1.061674804687500 büyük y i=-0.9321874999999984 0 ikinci büyük y i=-1.0616748046875 2 küçük y i=-1.0792529296874995 1 iter=17p= 0.859374999999998 1.175781249999999 -1.096405029296875 1.193749999999998 1.507812500000000 -1.079252929687500 0.943749999999998 1.020312499999998 -1.061674804687500 …………………………………………………………………………………………………………….. iter=49p= 1.000000969021338 1.250005597923464 -1.124999999956208 0.999993292813279 1.249984113824493 -1.124999999786506 1.000019269216091 1.250017992060081 -1.124999999625434 büyük y i=-1.1249999996254345 2 ikinci büyük y i=-1.124999999786506 1 küçük y i=-1.1249999999562075 0 Amip hareketlerini grafik olarak görmek istersek : Program 5.9-2 Problem 5.9-1 deki Nelder ve Mead simpleks optimizasyon sonuçlarını görmek amacıyla olan grafik programı import java.io.*; class PlotT01 { public static void main (String args[]) throws java.io.IOException { double x1[]={-2.4,-2,-2,-2.4}; double y1[]={2,2.4,2,2}; double x2[]={-1.2,-2,-2,-1.2}; double y2[]={2.6,2.4,2,2.6}; double x3[]={-1.2,-0.8,-2,-1.2}; double y3[]={2.6,2.1,2,2.6}; double x4[]={-1.2,-0.8,1,-1.2}; double y4[]={2.6,2.1,3.05,2.6}; double x5[]={1.4,-0.8,1,1.4}; double y5[]={2.55,2.1,3.05,2.55}; double x6[]={1.4,3.2,1,1.4}; double y6[]={2.55,3.5,3.05,2.55}; double x7[]={1.4,3.2,1.65,1.4}; double y7[]={2.55,3.5,3.0375,2.55}; double x8[]={1.4,2.3625,1.65,1.4}; double y8[]={2.55,3.146875,3.0375,2.55}; double x9[]={1.4,2.3625,2.1125,1.4}; double y9[]={2.55,3.146875,2.659375,2.55}; double x10[]={1.4,1.15,2.1125,1.4}; double y10[]={2.55,2.0625,2.659375,2.55}; double x11[]={1.8625,1.15,2.1125,1.8625}; double y11[]={2.171875,2.0625,2.659375,2.171875}; double x12[]={1.8625,1.15,0.9,1.8625}; double y12[]={2.171875,2.0625,1.575,2.171875}; double x13[]={1.8625,1.6125,0.9,1.8625}; double y13[]={2.171875,1.684375,1.575,2.171875}; double x14[]={0.65,1.6125,0.9,0.65}; double y14[]={1.0874,1.684375,1.575,1.0874}; double x15[]={0.65,1.19375,0.9,0.65}; double y15[]={1.0874,1.5078125,1.575,1.0874}; double x16[]={0.65,1.19375,0.94375,0.65}; double y16[]={1.0874,1.5078125,1.0203125,1.0874}; double x17[]={0.859375,1.19375,0.94375,0.859375}; double y17[]={1.17578125,1.5078125,1.0203125,1.17578125}; Plot pp=new Plot(x1,y1); pp.addData(x2,y2); pp.addData(x3,y3); pp.addData(x4,y4); pp.addData(x5,y5); pp.addData(x6,y6); pp.addData(x7,y7); pp.addData(x8,y8); pp.addData(x9,y9); pp.addData(x10,y10); pp.addData(x11,y11); pp.addData(x12,y12); pp.addData(x13,y13); pp.addData(x14,y14); pp.addData(x15,y15); pp.addData(x16,y16); pp.addData(x17,y17); pp.plot(); } } Çıktı 5.9-3 Nelder ve Mead simpleks optimizasyon arama örneği simpleks hareketi grafik programı çıktısı Grafikte çözüm noktası 0 ile gösterilmiştir. 500 iterasyon sonunda sonuç : ÖRNEK PROBLEM İkinci bir örnek olarak fabrika yeri problemini inceleyelim: Yeni bir ürün için fabrika yeri seçilmek isteniyor.Her şehrin koordinatları ve şehirdeki müşteri sayıları (şehir nüfusları olabilir) verildiğinde minimum mal taşıma maliyetini minimum toplam yol) veren fabrika yerini seçmeyi göz önüne alalım. Eğer N i i şehrinin nüfusu, xi ve yi i şehrinin koordinatları ise ve fabrika koordinatları x,y olarak verilirse, Minimizasyon fonksiyonunu f N i ( x xi ) 2 ( y yi ) 2 olacaktır. Bir örnek test fonksiyonu olarak n i 1 Nüfus 10 10 10 10 X koordinatı 0 0 1 1 Y koordinatı 0 1 0 1 Bu veri seti için çözümün 0.5,0.5 noktası olacağı görülmektedir. Şimdi problemi oluşturalım ve çözümü inceleyelim. Program 5.9-3 Fabrika yeri seçimi optimizasyonu problemi, Nelder ve Mead simpleks optimizasyonu // Nelder-Mead metodu ile optimizasyon // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class ff1 extends f_xj { double a[][]; public ff1(String s) {a=Text.readDoubleT(s);} public double func(double x[]) { //çözümü istenen fonksiyon double ff=0; int n=a[0].length; for(int i=0;i<n;i++) ff+=a[0][i]*((x[0]-a[1][i])*(x[0]-a[1][i])+(x[1]-a[2][i])*(x[1]-a[2][i])); return ff; } } public class OPO7B1 { public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=OPO7B.verigir(s); double [] dx0=new double[x0.length]; for(int i=0;i<x0.length;i++) dx0[i]=0.2*x0[i]; ff1 f=new ff1("sehir.txt"); double [] r1= OPO7B.nelder(f,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Nelder-Mead metodu ile lineer olmıyan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.9-4 Fabrika yeri seçimi optimizasyonu problemi, Nelder ve Mead simpleks optimizasyonu, step step nelder-Med simpleksinin aldığı değerlerin dökümü ---------- Capture Output ---------> "C:\co\java\bin\java.exe" OPO7B1 iter=1p= 0.120000000000000 0.100000000000000 0.100000000000000 0.120000000000000 0.100000000000000 0.100000000000000 32.176000000000000 32.176000000000000 32.800000000000004 büyük y i=32.800000000000004 2 ikinci büyük y i=32.176 0 küçük y i=32.176 0 iter=2p= 0.120000000000000 0.100000000000000 0.130000000000000 0.100000000000000 0.120000000000000 0.130000000000000 32.176000000000000 32.176000000000000 30.951999999999990 büyük y i=32.176 0 ikinci büyük y i=32.176 1 küçük y i=30.95199999999999 2 iter=3p= 0.110000000000000 0.150000000000000 30.983999999999995 0.100000000000000 0.120000000000000 32.176000000000000 0.130000000000000 0.130000000000000 30.951999999999990 büyük y i=32.176 1 ikinci büyük y i=30.983999999999995 0 küçük y i=30.95199999999999 2 iter=4p= 0.110000000000000 0.150000000000000 30.983999999999995 0.160000000000000 0.180000000000000 28.719999999999995 0.130000000000000 0.130000000000000 30.951999999999990 büyük y i=30.983999999999995 0 ikinci büyük y i=30.95199999999999 2 küçük y i=28.719999999999995 1 iter=5p= 0.215000000000000 0.165000000000000 27.737999999999985 0.160000000000000 0.180000000000000 28.719999999999995 0.130000000000000 0.130000000000000 30.951999999999990 büyük y i=30.95199999999999 2 ikinci büyük y i=28.719999999999995 1 küçük y i=27.737999999999985 0 iter=6p= 0.215000000000000 0.165000000000000 27.737999999999985 0.160000000000000 0.180000000000000 28.719999999999995 0.302500000000000 0.257500000000001 23.912499999999984 büyük y i=28.719999999999995 1 ikinci büyük y i=27.737999999999985 0 küçük y i=23.912499999999984 2 iter=7p= 0.215000000000000 0.165000000000000 27.737999999999985 0.456250000000000 0.273750000000001 22.124124999999978 0.302500000000000 0.257500000000001 23.912499999999984 büyük y i=27.737999999999985 0 ikinci büyük y i=23.912499999999984 2 küçük y i=22.124124999999978 1 iter=8p= 0.543750000000001 0.366250000000001 20.792124999999988 0.456250000000000 0.273750000000001 22.124124999999978 0.302500000000000 0.257500000000001 23.912499999999984 büyük y i=23.912499999999984 2 ikinci büyük y i=22.124124999999978 1 küçük y i=20.792124999999988 0 iter=9p= 0.543750000000001 0.366250000000001 20.792124999999988 0.456250000000000 0.273750000000001 22.124124999999978 0.697500000000001 0.382500000000002 22.112499999999997 büyük y i=22.124124999999978 1 ikinci büyük y i=22.112499999999997 2 küçük y i=20.792124999999988 0 iter=10p= 0.543750000000001 0.366250000000001 20.792124999999988 0.538437500000001 0.324062500000001 21.297257812499986 0.697500000000001 0.382500000000002 22.112499999999997 büyük y i=22.112499999999997 2 ikinci büyük y i=21.297257812499986 1 küçük y i=20.792124999999988 0 iter=11p= 0.543750000000001 0.366250000000001 20.792124999999988 0.538437500000001 0.324062500000001 21.297257812499986 0.462890625000000 0.326484375000001 21.259391113281236 büyük y i=21.297257812499986 1 ikinci büyük y i=21.259391113281236 2 küçük y i=20.792124999999988 0 iter=12p= 0.543750000000001 0.366250000000001 20.792124999999988 0.433085937500000 0.390976562500001 20.654544067382805 0.462890625000000 0.326484375000001 21.259391113281236 büyük y i=21.259391113281236 2 ikinci büyük y i=20.792124999999988 0 küçük y i=20.654544067382805 1 iter=13p= 0.543750000000001 0.366250000000001 20.792124999999988 0.433085937500000 0.390976562500001 20.654544067382805 0.539472656250001 0.482871093750001 20.074059600830080 büyük y i=20.792124999999988 0 ikinci büyük y i=20.654544067382805 1 küçük y i=20.07405960083008 2 iter=14p= 0.428808593750000 0.507597656250001 20.205037628173827 0.433085937500000 0.390976562500001 20.654544067382805 0.539472656250001 0.482871093750001 20.074059600830080 büyük y i=20.654544067382805 1 ikinci büyük y i=20.205037628173827 0 küçük y i=20.07405960083008 2 iter=15p= 0.428808593750000 0.507597656250001 20.205037628173827 0.509667968750000 0.547363281250001 20.093470001220710 0.539472656250001 0.482871093750001 20.074059600830080 büyük y i=20.205037628173827 0 ikinci büyük y i=20.09347000122071 1 küçük y i=20.07405960083008 2 iter=16p= 0.476689453125000 0.511357421875001 20.026894905090334 0.509667968750000 0.547363281250001 20.093470001220710 0.539472656250001 0.482871093750001 20.074059600830080 büyük y i=20.09347000122071 1 ikinci büyük y i=20.07405960083008 2 küçük y i=20.026894905090334 0 iter=17p= 0.476689453125000 0.511357421875001 20.026894905090334 0.508874511718750 0.522238769531251 20.022932793140413 0.539472656250001 0.482871093750001 20.074059600830080 büyük y i=20.07405960083008 2 ikinci büyük y i=20.026894905090334 0 küçük y i=20.022932793140413 1 iter=18p= 0.476689453125000 0.511357421875001 20.026894905090334 0.508874511718750 0.522238769531251 20.022932793140413 0.516127319335938 0.499834594726564 20.010404711514713 büyük y i=20.07405960083008 2 ikinci büyük y i=20.026894905090334 0 küçük y i=20.022932793140413 1 iter=52p= 0.500002657994614 0.499999541116936 20.000000000291020 0.499999313009312 0.500000148257349 20.000000000019753 0.499999853685161 0.499998268210034 20.000000000120820 büyük y i=20.00000000029102 0 ikinci büyük y i=20.00000000012082 2 küçük y i=20.000000000019753 1 > Terminated with exit code 0. Çıktı 5.9-5 Fabrika yeri seçimi optimizasyonu problemi, Nelder ve Mead simpleks optimizasyonu, step step nelder-Mead simpleksinin aldığı değerlerin ilk 18 inin grafik ortamda gösterilişi başlangıç değeri [0.1, 0.1] , çözüm değeri [0.5,0.5] Çıktı 5.9-6 Fabrika yeri seçimi optimizasyonu problemi, Nelder ve Mead simpleks optimizasyonu, başlangıç değeri [0.1, 0.1] 5.10 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK-EN DİK YAMAÇ METODU N boyutlu sınırlamasız optimizasyon problemine Minimum : f(x0,x1,x2,…,xn) problemini çözme yöntemlerine devam ediyoruz. Denklemimizin türev fonksiyonu f ( x1 , x2 , x3 ,..., xn ) x1 f ( x1 , x2 , x3 ,..., xn ) x2 f ( x1 , x2 , x3 ,..., xn ) f ( x1 , x2 , x3 ,..., xn ) x3 ... f ( x1 , x2 , x3 ,..., xn ) xn olarak verilmişti. Bu metoda bir başlangıç noktası seçerek başlarız. Örneğin başlangıç noktası P 0 f ( x10 , x20 , x30 ,..., xn0 ) olsun. Önce her yeni step için türev denklemi d k f ( x1k , x2k , x3k ,..., xnk ) k 0....n hesaplanır. Sonra bu değer kullanılarak katsayısı cinsinden yeni değere geçilir. f ( x , x , x ,...,x ) f ( x , x , x ,...,x ) f ( x , x , x ,...,x ) 1 2 3 n ],[ x k k 1 2 3 n ],...,[ x k k 1 2 3 n ]) f ( k ) f ( x k k d k ) f ([ x k k 1 2 n x x2 x 1 n f ( ) tek boyutlu fonksiyon değerini minimum yapan değeri tek boyutlu optimizasyon tekniklerinden birisi k 1 kullanılarak bulunur. Yeni x değeri x k 1 x k k d k formülünü kullanarak hata küçülene kadar iteratif olarak tekrarlanır. ÖRNEK PROBLEM 5.10-1 ÖRNEK PROBLEM Genel formül : 1 {x m1} {x m } m H m {f m } En dik yamaç formülü : {xm1} {xm } m{f m } veya yukarıda yazdığımız şekliyle xm1 xm m d m , d m {f m } f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulunuz. 6 x 4 x1 1 21 f 0 4 x1 4 x0 1 15 x00 2 0 x1 2 6 x00 4 x10 1 x01 x00 1 0 0 0 x1 x1 4 x0 4 x1 1 x01 2 21 1 15 x1 2 x01 = -2 -21 x11 = 2 +15 Bu değerleri f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunda yerine koyarsak y)2-4(-2 -21)(2 +15)+2(2 +15)2-(-2 -21)-(2 +15) y = 36 +666+3033Birinci derece denklemini buluruz. Bizim optimal noktamız birinci dereceye dönüşmüş olan y fonksiyonunun minimum noktasıdır. Bu yüzden ’nın y yi minimum yapan değerini bulacağız. Programda bunun için brent metodu kullanılmıştır. Burada ise analitik olarak direk çözüm yapalım: y’ = 666+6066=-0.109792284 1 1 Bu değeri x0 ve x1 de yerine koyarsak x01 0.3056379 x02 0.9544105 =-0.109792284 için 1 =-1.121212 için 2 x1 0.35311572 x1 1.2613973 x3 0.9894 x04 0.9993 =-0.109792284 için 03 =-1.121212 için 4 1.2363 x 1 x1 1.250173 bundan sonra aynı iterasyona görüldüğü gibi devam ederiz. Programda bu işlemi yapan algorimalar mevcuttur, aynı problem çözülmektedir. Program 5.10-1 en dik yamaç algoritması programı import javax.swing.*; import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import java.io.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class f1dim extends f_x { // iki boyutlu fonksiyonu tek boyutlu fonksiyona çeviren // pseudo fonksiyon f_xj ff1; double pc[]; double xc[]; double xt[]; int n; public f1dim(f_xj ff,double pi[],double xi[]) { n=pi.length; ff1=ff; pc=new double[n]; xc=new double[n]; xt=new double[n]; for(int i=0;i<n;i++) {pc[i]=pi[i];xc[i]=xi[i];} } public double func(double x) { for (int j=0;j<n;j++) xt[j]=pc[j]+x*xc[j]; return ff1.func(xt); } } public class OPO8 { public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} // 3. brent metodu //________________________________________________________________ // golden (altın) oran - Fibonacchi metodu ve ikinci derece polinom metodunu birlikte kullanır public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } // 3. en dik yamac metodu //________________________________________________________________ public static double[] endikyamac( f_xj f,double x[]) { // en dik yamac metodu // linmin ve brent metodunukullanır double ti=1.0; int i,ii,jj; int nmax=5; double tolerance=1.0e-10; int n=x.length; double b[]; b=new double[n]; double lambda; double dy[]=new double[n]; //dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } i=0; while( i++ < nmax && Matrix.abs(b) > tolerance ) { dy=turev(f,x); lambda=linmin(f,x,dy); b=Matrix.multiply(dy,lambda); x=Matrix.add(x,b); System.out.println("i= "+i+"alfa="+lambda+"\n"+Matrix.toString(x)); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[] turev(f_xj f_deriv,double x[]) { // df/dxj j=0...x.length // This method calculates turev of a function with more than one independent variable. // Accuracy of method can be adjusted by changing variables h0 and n // function input should be in the form given in abstract class // f_xj,j=0...x.length = df/dx(x_ref) double a[]=new double[x.length]; for(int x_ref=0;x_ref<x.length;x_ref++) { a[x_ref]=turev(f_deriv,x,x_ref); } return a; } public static double turev(f_xj f,double xxi[],int x_ref) { // df/dxj double h0=0.256808; int i,m; int n=7; double x1[]; x1=new double[xxi.length]; double x2[]; x2=new double[xxi.length]; for(i=0;i<xxi.length;i++) { x1[i]=xxi[i]; x2[i]=xxi[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { //h[i]=h0*Math.pow(r,i); h0/=2.0; h[i]=h0; } //first turev (difference formula) for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; T[i][0]=(f.func(x1)-f.func(x2))/(2.0*h[i]); x1[x_ref]=xxi[x_ref]; x2[x_ref]=xxi[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } // veri giriş çıkış metodu //________________________________________________________________ public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); double [] r1= endikyamac(f_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="En dik yamaç lineer olmıyan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.10-1 En dik yamaç metodu çıktısı ikinci bir örnek fonksiyona bakalım : ÖRNEK PROBLEM 5.10-2 f(x0,x1)=sin(x0)cos(x1) fonksiyonunun {x}=[1,0.5] noktasından başlayarak minimum değerlerini bulunuz. Burada sadece fonksiyon tanımını yeniden verelim, program aynı olacaktır. : Program 5.10-2 en dik yamaç PROBLEM 5.10-2 örnek fonksiyonu class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=Math.sin(x[0])*Math.cos(x[1]); return ff; }} Çıktı 5.10-2 En dik yamaç metodu çıktısı Şekil 5.10-1 En dik yamaç metodu step ilerlemesi 5.11 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK- DEĞİŞTİRİLMİŞ NEWTON METODU Newton metodu köke yaklaştığı zaman çok iyi bir yakınsama sağlarken, kökten uzaktayken performansı daha kötüdür. Değiştirilmiş Newton metodu Newton metoduyla tepe tırmanma metodunu birleştirir. Program 5.11-1 Değiştirilmiş Newton metodu- türevler sayısal hesaplanıyor import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; return -ff; //minimum değil maxsimum istendiğinden - ile çarptık } } public class OPO12 { public static double turev(f_xj f,double x[],int denklem_ref,int x_ref) { // // verilen fonksiyonun ikinci türevlerinin matrisi // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref] değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.256808; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]*1.0094847; f1=df(f,x1); f2=df(f,x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=turev(f,xxi,i); } return a; } public static double turev(f_xj f,double xxi[],int x_ref) { // df/dxj double h0=0.256808; int i,m; int n=7; double x1[]; x1=new double[xxi.length]; double x2[]; x2=new double[xxi.length]; for(i=0;i<xxi.length;i++) { x1[i]=xxi[i]; x2[i]=xxi[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { //h[i]=h0*Math.pow(r,i); h0/=2.0; h[i]=h0; } //first turev (difference formula) for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; T[i][0]=(f.func(x1)-f.func(x2))/(2.0*h[i]); x1[x_ref]=xxi[x_ref]; x2[x_ref]=xxi[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] turev(f_xj f_deriv,double x[]) { // df/dxj j=0...x.length // This method calculates turev of a function with more than one independent variable. // Accuracy of method can be adjusted by changing variables h0 and n // function input should be in the form given in abstract class // f_xj,j=0...x.length = df/dx(x_ref) double a[]=new double[x.length]; for(int x_ref=0;x_ref<x.length;x_ref++) { a[x_ref]=turev(f_deriv,x,x_ref); } return a; } public static double[][]H(f_xj f,double x[]) { int n=x.length; double dy[][]=new double[n][n];; for(int ii=0;ii<n;ii++) { for(int jj=0;jj<n;jj++) { //Hessian matrisi dy[ii][jj]=turev(f,x,ii,jj); } } return dy; } public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } // 4. modifiye Newton metodu (en dik yamaç ve newton metodlarını birleştirir) //________________________________________________________________ public static double[] dampednewton( f_xj f,double x[]) { // Damped Newton metodu // Newton-Raphson metodu ile en dik yamaç metodunu birlikte kullanır. // linmin ve brent metodunukullanır double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-12; int n=x.length; double b[]; b=new double[n]; double lambda; double g[]=new double[n]; double G[][]=H(f,x); double g1,g2,g3,g4,g5; //dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { g=turev(f,x); g1=Matrix.VT_V(g); g2=Matrix.VT_G_V(g,G); g1*=g1; g3=g1/g2; g4=Matrix.VT_G_V(g,Matrix.inverse(G)); lambda=linmin(f,x,g); if(g4>Math.max(g3,0)) b=Matrix.multiply(Matrix.divide(g,G),lambda); else b=Matrix.multiply(g,lambda); x=Matrix.add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); double [] r1= dampednewton(f_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Modifiye newton çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.11-1 Değiştirilmiş Newton metodu Program 5.11-1 de türevler sayısal olarak hesaplanmıştı. Aynı problemin türevlerin fonksiyon olarak verildiği versiyonu problem 5.11-2 de verilmiştir. Program 5.11-2 Değiştirilmiş Newton metodu- türevler sayısal fonksion olarak verilmiş // Newton metodu ile optimizasyon // import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; return -ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class f2 extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyon double ff[]={-(2.0*x[1]+2.0-2.0*x[0]),-(2.0*x[0]-4.0*x[1])}; return ff; } } class f3 extends fij_xi { public double[][] func(double x[]) { //çözümü istenen fonksiyon double ff[][]={{2,-2},{-2,-4}}; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } public class OPO12D { public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=dfdx(f,xxi,i); } return a; } public static double dfdx(f_xj f,double xxi[],int xref) { int i; double h=1.0e-3; double hh=1.0/h; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(i=0;i<xxi.length;i++) { if(i!=xref) {xp2h[i]=xxi[i];xph[i]=xxi[i];xm2h[i]=xxi[i];xmh[i]=xxi[i];} else {xp2h[i]=xxi[i]+2.0*h;xph[i]=xxi[i]+h;xm2h[i]=xxi[i]-2.0*h;xmh[i]=xxi[i]-h;} } fp2h=f.func(xp2h); fph=f.func(xph); fm2h=f.func(xm2h); fmh=f.func(xmh); return (-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; } public static double d2fdx2(f_xj f,double xxi[],int xiref,int xjref) { //ikincitürev matrisi int i; double h=1.0e-4; double hh=1.0/h; int n=xxi.length; double ff; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(int j=0;j<n;j++) {if(j!=xjref) {xp2h[j]=xxi[j];xph[j]=xxi[j];xm2h[j]=xxi[j];xmh[j]=xxi[j];} else {xp2h[j]=xxi[j]+2.0*h;xph[j]=xxi[j]+h;xm2h[j]=xxi[j]-2.0*h;xmh[j]=xxi[j]-h;} } fp2h=dfdx(f,xp2h,xiref); fph=dfdx(f,xph,xiref); fm2h=dfdx(f,xm2h,xiref); fmh=dfdx(f,xmh,xiref); ff=(-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; return ff; } public static double[][]H(f_xj f,double x[]) { int n=x.length; double dy[][]=new double[n][n];; for(int ii=0;ii<n;ii++) { for(int jj=0;jj<n;jj++) { //Hessian matrisi dy[ii][jj]=d2fdx2(f,x,ii,jj); } } return dy; } // 4. modifiye Newton metodu (en dik yamaç ve newton metodlarını birleştirir) //________________________________________________________________ public static double[] newton( f_xj f,fi_xi df,fij_xi d2f,double x[]) { double ti=1.0; int i,ii,jj; int nmax=500; double tolerance=1.0e-10; int n=x.length; double b[]; b=new double[n]; i=0; for(i=0;i<n;i++) {b[i]=1.0;} while( i++ < nmax && Matrix.abs(b) > tolerance ) { b=Matrix.multiply(Matrix.divide(df.func(x),d2f.func(x)),-ti); x=Matrix.add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] dampednewton(f_xj f,fi_xi df,fij_xi d2f,double x[]) { // Damped Newton metodu // Newton-Raphson metodu ile en dik yamaç metodunu birlikte kullanır. // linmin ve brent metodunukullanır double ti=1.0; int i,ii,jj; int nmax=800; double tolerance=1.0e-14; int n=x.length; double b[]; b=new double[n]; double lambda; double g[]=new double[n]; double G[][]=d2f.func(x);//Hessian matrix double g1,g2,g3,g4,g5; //dy=new double[n][n]; i=0; for(i=0;i<n;i++) { b[i]=1.0; } while( i++ < nmax && Matrix.abs(b) > tolerance ) { g=df.func(x); g1=Matrix.VT_V(g); g2=Matrix.VT_G_V(g,G); g1*=g1; g3=g1/g2; g4=Matrix.VT_G_V(g,Matrix.inverse(G)); lambda=linmin(f,x,g); if(g4>Math.max(g3,0)) b=Matrix.multiply(Matrix.divide(g,G),lambda); else b=Matrix.multiply(g,lambda); x=Matrix.add(x,b); } if(i >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } // veri giriş çıkış metodu //________________________________________________________________ public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f=new f1(); f2 df=new f2(); f3 d2f=new f3(); double r1[]=dampednewton(f,df,d2f,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Newton metodu ile lineer olmayan çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 5.12 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK FLETCHER-REEVES VE POLAK-RİBİERE METODLARI (KONJUGE GRADYEN METODU) FLETCHER-REEVES METODU (KONJUGE GRADYEN METODU) En dik tepe metodunun verimini arttırmak için çeşitli yöntemler uygulanması mümkündür. Bu yöntemlerden birisi daha önceki arama yönlerinin bir kombinasyonunu yeni arama yönünü bulmak için kullanmaktır. İterasyona önce en dik yamaç metodu ile başlarız. d 0 g 0 g k f ( x1k , x2k , x3k ,...,xnk ) , k 0,...,n k=0 için x k 1 x k k d k denklemini hesaplayabiliriz. Bundan sonra 1 k n için k ( g k )T ( g k ) ( g k 1 ) T ( g k 1 ) d k g k k d k 1 x k 1 x k k d k ÖRNEK PROBLEM 5.12.1 Genel formül : 1 {x m1} {x m } m H m {f m } En dik yamaç formülü : {xm1} {xm } m{f m } veya yukarıda yazdığımız şekliyle xm1 xm m d m , d m {f m } f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulunuz. 6 x 4 x1 1 21 f 0 4 x1 4 x0 1 15 x00 2 0 x1 2 6 x00 4 x10 1 x01 x00 1 0 0 0 x1 x1 4 x0 4 x1 1 x01 2 0 21 1 15 x1 2 x01 = -2 -21 x11 = 2 +15 Bu değerleri f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunda yerine koyarsak y)2-4(-2 -21)(2 +15)+2(2 +15)2-(-2 -21)-(2 +15) y = 36 +666+3033Birinci derece denklemini buluruz. Bizim optimal noktamız birinci dereceye dönüşmüş olan y fonksiyonunun minimum noktasıdır. Bu yüzden ’nın y yi minimum yapan değerini bulacağız. Programda bunun için brent metodu kullanılmıştır. Burada ise analitik olarak direk çözüm yapalım: y’ = 666+6066=-0.109792284 1 1 Bu değeri x0 ve x1 de yerine koyarsak x1 0.305637982195846 =-0.109792284 için 01 olur. Bu ilk stepimiz en dik yamaç stepi idi x1 0.353115727002967 şimdi Fletcher-Reeves dik gradyan yöntemini hesaplayabiliriz. 6 x 4 x1 1 -0.578635014836797 g f 0 4 x1 4 x0 1 -0.810089020771512 0.9910627019697276 ( g k )T ( g k ) k k 1 T k 1 = =0.001488082135089681 (g ) (g ) 666.0 0.609884739673680 d k g k k d k 1 = 0.787767788745167 0.3056379 0.609884739673680 x k 1 x k k d k = 0.35311572 0.787767788745167 =1.138513513513513 x02 1.000000000000001 2 olarak elde ederiz. x1 1.249999999999998 Problem 5.12.1 Fletcher – Reeves dik gradyan metodu ile optimizasyon, fonksiyon ve türevi verilmiş formül import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; //ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fxb extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[]=new double[2]; ff[0]=6.0*x[0]-4.0*x[1]-1.0; ff[1]=-4.0*x[0]+4.0*x[1]-1.0; return ff; } } public class OPO12E1 { public static double VT_V(double [] left) { //multiplies a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } System.out.println("v = \n"+Matrix.toString(left)+"carpim="+tot); return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) {aa[i][j]=left[i]*left[j];} } return aa; } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=dfdx(f,xxi,i); } return a; } public static double dfdx(f_xj f,double xxi[],int xref) { int i; double h=1.0e-3; double hh=1.0/h; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(i=0;i<xxi.length;i++) { if(i!=xref) {xp2h[i]=xxi[i];xph[i]=xxi[i];xm2h[i]=xxi[i];xmh[i]=xxi[i];} else {xp2h[i]=xxi[i]+2.0*h;xph[i]=xxi[i]+h;xm2h[i]=xxi[i]-2.0*h;xmh[i]=xxi[i]-h;} } fp2h=f.func(xp2h); fph=f.func(xph); fm2h=f.func(xm2h); fmh=f.func(xmh); return (-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; } public static double d2fdx2(f_xj f,double xxi[],int xiref,int xjref) { //ikincitürev matrisi int i; double h=1.0e-4; double hh=1.0/h; int n=xxi.length; double ff; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(int j=0;j<n;j++) {if(j!=xjref) {xp2h[j]=xxi[j];xph[j]=xxi[j];xm2h[j]=xxi[j];xmh[j]=xxi[j];} else {xp2h[j]=xxi[j]+2.0*h;xph[j]=xxi[j]+h;xm2h[j]=xxi[j]-2.0*h;xmh[j]=xxi[j]-h;} } fp2h=dfdx(f,xp2h,xiref); fph=dfdx(f,xph,xiref); fm2h=dfdx(f,xm2h,xiref); fmh=dfdx(f,xmh,xiref); ff=(-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; return ff; } public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } // 4. fletcher Reeves metodu //________________________________________________________________ public static double[] fletcher_reeves( f_xj f,fi_xi df,double x[]) { int i,j,ii,jj,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-11; int n=x.length; double alpha; double g[]=new double[n]; double ge[]=new double[n]; double d[]=new double[n]; double beta=0; double alpha_d; double Q[]=new double[n]; int nn=15; i=0; j=0;k=0; while( j < nmax && gamma > tolerance ) { g=df.func(x); gamma=norm(g); if(k<1) {for(i=0;i<n;i++){d[i]=-g[i];};ge=g;} else {beta=VT_V(g)/VT_V(ge); for(i=0;i<n;i++){Q[i]=beta*d[i];}; } for(i=0;i<n;i++){d[i]=-g[i]+Q[i];} alpha=linmin(f,x,d); for(i=0;i<n;i++){x[i]+=alpha*d[i];} System.out.println("alpha="+alpha+"beta="+beta+"\nx\n"+Matrix.toString(x)+"\nd\n"+Matrix.toString(d)); ge=g; j++;k++; if(k>=nn) k=0; //tekrar bir en dik yamaç metodu uygulaması } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); fxb df_x=new fxb(); double [] r1= fletcher_reeves(f_x,df_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Fletcher-Reeves çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.12.1 Fletcher – Reeves dik gradyan metodu ile optimizasyon, fonksiyon ve türevi verilmiş formül Problem 5.12.2 Fletcher – Reeves dik gradyan metodu ile optimizasyon, fonksiyon verilmiş ve türevi sayısal olarak hesaplanıyor import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; //ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } public class OPO12E { public static double VT_V(double [] left) { //multiplies a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } System.out.println("v=\n"+Matrix.toString(left)+"carpim="+tot); return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } //=================== public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=dfdx(f,xxi,i); } return a; } public static double dfdx(f_xj f,double xxi[],int xref) { int i; double h=1.0e-3; double hh=1.0/h; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(i=0;i<xxi.length;i++) { if(i!=xref) {xp2h[i]=xxi[i];xph[i]=xxi[i];xm2h[i]=xxi[i];xmh[i]=xxi[i];} else {xp2h[i]=xxi[i]+2.0*h;xph[i]=xxi[i]+h;xm2h[i]=xxi[i]-2.0*h;xmh[i]=xxi[i]-h;} } fp2h=f.func(xp2h); fph=f.func(xph); fm2h=f.func(xm2h); fmh=f.func(xmh); return (-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; } public static double d2fdx2(f_xj f,double xxi[],int xiref,int xjref) { //ikincitürev matrisi int i; double h=1.0e-4; double hh=1.0/h; int n=xxi.length; double ff; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(int j=0;j<n;j++) {if(j!=xjref) {xp2h[j]=xxi[j];xph[j]=xxi[j];xm2h[j]=xxi[j];xmh[j]=xxi[j];} else {xp2h[j]=xxi[j]+2.0*h;xph[j]=xxi[j]+h;xm2h[j]=xxi[j]-2.0*h;xmh[j]=xxi[j]-h;} } fp2h=dfdx(f,xp2h,xiref); fph=dfdx(f,xph,xiref); fm2h=dfdx(f,xm2h,xiref); fmh=dfdx(f,xmh,xiref); ff=(-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; return ff; } //=================== public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } // 4. fletcher Reeves metodu //________________________________________________________________ public static double[] fletcher_reeves( f_xj f,double x[]) { int i,j,ii,jj,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-11; int n=x.length; double alpha; double g[]=new double[n]; double ge[]=new double[n]; double d[]=new double[n]; double beta; double alpha_d; double Q[]=new double[n]; int nn=15; i=0; j=0;k=0; while( j < nmax && gamma > tolerance ) { g=df(f,x); gamma=norm(g); if(k<1) {for(i=0;i<n;i++){d[i]=-g[i];};ge=g;} else {beta=VT_V(g)/VT_V(ge); for(i=0;i<n;i++){Q[i]=beta*d[i];}; } for(i=0;i<n;i++){d[i]=-g[i]+Q[i];} alpha=linmin(f,x,d); for(i=0;i<n;i++){x[i]+=alpha*d[i];} ge=g; j++;k++; if(k>=nn) k=0; //tekrar bir en dik yaöaç metodu uygulaması } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); double [] r1= fletcher_reeves(f_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Fletcher-Reeves çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } POLAK-RİBİERE METODU (KONJUGE GRADYEN METODU) Polak-Ribiere metodu Fletcher reeves metodu formülünde küçük bir değişikliği içeren benzer bir metoddur. Fletcher-Reeves metodunda değeri ( g k )T ( g k ) k k 1 T k 1 olarak tanımlanmıştı. Bu tanımı biraz değiştirirsek, (g ) (g ) k ( g k 1 g k )T ( g k ) tanımıyla verecek olursak Polak-Ribiere metodunu elde etmiş oluruz. ( g k 1 )T ( g k 1 ) Problem 5.12.2 polak-Ribiere dik gradyan metodu ile optimizasyon import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; } } public class OPO12E4 { public static double VT_V(double [] left) { //multiplies a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } //System.out.println("v=\n"+Matrix.toString(left)+"carpim="+tot); return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double[] substract(double[] left,double[] right) { //addition of two vectors int n1=left.length; int n2=right.length; int nMax; int i; if(n1>=n2) nMax=n1; else nMax=n2; double b[]; b=new double[nMax]; for(i=0;i<n1;i++) { b[i]=b[i]+left[i]; } for(i=0;i<n2;i++) { b[i]=b[i]-right[i]; } return b; //end of vector substraction method } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } //=================== public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=dfdx(f,xxi,i); } return a; } public static double dfdx(f_xj f,double xxi[],int xref) { int i; double h=1.0e-3; double hh=1.0/h; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(i=0;i<xxi.length;i++) { if(i!=xref) {xp2h[i]=xxi[i];xph[i]=xxi[i];xm2h[i]=xxi[i];xmh[i]=xxi[i];} else {xp2h[i]=xxi[i]+2.0*h;xph[i]=xxi[i]+h;xm2h[i]=xxi[i]-2.0*h;xmh[i]=xxi[i]-h;} } fp2h=f.func(xp2h); fph=f.func(xph); fm2h=f.func(xm2h); fmh=f.func(xmh); return (-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; } public static double d2fdx2(f_xj f,double xxi[],int xiref,int xjref) { //ikincitürev matrisi int i; double h=1.0e-4; double hh=1.0/h; int n=xxi.length; double ff; double xp2h[]=new double[xxi.length]; double xph[]=new double[xxi.length]; double xm2h[]=new double[xxi.length]; double xmh[]=new double[xxi.length]; double fp2h,fph,fm2h,fmh; for(int j=0;j<n;j++) {if(j!=xjref) {xp2h[j]=xxi[j];xph[j]=xxi[j];xm2h[j]=xxi[j];xmh[j]=xxi[j];} else {xp2h[j]=xxi[j]+2.0*h;xph[j]=xxi[j]+h;xm2h[j]=xxi[j]-2.0*h;xmh[j]=xxi[j]-h;} } fp2h=dfdx(f,xp2h,xiref); fph=dfdx(f,xph,xiref); fm2h=dfdx(f,xm2h,xiref); fmh=dfdx(f,xmh,xiref); ff=(-fp2h+8.0*fph-8.0*fmh+fm2h)/12.0*hh; return ff; } //=================== public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } // 4. Polak Ribiere Metodu //________________________________________________________________ public static double[] polak_ribiere( f_xj f,double x[]) { int i,j,ii,jj,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-7; int n=x.length; double alpha; double g[]=new double[n]; double ge[]=new double[n]; double d[]=new double[n]; double beta; double alpha_d; double Q[]=new double[n]; int nn=15; i=0; j=0;k=0; while( j < nmax && gamma > tolerance ) { g=df(f,x); gamma=norm(g); if(k<1) {for(i=0;i<n;i++){d[i]=-g[i];};ge=g;} else { // Polack-Ribiere conjugate gradient tanımı beta=VT_X(substract(ge,g),g)/VT_V(ge); for(i=0;i<n;i++){Q[i]=beta*d[i];}; } for(i=0;i<n;i++){d[i]=-g[i]+Q[i];} alpha=linmin(f,x,d); for(i=0;i<n;i++){x[i]+=alpha*d[i];} ge=g; j++;k++; if(k>=nn) k=0; //tekrar bir en dik yaöaç metodu uygulaması } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); double [] r1= polak_ribiere(f_x,x0); s=" çözüm seti : \n"+Matrix.toStringT(r1); String s2="Polak-Ribiere çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } 5.13 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK DAVİDON-FLETCHER-POWELL METODU Newton-Raphson metodunda { k 1} H k {f k } 1 {x k 1} {x k 1} H k {f k } 1 şeklinde çözüme ulaşabiliyorduk. Bu denkleme adım miktarını ayarlayabileceğimiz (en dik yamaç metodunda olduğu gibi) k faktörünü eklersek, genel denklem 1 {x k 1} {x k 1} k H k {f k } formunu alır. g k f ( x1k , x2k , x3k ,...,xnk ) , k 0,...,n ve d k H k g k 1 x k 1 x k k d k şeklinde yazılabilir. Bu metodumuzda ikinci türev, hessian yerine türevi hesaplamadan onun yerine geçebilecek bir fonksiyon oluşturmaya çalışacağız. Qk H k 1 ,k 0 olarak tanımlayalım. d k Qk g k x k 1 x k k Qk g k x k k d k şeklinde yazabiliriz. Davidon – Fletcher – Powell metodu Q yu hesaplamak için g k g k 1 g k r k Qk g k x k { k 1} x k 1 x k olarak yazarsak Qk 1 Qk r k (r k )T x k (x k )T , 0k n (r k )T g k (x k )T g k formülünü kullanır. Program 5.13-1 de Davidon-Fletcher-Powell metodu algoritması verilmiştir. Programımımızda Q hesaplanmasında ikinci bir versiyon daha kullanılmıştır ikinci denklemde yeni Q değeri bir önceki değer kullanılarak modifiye edilmektedir. Qk 1 k [Qk k r k (r k ) T x k (x k )T ] , 0k n (r k )T g k (x k )T g k (x k )T x k , 0k n (r k )T g k İteratif çözüm yönteminde iterasyona Q 0 değeri birim matrise eşit alınarak başlanır. Q0=I xk 1 xk k Qk g k xk k dk denklemindeki k katsayısı birinci dereceden tek boyutlu optimizasyon metodlarından birisi kullanılarak bulunur. Bizim programımızda brent yöntemi kullanılmıştır. Bu birinci step temel olarak tepe tırmanma metodudur. Daha sonra Q değerleri verilen denklemle hesaplanarak Davidon-Fletcher-Powell iterasyon stepleri hesaplanır. Her n stepte Q=I değerine geri dönülerek bir step tepe tırmanma metodu kullanılır ve tekrar DavidonFletcher-Powell iterasyon steplerine dönülür. ÖRNEK PROBLEM 5.13.1 Genel formül : 1 {x m1} {x m } m H m {f m } En dik yamaç formülü : {xm1} {xm } m{f m } veya yukarıda yazdığımız şekliyle xm1 xm m d m , d m {f m } f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulunuz. 6 x 4 x1 1 21 f 0 4 x1 4 x0 1 15 x00 2 0 x1 2 6 x00 4 x10 1 x01 x00 1 0 0 0 x1 x1 4 x0 4 x1 1 x01 2 0 21 1 15 x1 2 x01 = -2 -21 x11 = 2 +15 Bu değerleri f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunda yerine koyarsak y)2-4(-2 -21)(2 +15)+2(2 +15)2-(-2 -21)-(2 +15) y = 36 +666+3033Birinci derece denklemini buluruz. Bizim optimal noktamız birinci dereceye dönüşmüş olan y fonksiyonunun minimum noktasıdır. Bu yüzden ’nın y yi minimum yapan değerini bulacağız. Programda bunun için brent metodu kullanılmıştır. Burada ise analitik olarak direk çözüm yapalım: y’ = 666+6066=-0.109792284 1 1 Bu değeri x0 ve x1 de yerine koyarsak x1 0.305637982195846 =-0.109792284 için 01 olur. Bu ilk stepimiz en dik yamaç stepi idi 0.353115727002967 x 1 şimdi Davidon-Fletcher-Powell dik gradyan yöntemini hesaplayabiliriz. 6 x 4 x1 1 -0.578635014836797 g f 0 4 x1 4 x0 1 -0.810089020771512 20.4213649 85163200 g k g k 1 g k = - 15.810089020771512 1 0 Q 0 1 20.421364985163200 r k Qk g k - 15.810089020771512 2.305637982195846 x k { k 1} x k 1 x k - 1.646884272997033 Qk 1 Qk r k (r k )T x k (x k )T (r k )T g k (x k )T g k 0.447456314953212 0.432131073481232 0.432131073481232 0.662335969913257 0.608978529603123 d k Qk g k = 0.786597267404034 0.305637982195846 0.608978529603123 x k 1 x k k d k = 0.353115727002967 0.786597267404034 Bu değerleri Bu değerleri f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunda yerine koyarsak ve çözersek : =1.1402077151335304 bulunur. Buradan da : x02 1.000000000000000 2 x1 1.250000000000000 olarak ikinci iterasyon sonuçlarını elde ederiz. Program 5.13-1 Davidon-Fletcher-Powell metodu (türev sayısal olarak hesaplanıyor) // OPO12F Davidon-Fletcher-Powell optimizasyonu // Metod Referansı : Numerical Analysis, 8th edition Richard L. Burden, J. Douglas Faires 3 // sayfa 617 import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; //ff=7.9+0.13*x[0]+0.21*x[1]-0.05*x[0]*x[0]-0.016*x[1]*x[1]-0.007*x[0]*x[1]; //ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } public class OPO12F { public static double VT_V(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double turev(f_xj f,double x[],int denklem_ref,int x_ref) { // // verilen fonksiyonun ikinci türevlerinin matrisi // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref] değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.256808; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]*1.0094847; f1=df(f,x1); f2=df(f,x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=turev(f,xxi,i); } return a; } public static double turev(f_xj f,double xxi[],int x_ref) { // df/dxj double h0=0.256808; int i,m; int n=7; double x1[]; x1=new double[xxi.length]; double x2[]; x2=new double[xxi.length]; for(i=0;i<xxi.length;i++) { x1[i]=xxi[i]; x2[i]=xxi[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { //h[i]=h0*Math.pow(r,i); h0/=2.0; h[i]=h0; } //first turev (difference formula) for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; T[i][0]=(f.func(x1)-f.func(x2))/(2.0*h[i]); x1[x_ref]=xxi[x_ref]; x2[x_ref]=xxi[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] turev(f_xj f_deriv,double x[]) { // df/dxj j=0...x.length // This method calculates turev of a function with more than one independent variable. // Accuracy of method can be adjusted by changing variables h0 and n // function input should be in the form given in abstract class // f_xj,j=0...x.length = df/dx(x_ref) double a[]=new double[x.length]; for(int x_ref=0;x_ref<x.length;x_ref++) { a[x_ref]=turev(f_deriv,x,x_ref); } return a; } public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } public static double[][] I(int n) { //unit matrix double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=1.0; return b; } // Davidon - Fletcher-Powell metodu //________________________________________________________________ public static double[] davidon_fletcher_powell( f_xj f,double x[]) { int i,j,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-12 ; int n=x.length; double alpha; double dx[]=new double[n]; double g[] =new double[n]; double ge[]=new double[n]; double dg[]=new double[n]; double d[] =new double[n]; double r[] =new double[n]; double rdg,dxdg; double beta; double alpha_d; double Q[][]=I(n); double Q1[][]=new double[n][n]; double Q2[][]=new double[n][n]; int nn=15; i=0; j=0;k=0; g=turev(f,x); while( j++ < nmax && gamma > tolerance ) { for(int ii=0;ii<n;ii++) { d[ii]=0.0; for(int kk=0;kk<n;kk++) {d[ii]=d[ii]-Q[ii][kk]*g[kk];} } System.out.println("j="+j+"d="+Matrix.toString(d)); alpha=linmin(f,x,d); System.out.println("alfa="+alpha); if(alpha==0) break; for(i=0;i<n;i++){dx[i]=alpha*d[i];x[i]+=dx[i];ge[i]=g[i];} System.out.println("j="+j+"dx=\n"+Matrix.toString(dx)); System.out.println("j="+j+"x=\n"+Matrix.toString(x)); g=turev(f,x); System.out.println("j="+j+"g=\n"+Matrix.toString(g)); for(i=0;i<n;i++){dg[i]=g[i]-ge[i];} gamma=norm(g); for(int ii=0;ii<n;ii++) {r[ii]=0.0; for(int kk=0;kk<n;kk++) {r[ii]+=Q[ii][kk]*dg[kk];} } rdg=VT_X(r,dg); dxdg=VT_X(dx,dg); Q1=V_VT(r); Q2=V_VT(dx); for(int ii=0;ii<n;ii++) for(int jj=0;jj<n;jj++) Q[ii][jj]=Q[ii][jj]-Q1[ii][jj]/rdg+Q2[ii][jj]/dxdg; gamma=norm(dx); System.out.println("j="+j+"Q=\n"+Matrix.toString(Q)); j++;k++; if(k>=nn) {k=0;Q=I(n);} } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] davidon_fletcher_powell_V1( f_xj f,double x[]) { int i,j,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-12 ; int n=x.length; double alpha; double dx[]=new double[n]; double g[] =new double[n]; double ge[]=new double[n]; double dg[]=new double[n]; double d[] =new double[n]; double r[] =new double[n]; double rdg,dxdg; double beta; double alpha_d; double Q[][]=I(n); double Q1[][]=new double[n][n]; double Q2[][]=new double[n][n]; int nn=15; i=0; j=0;k=0; g=turev(f,x); while( j++ < nmax && gamma > tolerance ) { for(int ii=0;ii<n;ii++) { d[ii]=0.0; for(int kk=0;kk<n;kk++) {d[ii]=d[ii]-Q[ii][kk]*g[kk];} } alpha=linmin(f,x,d); if(alpha==0) break; for(i=0;i<n;i++){dx[i]=alpha*d[i];x[i]+=dx[i];ge[i]=g[i];} g=turev(f,x); for(i=0;i<n;i++){dg[i]=g[i]-ge[i];} gamma=norm(g); for(int ii=0;ii<n;ii++) {for(int kk=0;kk<n;kk++) {r[ii]=Q[ii][kk]*dg[kk];} } rdg=VT_X(r,dg); dxdg=VT_X(dx,dg); beta=dxdg/rdg; Q1=V_VT(r); Q2=V_VT(dx); for(int ii=0;ii<n;ii++) for(int jj=0;jj<n;jj++) Q[ii][jj]=beta*(Q[ii][jj]-Q1[ii][jj]/rdg)+Q2[ii][jj]/dxdg; gamma=norm(dx); j++;k++; if(k>=nn) {k=0;Q=I(n);} } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); double [] r1= davidon_fletcher_powell(f_x,x0); double [] r2= davidon_fletcher_powell_V1(f_x,x0); s=" çözüm seti DFP : \n"+Matrix.toStringT(r1); s+=" çözüm seti düzeltilmiş DFP : \n"+Matrix.toStringT(r2); String s2="Davidon - Fletcher - Powell çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.13-1 Davidon-Fletcher-Powell metodu Program 5.13-2 Davidon-Fletcher-Powell metodu (türev vektörü fonksiyon olarak verilmiş) // OPO12F Davidon-Fletcher-Powell optimizasyonu // Metod Referansı : Numerical Analysis, 8th edition Richard L. Burden, J. Douglas Faires 3 // sayfa 617 import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; //ff=7.9+0.13*x[0]+0.21*x[1]-0.05*x[0]*x[0]-0.016*x[1]*x[1]-0.007*x[0]*x[1]; //ff=2.0*x[0]*x[1]+2.0*x[0]-x[0]*x[0]-2.0*x[1]*x[1]; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class fxb extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[]=new double[2]; ff[0]=6.0*x[0]-4.0*x[1]-1.0; ff[1]=-4.0*x[0]+4.0*x[1]-1.0; return ff; } } public class OPO12F1 { public static double VT_V(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*left[i]; } return tot; } public static double[][] V_VT(double [] left) { //multiplys a vector transpose with a vector int n=left.length; double aa[][]=new double[n][n]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { aa[i][j]=left[i]*left[j]; } } return aa; } public static double VT_X(double [] left,double [] right) { //multiplys a vector transpose with a vector int n=left.length; double tot=0; for(int i=0;i<n;i++) { tot+=left[i]*right[i]; } return tot; } public static double norm(double v[]) { // vector norm double total=0;; for(int i=0;i<v.length;i++) {total+=v[i]*v[i];} return Math.sqrt(total); } public static double turev(f_xj f,double x[],int denklem_ref,int x_ref) { // // verilen fonksiyonun ikinci türevlerinin matrisi // fonksiyon f in denklem_ref sayılı fonksiyonunun(sayılar 0 dan başlar) // x[x_ref] değişkenine göre türevi (sayılar 0 dan başlar) // df_denklem_ref(x)/d_x_ref // bu metod newtond metodu içinde kullanılmak içindir. double h0=0.256808; int i,m; int n=7; double f1[]; f1=new double[x.length]; double f2[]; f2=new double[x.length]; double x1[]; x1=new double[x.length]; double x2[]; x2=new double[x.length]; for(i=0;i<x.length;i++) { x1[i]=x[i]; x2[i]=x[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; //vector<double> h(n,0); for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { h[i]=h0*Math.pow(r,i); } for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]*1.0094847; f1=df(f,x1); f2=df(f,x2); T[i][0]=( f1[denklem_ref] - f2[denklem_ref])/(2.0*h[i]); x1[x_ref]=x[x_ref]; x2[x_ref]=x[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] - h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] df(f_xj f,double xxi[]) { //Gredyen vektörü // f(x0,x1,x2,...xn) founksiyonunun türev vektörü // [df/dx0, df/dx1,df/dx2,....,df/dxn] // df/dxj j=0...x.length // // bu fonksiyon bilgisayar tarafından hesaplanmaktadır // kullanıcı tarafından tanımlanan f(x) fonksiyonunun // sayısal olarak alınan türevidir. // double a[]=new double[xxi.length]; for(int i=0;i<xxi.length;i++) { a[i]=turev(f,xxi,i); } return a; } public static double turev(f_xj f,double xxi[],int x_ref) { // df/dxj double h0=0.256808; int i,m; int n=7; double x1[]; x1=new double[xxi.length]; double x2[]; x2=new double[xxi.length]; for(i=0;i<xxi.length;i++) { x1[i]=xxi[i]; x2[i]=xxi[i]; } //turev of a simple function double T[][]; T=new double[n][n]; double h[]; h=new double[n]; for(i=0;i<n;i++) { h[i]=0; for(int j=0;j<n;j++) T[i][j]=0; } h[0]=h0; double r=0.5; for( i=1;i<n;i++) { //h[i]=h0*Math.pow(r,i); h0/=2.0; h[i]=h0; } //first turev (difference formula) for(i=0;i<n;i++) { x1[x_ref]+=h[i]; x2[x_ref]-=h[i]; T[i][0]=(f.func(x1)-f.func(x2))/(2.0*h[i]); x1[x_ref]=xxi[x_ref]; x2[x_ref]=xxi[x_ref]; } for(m=1;m<n;m++) { for(i=0;i<n-m;i++) { T[i][m]=(h[i]*h[i]*T[i+1][m-1] h[i+m]*h[i+m]*T[i][m-1])/(h[i]*h[i] - h[i+m]*h[i+m]); } } double xx=T[0][n-1]; return xx; } public static double[] turev(f_xj f_deriv,double x[]) { // df/dxj j=0...x.length // This method calculates turev of a function with more than one independent variable. // Accuracy of method can be adjusted by changing variables h0 and n // function input should be in the form given in abstract class // f_xj,j=0...x.length = df/dx(x_ref) double a[]=new double[x.length]; for(int x_ref=0;x_ref<x.length;x_ref++) { a[x_ref]=turev(f_deriv,x,x_ref); } return a; } public static double SIGN(double a,double b) {return (b > 0.0 ? Math.abs(a) : -Math.abs(a));} public static double MAX(double a,double b) {return (a > b ? a : b);} public static double linmin(f_xj f,double p[],double xi[]) { double tol=2.0e-4; int n=p.length; double pcom[],xicom[]; int j; double xx,xmin,bx,ax; f1dim f1=new f1dim(f,p,xi); ax=0.0; xx=1.0; bx=2.0; double aa[]=mnbrak(f1,ax,xx,bx); ax=aa[0]; xx=aa[1]; bx=aa[2]; xmin=brent(f1,ax,xx,bx,tol); return xmin; } public static double[][] linminiter(f_xj f,double p[],double xi[]) { // yeni iterasyon noktasını verir int n=p.length; double xmin=linmin(f,p,xi); double aa[][]=new double[2][n]; for (int j=0;j<n;j++) { xi[j] *= xmin; p[j] += xi[j]; aa[0][j]=p[j]; aa[1][j]=xi[j]; } return aa; } public static double[] brentf(f_x f,double ax,double bx,double cx,double tol) { // ax,bx,cx üç adet tahmin noktası (bxax ile cx arasında yer almalıdır) // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double CGOLD=(3.0-Math.sqrt(5))/2.0; //altın oran double ZEPS=1.0e-10; double xmin; double aa[]=new double[2]; // SHFT(double a,double b,double c,d) (a)=(b);(b)=(c);(c)=(d); int iter; double a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; double e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; fw=fv=fx=f.func(x); for (iter=1;iter<=ITMAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*Math.abs(x)+ZEPS); if (Math.abs(x-xm) <= (tol2-0.5*(b-a))) { xmin=x; aa[0]=xmin; aa[1]=fx; return aa; } if (Math.abs(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if (q > 0.0) p = -p; q=Math.abs(q); etemp=e; e=d; if (Math.abs(p) >= Math.abs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) d=CGOLD*(e=(x >= xm ? a-x : b-x)); else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); } } else { d=CGOLD*(e=(x >= xm ? a-x : b-x)); } u=(Math.abs(d) >= tol1 ? x+d : x+SIGN(tol1,d)); fu=f.func(u); if (fu <= fx) { if (u >= x) a=x; else b=x; {v=w;w=x;x=u;} {fv=fw;fw=fx;fx=fu;} } else { if (u < x) a=u; else b=u; if (fu <= fw || w == x) { v=w; w=u; fv=fw; fw=fu; } else if (fu <= fv || v == x || v == w) { v=u; fv=fu; } } } System.out.println("BRENT metodunda maksimum iterasyon sayısı aşıldı"); xmin=x; //minumum değer a[0] ile fonksiyon değeri a[1] ile geridöndürülmektedir aa[0]=xmin; aa[1]=fx; return aa; } public static double[] mnbrak(f_x f,double ax,double dx) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçilen uzaklık return mnbrak(f,ax,(ax-dx),(ax+dx)); } public static double[] mnbrak(f_x f,double ax) { // dx ikinci derece polinom için gerekli iki ek noktayı oluşturmak için // ana noktadan seçiln uzaklık return mnbrak(f,ax,(ax-0.1),(ax+0.1)); } public static double[] mnbrak(f_x f,double ax,double bx,double cx) { // ax,bx,cx üç adet tahmin noktası verildiğinde içinde minimum bulunan ax,bx,cx üç adetnoktayı bize arama // sonucu bulur // f : fonksiyon (f_x abstract sınıfında tanımlanmış) // tol tolerans int ITMAX=100; double xmin; double GOLD=(Math.sqrt(5.0)+1.0)/2.0;; double GLIMIT=100.0; double TINY=1.0e-20; double fa,fb,fc; fa=0; fb=0; fc=0; double ulim,u,r,q,fu,dum; double aa[]=new double[3]; fa=f.func(ax); fb=f.func(bx); if (fb > fa) { //SHFT(dum,*ax,*bx,dum) {dum=ax;ax=bx;bx=dum;} //SHFT(dum,*fb,*fa,dum) {dum=fb;fb=fa;fa=dum;} } cx=(bx)+GOLD*(bx-ax); fc=f.func(cx); aa[0]=ax; aa[1]=bx; aa[2]=cx; while (fb > fc) { r=(bx-ax)*(fb-fc); q=(bx-cx)*(fb-fa); u=(bx)-((bx-cx)*q-(bx-ax)*r)/ (2.0*SIGN(MAX(Math.abs(q-r),TINY),q-r)); ulim=(bx)+GLIMIT*(cx-bx); if ((bx-u)*(u-cx) > 0.0) { fu=f.func(u); if (fu < fc) { ax=bx; bx=u; fa=fb; fb=fu; return aa; } else if (fu > fb) { cx=u; fc=fu; return aa; } u=(cx)+GOLD*(cx-bx); fu=f.func(u); } else if ((cx-u)*(u-ulim) > 0.0) { fu=f.func(u); if (fu < fc) { //SHFT(bx,cx,u,cx+GOLD*(cx-bx)) {bx=cx;cx=u;u=cx+GOLD*(cx-bx);} //SHFT(fb,fc,fu,f.func(u)) {fb=fc;fc=fu;fu=f.func(u);} } } else if ((u-ulim)*(ulim-cx) >= 0.0) { u=ulim; fu=f.func(u); } else { u=cx+GOLD*(cx-bx); fu=f.func(u); } //SHFT(ax,bx,cx,u) {ax=bx;bx=cx;cx=u;} //SHFT(fa,fb,fc,fu) {fa=fb;fb=fc;fc=fu;} aa[0]=ax; aa[1]=bx; aa[2]=cx; } return aa; } public static double brent(f_x f,double ax,double bx,double cx,double tol) { double aa[]=brentf(f,ax,bx,cx,tol); return aa[0]; } public static double[][] I(int n) { //unit matrix double b[][]; b=new double[n][n]; for(int i=0;i<n;i++) b[i][i]=1.0; return b; } // Davidon - Fletcher-Powell metodu //________________________________________________________________ public static double[] davidon_fletcher_powell( f_xj f,fi_xi df,double x[]) { int i,j,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-12 ; int n=x.length; double alpha; double dx[]=new double[n]; double g[] =new double[n]; double ge[]=new double[n]; double dg[]=new double[n]; double d[] =new double[n]; double r[] =new double[n]; double rdg,dxdg; double beta; double alpha_d; double Q[][]=I(n); double Q1[][]=new double[n][n]; double Q2[][]=new double[n][n]; int nn=15; i=0; j=0;k=0; g=df.func(x); while( j < nmax && gamma > tolerance ) { for(int ii=0;ii<n;ii++) { d[ii]=0.0; for(int kk=0;kk<n;kk++) {d[ii]=d[ii]-Q[ii][kk]*g[kk];} } System.out.println("j="+j+"d="+Matrix.toString(d)); alpha=linmin(f,x,d); System.out.println("alfa="+alpha); if(alpha==0) break; for(i=0;i<n;i++){dx[i]=alpha*d[i];x[i]+=dx[i];ge[i]=g[i];} System.out.println("j="+j+"dx=\n"+Matrix.toString(dx)); System.out.println("j="+j+"x=\n"+Matrix.toString(x)); g=df.func(x); System.out.println("j="+j+"g=\n"+Matrix.toString(g)); for(i=0;i<n;i++){dg[i]=g[i]-ge[i];} System.out.println("j="+j+"dg=\n"+Matrix.toString(dg)); gamma=norm(g); for(int ii=0;ii<n;ii++) {r[ii]=0.0; for(int kk=0;kk<n;kk++) {r[ii]+=Q[ii][kk]*dg[kk];} } System.out.println("j="+j+"Q=\n"+Matrix.toString(Q)); System.out.println("j="+j+"r=\n"+Matrix.toString(r)); rdg=VT_X(r,dg); dxdg=VT_X(dx,dg); Q1=V_VT(r); Q2=V_VT(dx); for(int ii=0;ii<n;ii++) for(int jj=0;jj<n;jj++) Q[ii][jj]=Q[ii][jj]-Q1[ii][jj]/rdg+Q2[ii][jj]/dxdg; gamma=norm(dx); System.out.println("j="+j+"Q=\n"+Matrix.toString(Q)); j++;k++; if(k>=nn) {k=0;Q=I(n);} } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] davidon_fletcher_powell_V1( f_xj f,fi_xi df,double x[]) { int i,j,k; int nmax=500; double gamma=1.0; double tolerance=1.0e-12 ; int n=x.length; double alpha; double dx[]=new double[n]; double g[] =new double[n]; double ge[]=new double[n]; double dg[]=new double[n]; double d[] =new double[n]; double r[] =new double[n]; double rdg,dxdg; double beta; double alpha_d; double Q[][]=I(n); double Q1[][]=new double[n][n]; double Q2[][]=new double[n][n]; int nn=15; i=0; j=0;k=0; g=df.func(x); while( j++ < nmax && gamma > tolerance ) { for(int ii=0;ii<n;ii++) { d[ii]=0.0; for(int kk=0;kk<n;kk++) {d[ii]=d[ii]-Q[ii][kk]*g[kk];} } alpha=linmin(f,x,d); if(alpha==0) break; for(i=0;i<n;i++){dx[i]=alpha*d[i];x[i]+=dx[i];ge[i]=g[i];} g=df.func(x); for(i=0;i<n;i++){dg[i]=g[i]-ge[i];} gamma=norm(g); for(int ii=0;ii<n;ii++) { r[ii]=0.0; for(int kk=0;kk<n;kk++) {r[ii]+=Q[ii][kk]*dg[kk];} } rdg=VT_X(r,dg); dxdg=VT_X(dx,dg); beta=dxdg/rdg; Q1=V_VT(r); Q2=V_VT(dx); for(int ii=0;ii<n;ii++) for(int jj=0;jj<n;jj++) Q[ii][jj]=beta*(Q[ii][jj]-Q1[ii][jj]/rdg)+Q2[ii][jj]/dxdg; gamma=norm(dx); j++;k++; if(k>=nn) {k=0;Q=I(n);} } if(j >= nmax) JOptionPane.showMessageDialog(null,"Uyarı maximum iterasyon sayısı aşıldı \n"+ " çözüm geçerli olmıyabilir","MAKSİMUM ITERASYON SAYISI UYARISI",JOptionPane.WARNING_MESSAGE); return x; } public static double[] verigir(String s) { String s1=JOptionPane.showInputDialog(s); StringTokenizer token=new StringTokenizer(s1); int n=token.countTokens()-1; int m=n+1; double a[]=new double[m]; int j=0; while(token.hasMoreTokens()) { Double ax=new Double(token.nextToken()); a[j++]=ax.doubleValue(); } return a; } public static void main (String args[]) { String s="kök tahmin değerlerini arada bir boşluk bırakarak giriniz: "; double [] x0=verigir(s); f1 f_x=new f1(); fxb df_x=new fxb(); double [] r1= davidon_fletcher_powell(f_x,df_x,x0); double [] r2= davidon_fletcher_powell_V1(f_x,df_x,x0); s=" çözüm seti DFP : \n"+Matrix.toStringT(r1); s+=" çözüm seti düzeltilmiş DFP : \n"+Matrix.toStringT(r2); String s2="Davidon - Fletcher - Powell çok değişkenli fonksiyon optimizasyonu:"; JOptionPane.showMessageDialog(null,s,s2,JOptionPane.PLAIN_MESSAGE); System.exit(0); } } Çıktı 5.13-2 Davidon-Fletcher-Powell metodu (türev vektörü fonksiyon olarak verilmiş) 5.14 ÇOK BİLİNMİYENLİ-LİNEER OLMAYAN-GEOMETRİK DİREK HESSİAN DEĞİŞTİRME METODU : BROYDEN-FLETCHER-GOLDBERG-SHANNO (BFGS) Önceki iki konuda dik iki vektör (conjuge gradyan) kullanarak İkinci türev matrisinin (Hessian matrisi) ters matrisinin döngüsel olarak oluşturulmasını vere Fletcher-Reeves, Polak-Ribiere ve Davidon-Fletcher-Powell metodlarını incelemiştik. Metodumuzu Hessian matrisinin direk olarak yine benzer dik iki vektör döngüsel yöntemleriyle hesaplanıp ters matrisinin çözümle hesaplanması şeklinde de oluşturabiliriz. Bu tür metod örneği olarak Broyden-Fletcher-Goldberg ve Shanno metodunu verebiliriz. Bu metodu Bir algoritma olarak adım adım tanımlıyalım: 1. Bir ilk tahmin vektörü, x(0) verelim. Hessian matrisinin ilk tahmin değeri olarak birim vektörü alalım. H(0) = I. Dönüştürme parametresi ve maksimum döngü (iterasyon) sayısı nmax’ı tanımlıyalım. K=0 olarak döngüye başlayalım c( 0) f ( x ( 0) ) birinci türev (gradyan) vektörünü hesaplayalım. 2. Birinci türev (gradyan) vektörünün normunu c (k ) hesaplayalım. Eğer c (k ) ise döngüyü durduralım sonuca ulaşmış bulunuyoruz. 3. Yeni arama yönü vektörü d’yi çözmek için H d c lineer denklem sistemini çözelim. 4. d yönündeki optimum değer olan (k) değerini f(x(k)+(k)d(k)) tek boyutlu fonksiyonunun minimum değerini bularak saptayalım. Burada k=0 için olan ilk çözümün en dik yamaç problemine eşdeğer olduğunu not edelim 5. x vektörünün yeni değerini hesaplayalım x( k 1) x( k ) ( k ) d ( k ) 6. Hessian matrisinin yeni değerini hesaplayalım: (k ) (k ) (k ) H ( k 1) H ( k ) D( k ) E ( k ) y ( k ) y ( k )T c ( k ) c ( k )T D(k ) (k ) (k ) E (k ) (k ) (k ) (c .d ) ( y .s ) (k ) (k ) (k ) (k ) s d y c ( k 1) c ( k ) c( k 1) f ( x( k 1) ) 7. k’yi bir arttır k=k+1 ve step 2 ye geri dön. Eğer k değeri maksimum döngü (iterasyon) sayısı nmax a ulaşmışsa uyarı mesajı ver ve en son döngü değerlerini çıktı olarak ver. Bu algoritmada birinci türev (gradyan) vektörü dışarıdan girilen bir sınıfta tanımlanacağı gibi, sayısal türv programları tarafından da hesaplanabilir. Örnek programımızda iki durum için de metod verilmiştir. Örnek olarak yine bir önceki bölümde incelediğimiz f(x0,x1)=3x02-4x0x1+2x12-x0-x1 fonksiyonunun {x}=[-2,2] noktasından başlayarak minimum değerlerini bulma problemini irdeleyelim. Birinci ve ikinci döngü değerlerini elde hesaplama ödev olarak size bırakılmıştır. Program 5.14-1 Broyden - Fletcher-Goldfarb-Shanno (BFGS) metodu // Broyden - Fletcher-Goldfarb-Shanno (BFGS) metodu // Metod Referansı : Intruduction to Optimum Design, Second Edition // Jasbir S. Arora, Elsevier, ISBN: 0-12-064155-0 import java.util.*; import java.awt.*; import java.applet.Applet; import java.awt.event.*; import javax.swing.*; class f1 extends f_xj { public double func(double x[]) { //çözümü istenen fonksiyon double ff; ff=3.0*x[0]*x[0]-4.0*x[0]*x[1]+2.0*x[1]*x[1]-x[0]-x[1]; //ff=5.0*x[0]*x[0]+2.0*x[0]*x[1]+x[1]*x[1]+7.0; return ff; //minimum değil maxsimum istendiğinden - ile çarptık } } class df1 extends fi_xi { public double[] func(double x[]) { //çözümü istenen fonksiyonun türev fonksiyonları double ff[]=new double[2]; //ff[0]=10.0*x[0]+2.0*x[1]; //ff[1]=2.0*x[0]+2.0*x[1]; ff[0]=6*x[0]-4.0*x[1]-1; ff[1]=-4.0*x[0]+4.0*x[1]-1; return ff; } }