PROBLEMS & SOLUTIONS IN SCIENTIFIC COMPUTING WITH C++AND JAVA SIMULATIONS PROBLEMS & SOLUTIONS IN SCIENTIFIC COMPUTING WITH C++AND JAVA SIMULATIONS "VTOj ,-^Of/ jCjf Willi-Hans Steeb > >r^i^ Ybrick Hardy Alexandre Hardy '-•-•'' Rand Afrikaans University, South Africa 0-9 \ 0-9 /f^ri 0 © Cj 0-9 Cj 0-9 'ip •/ \ j \ \) f\\\ V : *< \ i N 1-T^~ v 'ry Ruedi Stoop hstituteforNeuromfomatics,ETHZ,SwitZerla \[P World Scientific NEW JERSEY • LONDON • SINGAPORE • BEIJING • SHANGHAI • HONGKONG • TAIPEI • CHENNAI Published by World Scientific Publishing Co Pte Ltd Toh Tuck Link, Singapore 596224 USA office: 27 Warren Street, Suite 401-402, Hackensack, NJ 07601 UK office: 57 Shelton Street, Covent Garden, London WC2H 9HE British Library Cataloguing-in-Publication Data A catalogue record for this book is available from the British Library PROBLEMS AND SOLUTIONS IN SCIENTIFIC COMPUTING WITH C++ AND JAVA SIMULATIONS Copyright © 2004 by World Scientific Publishing Co Pte Ltd All rights reserved This book, or parts thereof, may not be reproduced in any form or by any means, electronic or mechanical, including photocopying, recording or any information storage and retrieval system now known or to be invented, without written permission from the Publisher For photocopying of material in this volume, please pay a copying fee through the Copyright Clearance Center, Inc., 222 Rosewood Drive, Danvers, MA 01923, USA In this case permission to photocopy is not required from the publisher ISBN 981-256-112-9 ISBN 981-256-125-0 (pbk) Printed in Singapore Preface Scientific computing is a collection of tools, techniques and theories required to develop and solve mathematical models in science and engineering on a computer The purpose of this book is to supply a collection of problems together with their detailed solution which will prove to be valuable to students as well as to research workers in the fields of scientific computing The book provides the various skills and techniques needed in scientific computing The topics range in difficulty from elementary to advanced Almost all problems are solved in detail and most of the problems are selfcontained A number of problems contain C++ or Java code All fields in scientific computing are covered such as matrices, numerical analysis, neural networks, genetic algorithms etc All relevant definitions are given Students can learn important principles and strategies required for problem solving Chapter gives a gentle introduction to problems in scientific computing Teachers will also find this text useful as a supplement, since important concepts and techniques are developed in the problems Basic knowledge in linear algebra, analysis, C++ and Java programming are required We have tested the C++ programs with gcc 3.3 and Microsoft Visual Studio.NET (VC 7) The Java programs have been tested with version 1.5.0 The material was tested in our lectures given around the world Any useful suggestions and comments are welcome, email addresses of the authors: steeb_wh@yahoo.com whsSna.rau.ac.za yorickhardyOyahoo.com yhaSna.rau.ac.za ah@na.rau.ac.za ruediOini.phys.ethz.ch Home pages of the author: http://issc.rau.ac.za v Contents Preface v Notation ix Quickies Bitwise Operations 23 Number Manipulations 51 Combinatorical Problems 89 Matrix Calculus 103 Recursion 149 Finite State Machines 167 Lists, Trees and Queues 177 Numerical Techniques 199 10 Random Numbers and Monte Carlo Techniques 243 11 Ordinary Differential Equations 263 12 Partial Differential Equations 275 vii viii Contents 13 Wavelets 285 14 Graphs 295 15 Neural Networks 305 16 Genetic Algorithms 321 17 Optimization 331 18 File and String Manipulations 347 19 Computer Graphics 379 Bibliography 413 Index 417 Notation N Z Q R R+ C Rn Cn Kz Qz xeR" Ac B An B AUB fog [x\ \x\ © u t x xT = (xi, ^ , , xn) u T = {u\, U2, , un) empty set natural numbers integers rational numbers real numbers nonnegative real numbers complex numbers n-dimensional Euclidian space n-dimensional complex linear space \fzl real part of the complex number z imaginary part of the complex number z element x of R" subset A of set B the intersection of the sets A and B the union of the sets A and B composition of two mappings (/ o g)(x) = f(g{x)) floor function [3.14J = ceiling function [3.14] = XOR operation dependent variable independent variable (time variable) independent variable (space variable) vector of independent variables, T means transpose vector of dependent variables, T means transpose xy xx y đ det tr I [, ] Sjk scalar product (inner product) vector product Kronecker product, tensor product determinant of a square matrix trace of a square matrix unit matrix commutator Kronecker delta with djk = for j = k and Sjk = for j ^ k the sign of x, if x > 0, - if x < 0, if x = eigenvalue real parameter 11.11 sgn(x) A e norm ix 406 Problems and Solutions cout « el->ol->name « "E" « el->o2->name; cout « " e2="; cout « e2->ol->name « "E" « e2->o2->name « endl; } return s; } void replace(vector &L,int k,region Rq.edge *Bpq, region Rp) •C int i=0; vector::iterator iter; region r; iter = L.beginO ; while(iintersect.el == e) { delete *iter; iter = Q.erase(iter); } else if ((*iter)->intersect.e2==e) { delete *iter; iter=Q.erase(iter); } else iter++; y else iter++; } } site_info *extract_min(vector &Q) i 408 Problems and Solutions int = 0; site_info *m; for(int i=0;isite.y-v2->site.y; perp.y=v2->site.x-vl->site.x; if(perp.xparent = NULL; e->count = 0; e->marked[0] = false; e->marked[l] = false; e->ol=vl; e->o2=v2; e->pl=(vl->site+v2->site)/2.0-perp; e->p2=(vl->site+v2->site)/2.0+perp; e->tl=-le7; e->t2=le7; return e; } int get_index(const vector &L,edge *e) { for(int i=0;iparent!=NULL) ep = e->parent; double t = gett(e,p->site); if(gety(e,e->tl)>gety(e,t)) { ep->tl=t; ep->marked[0]=true; Computer Graphics 409 } else { ep->t2=t; ep->marked[l]=true; } } void markbeg(edge *e,site_info *p) { edge *ep = e; if(e->parent!=NULL) ep = e->parent; double t = gett(e,p->site); if(gety(e,e->tl)>gety(e, t)) { ep->t2 = t; ep->marked[l] = true; } else { ep->tl=t; ep->marked[0]=true; } } void clip(edge *e) { point p = getpoint(e,e->tl); if(p.xtl=gettx(e,0.0); if(p.x>1.0) {e->tl=gettx(e,1.0); p=getpoint(e,e->tl); if(p.ytl=getty(e,0.0); if(p.y>1.0) -Ce->tl=getty(e,1.0); p=getpoint(e,e->t2); if(p.xt2=gettx(e,0.0); if(p.x>1.0) {e->t2=gettx(e,1.0); p=getpoint(e,e->t2); if(p.yt2=getty(e,0.0); if(p.y>1.0) {e->t2=getty(e,1.0); e->count=0; if(e->marked[0]) e->count++; if(e->marked[l]) e->count++; e->marked[0]=false;} e->marked[0]=false;} e->marked[O]=false;} e->marked[O]=false;} e->marked[l]=false;} e->marked[l]=false;} e->marked[l]=false;} e->marked[l]=false;} } void metapost_edges(const vector feedges) { for(int i=0;iparent==NULL) { clip(edges[i]); if(edges[i]->tl==edges[i]->t2) continue; if(edges[i]->count==2) cout « "\tdraw " « getpoint(edges[i].edges[i]->tl) « "—" « getpoint(edges[i].edges[i]->t2) « " ; " « endl; if(edges[i]->count==l) if(edges[i]->marked[0]) cout « "\tdrawarrow " 410 Problems and Solutions « « getpoint (edges [i] , edges [i]->tl) « " — " getpoint(edges[i].edges[i]->t2) « ";" « endl; else cout « "\tdrawarrow " « getpoint(edges[i],edges[i]->t2) « " — " « getpoint(edges[i].edges[i]->tl) « ";" « endl; if(edges[i]->count==0) { cout « "\tdrawarrow " « getpoint(edges[i],0.5*(edges[i]->tl+edges[i]->t2)) « " — " « getpoint (edges [i] edges [i]->t2) « " ; " « endl; cout « "\tdrawarrow " « getpoint(edges[i],0.5*(edges[i]->tl+edges[i]->t2)) « " — " « getpoint(edges[i].edges[i]->tl) « " ; " « endl; } } > } void split(edge *Bpq,edge *&Cpq_m,edge *&Cpq_p,site_info *p) { double t = gettx(Bpq,p->site.x); Cpq_m = new edge; *Cpq_m = *Bpq; Cpq_m -> count = 0; Cpq_p = new edge; *Cpq_p = *Bpq; Cpq_p -> count = 0; Cpq_m -> parent = Bpq; Cpq_p -> parent = Bpq; Cpq_m -> t2 = t; Cpq_p -> tl = t; } int main(int argc.char *argv[]) { vector S, Q; vector L; vector edges; site_info *p, *s, *q; region r, Rp, Rq; edge *Bpq, *Bqs; edge *Cpq_p, *Cpq_m, *Cqr, *Cqs, *Crs, *Cqs_p, *Cqs_m; double t; int i, j ; if(argc!=2) { cout « "Usage: " « argv[0] « " file.pts " « endl; return 0; } S = read_points(argv[l]); Computer Graphics 411 begin_metapost(S); Q = S; p = extract_min(Q); r.type = REGION; r.data.site=p; L.push_ba.ck(r); while(Q.size()>0) { p = extract_min(Q); switch(p->type) { case SITE: i = find_region(L,p); Rq = L [ i ] ; q = Rq.data.site; Bpq = bisector(p,q); edges.push_back(Bpq); Rp.type=REGION; Rp.data.site=p; if(fabs(q->site.y-p->site.y) else { split(Bpq,Cpq_m,Cpq_p,p); edges.push_back(Cpq_p); edges.push_back(Cpq_m); } if(i-l>=0) { s = intersect(L[i-1].data.bisector,Cpq_m); if(s!=NULL) q.push.back(s); } if(i+KL.size()) { s = intersect(L[i+1].data.bisector,Cpq_p); if(s!=NULL) q.push_back(s); } if(fabs(q->site.y-p->site.y)site.xsite.x) replace(L,i,Rp,Bpq,Rq); else replace(L,i,Rq,Bpq,Rp); } else { replace(L,i,Rq,Cpq_m,Rp,Cpq_p,Rq); } break; case INTERSECT: q = p->intersect.q; s=p->intersect.s; Cqr = p->intersect.el; Crs = p->intersect.e2; Bqs = bisector(q.s); edges.push_back(Bqs); i = get_index(L,Cqr); j = get_index(L,Crs); if(jsite.y>s->site.y) h = q; else h=s; split(Bqs,Cqs_m,Cqs_p,h); if(fabs(q->site.y-s->site.y)site.x>h->site.x) Cqs=Cqs_p; else Cqs=Cqs_m; } if(Cqs==Cqs_m) delete Cqs_p; else delete Cqs_m; edges.push_back(Cqs); markend(Cqr,p); markend(Crs,p); markbeg(Cqs,p); if(j-i!=2) { cout « "'/.Internal error (>2) i=" « i « " j = " « j « e n d l ; break; } remove_intersections(Q,Cqr); remove_intersections(Q,Crs); replace(L,i,j,Cqs); if(i-2>=0) { s = intersect(L[i-2].data.bisector,Cqs); if(s!=NULL) Q.push_back(s); } if(i+2