├── +sctool ├── dabsquad.m ├── findz0.m ├── gaussj.m ├── isinpoly.m ├── linspace.m ├── nebroyuf.m ├── nechdcmp.m ├── neconest.m ├── nefdjac.m ├── nefn.m ├── nehook.m ├── neinck.m ├── nelnsrch.m ├── nemodel.m ├── neqrdcmp.m ├── neqrsolv.m ├── nersolv.m ├── nesolve.m ├── nesolvei.m ├── nestop.m ├── netrust.m ├── parseopt.m ├── plotptri.m ├── runTests.m ├── scaddvtx.m ├── scangle.m ├── sccheck.m ├── scfix.m ├── scimapz0.m ├── scinvopt.m ├── scmapopt.m ├── scpadapt.m ├── scparopt.m ├── scpltopt.m ├── scqdata.m └── scselect.m ├── @annulusmap ├── annulusmap.m ├── display.m ├── eval.m ├── evalinv.m ├── plot.m ├── private │ ├── dscfun.m │ ├── dscsolv.m │ ├── nearw.m │ ├── nearz.m │ ├── plotdouble.m │ ├── qinit.m │ ├── thdata.m │ ├── wdsc.m │ ├── wprod.m │ ├── wqsum.m │ ├── wquad.m │ ├── wquad1.m │ ├── wtheta.m │ ├── xwtran.m │ └── zdsc.m └── subsref.m ├── @composite ├── composite.m ├── disp.m ├── display.m ├── eval.m ├── feval.m ├── inv.m ├── members.m └── subsref.m ├── @crdiskmap ├── accuracy.m ├── center.m ├── char.m ├── crdiskmap.m ├── diskmap.m ├── display.m ├── embedding.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── get.m ├── mtimes.m ├── parameters.m ├── plot.m ├── plottriang.m ├── plus.m └── private │ ├── craffine.m │ ├── crcdt.m │ ├── crderiv.m │ ├── crembed.m │ ├── crfixwc.m │ ├── crgather.m │ ├── crimap0.m │ ├── crinvmap.m │ ├── crmap.m │ ├── crmap0.m │ ├── crossrat.m │ ├── crparam.m │ ├── crpfun.m │ ├── crplot.m │ ├── crpsdist.m │ ├── crqgraph.m │ ├── crquad.m │ ├── crsplit.m │ ├── crspread.m │ ├── crtriang.m │ └── dderiv.m ├── @crrectmap ├── accuracy.m ├── char.m ├── crrectmap.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── get.m ├── mtimes.m ├── parameters.m ├── plot.m ├── plus.m ├── private │ ├── crembed.m │ ├── crrderiv.m │ ├── crrect.m │ ├── crrmap.m │ ├── crrplot.m │ └── dderiv.m └── rectpoly.m ├── @diskmap ├── accuracy.m ├── center.m ├── char.m ├── diskmap.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── forwardpoly.m ├── get.m ├── hplmap.m ├── mtimes.m ├── parameters.m ├── plot.m ├── plus.m └── private │ ├── dderiv.m │ ├── ddisp.m │ ├── dfixwc.m │ ├── dimapfun.m │ ├── dinvmap.m │ ├── disk2hp.m │ ├── dmap.m │ ├── dparam.m │ ├── dplot.m │ └── dquad.m ├── @dscpolygons ├── display.m ├── dscpolygons.m ├── get.m └── plot.m ├── @extermap ├── accuracy.m ├── capacity.m ├── char.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── extermap.m ├── feval.m ├── forwardpoly.m ├── get.m ├── mtimes.m ├── parameters.m ├── plot.m └── private │ ├── dederiv.m │ ├── dedisp.m │ ├── deinvmap.m │ ├── demap.m │ ├── deparam.m │ ├── deplot.m │ └── dequad.m ├── @hplmap ├── accuracy.m ├── char.m ├── diskmap.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── forwardpoly.m ├── get.m ├── hplmap.m ├── mtimes.m ├── parameters.m ├── plot.m └── private │ ├── hp2disk.m │ ├── hpderiv.m │ ├── hpdisp.m │ ├── hpimapfun.m │ ├── hpinvmap.m │ ├── hpmap.m │ ├── hpparam.m │ ├── hpplot.m │ └── hpquad.m ├── @moebius ├── char.m ├── diff.m ├── disp.m ├── display.m ├── double.m ├── eval.m ├── feval.m ├── inv.m ├── minus.m ├── moebius.m ├── mrdivide.m ├── mtimes.m ├── normal.m ├── plus.m ├── subsref.m ├── uminus.m └── uplus.m ├── @polygon ├── angle.m ├── boundingbox.m ├── cdt.m ├── diam.m ├── display.m ├── double.m ├── fill.m ├── get.m ├── intersect.m ├── isempty.m ├── isinf.m ├── isinpoly.m ├── length.m ├── linspace.m ├── minus.m ├── modify.m ├── mrdivide.m ├── mtimes.m ├── perimeter.m ├── plot.m ├── plotcdt.m ├── plus.m ├── polygon.m ├── size.m ├── subsasgn.m ├── subsref.m ├── triangulate.m ├── truncate.m ├── uminus.m ├── vertex.m └── winding.m ├── @rectmap ├── accuracy.m ├── char.m ├── corners.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── get.m ├── modulus.m ├── mtimes.m ├── parameters.m ├── plot.m ├── private │ ├── ellipjc.m │ ├── ellipkkp.m │ ├── r2strip.m │ ├── rcorners.m │ ├── rderiv.m │ ├── rdisp.m │ ├── rimapfun.m │ ├── rinvmap.m │ ├── rmap.m │ ├── rparam.m │ ├── rpfun.m │ ├── rplot.m │ └── rptrnsfm.m ├── rectangle.m └── rectmap.m ├── @riesurfmap ├── accuracy.m ├── center.m ├── char.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── forwardpoly.m ├── mtimes.m ├── parameters.m ├── plot.m ├── plus.m ├── private │ ├── rsderiv.m │ ├── rsmap.m │ ├── rsparam.m │ ├── rsplot.m │ └── rsquad.m └── riesurfmap.m ├── @scmap ├── char.m ├── diff.m ├── diskmap.m ├── disp.m ├── display.m ├── extermap.m ├── get.m ├── hplmap.m ├── inv.m ├── minus.m ├── mrdivide.m ├── mtimes.m ├── options.m ├── plus.m ├── polygon.m ├── prevertex.m ├── scmap.m ├── scmapopt.m ├── stripmap.m ├── subsref.m ├── uminus.m └── uplus.m ├── @scmapdiff ├── disp.m ├── display.m ├── eval.m ├── feval.m ├── scmapdiff.m └── subsref.m ├── @scmapinv ├── disp.m ├── display.m ├── eval.m ├── feval.m ├── inv.m ├── scmapinv.m └── subsref.m ├── @stripmap ├── accuracy.m ├── char.m ├── diskmap.m ├── display.m ├── eval.m ├── evaldiff.m ├── evalinv.m ├── feval.m ├── get.m ├── hplmap.m ├── mtimes.m ├── parameters.m ├── plot.m ├── private │ ├── stderiv.m │ ├── stdisp.m │ ├── stimapfun.m │ ├── stinvmap.m │ ├── stmap.m │ ├── stparam.m │ ├── stplot.m │ ├── stquad.m │ └── stquadh.m └── stripmap.m ├── CITATION.cff ├── Contents.m ├── LICENSE ├── README.md ├── drawpoly.m ├── faber.m ├── guide.pdf ├── lapsolve.m ├── lapsolvegui.fig ├── lapsolvegui.m ├── lsprogress.fig ├── modpoly.m ├── moebiuscoeffs.m ├── plotpoly.m ├── polyedit.m ├── private ├── OK.png ├── addexist.png ├── addseq.png ├── bullseye.png ├── eraser.png ├── floppy.png ├── grid.png ├── gt2.png ├── gtsign.png ├── magglass.png ├── move.png ├── pencil.png ├── pencileraser.png ├── plot.png ├── polyclose.png ├── polygon5.png ├── prompt.png ├── quantang.png ├── quantlen.png ├── quit.png ├── rescale.png ├── snapxy.png ├── solve.png └── trash.png ├── ptsource.m ├── scdemo.m ├── scdfaber.m ├── scdinf.m ├── scdlong.m ├── scdtutor.m ├── scgexprt.m ├── scgimprt.m ├── scgui.m ├── sdogleg.m └── tests ├── dctests.m ├── testAnnulus.m ├── testDisk.m ├── testExterior.m ├── testHalfplane.m ├── testRectangle.m └── testStrip.m /+sctool/gaussj.m: -------------------------------------------------------------------------------- 1 | function [z,w] = gaussj(n,alf,bet); 2 | %GAUSSJ Nodes and weights for Gauss-Jacobi integration. 3 | % [X,W] = GAUSSJ(N,ALF,BET) returns nodes and weights for Gauss-Jacobi 4 | % integration. Z and W are N-vectors such that 5 | % 6 | % _ +1 7 | % / 8 | % | ALF BET 9 | % | f(x) (1-x) (1+x) dx 10 | % | 11 | % _/ 12 | % -1 13 | % 14 | % is approximated by sum(f(Z) .* W). 15 | % 16 | % Copyright 1997 by Toby Driscoll. Last updated 04/11/97. 17 | 18 | % Uses the Lanczos iteration connection to orthogonal polynomials. 19 | % Borrows heavily from GAUSSJ out of SCPACK Fortran. 20 | 21 | % Calculate coeffs a,b of Lanczos recurrence relation (closed form is 22 | % known). Break out n=1 specially to avoid possible divide by zero. 23 | apb = alf+bet; 24 | a(1) = (bet-alf)/(apb+2); 25 | b(1) = sqrt(4*(1+alf)*(1+bet) / ((apb+3)*(apb+2)^2)); 26 | N = 2:n; 27 | a(N) = (apb)*(bet-alf) ./ ((apb+2*N).*(apb+2*N-2)); 28 | N = 2:(n-1); 29 | b(N) = sqrt(4*N.*(N+alf).*(N+bet).*(N+apb) ./ ... 30 | (((apb+2*N).^2-1).*(apb+2*N).^2)); 31 | 32 | % Find eigvals/eigvecs of tridiag "Ritz" matrix 33 | if n > 1 34 | [V,D] = eig(diag(a) + diag(b,1) + diag(b,-1)); 35 | else 36 | V = 1; 37 | D = a; 38 | end 39 | 40 | % Compute normalization (integral of w(x)) 41 | c = 2^(apb+1)*gamma(alf+1)*gamma(bet+1)/gamma(apb+2); 42 | 43 | % return the values 44 | z = diag(D); 45 | w = c*(V(1,:)').^2; 46 | [z,ind] = sort(z); 47 | w = w(ind); 48 | 49 | -------------------------------------------------------------------------------- /+sctool/linspace.m: -------------------------------------------------------------------------------- 1 | function y = linspace(d1, d2, n) 2 | %LINSPACE Linearly spaced vector. 3 | % LINSPACE(x1, x2) generates a row vector of 100 linearly 4 | % equally spaced points between x1 and x2. 5 | % 6 | % LINSPACE(x1, x2, N) generates N points between x1 and x2. 7 | % 8 | % See also LOGSPACE, :. 9 | % 10 | % This version is modified from that provided in MATLAB 5.2, 11 | % because that version fails when the first two arguments are 12 | % complex. 13 | % 14 | % Copyright (c) 1998 by Toby Driscoll. 15 | % $Id: linspace.m 2 1998-05-10 02:57:52Z tad $ 16 | 17 | if nargin == 2 18 | n = 100; 19 | end 20 | if n~=1 21 | % Original: y = d1:(d2-d1)/(n-1):d2; 22 | y = d1 + (d2-d1)*(0:1/(n-1):1); 23 | else 24 | y = d2; 25 | end 26 | -------------------------------------------------------------------------------- /+sctool/nebroyuf.m: -------------------------------------------------------------------------------- 1 | function A = nebroyuf(A,xc,xp,fc,fp,sx,eta) 2 | % 3 | % A = nebroyuf(A,xc,xf,fc,fp,sx,eta) 4 | % 5 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 6 | % 7 | % This updates A, a secant approximation to the jacobian, using 8 | % BROYDEN'S UNFACTORED SECANT UPDATE. 9 | % 10 | % Algorithm A8.3.1: Part of the modular software system from 11 | % the appendix of the book "Numerical Methods for Unconstrained 12 | % Optimization and Nonlinear Equations" by Dennis & Schnabel 1983. 13 | % 14 | % 15 | % Coded in Matlab by Sherkat Masoum M., April 1988. 16 | % Edited by Richard T. Behrens, June 1988. 17 | % 18 | 19 | % 20 | % Algorithm step 1. 21 | % 22 | n = length(A); 23 | s=xp-xc; 24 | 25 | % 26 | % Algorithm step 2. 27 | % 28 | denom=norm(sx.*s)^2; 29 | 30 | % 31 | % Algorithm step 3. 32 | % 33 | tempi = (fp - fc - A*s); 34 | ii = find(abs(tempi) < eta*(abs(fp)+abs(fc))); 35 | tempi(ii) = zeros(length(ii),1); 36 | A = A + (tempi/denom)*(s.*(sx.*sx))'; 37 | 38 | -------------------------------------------------------------------------------- /+sctool/neconest.m: -------------------------------------------------------------------------------- 1 | function est = neconest(M,M2) 2 | % 3 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 4 | % 5 | % est = neconest(M,M2) 6 | % This is an estimate of the l-1 condition number of an upper triangular 7 | % matrix. 8 | % 9 | % Algorithm A3.3.1: Part of the modular software system from the 10 | % appendix of the book "Numerical Methods for Unconstrained Optimization 11 | % and Nonlinear Equations" by Dennis & Schnabel, 1983. 12 | % 13 | % Coded in MATLAB by Richard T. Behrens, March 1988. 14 | % 15 | 16 | % 17 | % Allocate variables. 18 | % 19 | n = length(M); 20 | p = zeros(n,1); 21 | pm = zeros(n,1); 22 | x = zeros(n,1); 23 | 24 | % 25 | % Algorithm steps 1 & 2. 26 | % 27 | est = norm( triu(M)-diag(diag(M))+diag(M2) ,1); 28 | 29 | % 30 | % Algorithm step 3. 31 | % 32 | x(1) = 1/M2(1); 33 | 34 | % 35 | % Algorithm step 4. 36 | % 37 | p(2:n) = M(1,2:n) * x(1); 38 | 39 | % 40 | % Algorithm step 5. 41 | % 42 | for j = 2:n 43 | xp = (+1-p(j)) / M2(j); 44 | xm = (-1-p(j)) / M2(j); 45 | temp = abs(xp); 46 | tempm = abs(xm); 47 | for i = (j+1):n 48 | pm(i) = p(i) + M(j,i)*xm; 49 | tempm = tempm + abs(p(i))/abs(M2(i)); 50 | p(i) = p(i) + M(j,i) * xp; 51 | temp = temp + abs(p(i))/abs(M2(i)); 52 | end 53 | if (temp > tempm) 54 | x(j) = xp; 55 | else 56 | x(j) = xm; 57 | p((j+1):n) = pm((j+1):n); 58 | end 59 | end 60 | 61 | % 62 | % Algorithm steps 6 & 7. 63 | % 64 | est = est / norm(x,1); 65 | 66 | % 67 | % Algorithm step 8. 68 | % 69 | x = sctool.nersolv(M,M2,x); 70 | 71 | % 72 | % Algorithm steps 9 & 10. 73 | % 74 | est = est * norm(x,1); 75 | 76 | -------------------------------------------------------------------------------- /+sctool/nefdjac.m: -------------------------------------------------------------------------------- 1 | function [J,nofun] = nefdjac(fvec,fc,xc,sx,details,nofun,fparam) 2 | % 3 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 4 | % 5 | % [J,nofun] = nefdjac(fvec,fc,xc,sx,details,nofun,fparam) 6 | % This is a "Finite Differance Jacobian Approximation". It 7 | % calculates a finite differance appproximation to J(xc) 8 | % (the Jacobin of F(x) at x = xc). 9 | % 10 | % Algorithm A5.4.1: Part of the modular software system from 11 | % the appendix of the book "Numerical Methods for Unconstrained 12 | % Optimization and Nonlinear Equations" by Dennis & Schnabel 1983. 13 | % 14 | % Coded in Matlab by Sherkat Masoum M., March 1988. 15 | % Edited by Richard T. Behrens, June 1988. 16 | % 17 | 18 | % 19 | % Algorithm step 1. 20 | % 21 | n=length(fc); 22 | sqrteta = sqrt(details(13)); 23 | 24 | % 25 | % Algorithm step 2. 26 | % 27 | for j =1:n 28 | stepsizej = sqrteta * max(abs(xc(j)),1/sx(j)) * (sign(xc(j))+(xc(j)==0)); 29 | % To incorporate a different stepsize rule, change the previous line. 30 | tempj = xc(j); 31 | xc(j) = xc(j) + stepsizej; 32 | stepsizej=xc(j)-tempj; 33 | % The previous line reduces finite precision error slightly, 34 | % see section 5.4 of the book. 35 | if details(15) 36 | fj =feval(fvec,xc,fparam); % Evaluate function w/parameters. 37 | else 38 | fj =feval(fvec,xc); % Evaluate function w/o parameters. 39 | end 40 | nofun = nofun + 1; 41 | J(1:n,j) = (fj(1:n) - fc(1:n))/stepsizej; 42 | xc(j) = tempj; 43 | end 44 | 45 | -------------------------------------------------------------------------------- /+sctool/nefn.m: -------------------------------------------------------------------------------- 1 | function [fplus,FVplus,nofun] = nefn(xplus,SF,fvec,nofun,fparam) 2 | % 3 | % [fplus,FVplus] = nefn(xplus,SF,fvec) 4 | % 5 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 6 | % 7 | % It evaluates the vector function and calculates the sum of squares 8 | % for nonlinear equations. 9 | % 10 | % Part of the modular software system from the appendix of the book 11 | % "Numerical Methods for Unconstrained Optimization and Nonlinear 12 | % Equations" by Dennis & Schnabel, 1983. 13 | % 14 | % Coded in MATLAB by Richard T. Behrens, April 1988. 15 | % 16 | 17 | if (nargin < 5) 18 | FVplus = feval(fvec,xplus); 19 | else 20 | FVplus = feval(fvec,xplus,fparam); 21 | end 22 | fplus = .5 * sum((SF .* FVplus).^2); 23 | nofun = nofun + 1; 24 | 25 | -------------------------------------------------------------------------------- /+sctool/neqrdcmp.m: -------------------------------------------------------------------------------- 1 | function [M,M1,M2,sing] = neqrdcmp(M) 2 | % 3 | % [M,M1,M2,sing] = neqrdcmp(M) 4 | % 5 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 6 | % 7 | % It is a QR decomposition function. It differs from the one built 8 | % into MATLAB in that the result is encoded as rotation angles. Also, 9 | % it is designed for square matrices only. 10 | % 11 | % Algorithm A3.2.1: Part of the modular software system from the 12 | % appendix of the book "Numerical Methods for Unconstrained Optimization 13 | % and Nonlinear Equations" by Dennis & Schnabel, 1983. 14 | % 15 | % Coded in MATLAB by Richard T. Behrens, March 1988. 16 | % 17 | 18 | % 19 | % Check size of input argument and allocate variables. 20 | % 21 | n = length(M); 22 | M1 = zeros(n,1); 23 | M2 = zeros(n,1); 24 | 25 | % 26 | % Algorithm step 1. 27 | sing = 0; 28 | 29 | % 30 | % Algorithm step 2. 31 | % 32 | for k = 1:(n-1) 33 | eta = max(M(k:n,k)); 34 | if (eta == 0) 35 | M1(k) = 0; 36 | M2(k) = 0; 37 | sing = 1; 38 | else 39 | M(k:n,k) = M(k:n,k) / eta; 40 | sigma = (sign(M(k,k))+(M(k,k)==0)) * norm(M(k:n,k)); 41 | M(k,k) = M(k,k) + sigma; 42 | M1(k) = sigma * M(k,k); 43 | M2(k) = -eta * sigma; 44 | tau = (M(k:n,k)' * M(k:n,(k+1):n)) / M1(k); 45 | M(k:n,(k+1):n) = M(k:n,(k+1):n) - M(k:n,k) * tau; 46 | end 47 | end 48 | 49 | % 50 | % Algorithm step 3. 51 | % 52 | M2(n) = M(n,n); 53 | 54 | -------------------------------------------------------------------------------- /+sctool/neqrsolv.m: -------------------------------------------------------------------------------- 1 | function b = neqrsolv(M,M1,M2,b) 2 | % 3 | % b = neqrsolv(M,M1,M2,b) 4 | % 5 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 6 | % 7 | % It is a linear equation solve function using the QR decomposition. 8 | % 9 | % Algorithm A3.2.2: Part of the modular software system from the 10 | % appendix of the book "Numerical Methods for Unconstrained Optimization 11 | % and Nonlinear Equations" by Dennis & Schnabel, 1983. 12 | % 13 | % Coded in MATLAB by Richard T. Behrens, March 1988. 14 | % 15 | 16 | % 17 | % Algorithm step 1. 18 | % 19 | n = length(M); 20 | for j = 1:(n-1) 21 | tau = (M(j:n,j)' * b(j:n)) / M1(j); 22 | b(j:n) = b(j:n) - tau * M(j:n,j); 23 | end 24 | 25 | % 26 | % Algorithm step 2. 27 | % 28 | b = sctool.nersolv(M,M2,b); 29 | 30 | -------------------------------------------------------------------------------- /+sctool/nersolv.m: -------------------------------------------------------------------------------- 1 | function b = nersolv(M,M2,b) 2 | % 3 | % b = nersolv(M,M2,b) 4 | % 5 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 6 | % 7 | % It is a linear equation solve function for upper triangular systems. 8 | % 9 | % Algorithm A3.2.2a: Part of the modular software system from the 10 | % appendix of the book "Numerical Methods for Unconstrained Optimization 11 | % and Nonlinear Equations" by Dennis & Schnabel, 1983. 12 | % 13 | % Coded in MATLAB by Richard T. Behrens, March 1988. 14 | % 15 | 16 | % 17 | % Algorithm step 1. 18 | % 19 | n = length(M); 20 | b(n) = b(n) / M2(n); 21 | 22 | % 23 | % Algorithm step 2. 24 | % 25 | for i = (n-1):-1:1 26 | b(i) = (b(i) - M(i,(i+1):n) * b((i+1):n)) / M2(i); 27 | end 28 | 29 | -------------------------------------------------------------------------------- /+sctool/nestop.m: -------------------------------------------------------------------------------- 1 | function [consecmax,termcode] = nestop(xc,xp,F,Fnorm,g,sx,sf,retcode,... 2 | details,itncount,maxtaken,consecmax) 3 | % 4 | % [consecmax,termcode] = nestop(xc,xp,F,Fnorm,g,sx,sf,retcode,... 5 | % details,itncount,maxtaken,consecmax) 6 | % 7 | % This function is part of the Nonlinear Equations package, see NESOLVE.M. 8 | % 9 | % It decides whether or not to stop iterating when solving a set of 10 | % nonlinear equations. 11 | % 12 | % Algorithm A7.2.3: Part of the modular software system from the 13 | % appendix of the book "Numerical Methods for Unconstrained Optimization 14 | % and Nonlinear Equations" by Dennis & Schnabel, 1983. 15 | % 16 | % Coded in MATLAB by Richard T. Behrens, March 1988. 17 | % 18 | 19 | % 20 | % Algorithm step 1. 21 | % 22 | n = length(xc); 23 | termcode = 0; 24 | 25 | % 26 | % Algorithm step 2. 27 | % 28 | if (retcode == 1) 29 | termcode = 3; 30 | elseif (max(sf .* abs(F)) <= details(8)) 31 | termcode = 1; 32 | elseif (max( abs(xp - xc) ./ max(abs(xp),ones(n,1)./sx)) <= details(9)) 33 | termcode = 2; 34 | elseif (itncount >= details(6)) 35 | termcode = 4; 36 | elseif (maxtaken) 37 | consecmax = consecmax + 1; 38 | if (consecmax == 5) 39 | termcode = 5; 40 | end 41 | else 42 | consecmax = 0; 43 | if (details(4) | details(3)) 44 | if (max(abs(g).*max(abs(xp),ones(n,1)./sx)/max(Fnorm,(n/2))) ... 45 | <= details(10)) 46 | termcode = 6; 47 | end 48 | end 49 | end 50 | 51 | -------------------------------------------------------------------------------- /+sctool/parseopt.m: -------------------------------------------------------------------------------- 1 | function varargout = parseopt(options) 2 | 3 | % Copyright 1998--2001 by Toby Driscoll. 4 | % $Id: parseopt.m 199 2002-09-13 18:54:27Z driscoll $ 5 | 6 | % There are 2 allowable inputs: old-fashioned array and newfangled 7 | % structure. Handle both here. 8 | 9 | if ~isstruct(options) 10 | user = options; 11 | lenu = length(user); 12 | options = zeros(1,3); 13 | options(1:lenu) = user(1:lenu); 14 | options = options + (options==0).*[0,1e-8,2]; 15 | 16 | trace = options(1); 17 | tol = options(2); 18 | method = options(3); 19 | varargout = { trace,tol,method }; 20 | else 21 | switch(options.TraceSolution) 22 | case 'full' 23 | trace = 2; 24 | case 'on' 25 | trace = 1; 26 | otherwise 27 | trace = 0; 28 | end 29 | tol = options.Tolerance; 30 | method = strmatch(options.SolverMethod,{'line','trust'}); 31 | %%newwindow = strcmp(options.WindowPopup,'on'); 32 | varargout = { trace, tol, method }; 33 | end 34 | -------------------------------------------------------------------------------- /+sctool/plotptri.m: -------------------------------------------------------------------------------- 1 | function h = plotptri(w,Q,lab) 2 | %PLOTPTRI Plot a polygon triangulation. 3 | % PLOTPTRI(W,E) plots the polygon W and the edges of a triangulation 4 | % whose edges are described by E. Instead of E, you may also pass the 5 | % quadrilateral graph structure, Q. 6 | % 7 | % If a nonempty third argument is given, the edges and vertices are 8 | % labeled by number. 9 | % 10 | % An output argument will be assigned a vector of handles to the edges 11 | % drawn. 12 | 13 | % Copyright 1998 by Toby Driscoll. 14 | % $Id: plotptri.m 298 2009-09-15 14:36:37Z driscoll $ 15 | 16 | % Parse input 17 | if isstruct(Q) 18 | edge = Q.edge; 19 | else 20 | edge = Q; 21 | end 22 | 23 | % Plot all edges 24 | we = edge; 25 | we(:) = w(edge); 26 | han = plot(we,'--','color',[0 .5 0]); 27 | 28 | turn_off_hold = ~ishold; 29 | hold on 30 | 31 | % Label if requested 32 | if nargin > 2 & ~isempty(lab) 33 | [he,hl] = plotpoly(w,scangle(w),1); 34 | 35 | % Add circles at vertices 36 | %hll = findobj(hl,'type','line'); 37 | %set(hll,'marker','o','markersize',get(gca,'defaultlinemarkersize')) 38 | 39 | % Edge labels 40 | for k=1:size(edge,2) 41 | mp = mean(w(edge(:,k))); 42 | text(real(mp),imag(mp),int2str(k),'color',[0,0,0],... 43 | 'vert','mid','hor','cen') 44 | end 45 | else 46 | % Unlabeled version 47 | plotpoly(w,scangle(w)); 48 | plot(w,'o') 49 | end 50 | 51 | if turn_off_hold 52 | hold off 53 | end 54 | 55 | if nargout > 0 56 | h = han; 57 | end 58 | -------------------------------------------------------------------------------- /+sctool/runTests.m: -------------------------------------------------------------------------------- 1 | function result = runTests 2 | 3 | import matlab.unittest.TestSuite; 4 | 5 | dirname = which('lapsolve'); 6 | [pathstr,fname,fext] = fileparts(dirname); 7 | dirname = fullfile(pathstr,'tests'); 8 | suiteClass = TestSuite.fromFolder(dirname); 9 | result = run(suiteClass); 10 | 11 | end -------------------------------------------------------------------------------- /+sctool/scangle.m: -------------------------------------------------------------------------------- 1 | function beta = scangle(w) 2 | %SCANGLE Turning angles of a polygon. 3 | % SCANGLE(W) computes the turning angles of the polygon whose vertices 4 | % are specified in the vector W. The turning angle of a vertex 5 | % measures how much the heading changes at that vertex from the 6 | % incoming to the outgoing edge, normalized by pi. For a finite 7 | % vertex, it is equal in absolute value to (exterior angle)/pi, with a 8 | % negative sign for left turns and positive for right turns. Thus the 9 | % turn at a finite vertex is in (-1,1], with 1 meaning a slit. 10 | % 11 | % At an infinite vertex the turning angle is in the range [-3,-1] and 12 | % is equal to the exterior angle of the two sides extended back from 13 | % infinity, minus 2. SCANGLE cannot determine the angle at an 14 | % infinite vertex or its neighbors, and will return NaN's in those 15 | % positions. 16 | % 17 | % See also DRAWPOLY, DEMOINF. 18 | 19 | % Copyright 1998 by Toby Driscoll. 20 | % $Id: scangle.m 298 2009-09-15 14:36:37Z driscoll $ 21 | 22 | w = w(:); 23 | n = length(w); 24 | if n==0 25 | beta = []; 26 | return 27 | end 28 | 29 | atinf = isinf(w); 30 | % These can't be determined. 31 | mask = ~(atinf | atinf([2:n,1]) | atinf([n,1:n-1])); 32 | 33 | dw = diff( w([n 1:n]) ); 34 | dwshift = dw([2:n,1]); 35 | beta = NaN*ones(size(w)); 36 | beta(mask) = angle( dw(mask).*conj(dwshift(mask)) )/pi; 37 | 38 | % It's ill-posed to tell a point (outward) from a slit (inward). Since 39 | % the latter is much more common and important, we'll be generous in 40 | % giving it the tie. 41 | mod = abs(beta+1) < 1e-12; 42 | beta(mod) = ones(size(beta(mod))); 43 | -------------------------------------------------------------------------------- /+sctool/scinvopt.m: -------------------------------------------------------------------------------- 1 | function [ode,newton,tol,maxiter] = scinvopt(options) 2 | %SCINVOPT Parameters used by S-C inverse-mapping routines. 3 | % OPTIONS(1): Algorithm (default 0) 4 | % 0--use ode to get initial guess, then Newton iters. 5 | % 1--use ode only 6 | % 2--use Newton only; take Z0 as initial guess 7 | % OPTIONS(2): Error tolerance for solution (default 1e-8) 8 | % OPTIONS(3): Maximum number of Newton iterations (default 10) 9 | % 10 | % See also HPINVMAP, DINVMAP, DEINVMAP, RINVMAP, STINVMAP. 11 | 12 | % Copyright 1998 by Toby Driscoll. 13 | % $Id: scinvopt.m 298 2009-09-15 14:36:37Z driscoll $ 14 | 15 | user = options; 16 | lenu = length(user); 17 | options = zeros(1,3); 18 | options(1:lenu) = user(1:lenu); 19 | options = options + (options==0).*[0,1e-8,10]; 20 | 21 | ode = options(1)==0 | options(1)==1; 22 | newton = options(1)==0 | options(1)==2; 23 | tol = options(2); 24 | maxiter = options(3); 25 | -------------------------------------------------------------------------------- /+sctool/scparopt.m: -------------------------------------------------------------------------------- 1 | function scparopt(varargin) 2 | %SCPAROPT is defunct. Use SCMAPOPT instead. 3 | 4 | help scparopt 5 | 6 | 7 | -------------------------------------------------------------------------------- /+sctool/scpltopt.m: -------------------------------------------------------------------------------- 1 | function [nqpts,minlen,maxlen,maxrefn] = scpltopt(options) 2 | %SCPLTOPT Parameters used by S-C plotting routines. 3 | % OPTIONS(1): Number of quadrature points per integration. 4 | % Approximately equals -log10(error). Increase if plot 5 | % has false little zigzags in curves (default 4). 6 | % OPTIONS(2): Minimum line segment length, as a proportion of the 7 | % axes box (default 0.005). 8 | % OPTIONS(3): Maximum line segment length, as a proportion of the 9 | % axes box (default 0.05). 10 | % OPTIONS(4): Max allowed number of adaptive refinements made to meet 11 | % other requirements (default 10). 12 | % 13 | % See also HPPLOT, DPLOT, DEPLOT, STPLOT, RPLOT, CRPLOT, CRRPLOT. 14 | 15 | % Copyright 1998 by Toby Driscoll. 16 | % $Id: scpltopt.m 298 2009-09-15 14:36:37Z driscoll $ 17 | 18 | user = options; 19 | lenu = length(user); 20 | options = zeros(1,4); 21 | options(1:lenu) = user(1:lenu); 22 | options = options + (options==0).*[5,.005,.02,16]; 23 | 24 | nqpts = options(1); 25 | minlen = options(2); 26 | maxlen = options(3); 27 | maxrefn = options(4); 28 | -------------------------------------------------------------------------------- /+sctool/scqdata.m: -------------------------------------------------------------------------------- 1 | function qdat = scqdata(beta,nqpts); 2 | %SCQDATA Gauss-Jacobi quadrature data for SC Toolbox. 3 | % SCQDATA(BETA,NQPTS) returns a matrix of quadrature data suitable for 4 | % other SC routines. BETA is a vector of turning angles corresponding 5 | % to *finite* singularities (prevertices and, for exterior map, the 6 | % origin). NQPTS is the number of quadrature points per subinterval, 7 | % roughly equal to -log10(error). 8 | % 9 | % All the SC routines call this routine as needed, and the work 10 | % required is small, so you probably never have to call this function 11 | % directly. 12 | % 13 | % See also GAUSSJ, HPPARAM, DPARAM, DEPARAM, STPARAM, RPARAM. 14 | 15 | % Copyright 1998 by Toby Driscoll. 16 | % $Id: scqdata.m 298 2009-09-15 14:36:37Z driscoll $ 17 | 18 | import sctool.gaussj 19 | 20 | n = length(beta); 21 | qnode = zeros(nqpts,n+1); 22 | qwght = zeros(nqpts,n+1); 23 | for j = find(beta(:)>-1)' 24 | [qnode(:,j),qwght(:,j)] = gaussj(nqpts,0,beta(j)); 25 | end 26 | [qnode(:,n+1),qwght(:,n+1)] = gaussj(nqpts,0,0); 27 | qdat = [qnode,qwght]; 28 | -------------------------------------------------------------------------------- /@annulusmap/eval.m: -------------------------------------------------------------------------------- 1 | function z = eval(map,w) 2 | %EVAL Evaluate Schwarz-Christoffel annulus map at points. 3 | % EVAL(MAP,Z) evaluates the Schwarz-Christoffel map MAP at the points Z 4 | % in the canoncial annulus. 5 | % 6 | % See also ANNULUSMAP. 7 | 8 | % Copyright 2014 by Toby Driscoll. 9 | % Written by Alfa Heryudono. 10 | 11 | % TODO: check if w is in the annulus 12 | 13 | kww = 0; 14 | ic = 2; 15 | 16 | % check if w is in W0. 17 | idx = find(map.w0 == w, 1 ); 18 | if isempty(idx)==0 19 | kww = idx; 20 | ic = 0; 21 | else 22 | % check if w is in W1. 23 | idx = find(map.w1 == w, 1 ); 24 | if isempty(idx)==0 25 | kww = idx; 26 | ic = 1; 27 | end 28 | end 29 | nptq = 8; 30 | 31 | %Making the bridge to old subroutine 32 | dataz = struct('M',map.M,'N',map.N,'Z0',map.Z0,'Z1',map.Z1,'ALFA0',map.ALFA0,'ALFA1',map.ALFA1,'ISHAPE',map.ISHAPE); 33 | z = zdsc(w,kww,ic,map.u,map.c,map.w0,map.w1,map.phi0,map.phi1,nptq,map.qwork,1,dataz); 34 | 35 | end -------------------------------------------------------------------------------- /@annulusmap/evalinv.m: -------------------------------------------------------------------------------- 1 | function w = evalinv(map,z) 2 | %EVALINV Evaluate the inverse map. 3 | % EVALINV(MAP,Z) finds the inverse image of a point Z under the annulusmap 4 | % MAP. That is, it maps from a doubly connected polygonal domain to the 5 | % canonical annulus. 6 | % 7 | % See also ANNULUSMAP, ANNULUSMAP.EvAL. 8 | 9 | % Copyright by Toby Driscoll, 2014. 10 | % Written by Alfa Heryudono, 2003. 11 | 12 | % TODO: check if z is in the doubly connected region 13 | 14 | % z is not allowed to be a vertex. 15 | % check if z is in Z0. 16 | idx = find(map.Z0 == z, 1 ); 17 | if isempty(idx)==0 18 | error('The point calculated is a vertex.'); 19 | else 20 | % check if z is in Z1. 21 | idx = find(map.Z1 == z, 1 ); 22 | if isempty(idx)==0 23 | error('The point calculated is a vertex.'); 24 | end 25 | end 26 | nptq = 8; 27 | eps = 1e-9; 28 | 29 | %Making the bridge to old subroutine 30 | dataz = struct('M',map.M,'N',map.N,'Z0',map.Z0,'Z1',map.Z1,'ALFA0',map.ALFA0,'ALFA1',map.ALFA1,'ISHAPE',map.ISHAPE); 31 | w = wdsc(z,map.u,map.c,map.w0,map.w1,map.phi0,map.phi1,nptq,map.qwork,eps,1,dataz); -------------------------------------------------------------------------------- /@annulusmap/private/nearw.m: -------------------------------------------------------------------------------- 1 | function [knear,inear] = nearw(w,w0,w1,dataz) 2 | % NEARW determines the nearest prevertex to a given pt w. On return integer 3 | % inear indicates that the nearest pt is found either in w0 (inear = 0) or 4 | % in w1 (inear = 1). knear contains the corresponding index in w0 or in w1. 5 | % Note: the prevertices corresponding to infinite vertices will be skipped. 6 | % (outer circle only). 7 | 8 | dist = 2; 9 | d = abs(w - w0); 10 | knear = find(dataz.ALFA0 > 0 & d < dist); 11 | if isempty(knear)==0 12 | knear = find(d==min(d(knear))); 13 | knear = knear(1); % Avoid multiple nearest vertices. 14 | dist = d(knear); 15 | end 16 | 17 | inear = 0; 18 | d = abs(w - w1); 19 | idx = find(d < dist); 20 | if isempty(idx)==0 21 | knear = find(d==min(d(idx))); 22 | knear = knear(1); % Avoid multiple nearest vertices. 23 | inear = 1; 24 | end -------------------------------------------------------------------------------- /@annulusmap/private/nearz.m: -------------------------------------------------------------------------------- 1 | function [knz,inz] = nearz(z,dataz) 2 | % NEARZ determines the nearest vertex to a given pt z. On return integer 3 | % inz indicates that the nearest pt is found either in Z0 (inz = 0) or 4 | % in Z1 (inz = 1). knz contains the corresponding index in Z0 or in Z1. 5 | % If on return inz=2, that means no appropriate vertex is found, which is a 6 | % device used for inverse mapping routine. 7 | inz = 2; 8 | dist = 99; 9 | 10 | d = abs(z - dataz.Z0); 11 | knz = find(dataz.ALFA0 > 0 & d < dist); 12 | if isempty(knz)==0 13 | knz = find(d==min(d(knz))); 14 | knz = knz(1); % Avoid multiple nearest vertices. 15 | dist = d(knz); 16 | inz = 0; 17 | end 18 | 19 | d = abs(z - dataz.Z1); 20 | idx = find(d < dist); 21 | if isempty(idx)==0 22 | knz = find(d==min(d(idx))); 23 | knz = knz(1); % Avoid multiple nearest vertices. 24 | inz = 1; 25 | end 26 | -------------------------------------------------------------------------------- /@annulusmap/private/plotdouble.m: -------------------------------------------------------------------------------- 1 | function plotdouble(pOuter,pInner) 2 | 3 | if (nargin==1) 4 | pInner = pOuter{2}; 5 | pOuter = pOuter{1}; 6 | end 7 | 8 | turn_off_hold = ~ishold; 9 | 10 | plot(pOuter) 11 | hold on 12 | plot(pInner) 13 | 14 | if turn_off_hold, hold off, end; 15 | 16 | end -------------------------------------------------------------------------------- /@annulusmap/private/qinit.m: -------------------------------------------------------------------------------- 1 | function qwork = qinit(dataz,nptq) 2 | % QINIT computes the Gauss-Jacobi nodes & weights for Gauss-Jacobi quadrature. 3 | % Work array qwork must be dimensioned 2*nptq*(M+N+1). It is divided into 2*(M+N+1) 4 | % vectors of length nptq: The first M+N+1 contain quadrature nodes on output, the next 5 | % M+N+1 contain the corresponding weights on output. nptq is the number of 6 | % G-J nodes (same as weights) used. 7 | 8 | % For each finite vertex, compute nodes & weights 9 | % For one-sided Gauss-Jacobi quadrature 10 | 11 | import sctool.gaussj 12 | for K=1:(dataz.M+dataz.N) 13 | inodes = nptq*(K-1)+1; 14 | iwts = nptq*(dataz.M+dataz.N+K)+1; 15 | if (K <= dataz.M) 16 | alpha = dataz.ALFA0(K)-1; 17 | if (dataz.ALFA0(K) > 0) 18 | [qwork(inodes:inodes+nptq-1),qwork(iwts:iwts+nptq-1)]=gaussj(nptq,0,alpha); 19 | else 20 | qwork(iwts:iwts+nptq-1)=0; 21 | qwork(inodes:inodes+nptq-1)=0; 22 | end 23 | else 24 | alpha = dataz.ALFA1(K-dataz.M)-1; 25 | [qwork(inodes:inodes+nptq-1),qwork(iwts:iwts+nptq-1)]=gaussj(nptq,0,alpha); 26 | end 27 | 28 | % Take singularities into account in advance for the purpose of saving 29 | % certain amount of calculation in WQSUM 30 | qwork(iwts:iwts+nptq-1)=qwork(iwts:iwts+nptq-1).*((1+qwork(inodes:inodes+nptq-1)).^(-alpha)); 31 | end 32 | % Compute nodes & weights for pure Gaussian quadrature: 33 | inodes = nptq*(dataz.M+dataz.N)+1; 34 | iwts = nptq*(2*(dataz.M+dataz.N)+1)+1; 35 | [qwork(inodes:inodes+nptq-1),qwork(iwts:iwts+nptq-1)]=gaussj(nptq,0,0); 36 | -------------------------------------------------------------------------------- /@annulusmap/private/thdata.m: -------------------------------------------------------------------------------- 1 | function param4 = thdata(u) 2 | % THDATA generates data related only to inner radius u and used in 3 | % computing the theta-function. 4 | param4 = struct('UARY','VARY','DLAM','IU','POWER','ONEIU'); 5 | 6 | if (u >= 0.63) 7 | param4.VARY = exp(pi^2/log(u)); 8 | param4.DLAM = -log(u)/pi; 9 | return; 10 | elseif (u < 0.06) 11 | param4.IU = 3; 12 | elseif (u < 0.19) 13 | param4.IU = 4; 14 | elseif (u < 0.33) 15 | param4.IU = 5; 16 | elseif (u < 0.45) 17 | param4.IU = 6; 18 | elseif (u < 0.55) 19 | param4.IU = 7; 20 | else 21 | param4.IU = 8; 22 | end 23 | 24 | % Setting some parameter in advanced to be used in some functions. 25 | param4.POWER = []; 26 | param4.POWER(1,1,:) = (1:param4.IU); 27 | param4.UARY = []; 28 | param4.UARY(1,1,:) = (u*ones(1,param4.IU)).^((1:1:param4.IU).^2); 29 | param4.ONEIU = ones(param4.IU,1); -------------------------------------------------------------------------------- /@annulusmap/private/wprod.m: -------------------------------------------------------------------------------- 1 | function w_prod = wprod(w,u,uw0,u_w1,dataz,param4) 2 | % WPROD computes the product (DSC integrand) 3 | % The definition of the integrand can be found in 4 | % USER'S GUIDE to DSCPACK, Chenglie Hu 1995 5 | 6 | w = w(:); 7 | 8 | mattemp = w(:,ones(length(uw0),1)) ./ uw0(ones(length(w),1),:); 9 | param4temp = param4; 10 | param4temp.POWER = param4temp.POWER(ones(length(w),1),ones(length(uw0),1),:); 11 | param4temp.UARY = param4temp.UARY(ones(length(w),1),ones(length(uw0),1),:); 12 | wth = log(wtheta(u,param4temp,mattemp)); 13 | w_prod = wth*(dataz.ALFA0(:)-1); 14 | 15 | mattemp = w(:,ones(length(u_w1),1)) .* u_w1(ones(length(w),1),:); 16 | param4temp = param4; 17 | param4temp.POWER = param4temp.POWER(ones(length(w),1),ones(length(u_w1),1),:); 18 | param4temp.UARY = param4temp.UARY(ones(length(w),1),ones(length(u_w1),1),:); 19 | wth = log(wtheta(u,param4temp,mattemp)); 20 | w_prod = w_prod + wth*(dataz.ALFA1(:)-1); 21 | 22 | w_prod = exp(w_prod); -------------------------------------------------------------------------------- /@annulusmap/private/wqsum.m: -------------------------------------------------------------------------------- 1 | function wq_sum = wqsum(wa,phia,kwa,ic,wb,phib,radius,u,w0,w1,nptq,qwork,linearc,data,param4) 2 | % WQSUM calculates the complex integral from wa to wb along a line 3 | % segment or a circular arc with possible singularity at wa. The 4 | % definition of WQSUM can be found in USER'S GUIDE to DSCPACK, Chenglie Hu 1995 5 | 6 | % Index arrangement: 7 | iwt1=nptq*(ic*data.M+kwa-1)+1; 8 | if (kwa == 0) 9 | iwt1=nptq*(data.M+data.N)+1; 10 | end 11 | iwt2=iwt1+nptq-1; 12 | ioffst=nptq*(data.M+data.N+1); 13 | 14 | % Compute Gauss-Jacobi sum(w(j)*prod(x(j))): 15 | if (linearc==1) 16 | % Integrate along a circular arc: 17 | pwh = (phib-phia)/2; 18 | pwc = (phib+phia)/2; 19 | uw0 = u*w0; 20 | u_w1 = u ./ w1; 21 | w = radius*exp(i*(pwc+pwh*qwork(iwt1:iwt2))); 22 | wq_sum = i*pwh*qwork(ioffst+iwt1:ioffst+iwt2).*w*wprod(w,u,uw0,u_w1,data,param4); 23 | return; 24 | else 25 | % Integrate along a line segment: 26 | wh = (wb-wa)/2; 27 | wc = (wa+wb)/2; 28 | uw0 = u*w0; 29 | u_w1 = u ./ w1; 30 | w = wc+wh*qwork(iwt1:iwt2); 31 | wq_sum = wh*qwork(ioffst+iwt1:ioffst+iwt2)*wprod(w,u,uw0,u_w1,data,param4); 32 | return; 33 | end -------------------------------------------------------------------------------- /@annulusmap/private/wtheta.m: -------------------------------------------------------------------------------- 1 | function w_theta = wtheta(u,param4,w) 2 | % WTHETA evaluates theta-function at matrix w, 3 | % where u is the inner radius of the annulus. The 4 | % definition of theta function can be found in 5 | % USER'S GUIDE to DSCPACK, Chenglie Hu 1995 6 | if (u < 0.63) 7 | w_theta = -w; 8 | w_theta = w_theta(:,:,param4.ONEIU); 9 | w_theta = w_theta .^ param4.POWER; 10 | w_theta = 1 + sum(param4.UARY .* (w_theta + 1./w_theta),3); 11 | else 12 | wt = -i*log(-w); 13 | if (u >= 0.94) 14 | w_theta = exp(-0.25*(wt.^2)/(pi*param4.DLAM))/sqrt(param4.DLAM); 15 | return; 16 | end 17 | w_theta = 1 + 2*param4.VARY*cosh(wt/param4.DLAM); 18 | w_theta = exp(-0.25*(wt.^2)/(pi*param4.DLAM)).*(w_theta/sqrt(param4.DLAM)); 19 | end -------------------------------------------------------------------------------- /@annulusmap/private/xwtran.m: -------------------------------------------------------------------------------- 1 | function [u,c,w0,w1,phi0,phi1] = xwtran(x,w0,w1,phi0,phi1,dataz) 2 | % XWTRAN transforms x(k) (unconstrained parameters suggested by Daeppen) 3 | % to actual DSC parameters : u,c,w0,w1. phi0 & phi1 are arguments of the 4 | % prevertices contained in w0 & w1. 5 | 6 | if (abs(x(1)) <= 1e-14) 7 | u = 0.50; 8 | else 9 | u = (x(1)-2-sqrt(0.9216*x(1)^2+4))/(2*x(1)); 10 | u = (0.0196*x(1)-1)/(u*x(1)); 11 | end 12 | 13 | c = complex(x(2),x(3)); 14 | if (abs(x(dataz.N + 3)) <= 1e-14) 15 | phi1(dataz.N) = 0; 16 | else 17 | ph = (1+sqrt(1+(pi^2)*(x(dataz.N + 3)^2)))/x(dataz.N + 3); 18 | phi1(dataz.N) = (pi^2)/ph; 19 | end 20 | dph = 1; 21 | phsum = dph; 22 | for k = 1:dataz.N - 1 23 | dph = dph/exp(x(3+k)); 24 | phsum = phsum + dph; 25 | end 26 | dph = 2*pi/phsum; 27 | phi1(1) = phi1(dataz.N) + dph; 28 | w1(1) = u*complex(cos(phi1(1)),sin(phi1(1))); 29 | w1(dataz.N) = u*complex(cos(phi1(dataz.N)),sin(phi1(dataz.N))); 30 | phsum = phi1(1); 31 | for k = 1:dataz.N - 2 32 | dph = dph/exp(x(3+k)); 33 | phsum = phsum + dph; 34 | phi1(k+1) = phsum; 35 | w1(k+1) = u*complex(cos(phsum),sin(phsum)); 36 | end 37 | dph = 1; 38 | phsum = dph; 39 | for k = 1:dataz.M - 1 40 | dph = dph/exp(x(dataz.N + 3 + k)); 41 | phsum = phsum + dph; 42 | end 43 | dph = 2*pi/phsum; 44 | phsum = dph; 45 | phi0(1) = dph; 46 | w0(1) = complex(cos(dph),sin(dph)); 47 | for k = 1:dataz.M - 2 48 | dph = dph/exp(x(dataz.N + 3 + k)); 49 | phsum = phsum + dph; 50 | phi0(k+1) = phsum; 51 | w0(k+1) = complex(cos(phsum),sin(phsum)); 52 | end 53 | -------------------------------------------------------------------------------- /@annulusmap/subsref.m: -------------------------------------------------------------------------------- 1 | function wp = subsref(M,S) 2 | %SUBSREF Evaluate map by subscript notation. 3 | % M(ZP), where M is a SC map and ZP is a vector of points in the 4 | % canonical domain of the map, returns the image of the points in ZP. 5 | % 6 | % This just a synonym for EVAL(M,ZP). 7 | % 8 | % See also EVAL, SCMAP. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: subsref.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | if length(S) == 1 & strcmp(S.type,'()') 14 | wp = eval(M,S.subs{1}); 15 | else 16 | error('Only syntax for SCMAP is a single parenthesized subscript.') 17 | end 18 | 19 | -------------------------------------------------------------------------------- /@composite/composite.m: -------------------------------------------------------------------------------- 1 | function f = composite(varargin) 2 | %COMPOSITE Form a composition of maps. 3 | % F = COMPOSITE(F1,F2,...) defines F as the composite map obtained by 4 | % first applying F1, then F2, etc. Each member map may be an SCMAP, 5 | % SCMAPINV (inverse SC), INLINE function, or MOEBIUS map. Note that 6 | % composites not including an INLINE member may be inverted using INV. 7 | % 8 | % See also COMPOSITE/EVAL, COMPOSITE/INV, SCMAP, SCMAPINV, MOEBIUS 9 | 10 | % Copyright 2001 by Toby Driscoll. 11 | % $Id: composite.m 195 2002-09-10 19:11:44Z driscoll $ 12 | 13 | f.maps = {}; 14 | 15 | for n = 1:nargin 16 | map = varargin{n}; 17 | switch class(map) 18 | case 'composite' 19 | m = members(map); 20 | f.maps = {f.maps{:}, m{:}}; 21 | case {'moebius','diskmap','hplmap','extermap','stripmap','rectmap',... 22 | 'crdiskmap','crrectmap','riesurfmap','scmapinv'} 23 | f.maps{end+1} = map; 24 | case 'inline' 25 | if nargin(map) > 1 26 | error('Inline functions must have only one argument.') 27 | else 28 | f.maps{end+1} = map; 29 | end 30 | otherwise 31 | error(sprintf('Object type ''%s'' not recognized.',class(map))) 32 | end 33 | end 34 | 35 | f = class(f,'composite'); 36 | 37 | 38 | -------------------------------------------------------------------------------- /@composite/disp.m: -------------------------------------------------------------------------------- 1 | function disp(f) 2 | 3 | N = length(f.maps); 4 | for n = 1:N 5 | disp(sprintf('#%i',n)) 6 | disp(f.maps{n}) 7 | end 8 | -------------------------------------------------------------------------------- /@composite/display.m: -------------------------------------------------------------------------------- 1 | function display(f) 2 | %DISPLAY Display the members of a composite map. 3 | 4 | fprintf('\n%s = composite of the sequence:\n',inputname(1)) 5 | disp(f) 6 | -------------------------------------------------------------------------------- /@composite/eval.m: -------------------------------------------------------------------------------- 1 | function w = eval(f,z) 2 | %EVAL Evaluate a composite map. 3 | % EVAL(F,Z) evaluates the composite map F at Z. 4 | 5 | % Copyright 2001 by Toby Driscoll. 6 | % $Id: eval.m 169 2001-07-20 15:19:13Z driscoll $ 7 | 8 | w = z; 9 | for n = 1:length(f.maps) 10 | w = feval(f.maps{n},w); 11 | end 12 | -------------------------------------------------------------------------------- /@composite/feval.m: -------------------------------------------------------------------------------- 1 | function w = feval(f,z) 2 | %FEVAL Evaluate a composite map. 3 | 4 | w = z; 5 | for n = 1:length(f.maps) 6 | w = feval(f.maps{n},w); 7 | end 8 | -------------------------------------------------------------------------------- /@composite/inv.m: -------------------------------------------------------------------------------- 1 | function fi = inv(f) 2 | %INV Invert a composite map if possible. 3 | % INV(F) will return a composite that is the inverse of F. However, 4 | % composites using INLINE maps cannot be inverted. 5 | 6 | % Copyright 2001 by Toby Driscoll. 7 | % $Id: inv.m 170 2001-07-20 15:19:52Z driscoll $ 8 | 9 | N = length(f.maps); 10 | list = cell(1,N); 11 | for n = 1:N 12 | m = N+1-n; 13 | if ~isa(f.maps{m},'inline') 14 | list{n} = inv(f.maps{m}); 15 | else 16 | error('Can''t invert INLINE maps.') 17 | end 18 | end 19 | fi = composite(list{:}); 20 | 21 | -------------------------------------------------------------------------------- /@composite/members.m: -------------------------------------------------------------------------------- 1 | function m = members(f) 2 | 3 | m = f.maps; 4 | -------------------------------------------------------------------------------- /@composite/subsref.m: -------------------------------------------------------------------------------- 1 | function wp = subsref(f,S) 2 | %SUBSREF Evaluate composite map by subscript notation. 3 | % F(ZP) is a synonym for EVAL(F,ZP). 4 | % 5 | % See also EVAL, COMPOSITE. 6 | 7 | % Copyright 2001 by Toby Driscoll. 8 | % $Id: subsref.m 154 2001-07-20 13:52:46Z driscoll $ 9 | 10 | if length(S) == 1 & strcmp(S.type,'()') 11 | wp = eval(f,S.subs{1}); 12 | elseif length(S) == 1 & strcmp(S.type,'{}') 13 | idx = S.subs{1}; 14 | if length(idx)==1 & ~ischar(idx) 15 | wp = f.maps{idx}; 16 | else 17 | wp = f.maps(idx); 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /@crdiskmap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of Schwarz-Christoffel cross-ratio disk map. 3 | % ACCURACY(M) estimates the accuracy of the Schwarz-Christoffel CR disk 4 | % map M. The technique used is to compare the cross-ratios of the actual 5 | % polygon image with those of the target polygon, and return the maximum. 6 | % 7 | % See also CRDISKMAP. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: accuracy.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | % If an accuracy has been assigned, don't question it 13 | if ~isempty(M.accuracy) 14 | acc = M.accuracy; 15 | return 16 | end 17 | 18 | % Get data for low-level functions 19 | p = polygon(M); 20 | w = vertex(p); 21 | beta = angle(p) - 1; 22 | cr = M.crossratio; 23 | aff = M.affine; 24 | Q = M.qlgraph; 25 | qdata = M.qdata; 26 | 27 | n = length(w); 28 | 29 | % Crossratios of target polygon 30 | crtarget = crossrat(w,Q); 31 | 32 | % Actual crossratios 33 | crimage = zeros(n-3,1); % image vertex crossratios 34 | 35 | % Compute crossratio for each image quadrilateral 36 | for k = 1:n-3 37 | prever = crembed(cr,Q,k); 38 | wq = -crquad(prever(Q.qlvert(:,k)),Q.qlvert(:,k),prever,beta,qdata); 39 | crimage(k) = (wq(2)-wq(1))*(wq(4)-wq(3))/((wq(3)-wq(2))*(wq(1)-wq(4))); 40 | end 41 | 42 | % Compare them 43 | acc = max(abs(crimage-crtarget)); 44 | -------------------------------------------------------------------------------- /@crdiskmap/center.m: -------------------------------------------------------------------------------- 1 | function wc = center(M,wc) 2 | %CENTER Conformal center of Schwarz-Christoffel disk map. 3 | % CENTER(M) returns the conformal center (image of 0) of the 4 | % Schwarz-Christoffel crossratio disk map represented by M. 5 | % 6 | % CENTER(M,WC) computes a map conformally equivalent to M but with 7 | % conformal center WC (provided WC is inside the polygon of M), and 8 | % returns the new map. If WC is empty, you will be asked to select it 9 | % graphically. 10 | % 11 | % See also CRDISKMAP. 12 | 13 | % Copyright 1998 by Toby Driscoll. 14 | % $Id: center.m 7 1998-05-10 04:37:19Z tad $ 15 | 16 | if nargin == 1 17 | wc = M.center{1}; 18 | else 19 | p = polygon(M); 20 | cr = M.crossratio; 21 | w = vertex(p); 22 | beta = angle(p) - 1; 23 | 24 | if isempty(wc) 25 | [wcfix,wc] = crfixwc(w,beta,cr,M.affine,M.qlgraph); 26 | else 27 | wcfix = crfixwc(w,beta,cr,M.affine,M.qlgraph,wc); 28 | end 29 | 30 | M.center = {wc,wcfix}; 31 | 32 | wc = M; 33 | end 34 | -------------------------------------------------------------------------------- /@crdiskmap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Pretty-print a Schwarz-Christoffel crossratio disk map. 3 | 4 | % Copyright 1998-2001 by Toby Driscoll. 5 | % $Id: char.m 162 2001-07-20 14:33:00Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | beta = angle(p)-1; 10 | cr = f.crossratio; 11 | Q = f.qlgraph; 12 | 13 | L = cell(2,1); 14 | L{1}=' Quadrilateral vertices Prevertex crossratio '; 15 | L{2}=' ------------------------------------------------------'; 16 | for j = 1:length(cr) 17 | L{end+1}=sprintf(' %2i %2i %2i %2i %8.5f',... 18 | Q.qlvert(:,j),cr(j)); 19 | end 20 | wc = center(f); 21 | if imag(wc) < 0 22 | s = '-'; 23 | else 24 | s = '+'; 25 | end 26 | L{end+1} = ' '; 27 | L{end+1} = sprintf(' Conformal center at %.4f %c %.4fi',real(wc),s,abs(imag(wc))); 28 | L{end+1} = sprintf(' Apparent accuracy is %.2e',f.accuracy); 29 | L{end+1} = ' '; 30 | 31 | out = L; 32 | -------------------------------------------------------------------------------- /@crdiskmap/diskmap.m: -------------------------------------------------------------------------------- 1 | function Md = diskmap(M) 2 | %DISKMAP Convert to diskmap object. 3 | % DISKMAP(M), where M is a crossratio diskmap object, returns the 4 | % equivalent map as a diskmap object. This is done by computing the 5 | % prevertices which yield the correct conformal center and have the 6 | % last prevertex equal to 1. If the crossratios of M exceed about 20, 7 | % accuracy will probably be lost in some parts of the polygon. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: diskmap.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | cr = M.crossratio; 13 | wcfix = M.center{2}; 14 | 15 | % Prevertices in the embedding described in wcfix 16 | z = crembed(cr,M.qlgraph,wcfix(1)); 17 | 18 | % Transform to make conformal center correct 19 | mt = wcfix(2:5); 20 | z = (-mt(4)*z + mt(2))./(mt(3)*z - mt(1)); 21 | 22 | Md = diskmap(polygon(M),z); 23 | -------------------------------------------------------------------------------- /@crdiskmap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel crossratio disk map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | beta = angle(p)-1; 10 | cr = M.crossratio; 11 | Q = M.qlgraph; 12 | 13 | L = {' '; ' crdiskmap object:'; ' '}; 14 | L{4}=' Quadrilateral vertices Prevertex crossratio '; 15 | L{5}=' ------------------------------------------------------'; 16 | for j = 1:length(cr) 17 | L{end+1}=sprintf(' %2i %2i %2i %2i %8.5f',... 18 | Q.qlvert(:,j),cr(j)); 19 | end 20 | wc = center(M); 21 | if imag(wc) < 0 22 | s = '-'; 23 | else 24 | s = '+'; 25 | end 26 | L{end+1} = ' '; 27 | L{end+1} = sprintf(' Conformal center at %.4f %c %.4fi',real(wc),s,abs(imag(wc))); 28 | L{end+1} = ' '; 29 | L{end+1} = sprintf(' Apparent accuracy is %.2e',M.accuracy); 30 | L{end+1} = ' '; 31 | 32 | 33 | if nargout==0 34 | fprintf('%s\n',L{:}) 35 | else 36 | out = L; 37 | end -------------------------------------------------------------------------------- /@crdiskmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel crossratio disk map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the unit disk. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also CRDISKMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | if nargin < 3 15 | qdata = M.qdata; 16 | else 17 | qdata = tol; 18 | end 19 | 20 | p = polygon(M); 21 | w = vertex(p); 22 | beta = angle(p) - 1; 23 | cr = M.crossratio; 24 | aff = M.affine; 25 | wcfix = M.center{2}; 26 | Q = M.qlgraph; 27 | 28 | wp = NaN*zp; 29 | idx = abs(zp) <= 1+eps; 30 | wp(idx) = crmap(zp(idx),w,beta,cr,aff,wcfix,Q,qdata); 31 | -------------------------------------------------------------------------------- /@crdiskmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel crossratio disk map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % disk map M at the points ZP. 5 | % 6 | % See also CRDISKMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | beta = angle(polygon(M)) - 1; 12 | cr = M.crossratio; 13 | aff = M.affine; 14 | wcfix = M.center{2}; 15 | Q = M.qlgraph; 16 | qdata = M.qdata; 17 | 18 | fp = crderiv(zp,beta,cr,aff,wcfix,Q,qdata); 19 | -------------------------------------------------------------------------------- /@crdiskmap/evalinv.m: -------------------------------------------------------------------------------- 1 | function zp = evalinv(M,wp,tol) 2 | %EVALINV Invert Schwarz-Christoffel crossratio disk map at points. 3 | % EVALINV(M,WP) evaluates the inverse of the Schwarz-Christoffel map 4 | % M at the points WP in the polygon. The default tolerance of M is 5 | % used. 6 | % 7 | % EVALINV(M,WP,TOL) attempts to give an answer accurate to TOL. If TOL 8 | % is smaller than the accuracy of M, this is unlikely to be met. 9 | % 10 | % See also CRDISKMAP, CRDISKMAP/EVAL. 11 | 12 | % Copyright 1998 by Toby Driscoll. 13 | % $Id: evalinv.m 7 1998-05-10 04:37:19Z tad $ 14 | 15 | if nargin < 3 16 | % Default means use value stored in map object 17 | qdata = M.qdata; 18 | tol = M.accuracy; 19 | else 20 | % An argument was supplied. Is it qdata or a tolerance? 21 | qdata = tol; 22 | if length(tol) > 1 23 | tol = 10^(-size(qdata,1)); 24 | end 25 | end 26 | 27 | p = polygon(M); 28 | w = vertex(p); 29 | beta = angle(p) - 1; 30 | cr = M.crossratio; 31 | aff = M.affine; 32 | wcfix = M.center{2}; 33 | Q = M.qlgraph; 34 | 35 | zp = NaN*wp; 36 | idx = logical(isinpoly(wp,p)); 37 | 38 | zp(idx) = crinvmap(wp(idx),w,beta,cr,aff,wcfix,Q,qdata,[0 tol]); 39 | -------------------------------------------------------------------------------- /@crdiskmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@crdiskmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, crossratio, affine, qlgraph, 8 | % original, qdata, center 9 | 10 | % Copyright 1999-2003 by Toby Driscoll. 11 | % $Id: get.m 236 2003-01-15 15:29:14Z driscoll $ 12 | 13 | for j = 1:length(varargin) 14 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 15 | case 'pol' 16 | varargout{j} = map.scmap.polygon; 17 | case 'opt' 18 | varargout{j} = map.scmap.options; 19 | case 'pre' 20 | param = parameters(map); 21 | varargout{j} = param.prevertex; 22 | case 'cro' 23 | varargout{j} = map.crossratio; 24 | case 'aff' 25 | varargout{j} = map.affine; 26 | case 'qlg' 27 | varargout{j} = map.qlgraph; 28 | case 'ori' 29 | varargout{j} = map.original; 30 | case 'qda' 31 | varargout{j} = map.qdata; 32 | case 'cen' 33 | varargout{j} = map.center{1}; 34 | otherwise 35 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 36 | varargout{j} = []; 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /@crdiskmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 36 1998-06-29 23:14:51Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'crdiskmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | if length(c)==1 & isa(c,'double') 15 | M.affine = c*M.affine; 16 | M.scmap = c*M.scmap; 17 | M = center(M,c*M.center{1}); 18 | else 19 | error('Multiplication is not defined for these operands.') 20 | end 21 | -------------------------------------------------------------------------------- /@crdiskmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.crossratio = M.crossratio; 8 | v.affine = M.affine; 9 | v.center = M.center{1}; 10 | v.qlgraph = M.qlgraph; 11 | v.original = M.original; 12 | v.qdata = M.qdata; 13 | 14 | % We compute prevertices, even though they aren't used. 15 | wcfix = M.center{2}; 16 | mt = wcfix(2:5); 17 | z = embedding(M,wcfix(1)); 18 | v.prevertex = (mt(4)*z - mt(2)) ./ (-mt(3)*z + mt(1)); 19 | -------------------------------------------------------------------------------- /@crdiskmap/plottriang.m: -------------------------------------------------------------------------------- 1 | function plottriang(M,varargin) 2 | %PLOTTRIANG Plot triangulation for CR disk map. 3 | % PLOTTRIANG(M) plots the triangulation of the polygon used in CR disk 4 | % map M. PLOTTRIANG(M,LBL) also labels vertices and edges if LBL is 5 | % nonempty, 6 | 7 | % Copyright 1998 by Toby Driscoll. 8 | % $Id: plottriang.m 7 1998-05-10 04:37:19Z tad $ 9 | 10 | sctool.plotptri(vertex(polygon(M)),M.qlgraph,varargin{:}) 11 | -------------------------------------------------------------------------------- /@crdiskmap/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M,a) 2 | % Add a constant to the map (i.e., translate its image). 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: plus.m 36 1998-06-29 23:14:51Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(a,'crdiskmap') 9 | tmp = M; 10 | M = a; 11 | a = tmp; 12 | end 13 | 14 | if length(a)==1 & isa(a,'double') 15 | M.affine(:,2) = M.affine(:,2) + a; 16 | M.scmap = M.scmap + a; 17 | M = center(M,M.center{1}+a); 18 | else 19 | error('Addition is not defined for these operands.') 20 | end 21 | -------------------------------------------------------------------------------- /@crdiskmap/private/crderiv.m: -------------------------------------------------------------------------------- 1 | function fp = crderiv(zp,beta,cr,aff,wcfix,Q,qdat) 2 | %CRDERIV Derivative of the disk map in crossratio formulation. 3 | % CRDERIV(ZP,BETA,CR,AFF,WCFIX,Q) returns the derivative at the points 4 | % ZP of the Schwarz-Christoffel crossratio disk map. The arguments are 5 | % returned from CRPARAM, CRAFFINE, and CRFIXWC. 6 | % 7 | % CRDERIV(ZP,BETA,CR,AFF,WCFIX,Q,TOL) uses quadrature data intended to 8 | % give an answer accurate to within roughly TOL. 9 | % 10 | % See also CRPARAM, CRAFFINE, CRFIXWC, CRMAP. 11 | 12 | % Copyright 1998 by Toby Driscoll. 13 | % $Id: crderiv.m 7 1998-05-10 04:37:19Z tad $ 14 | 15 | % Parse input and initialize 16 | beta = beta(:); 17 | n = length(beta); 18 | if nargin < 6 19 | qdat = scqdata(beta,8); 20 | elseif length(qdat)==1 21 | qdat = scqdata(beta,max(ceil(-log10(qdat)),4)); 22 | end 23 | fp = zeros(size(zp)); 24 | zp = zp(:).'; 25 | p = length(zp); 26 | 27 | % Transform points into all embeddings, from the reference in wcfix 28 | quadnum = wcfix(1); 29 | mt = wcfix(2:5); 30 | zl = (mt(1)*zp + mt(2)) ./ (mt(3)*zp + mt(4)); 31 | d0 = (mt(1)*mt(4) - mt(2)*mt(3)) ./ (mt(3)*zp + mt(4)).^2; 32 | [zl,dl] = crspread(zl,quadnum,cr,Q); 33 | 34 | % Choose best embeddings based on proximity to origin 35 | [tmp,idx] = min(abs(zl)); 36 | 37 | % Compute derivatives via embeddings 38 | for q = unique(idx) 39 | z = crembed(cr,Q,q); 40 | mask = (idx==q); 41 | % Compose Moebius transformations with disk map, and apply the affine 42 | % transformation constant 43 | fp(mask) = aff(q,1)*d0(mask).*dl(q,mask).*dderiv(zl(q,mask),z,beta); 44 | end 45 | -------------------------------------------------------------------------------- /@crdiskmap/private/crinvmap.m: -------------------------------------------------------------------------------- 1 | function zp = crinvmap(wp,w,beta,cr,aff,wcfix,Q,qdat,options) 2 | %CRINVMAP S-C disk inverse map in crossratio formulation. 3 | % CRINVMAP(WP,W,BETA,CR,AFF,WCFIX,Q) computes the inverse of the disk 4 | % map with given conformal center. You may append the optional 5 | % parameters QDAT and OPTIONS as in DINVMAP. 6 | % 7 | % You must first run CRPARAM, CRAFFINE, and CRFIXWC. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: crinvmap.m 88 1999-11-23 18:20:45Z tad $ 11 | 12 | % Parse input and initialize 13 | import sctool.* 14 | n = length(w); 15 | beta = beta(:); 16 | zp = zeros(size(wp)); 17 | wp = wp(:); 18 | lenwp = length(wp); 19 | if nargin < 9 20 | options = []; 21 | if nargin < 8 22 | qdat = []; 23 | end 24 | end 25 | 26 | if isempty(qdat) 27 | qdat = scqdata(beta,8); 28 | elseif length(qdat)==1 29 | qdat = scqdata(beta,max(ceil(-log10(qdat)),2)); 30 | end 31 | 32 | % For each embedding, perform inverse maps for appropriate points 33 | quadnum = zeros(lenwp,1); % keep track of embeddings 34 | for q=1:n-3 35 | idx = find(~quadnum); 36 | mask = abs(isinpoly(wp(idx),w(Q.qlvert(:,q)),10^(-size(qdat,1)))); 37 | if any(mask) 38 | idx = idx(logical(mask)); 39 | z = crembed(cr,Q,q); 40 | zp(idx) = crimap0(wp(idx),z,beta,aff(q,:),qdat,options); 41 | quadnum(idx) = q*ones(length(idx),1); 42 | end 43 | if all(quadnum), break, end 44 | end 45 | 46 | % Convert from local embeddings to global one 47 | zp = crgather(zp,quadnum,wcfix(1),cr,Q); 48 | mt = wcfix(2:5); 49 | zp = (-mt(4)*zp + mt(2))./(mt(3)*zp - mt(1)); 50 | -------------------------------------------------------------------------------- /@crdiskmap/private/crmap.m: -------------------------------------------------------------------------------- 1 | function wp = crmap(zp,w,beta,cr,aff,wcfix,Q,qdat) 2 | %CRMAP Schwarz-Christoffel disk map in crossratio formulation. 3 | % CRMAP(ZP,W,BETA,CR,AFF,WCFIX,Q,QDAT) computes the values of the disk 4 | % map at the points in vector ZP. The arguments are returned from 5 | % CRPARAM, CRAFFINE, and CRFIXWC. 6 | % 7 | % CRMAP(ZP,W,BETA,CR,AFF,WCFIX,Q,TOL) uses quadrature data intended to 8 | % give an answer accurate to within roughly TOL. 9 | % 10 | % CRMAP(ZP,W,BETA,CR,AFF,WCFIX,Q) uses a tolerance of 1e-8. 11 | % 12 | % See also CRPARAM, CRAFFINE, CRFIXWC, CRPLOT, CRINVMAP. 13 | 14 | % Copyright 1998 by Toby Driscoll. 15 | % $Id: crmap.m 7 1998-05-10 04:37:19Z tad $ 16 | 17 | % Parse input and initialize 18 | n = length(w); 19 | w = w(:); 20 | beta = beta(:); 21 | if nargin < 8 22 | qdat = scqdata(beta,8); 23 | elseif length(qdat)==1 24 | qdat = scqdata(beta,max(ceil(-log10(qdat)),4)); 25 | end 26 | wp = zeros(size(zp)); 27 | zp = zp(:); 28 | p = length(zp); 29 | 30 | % Transform points into all embeddings, from the reference in wcfix 31 | quadnum = wcfix(1); 32 | zl = (wcfix(2)*zp + wcfix(3))./(wcfix(4)*zp + wcfix(5)); 33 | zl = crspread(zl,quadnum,cr,Q); 34 | 35 | % Choose best embeddings based on proximity to origin 36 | [tmp,idx] = min(abs(zl)); 37 | 38 | % Compute maps via embeddings 39 | for q = unique(idx) 40 | z = crembed(cr,Q,q); 41 | mask = (idx==q); 42 | wp(mask) = crmap0(zl(q,mask),z,beta,aff(q,:),qdat); 43 | end 44 | -------------------------------------------------------------------------------- /@crdiskmap/private/crmap0.m: -------------------------------------------------------------------------------- 1 | function wp = crmap0(zp,z,beta,aff,qdat) 2 | %CRMAP Single-embedding map in crossratio formulation. 3 | % CRMAP0(ZP,Z,BETA,AFF) computes the image of ZP under the map defined 4 | % by the single prevertex embedding Z and the affine transformation 5 | % AFF(1:2). 6 | % 7 | % CRMAP0(ZP,Z,BETA,AFF,TOL) uses quadrature data intended to give an 8 | % answer accurate to within roughly TOL. 9 | % 10 | % CRMAP0(ZP,Z,BETA,AFF,WC) uses a tolerance of 1e-8. 11 | % 12 | % In keeping with the CR approach, the integration is from the center 13 | % from the disk. Results may not be accurate for points near crowded 14 | % prevertices. Instead one should re-embed. 15 | % 16 | % See also CRPARAM, CREMBED, CRAFFINE, CRMAP. 17 | 18 | % Copyright 1998 by Toby Driscoll. 19 | % $Id: crmap0.m 7 1998-05-10 04:37:19Z tad $ 20 | 21 | % Parse input and initialize 22 | z = z(:); 23 | n = length(z); 24 | beta = beta(:); 25 | if nargin < 5 26 | qdat = sctool.scqdata(beta,8); 27 | elseif length(qdat)==1 28 | qdat = sctool.scqdata(beta,max(ceil(-log10(qdat)),2)); 29 | end 30 | wp = zp; 31 | zp = zp(:); 32 | np = length(zp); 33 | 34 | % Single out points that are essentially coincident with a prevertex 35 | dif = abs(z(:,ones(np,1)) - zp(:,ones(n,1)).') < 10*eps; 36 | [ir,ic] = find(dif); 37 | sing = zeros(np,1); 38 | % Assign them accurate Gauss-Jacobi quadrature 39 | sing(ic) = ir(:); 40 | 41 | % Do the maps 42 | wp(:) = -aff(1)*crquad(zp,sing,z,beta,qdat) + aff(2); 43 | -------------------------------------------------------------------------------- /@crdiskmap/private/crossrat.m: -------------------------------------------------------------------------------- 1 | function cr = crossrat(w,Q) 2 | %CROSSRAT Crossratios of a triangulated polygon. 3 | % CROSSRAT(W,Q) returns the N-3 crossratios of the N polygon vertices 4 | % W defined by the triangulation as given by the quadrilateral graph 5 | % in Q. 6 | % 7 | % See also CRTRIANG, CRCDT, QLGRAPH. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: crossrat.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | wql = Q.qlvert; % get size of wql right 13 | wql(:) = w(Q.qlvert); 14 | cr = (((wql(2,:)-wql(1,:)).*(wql(4,:)-wql(3,:)))./... 15 | ((wql(3,:)-wql(2,:)).*(wql(1,:)-wql(4,:)))).'; 16 | -------------------------------------------------------------------------------- /@crdiskmap/private/crpfun.m: -------------------------------------------------------------------------------- 1 | function f = crpfun(x,fdat) 2 | %CRPFUN (not intended for calling directly by the user) 3 | % Nonlinear function for CRPARAM. 4 | % Copyright 1999 by Toby Driscoll. 5 | % $Id: crpfun.m 64 1999-01-29 00:58:06Z tad $ 6 | 7 | [n,beta,crtarget,Q,qdat] = deal(fdat{:}); 8 | 9 | crprever = exp(x); % prevertex crossratios 10 | crimage = zeros(n-3,1); % image vertex crossratios 11 | 12 | % Compute crossratio for each image quadrilateral 13 | for k = 1:n-3 14 | prever = crembed(crprever,Q,k); 15 | w = -crquad(prever(Q.qlvert(:,k)),Q.qlvert(:,k),prever,beta,qdat); 16 | crimage(k) = (w(2)-w(1))*(w(4)-w(3))/((w(3)-w(2))*(w(1)-w(4))); 17 | end 18 | 19 | % Logarithmic scaling for residual 20 | f = log(abs(crimage./crtarget)); 21 | -------------------------------------------------------------------------------- /@crdiskmap/private/crpsdist.m: -------------------------------------------------------------------------------- 1 | function d = crpsdist(segment,pts) 2 | %CRPSDIST Distance from point(s) to a line segment. 3 | % CRPSDIST(SEG,PTS) returns a vector the size of PTS indicating the 4 | % distance from each entry to the line segment described by SEG. 5 | 6 | % Copyright 1997 by Toby Driscoll. Last updated 04/29/97. 7 | 8 | if isempty(pts) 9 | d = []; 10 | return 11 | end 12 | 13 | d = Inf*pts; 14 | 15 | % Rotate to make segment equal [0,xmax]. 16 | pts = (pts-segment(1))/sign(diff(segment)); 17 | xmax = abs(diff(segment)); 18 | 19 | % Some points are closest to segment's interior. 20 | mask = (real(pts)>=0) & (real(pts)<=xmax); 21 | d(mask) = abs(imag(pts(mask))); 22 | 23 | % The others are closest to an endpoint. 24 | mask = real(pts) < 0; 25 | d(mask) = abs(pts(mask)); 26 | mask = real(pts) > xmax; 27 | d(mask) = abs(pts(mask)-xmax); 28 | -------------------------------------------------------------------------------- /@crdiskmap/private/dderiv.m: -------------------------------------------------------------------------------- 1 | function [fprime,d2f] = dderiv(zp,z,beta,c) 2 | %DDERIV Derivative of the disk map. 3 | % DDERIV(ZP,Z,BETA,C) returns the derivative at the points of ZP of 4 | % the Schwarz-Christoffel disk map defined by Z, BETA, and C. 5 | % 6 | % See also DPARAM, DMAP. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: dderiv.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | % Support old syntax 12 | if nargin < 4 13 | c = 1; 14 | end 15 | 16 | z = z(:); 17 | beta = beta(:); 18 | zprow = zp(:).'; 19 | fprime = zeros(size(zp)); 20 | 21 | %terms = 1 - zprow./z; 22 | %fprime(:) = c*exp(sum(log(terms).*beta)); 23 | npts = length(zp(:)); 24 | terms = 1 - zprow(ones(length(beta),1),:)./z(:,ones(npts,1)); 25 | fprime(:) = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 26 | 27 | if nargout > 1 % 2nd derivative 28 | d2f = 0; 29 | for k = 1:length(z) 30 | d2f = d2f - (beta(k)/z(k))./terms(k,:).'; 31 | end 32 | d2f = d2f .* fprime; 33 | end 34 | 35 | -------------------------------------------------------------------------------- /@crrectmap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of Schwarz-Christoffel CR rectified map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: accuracy.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | % Just return accuracy of underlying crdiskmap. 8 | acc = accuracy(M.diskmap); 9 | -------------------------------------------------------------------------------- /@crrectmap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Display parameters of a Schwarz-Christoffel CR rectified map. 3 | 4 | % Copyright 1998-2001 by Toby Driscoll. 5 | % $Id: char.m 162 2001-07-20 14:33:00Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | wr = vertex(f.rectpolygon); 10 | alphar = angle(f.rectpolygon); 11 | 12 | L = cell(2,1); 13 | L{1} = ' vertex rectified angle prevertex '; 14 | L{2} = ' ------------------------------------------------------------'; 15 | 16 | u = real(w); 17 | v = imag(w); 18 | ur = real(wr); 19 | vr = imag(wr); 20 | sgn = ['-','+','+']; 21 | s = sgn(sign(v)+2); 22 | sr = sgn(sign(vr)+2); 23 | fmt = ' %8.5f %c %7.5fi %3.1f pi %8.5f %c %7.5fi'; 24 | for j = 1:length(w) 25 | L{end+1} = sprintf(fmt,... 26 | u(j),s(j),abs(v(j)),alphar(j),ur(j),sr(j),abs(vr(j))); 27 | end 28 | L{end+1} = ' '; 29 | L{end+1} = sprintf(' Apparent accuracy is %.2e',accuracy(f)); 30 | L{end+1} = ' '; 31 | 32 | out = L; 33 | -------------------------------------------------------------------------------- /@crrectmap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel CR rectified map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | wr = vertex(M.rectpolygon); 10 | alphar = angle(M.rectpolygon); 11 | 12 | L = {' '; ' crrectmap object:'; ' '}; 13 | L{4} = ' vertex rectified angle prevertex '; 14 | L{5} = ' ------------------------------------------------------------'; 15 | 16 | u = real(w); 17 | v = imag(w); 18 | ur = real(wr); 19 | vr = imag(wr); 20 | sgn = ['-','+','+']; 21 | s = sgn(sign(v)+2); 22 | sr = sgn(sign(vr)+2); 23 | fmt = ' %8.5f %c %7.5fi %3.1f pi %8.5f %c %7.5fi'; 24 | for j = 1:length(w) 25 | L{end+1} = sprintf(fmt,... 26 | u(j),s(j),abs(v(j)),alphar(j),ur(j),sr(j),abs(vr(j))); 27 | end 28 | L{end+1} = ' '; 29 | L{end+1} = sprintf(' Apparent accuracy is %.2e',accuracy(M)); 30 | L{end+1} = ' '; 31 | 32 | 33 | if nargout==0 34 | fprintf('%s\n',L{:}) 35 | else 36 | out = L; 37 | end 38 | -------------------------------------------------------------------------------- /@crrectmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel crossratio rectified map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the canonical domain. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also CRRECTMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | param = parameters(M.diskmap); 15 | 16 | if nargin < 3 17 | qdata = param.qdata; 18 | qdatar = M.rectqdata; 19 | else 20 | qdata = tol; 21 | qdatar = []; 22 | end 23 | 24 | p = polygon(M.diskmap); 25 | w = vertex(p); 26 | beta = angle(p) - 1; 27 | pr = M.rectpolygon; 28 | wr = vertex(pr); 29 | betar = angle(pr) - 1; 30 | cr = param.crossratio; 31 | aff = param.affine; 32 | affr = M.rectaffine; 33 | Q = param.qlgraph; 34 | 35 | wp = NaN*zp; 36 | idx = logical(ones(size(zp))); 37 | wp(idx) = crrmap(zp(idx),w,beta,wr,betar,cr,aff,affr,Q,qdata,qdatar); 38 | -------------------------------------------------------------------------------- /@crrectmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp,tol) 2 | %EVALDIFF Derivative of Schwarz-Christoffel crossratio disk map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % disk map M at the points ZP. 5 | % 6 | % See also CRDISKMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 87 1999-11-19 21:51:52Z tad $ 10 | 11 | % Special thanks to Stefano Costa, who actually made this work. 12 | 13 | 14 | param = parameters(M.diskmap); 15 | 16 | if nargin < 3 17 | qdata = param.qdata; 18 | qdatar = M.rectqdata; 19 | else 20 | qdata = tol; 21 | qdatar = []; 22 | end 23 | 24 | 25 | p = polygon(M.diskmap); 26 | w = vertex(p); 27 | beta = angle(p) - 1; 28 | pr = M.rectpolygon; 29 | wr = vertex(pr); 30 | betar = angle(pr) - 1; 31 | cr = param.crossratio; 32 | aff = param.affine; 33 | affr = M.rectaffine; 34 | Q = param.qlgraph; 35 | 36 | fp = crrderiv(zp,w,beta,wr,betar,cr,aff,affr,Q,qdata,qdatar); 37 | -------------------------------------------------------------------------------- /@crrectmap/evalinv.m: -------------------------------------------------------------------------------- 1 | function wp = evalinv(M,zp,tol) 2 | %EVALINV Invert Schwarz-Christoffel crossratio rectified map at points. 3 | % EVALINV(M,ZP) evaluates the inverse of the Schwarz-Christoffel map M 4 | % at the points WP in the polygon. The default tolerance of M is used. 5 | % 6 | % EVALINV(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL 7 | % is less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also CRRECTMAP, EVAL. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: evalinv.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | param = parameters(M.diskmap); 15 | 16 | if nargin < 3 17 | qdata = param.qdata; 18 | qdatar = M.rectqdata; 19 | else 20 | qdatar = tol; 21 | qdata = []; 22 | end 23 | 24 | p = polygon(M.diskmap); 25 | w = vertex(p); 26 | beta = angle(p) - 1; 27 | pr = M.rectpolygon; 28 | wr = vertex(pr); 29 | betar = angle(pr) - 1; 30 | cr = param.crossratio; 31 | aff = param.affine; 32 | affr = M.rectaffine; 33 | Q = param.qlgraph; 34 | 35 | wp = NaN*zp; 36 | idx = logical(ones(size(zp))); 37 | wp(idx) = crrmap(zp(idx),wr,betar,w,beta,cr,affr,aff,Q,qdatar,qdata); 38 | -------------------------------------------------------------------------------- /@crrectmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@crrectmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, diskmap, rectpoly, raffine 8 | 9 | % Copyright 1999 by Toby Driscoll. 10 | % $Id: get.m 79 1999-09-30 23:04:05Z tad $ 11 | 12 | for j = 1:length(varargin) 13 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 14 | case 'pol' 15 | varargin{j} = map.scmap.polygon; 16 | case 'opt' 17 | varargin{j} = map.scmap.options; 18 | case 'dis' 19 | varargin{j} = map.diskmap; 20 | case 'rec' 21 | varargin{j} = map.rectpolygon; 22 | case 'raf' 23 | varargin{j} = map.rectaffine; 24 | case 'pre' 25 | varargin{j} = vertex(map.rectpolygon); 26 | otherwise 27 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 28 | varargin{j} = []; 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /@crrectmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 36 1998-06-29 23:14:51Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'crrectmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | if length(c)==1 & isa(c,'double') 15 | M.diskmap = c*M.diskmap; 16 | else 17 | error('Multiplication is not defined for these operands.') 18 | end 19 | -------------------------------------------------------------------------------- /@crrectmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.diskmap = M.diskmap; 8 | v.rectpolygon = M.rectpolygon; 9 | v.rectaffine = M.rectaffine; 10 | v.prevertex = vertex(M.rectpolygon); 11 | -------------------------------------------------------------------------------- /@crrectmap/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M,a) 2 | % Add a constant to the map (i.e., translate its image). 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: plus.m 36 1998-06-29 23:14:51Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(a,'crrectmap') 9 | tmp = M; 10 | M = a; 11 | a = tmp; 12 | end 13 | 14 | if length(a)==1 & isa(a,'double') 15 | M.diskmap = M.diskmap + a; 16 | else 17 | error('Addition is not defined for these operands.') 18 | end 19 | -------------------------------------------------------------------------------- /@crrectmap/private/crrderiv.m: -------------------------------------------------------------------------------- 1 | function fp = crrderiv(zp,w,beta,wr,betar,cr,aff,affr,Q,qdat,qdatr) 2 | %CRRDERIV Derivative of the crossratio rectified map. 3 | % CRRDERIV(ZP,W,BETA,WR,BETAR,CR,AFF,AFFR,Q) returns the derivative at 4 | % the points ZP of the Schwarz-Christoffel crossratio rectified 5 | % map. The arguments are returned from CRPARAM, CRAFFINE, and CRRECT. 6 | % 7 | % CRRDERIV(ZP,W,BETA,WR,BETAR,CR,AFF,AFFR,Q,TOL) uses quadrature data 8 | % intended to give an answer accurate to within roughly TOL. 9 | % 10 | % See also CRPARAM, CRAFFINE, CRRECT, CRRMAP. 11 | 12 | % Copyright 1998 by Toby Driscoll. 13 | % $Id: crrderiv.m 89 1999-11-23 18:32:52Z tad $ 14 | 15 | % Parse input and initialize 16 | beta = beta(:); 17 | n = length(beta); 18 | if nargin < 11 19 | if nargin < 10 20 | qd = cell(0,0); 21 | else 22 | qd{1} = qdat; 23 | end 24 | else 25 | qd = {qdat,qdatr}; 26 | end 27 | 28 | fp = zeros(size(zp)); 29 | 30 | % Compute inverse images in disk 31 | [wp,qnum,up] = crrmap(zp,w,beta,wr,betar,cr,aff,affr,Q,qd{:}); 32 | qnum = qnum(:).'; 33 | 34 | % Compute derivatives via embeddings 35 | for q = unique(qnum(~isnan(qnum))) 36 | mask = (qnum==q); 37 | z = crembed(cr,Q,q); 38 | % Compose disk map with the affine transformation constant 39 | fp(mask) = aff(q,1)*dderiv(up(mask),z,beta); 40 | % Do same for inverse of rectified 41 | fp(mask) = fp(mask)./(affr(q,1)*dderiv(up(mask),z,betar)); 42 | end 43 | -------------------------------------------------------------------------------- /@crrectmap/private/dderiv.m: -------------------------------------------------------------------------------- 1 | function [fprime,d2f] = dderiv(zp,z,beta,c) 2 | %DDERIV Derivative of the disk map. 3 | % DDERIV(ZP,Z,BETA,C) returns the derivative at the points of ZP of 4 | % the Schwarz-Christoffel disk map defined by Z, BETA, and C. 5 | % 6 | % See also DPARAM, DMAP. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: dderiv.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | % Support old syntax 12 | if nargin < 4 13 | c = 1; 14 | end 15 | 16 | z = z(:); 17 | beta = beta(:); 18 | zprow = zp(:).'; 19 | fprime = zeros(size(zp)); 20 | 21 | %terms = 1 - zprow./z; 22 | %fprime(:) = c*exp(sum(log(terms).*beta)); 23 | npts = length(zp(:)); 24 | terms = 1 - zprow(ones(length(beta),1),:)./z(:,ones(npts,1)); 25 | fprime(:) = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 26 | 27 | if nargout > 1 % 2nd derivative 28 | d2f = 0; 29 | for k = 1:length(z) 30 | d2f = d2f - (beta(k)/z(k))./terms(k,:).'; 31 | end 32 | d2f = d2f .* fprime; 33 | end 34 | 35 | -------------------------------------------------------------------------------- /@crrectmap/rectpoly.m: -------------------------------------------------------------------------------- 1 | function pr = rectpoly(M) 2 | % Return rectified polygon. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: rectpoly.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | pr = M.rectpolygon; 8 | -------------------------------------------------------------------------------- /@diskmap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of Schwarz-Christoffel disk map. 3 | % ACCURACY(M) estimates the accuracy of the Schwarz-Christoffel disk 4 | % map M. The technique used is to compare the differences between 5 | % successive finite vertices to the integral between the corresponding 6 | % prevertices, and return the maximum. 7 | % 8 | % See also DISKMAP. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: accuracy.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | % If an accuracy has been assigned, don't question it 14 | if ~isempty(M.accuracy) 15 | acc = M.accuracy; 16 | return 17 | end 18 | 19 | % Get data for low-level functions 20 | p = polygon(M); 21 | w = vertex(p); 22 | beta = angle(p) - 1; 23 | z = M.prevertex; 24 | c = M.constant; 25 | qdata = M.qdata; 26 | 27 | % Test accuracy by integrating between consecutive finite prevertices, and 28 | % comparing to differences of vertices. 29 | 30 | n = length(w); 31 | idx = find(~isinf(w)); 32 | wf = w(idx); % finite vertices 33 | 34 | % Two columns hold endpoint indices for integrations 35 | idx = [idx(1:end) idx([2:end 1])]; 36 | 37 | % Always use center as the integration midpoint 38 | %dtheta = mod(angle(z(idx(:,2))./z(idx(:,1))),2*pi); 39 | %mid = z(idx(:,1)).*exp(i*dtheta/2); 40 | mid = zeros(length(idx),1); 41 | 42 | % Do the integrations 43 | I = dquad(z(idx(:,1)),mid,idx(:,1),z,beta,qdata) - ... 44 | dquad(z(idx(:,2)),mid,idx(:,2),z,beta,qdata); 45 | 46 | acc = max(abs( c*I - diff(wf([1:end 1])) )); 47 | -------------------------------------------------------------------------------- /@diskmap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Pretty-print a Schwarz-Christoffel disk map. 3 | 4 | % Copyright 2001 by Toby Driscoll. 5 | % $Id: char.m 157 2001-07-20 14:03:36Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = f.prevertex; 11 | c = f.constant; 12 | 13 | L = cell(2,1); 14 | L{1}=' vertex alpha prevertex arg/pi'; 15 | L{2}=' -----------------------------------------------------------------------'; 16 | u = real(w); 17 | v = imag(w); 18 | x = real(z); 19 | y = imag(z); 20 | ang = angle(z)/pi; 21 | ang(ang<=0) = ang(ang<=0) + 2; 22 | 23 | fmt = ' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f'; 24 | for j = 1:length(w) 25 | if v(j) < 0 26 | s1 = '-'; 27 | else 28 | s1 = '+'; 29 | end 30 | if y(j) < 0 31 | s2 = '-'; 32 | else 33 | s2 = '+'; 34 | end 35 | L{end+1}=sprintf(fmt,u(j),s1,abs(v(j)),alpha(j),x(j),s2,abs(y(j)),ang(j)); 36 | end 37 | 38 | L{end+1} = ' '; 39 | if imag(c) < 0 40 | s = '-'; 41 | else 42 | s = '+'; 43 | end 44 | L{end+1}=sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 45 | 46 | wc = center(f); 47 | if imag(wc) < 0 48 | s = '-'; 49 | else 50 | s = '+'; 51 | end 52 | L{end+1}=sprintf(' Conformal center at %.4f %c %.4fi',real(wc),s,abs(imag(wc))); 53 | 54 | L{end+1} = sprintf(' Apparent accuracy is %.2e',f.accuracy); 55 | L{end+1} = ' '; 56 | 57 | out = L; 58 | -------------------------------------------------------------------------------- /@diskmap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel disk map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = M.prevertex; 11 | c = M.constant; 12 | 13 | L = {' '; ' diskmap object:'; ' '}; 14 | L{4}=' vertex alpha prevertex arg/pi'; 15 | L{5}=' -----------------------------------------------------------------------'; 16 | u = real(w); 17 | v = imag(w); 18 | x = real(z); 19 | y = imag(z); 20 | ang = angle(z)/pi; 21 | ang(ang<=0) = ang(ang<=0) + 2; 22 | 23 | fmt = ' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f'; 24 | for j = 1:length(w) 25 | if v(j) < 0 26 | s1 = '-'; 27 | else 28 | s1 = '+'; 29 | end 30 | if y(j) < 0 31 | s2 = '-'; 32 | else 33 | s2 = '+'; 34 | end 35 | L{end+1}=sprintf(fmt,u(j),s1,abs(v(j)),alpha(j),x(j),s2,abs(y(j)),ang(j)); 36 | end 37 | 38 | L{end+1} = ' '; 39 | if imag(c) < 0 40 | s = '-'; 41 | else 42 | s = '+'; 43 | end 44 | L{end+1}=sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 45 | 46 | wc = center(M); 47 | if imag(wc) < 0 48 | s = '-'; 49 | else 50 | s = '+'; 51 | end 52 | L{end+1}=sprintf(' Conformal center at %.4f %c %.4fi',real(wc),s,abs(imag(wc))); 53 | 54 | L{end+1} = ' '; 55 | L{end+1} = sprintf(' Apparent accuracy is %.2e',M.accuracy); 56 | L{end+1} = ' '; 57 | 58 | 59 | if nargout==0 60 | fprintf('%s\n',L{:}) 61 | else 62 | out = L; 63 | end -------------------------------------------------------------------------------- /@diskmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel disk map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the unit disk. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also DISKMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | if nargin < 3 15 | qdata = M.qdata; 16 | else 17 | qdata = tol; 18 | end 19 | 20 | p = polygon(M); 21 | wp = NaN*zp; 22 | idx = abs(zp) <= 1+eps; 23 | wp(idx) = dmap(zp(idx),vertex(p),angle(p)-1,M.prevertex,M.constant,qdata); 24 | -------------------------------------------------------------------------------- /@diskmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel disk map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % disk map M at the points ZP. 5 | % 6 | % See also DISKMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | z = M.prevertex; 12 | c = M.constant; 13 | beta = angle(polygon(M)) - 1; 14 | 15 | fp = dderiv(zp,z,beta,c); 16 | -------------------------------------------------------------------------------- /@diskmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@diskmap/forwardpoly.m: -------------------------------------------------------------------------------- 1 | function p = forwardpoly(map) 2 | % Given a diskmap M, FORWARDPOLY(M) returns the polygon that is 3 | % formed using the prevertices, angles, and quadrature data of that 4 | % map. If the prevertices were found from the solution of a 5 | % parameter problem, then the result should agree closely with the 6 | % original polygon that was supplied. 7 | 8 | % Copyright (c) 1998 by Toby Driscoll. 9 | % $Id: forwardpoly.m 28 1998-06-22 22:32:30Z tad $ 10 | 11 | z = map.prevertex; 12 | alpha = angle(polygon(map)); 13 | c = map.constant; 14 | 15 | n = length(z); 16 | 17 | % Since there is no parameter problem, use high accuracy in quadrature. 18 | qdata = sctool.scqdata(alpha-1,16); 19 | 20 | w = zeros(n,1); 21 | atinf = (alpha < eps); 22 | w(atinf) = Inf; 23 | 24 | % Endpoints of integrations 25 | idx = find(~atinf); 26 | idx = [idx(1:end-1) idx(2:end)]; 27 | 28 | % Origin is midpoint of every integration 29 | mid = zeros(length(idx),1); 30 | 31 | % Integrations 32 | I = dquad(z(idx(:,1)),mid,idx(:,1),z,alpha-1,qdata) - ... 33 | dquad(z(idx(:,2)),mid,idx(:,2),z,alpha-1,qdata); 34 | 35 | % Deduce vertices 36 | w(~atinf) = c*cumsum([0;I]); 37 | 38 | p = polygon(w,alpha); 39 | -------------------------------------------------------------------------------- /@diskmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, constant, center 8 | 9 | % Copyright 1999-2003 by Toby Driscoll. 10 | % $Id: get.m 237 2003-01-15 15:29:15Z driscoll $ 11 | 12 | for j = 1:length(varargin) 13 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 14 | case 'pol' 15 | varargout{j} = map.scmap.polygon; 16 | case 'opt' 17 | varargout{j} = map.scmap.options; 18 | case 'pre' 19 | varargout{j} = map.prevertex; 20 | case 'con' 21 | varargout{j} = map.constant; 22 | case 'cen' 23 | varargout{j} = center(map); 24 | otherwise 25 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 26 | varargout{j} = []; 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /@diskmap/hplmap.m: -------------------------------------------------------------------------------- 1 | function M1 = hplmap(M) 2 | %HPLMAP Convert Schwarz-Christoffel disk map to a map from the half-plane. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: hplmap.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | p = polygon(M); 8 | [z1,c1] = disk2hp(vertex(p),angle(p)-1,M.prevertex,M.constant); 9 | M1 = hplmap(p,scmapopt(M),z1,c1); 10 | 11 | 12 | -------------------------------------------------------------------------------- /@diskmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 34 1998-06-29 23:01:00Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'diskmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.polygon = c*M.polygon; 16 | M.center = c*M.center; -------------------------------------------------------------------------------- /@diskmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.prevertex = M.prevertex; 8 | v.constant = M.constant; -------------------------------------------------------------------------------- /@diskmap/plot.m: -------------------------------------------------------------------------------- 1 | function [h,r,theta] = plot(M,varargin) 2 | %PLOT Visualize a Schwarz-Christoffel disk map. 3 | % PLOT(M) plots the polygon associated with the Schwarz-Christoffel 4 | % disk map M and the images of ten evenly spaced circles and radii 5 | % under the S-C transformation. 6 | % 7 | % PLOT(M,NR,NTHETA) plots the images of NR circles and NTHETA radii. 8 | % 9 | % PLOT(M,R,THETA) plots the circles at radii given by the entries of R 10 | % and radii at the angles specified in THETA. 11 | % 12 | % PLOT(M,TOL) or PLOT(M,NR,NTHETA,TOL) or PLOT(M,R,THETA,TOL) 13 | % computes the map with accuracy roughly TOL. Normally TOL defaults to 14 | % 1e-4 or the accuracy of M, whichever is greater. 15 | % 16 | % See also DISKMAP, EVAL. 17 | 18 | % Copyright 1998 by Toby Driscoll. 19 | % $Id: plot.m 7 1998-05-10 04:37:19Z tad $ 20 | 21 | p = polygon(M); 22 | w = vertex(p); 23 | beta = angle(p) - 1; 24 | z = M.prevertex; 25 | c = M.constant; 26 | 27 | if nargin == 1 28 | [a1,a2,a3] = dplot(w,beta,z,c); 29 | elseif length(varargin) == 1 30 | % Tolerance given only 31 | [a1,a2,a3] = dplot(w,beta,z,c,10,10,ceil(-log10(varargin{1}))); 32 | elseif length(varargin) == 2 33 | % R, theta given only 34 | [a1,a2,a3] = dplot(w,beta,z,c,varargin{1},varargin{2}); 35 | else 36 | % All given 37 | nqpts = ceil(-log10(varargin{3})); 38 | [a1,a2,a3] = dplot(w,beta,z,c,varargin{1},varargin{2},nqpts); 39 | end 40 | 41 | if nargout > 0 42 | h = a1; 43 | r = a2; 44 | theta = a3; 45 | end 46 | 47 | -------------------------------------------------------------------------------- /@diskmap/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M,a) 2 | % Add a constant to the image of a diskmap (i.e., translate image). 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: plus.m 35 1998-06-29 23:02:02Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(a,'diskmap') 9 | tmp = M; 10 | M = a; 11 | a = tmp; 12 | end 13 | 14 | if length(a)==1 & isa(a,'double') 15 | M.center = M.center + a; 16 | M.polygon = M.polygon + a; 17 | else 18 | error('Addition is not defined for these operands.') 19 | end 20 | -------------------------------------------------------------------------------- /@diskmap/private/dderiv.m: -------------------------------------------------------------------------------- 1 | function [fprime,d2f] = dderiv(zp,z,beta,c) 2 | %DDERIV Derivative of the disk map. 3 | % DDERIV(ZP,Z,BETA,C) returns the derivative at the points of ZP of 4 | % the Schwarz-Christoffel disk map defined by Z, BETA, and C. 5 | % 6 | % See also DPARAM, DMAP. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: dderiv.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | % Support old syntax 12 | if nargin < 4 13 | c = 1; 14 | end 15 | 16 | z = z(:); 17 | beta = beta(:); 18 | zprow = zp(:).'; 19 | fprime = zeros(size(zp)); 20 | 21 | %terms = 1 - zprow./z; 22 | %fprime(:) = c*exp(sum(log(terms).*beta)); 23 | npts = length(zp(:)); 24 | terms = 1 - zprow(ones(length(beta),1),:)./z(:,ones(npts,1)); 25 | fprime(:) = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 26 | 27 | if nargout > 1 % 2nd derivative 28 | d2f = 0; 29 | for k = 1:length(z) 30 | d2f = d2f - (beta(k)/z(k))./terms(k,:).'; 31 | end 32 | d2f = d2f .* fprime; 33 | end 34 | 35 | -------------------------------------------------------------------------------- /@diskmap/private/ddisp.m: -------------------------------------------------------------------------------- 1 | function ddisp(w,beta,z,c) 2 | %DDISP Display results of Schwarz-Christoffel disk parameter problem. 3 | % DDISP(W,BETA,Z,C) displays the results of DPARAM in a pleasant way. 4 | % 5 | % See also DPARAM, DPLOT. 6 | 7 | % Copyright 1998 by Toby Driscoll. 8 | % $Id: ddisp.m 7 1998-05-10 04:37:19Z tad $ 9 | 10 | disp(' ') 11 | disp(' vertex [w] beta prevertex [z] arg(z)/pi') 12 | disp(' -----------------------------------------------------------------------') 13 | u = real(w); 14 | v = imag(w); 15 | x = real(z); 16 | y = imag(z); 17 | ang = angle(z)/pi; 18 | ang(ang<=0) = ang(ang<=0) + 2; 19 | for j = 1:length(w) 20 | if v(j) < 0 21 | s1 = '-'; 22 | else 23 | s1 = '+'; 24 | end 25 | if y(j) < 0 26 | s2 = '-'; 27 | else 28 | s2 = '+'; 29 | end 30 | disp(sprintf(' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f',... 31 | u(j),s1,abs(v(j)),beta(j),x(j),s2,abs(y(j)),ang(j))); 32 | 33 | end 34 | disp(' ') 35 | if imag(c) < 0 36 | s = '-'; 37 | else 38 | s = '+'; 39 | end 40 | disp(sprintf(' c = %.8g %c %.8gi\n',real(c),s,abs(imag(c)))) 41 | -------------------------------------------------------------------------------- /@diskmap/private/dfixwc.m: -------------------------------------------------------------------------------- 1 | function [y,d] = dfixwc(w,beta,z,c,wc,tol) 2 | %DFIXWC Fix conformal center of disk map. 3 | % The conformal center WC of a Schwarz-Christoffel interior disk map 4 | % is defined as the image of zero. The parameter problem solver 5 | % DPARAM does not allow control over the placement of the conformal 6 | % center. Using the output Z,C from DPARAM, [Z0,C0] = 7 | % DFIXWC(W,BETA,Z,C,WC) computes a Moebius transformation so that if 8 | % Z0 and C0 are used in place of Z and C, the conformal center of the 9 | % resulting map will be WC. 10 | % 11 | % [Z0,C0] = DFIXWC(W,BETA,Z,C,WC,TOL) uses tolerance TOL. 12 | % 13 | % See also DPARAM, PTSOURCE. 14 | 15 | % Copyright 1998 by Toby Driscoll. 16 | % $Id: dfixwc.m 7 1998-05-10 04:37:19Z tad $ 17 | 18 | n = length(w); 19 | 20 | if nargin < 6 21 | [trace,tol,method] = sctool.scparopt([]); 22 | end 23 | 24 | zc = dinvmap(wc,w,beta,z,c,tol); 25 | 26 | % Transform prevertices. 27 | y = ((1-zc')/(1-zc))*(z-zc)./(1-zc'*z); 28 | y(n) = 1; % force it to be exact 29 | y = y./abs(y); 30 | 31 | % Recalculate constant from scratch. 32 | mid = (y(1)+y(2))/2; 33 | qdat = scqdata(beta,ceil(-log10(tol))); 34 | d = (w(1) - w(2))/... 35 | (dquad(y(2),mid,2,y,beta,qdat) - dquad(y(1),mid,1,y,beta,qdat)); 36 | 37 | -------------------------------------------------------------------------------- /@diskmap/private/dimapfun.m: -------------------------------------------------------------------------------- 1 | function zdot = dimapfun(wp,yp,scale,z,beta,c) 2 | % Used by DINVMAP for solution of an ODE. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: dimapfun.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | lenyp = length(yp); 8 | lenzp = lenyp/2; 9 | zp = (yp(1:lenzp)+sqrt(-1)*yp(lenzp+1:lenyp)); 10 | 11 | f = scale./dderiv(zp,z,beta,c); 12 | zdot = [real(f);imag(f)]; 13 | 14 | end 15 | -------------------------------------------------------------------------------- /@diskmap/private/disk2hp.m: -------------------------------------------------------------------------------- 1 | function [zhp,chp] = disk2hp(w,beta,z,c) 2 | %DISK2HP Convert solution from the disk to one from the half-plane. 3 | % [ZHP,CHP] = DISK2HP(W,BETA,Z,C) quickly transforms the solution Z,C 4 | % of the Schwarz-Christoffel disk mapping parameter problem to the 5 | % solution ZHP,CHP of the half-plane problem. 6 | % 7 | % See also HP2DISK, DPARAM, HPPARAM. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: disk2hp.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | n = length(w); 13 | zhp = zeros(size(z)); 14 | zhp(n) = Inf; 15 | zhp(1:n-1) = -i*(z(1:n-1)+1)./(z(1:n-1)-1); % Mobius transfmn 16 | zhp = real(zhp); 17 | 18 | % Recalculate constant from scratch. 19 | mid = mean(zhp(1:2)); 20 | qdat = sctool.scqdata(beta(1:n-1),16); 21 | chp = (w(1)-w(2))/(hplmap.hpquad(zhp(2),mid,2,zhp(1:n-1),beta(1:n-1),qdat) - ... 22 | hplmap.hpquad(zhp(1),mid,1,zhp(1:n-1),beta(1:n-1),qdat)); 23 | 24 | 25 | -------------------------------------------------------------------------------- /@dscpolygons/dscpolygons.m: -------------------------------------------------------------------------------- 1 | function rgn = dscpolygons(p1,p0) 2 | %DSCPOLYGONS Construct doubly connected regions. 3 | % DSCPOLYGONS(P1,P0) constructs a region which is bounded by an inner 4 | % polygon P1 and an outer polygon P0. 5 | % 6 | % See also POLYGON. 7 | % Written by Alfa Heryudono, 2003. 8 | 9 | superiorto('double'); 10 | 11 | if nargin ~= 2 12 | error('Wrong input') 13 | end 14 | 15 | % Check if p1 is "inside" p0. In other words, check for intesections between sides of the 16 | % polygon p1 and the polygon p0. 17 | % Not implemented yet. 18 | 19 | % Check if p1 and p0 are empty 20 | % Not implemented yet 21 | 22 | % Create a region bounded by p1 and p0 23 | rgn.p1 = p1; 24 | rgn.p0 = p0; 25 | rgn = class(rgn,'dscpolygons'); 26 | 27 | 28 | -------------------------------------------------------------------------------- /@dscpolygons/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(rgn) 2 | %GET Get outer and inner polygons of a doubly connected region. 3 | 4 | % [P1,P0] = GET(RGN) returns the values of the inner polygon P1 and the 5 | % values of the outer polygon P0 6 | 7 | % Written by Alfa Heryudono, 2003. 8 | 9 | varargout{1} = rgn.p1; 10 | varargout{2} = rgn.p0; -------------------------------------------------------------------------------- /@dscpolygons/plot.m: -------------------------------------------------------------------------------- 1 | function plot(rgn,varargin) 2 | %PLOT Plot a doubly connected region. 3 | % PLOT(RGN) plots the doubly connected region. 4 | % 5 | % PLOT(RGN,'num') or PLOT(RGN,'lab') also plots dots for the vertices and 6 | % numeric labels of inner polygon and outer polygon. For infinite vertices, 7 | % two numeric labels are printed. 8 | 9 | % Written by Alfa Heryudono, 2003. 10 | 11 | hold on; 12 | if nargin >1 13 | if strcmp(varargin,'lab')==1 14 | plot(rgn.p0,'lab'); 15 | plot(rgn.p1,'lab'); 16 | elseif strcmp(varargin,'num')==1 17 | plot(rgn.p0,'num'); 18 | plot(rgn.p1,'num'); 19 | else 20 | plot(rgn.p0); 21 | plot(rgn.p1); 22 | end 23 | else 24 | plot(rgn.p0); 25 | plot(rgn.p1); 26 | end 27 | hold off; 28 | -------------------------------------------------------------------------------- /@extermap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of Schwarz-Christoffel disk exterior map. 3 | % ACCURACY(M) estimates the accuracy of the Schwarz-Christoffel 4 | % exterior map M. The technique used is to compare the differences 5 | % between successive vertices to the integral between the 6 | % corresponding prevertices, and return the maximum. 7 | % 8 | % See also EXTERMAP. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: accuracy.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | % If an accuracy has been assigned, don't question it 14 | if ~isempty(M.accuracy) 15 | acc = M.accuracy; 16 | return 17 | end 18 | 19 | % Get data for low-level functions 20 | p = polygon(M); 21 | w = flipud(vertex(p)); 22 | beta = flipud(1 - angle(p)); 23 | z = M.prevertex; 24 | c = M.constant; 25 | qdata = M.qdata; 26 | n = length(w); 27 | 28 | % Test accuracy by integrating between consecutive finite prevertices, and 29 | % comparing to differences of vertices. 30 | 31 | idx = find(~isinf(w)); 32 | 33 | % Two columns hold endpoint indices for integrations 34 | idx = [idx(1:end) idx([2:end 1])]; 35 | 36 | % Find midpoints that are halfway between in angular sense 37 | dtheta = mod(angle(z(idx(:,2))./z(idx(:,1))),2*pi); 38 | mid = z(idx(:,1)).*exp(i*dtheta/2); 39 | 40 | % Do the integrations 41 | I = dequad(z(idx(:,1)),mid,idx(:,1),z,beta,qdata) - ... 42 | dequad(z(idx(:,2)),mid,idx(:,2),z,beta,qdata); 43 | 44 | acc = max(abs( c*I - diff(w([1:end 1])) )); 45 | -------------------------------------------------------------------------------- /@extermap/capacity.m: -------------------------------------------------------------------------------- 1 | function g = capacity(map) 2 | 3 | g = abs(map.constant); 4 | -------------------------------------------------------------------------------- /@extermap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Pretty-print a Schwarz-Christoffel exterior map. 3 | 4 | % Copyright 1998-2001 by Toby Driscoll. 5 | % $Id: char.m 161 2001-07-20 14:32:59Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | n = length(w); 11 | z = flipud(f.prevertex); 12 | c = f.constant; 13 | 14 | L = cell(2,1); 15 | L{1}=' vertex alpha prevertex arg/pi'; 16 | L{2}=' -----------------------------------------------------------------------'; 17 | u = real(w); 18 | v = imag(w); 19 | x = real(z); 20 | y = imag(z); 21 | ang = angle(z)/pi; 22 | ang(ang<=0) = ang(ang<=0) + 2; 23 | fmt = ' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f'; 24 | for j = 1:length(w) 25 | if v(j) < 0 26 | s1 = '-'; 27 | else 28 | s1 = '+'; 29 | end 30 | if y(j) < 0 31 | s2 = '-'; 32 | else 33 | s2 = '+'; 34 | end 35 | L{end+1}=sprintf(fmt,u(j),s1,abs(v(j)),alpha(j),x(j),s2,abs(y(j)),ang(j)); 36 | end 37 | 38 | L{end+1} = ' '; 39 | if imag(c) < 0 40 | s = '-'; 41 | else 42 | s = '+'; 43 | end 44 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 45 | L{end+1} = sprintf(' Logarithmic capacity = %.8g',abs(c)); 46 | L{end+1} = sprintf(' Apparent accuracy is %.2e',f.accuracy); 47 | L{end+1} = ' '; 48 | 49 | out = L; 50 | 51 | -------------------------------------------------------------------------------- /@extermap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel exterior map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | n = length(w); 11 | z = flipud(M.prevertex); 12 | c = M.constant; 13 | 14 | L = { ' '; ' extermap object:'; ' ' }; 15 | L{4}=' vertex alpha prevertex arg/pi'; 16 | L{5}=' -----------------------------------------------------------------------'; 17 | u = real(w); 18 | v = imag(w); 19 | x = real(z); 20 | y = imag(z); 21 | ang = angle(z)/pi; 22 | ang(ang<=0) = ang(ang<=0) + 2; 23 | fmt = ' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f'; 24 | for j = 1:length(w) 25 | if v(j) < 0 26 | s1 = '-'; 27 | else 28 | s1 = '+'; 29 | end 30 | if y(j) < 0 31 | s2 = '-'; 32 | else 33 | s2 = '+'; 34 | end 35 | L{end+1}=sprintf(fmt,u(j),s1,abs(v(j)),alpha(j),x(j),s2,abs(y(j)),ang(j)); 36 | end 37 | 38 | L{end+1} = ' '; 39 | if imag(c) < 0 40 | s = '-'; 41 | else 42 | s = '+'; 43 | end 44 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 45 | L{end+1} = sprintf(' Logarithmic capacity = %.8g',abs(c)); 46 | L{end+1} = ' '; 47 | L{end+1} = sprintf(' Apparent accuracy is %.2e',M.accuracy); 48 | L{end+1} = ' '; 49 | 50 | 51 | if nargout==0 52 | fprintf('%s\n',L{:}) 53 | else 54 | out = L; 55 | end 56 | -------------------------------------------------------------------------------- /@extermap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel exterior map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points 4 | % ZP in the unit disk. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL 7 | % is less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also EXTERMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | if nargin < 3 15 | qdata = M.qdata; 16 | else 17 | qdata = tol; 18 | end 19 | 20 | p = polygon(M); 21 | w = flipud(vertex(p)); 22 | beta = flipud(1 - angle(p)); 23 | n = length(w); 24 | 25 | wp = NaN*zp; 26 | idx = abs(zp) <= 1+eps; 27 | wp(idx) = demap(zp(idx),w,beta,M.prevertex,M.constant,qdata); 28 | -------------------------------------------------------------------------------- /@extermap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel exterior map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % exterior map M at the points ZP. 5 | % 6 | % See also EXTERMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | z = M.prevertex; 12 | c = M.constant; 13 | beta = flipud(1 - angle(polygon(M))); 14 | 15 | fp = dederiv(zp,z,beta,c); 16 | -------------------------------------------------------------------------------- /@extermap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@extermap/forwardpoly.m: -------------------------------------------------------------------------------- 1 | function p = forwardpoly(map) 2 | % Given an extermap M, FORWARDPOLY(M) returns the polygon that is 3 | % formed using the prevertices, angles, and quadrature data of that 4 | % map. If the prevertices were found from the solution of a 5 | % parameter problem, then the result should agree closely with the 6 | % original polygon that was supplied. 7 | 8 | % Copyright (c) 1998 by Toby Driscoll. 9 | % $Id: forwardpoly.m 39 1998-07-01 17:40:15Z tad $ 10 | 11 | z = map.prevertex; 12 | alpha = flipud(angle(polygon(map))); 13 | c = map.constant; 14 | 15 | n = length(z); 16 | 17 | % Since there is no parameter problem, use high accuracy in quadrature. 18 | qdata = scqdata(1-alpha,16); 19 | 20 | % Midpoints of integration 21 | theta = rem(angle(z(n)) + angle(z/z(n))+2*pi,2*pi); 22 | theta(end) = 2*pi; 23 | mid = exp(i*(theta(1:n-1)+theta(2:n))/2); 24 | 25 | % Integrations 26 | I = dequad(z(1:n-1),mid,1:n-1,z,1-alpha,qdata) - ... 27 | dequad(z(2:n),mid,2:n,z,1-alpha,qdata); 28 | 29 | % Deduce vertices 30 | w = c*cumsum([0;I]); 31 | 32 | p = polygon(w); 33 | -------------------------------------------------------------------------------- /@extermap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, constant 8 | 9 | % Copyright 1999-2003 by Toby Driscoll. 10 | % $Id: get.m 236 2003-01-15 15:29:14Z driscoll $ 11 | 12 | for j = 1:length(varargin) 13 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 14 | case 'pol' 15 | varargout{j} = map.scmap.polygon; 16 | case 'opt' 17 | varargout{j} = map.scmap.options; 18 | case 'pre' 19 | varargout{j} = map.prevertex; 20 | case 'con' 21 | varargout{j} = map.constant; 22 | otherwise 23 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 24 | varargout{j} = []; 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /@extermap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 33 1998-06-29 22:35:40Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'extermap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.scmap = c*M.scmap; 16 | -------------------------------------------------------------------------------- /@extermap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.prevertex = flipud(M.prevertex); 8 | v.constant = M.constant; -------------------------------------------------------------------------------- /@extermap/plot.m: -------------------------------------------------------------------------------- 1 | function [h,r,theta] = plot(M,varargin) 2 | %PLOT Visualize a Schwarz-Christoffel exterior map. 3 | % PLOT(M) plots the polygon associated with the Schwarz-Christoffel 4 | % exterior map M and the images of ten evenly spaced circles and radii 5 | % under the S-C transformation. 6 | % 7 | % PLOT(M,NR,NTHETA) plots the images of NR circles and NTHETA radii. 8 | % 9 | % PLOT(M,R,THETA) plots the circles at radii given by the entries of R 10 | % and radii at the angles specified in THETA. 11 | % 12 | % PLOT(M,TOL) or PLOT(M,NR,NTHETA,TOL) or PLOT(M,R,THETA,TOL) 13 | % computes the map with accuracy roughly TOL. Normally TOL defaults to 14 | % 1e-4 or the accuracy of M, whichever is greater. 15 | % 16 | % See also EXTERMAP, MAP. 17 | 18 | % Copyright 1998 by Toby Driscoll. 19 | % $Id: plot.m 7 1998-05-10 04:37:19Z tad $ 20 | 21 | p = polygon(M); 22 | w = flipud(vertex(p)); 23 | beta = flipud(1 - angle(p)); 24 | z = M.prevertex; 25 | c = M.constant; 26 | n = length(w); 27 | 28 | if nargin == 1 29 | [a1,a2,a3] = deplot(w,beta,z,c); 30 | elseif length(varargin) == 1 31 | % Tolerance given only 32 | [a1,a2,a3] = deplot(w,beta,z,c,10,10,ceil(-log10(varargin{1}))); 33 | elseif length(varargin) == 2 34 | % R, theta given only 35 | [a1,a2,a3] = deplot(w,beta,z,c,varargin{1},varargin{2}); 36 | else 37 | % All given 38 | nqpts = ceil(-log10(varargin{3})); 39 | [a1,a2,a3] = deplot(w,beta,z,c,varargin{1},varargin{2},nqpts); 40 | end 41 | 42 | if nargout > 0 43 | h = a1; 44 | r = a2; 45 | theta = a3; 46 | end 47 | 48 | -------------------------------------------------------------------------------- /@extermap/private/dederiv.m: -------------------------------------------------------------------------------- 1 | function fprime = dederiv(zp,z,beta,c) 2 | %DEDERIV Derivative of the exterior map. 3 | % DEDERIV(ZP,Z,BETA,C) returns the derivative at the points of ZP of the 4 | % Schwarz-Christoffel exterior map defined by Z, BETA, and C. 5 | % 6 | % See also DEPARAM, DEMAP. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: dederiv.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | % Support old syntax 12 | if nargin < 4 13 | c = 1; 14 | end 15 | 16 | z = z(:); 17 | beta = [beta(:);-2]; 18 | zprow = zp(:).'; 19 | fprime = zeros(size(zp)); 20 | 21 | npts = length(zp(:)); 22 | terms = 1 - zprow(ones(length(z),1),:)./z(:,ones(npts,1)); 23 | terms(length(z)+1,:) = zprow; 24 | fprime(:) = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 25 | -------------------------------------------------------------------------------- /@extermap/private/dedisp.m: -------------------------------------------------------------------------------- 1 | function dedisp(w,beta,z,c) 2 | %DEDISP Display results of Schwarz-Christoffel exterior parameter problem. 3 | % DEDISP(W,BETA,Z,C) displays the results of DEPARAM in a pleasant 4 | % way. 5 | % 6 | % See also DEPARAM, DEPLOT. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: dedisp.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | disp(' ') 12 | disp(' w beta z arg(z)/pi') 13 | disp(' -----------------------------------------------------------------------') 14 | u = real(w); 15 | v = imag(w); 16 | x = real(z); 17 | y = imag(z); 18 | ang = angle(z)/pi; 19 | ang(ang<=0) = ang(ang<=0) + 2; 20 | for j = 1:length(w) 21 | if v(j) < 0 22 | s1 = '-'; 23 | else 24 | s1 = '+'; 25 | end 26 | if y(j) < 0 27 | s2 = '-'; 28 | else 29 | s2 = '+'; 30 | end 31 | disp(sprintf(' %8.5f %c %7.5fi %8.5f %8.5f %c %7.5fi %14.12f',... 32 | u(j),s1,abs(v(j)),beta(j),x(j),s2,abs(y(j)),ang(j))); 33 | 34 | end 35 | disp(' ') 36 | if imag(c) < 0 37 | s = '-'; 38 | else 39 | s = '+'; 40 | end 41 | disp(sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c)))) 42 | -------------------------------------------------------------------------------- /@hplmap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of Schwarz-Christoffel half-plane map. 3 | % ACCURACY(M) estimates the accuracy of the Schwarz-Christoffel 4 | % half-plane map M. The technique used is to compare the differences 5 | % between successive finite vertices to the integral between the 6 | % corresponding prevertices, and return the maximum. 7 | % 8 | % See also HPLMAP. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: accuracy.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | % If an accuracy has been assigned, don't question it 14 | if ~isempty(M.accuracy) 15 | acc = M.accuracy; 16 | return 17 | end 18 | 19 | % Get data for low-level functions 20 | p = polygon(M); 21 | w = vertex(p); 22 | n = length(w); 23 | beta = angle(p) - 1; 24 | z = M.prevertex; 25 | c = M.constant; 26 | qdata = M.qdata; 27 | 28 | % Test accuracy by integrating between consecutive finite prevertices, and 29 | % comparing to differences of vertices. 30 | n = length(w); 31 | idx = find(~isinf(w(1:n-1))); % exclude last prevert, at Inf 32 | 33 | % Two columns hold endpoint indices for integrations 34 | idx = [idx(1:end-1) idx(2:end)]; 35 | 36 | % Find midpoints. Go into upper half-plane to avoid integrating through 37 | % skipped prevertices. 38 | zz = z(idx).'; 39 | mid = mean(zz).'; 40 | mid = mid + i*abs(diff(zz).')/2; 41 | 42 | % Do the integrations 43 | I = hpquad(z(idx(:,1)),mid,idx(:,1),z(1:n-1),beta(1:n-1),qdata) - ... 44 | hpquad(z(idx(:,2)),mid,idx(:,2),z(1:n-1),beta(1:n-1),qdata); 45 | 46 | acc = max(abs( c*I - diff(w(idx).').' )); 47 | -------------------------------------------------------------------------------- /@hplmap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Pretty-print a Schwarz-Christoffel half-plane map. 3 | 4 | % Copyright 2001 by Toby Driscoll. 5 | % $Id: char.m 158 2001-07-20 14:05:59Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = f.prevertex; 11 | c = f.constant; 12 | 13 | if length(z) < length(w) 14 | z = [z(:);Inf]; 15 | end 16 | 17 | L = cell(2,1); 18 | L{1} = ' vertex alpha prevertex '; 19 | L{2} = ' --------------------------------------------------------'; 20 | u = real(w); 21 | v = imag(w); 22 | fmt = ' %8.5f %c %7.5fi %8.5f %20.12e'; 23 | for j = 1:length(w) 24 | if v(j) < 0 25 | s = '-'; 26 | else 27 | s = '+'; 28 | end 29 | L{end+1} = sprintf(fmt,u(j),s,abs(v(j)),alpha(j),z(j)); 30 | end 31 | L{end+1} = ' '; 32 | if imag(c) < 0 33 | s = '-'; 34 | else 35 | s = '+'; 36 | end 37 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 38 | L{end+1} = sprintf(' Apparent accuracy is %.2e',f.accuracy); 39 | L{end+1} = ' '; 40 | 41 | out = L; 42 | -------------------------------------------------------------------------------- /@hplmap/diskmap.m: -------------------------------------------------------------------------------- 1 | function M1 = diskmap(M) 2 | %DISKMAP Convert Schwarz-Christoffel half-plane map to a map from the disk. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: diskmap.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | p = polygon(M); 8 | [z1,c1] = hp2disk(vertex(p),angle(p)-1,M.prevertex,M.constant); 9 | M1 = diskmap(p,scmapopt(M),z1,c1); 10 | 11 | 12 | -------------------------------------------------------------------------------- /@hplmap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel half-plane map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = M.prevertex; 11 | c = M.constant; 12 | 13 | if length(z) < length(w) 14 | z = [z(:);Inf]; 15 | end 16 | 17 | L = {' '; ' hplmap object:'; ' '}; 18 | L{4} = ' vertex alpha prevertex '; 19 | L{5} = ' --------------------------------------------------------'; 20 | u = real(w); 21 | v = imag(w); 22 | fmt = ' %8.5f %c %7.5fi %8.5f %20.12e'; 23 | for j = 1:length(w) 24 | if v(j) < 0 25 | s = '-'; 26 | else 27 | s = '+'; 28 | end 29 | L{end+1} = sprintf(fmt,u(j),s,abs(v(j)),alpha(j),z(j)); 30 | end 31 | L{end+1} = ' '; 32 | if imag(c) < 0 33 | s = '-'; 34 | else 35 | s = '+'; 36 | end 37 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 38 | L{end+1} = ' '; 39 | L{end+1} = sprintf(' Apparent accuracy is %.2e',M.accuracy); 40 | L{end+1} = ' '; 41 | 42 | 43 | if nargout==0 44 | fprintf('%s\n',L{:}) 45 | else 46 | out = L; 47 | end -------------------------------------------------------------------------------- /@hplmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel half-plane map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points 4 | % ZP in the upper half-plane. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL 7 | % is less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also HPLMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | p = polygon(M); 15 | n = length(p); 16 | 17 | if nargin < 3 18 | qdata = M.qdata; 19 | else 20 | qdata = tol; 21 | end 22 | 23 | wp = NaN*zp; 24 | idx = imag(zp) > -eps; 25 | wp(idx) = hpmap(zp(idx),vertex(p),angle(p)-1,M.prevertex,M.constant,qdata); 26 | -------------------------------------------------------------------------------- /@hplmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel half-plane map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % half-plane map M at the points ZP. 5 | % 6 | % See also HPLMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | z = M.prevertex; 12 | c = M.constant; 13 | beta = angle(polygon(M)) - 1; 14 | 15 | fp = hpderiv(zp,z,beta,c); 16 | -------------------------------------------------------------------------------- /@hplmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@hplmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, constant 8 | 9 | % Copyright 1999-2003 by Toby Driscoll. 10 | % $Id: get.m 237 2003-01-15 15:29:15Z driscoll $ 11 | 12 | for j = 1:length(varargin) 13 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 14 | case 'pol' 15 | varargout{j} = map.scmap.polygon; 16 | case 'opt' 17 | varargout{j} = map.scmap.options; 18 | case 'pre' 19 | varargout{j} = map.prevertex; 20 | case 'con' 21 | varargout{j} = map.constant; 22 | otherwise 23 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 24 | varargout{j} = []; 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /@hplmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 33 1998-06-29 22:35:40Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'hplmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.scmap = c*M.scmap; 16 | -------------------------------------------------------------------------------- /@hplmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.prevertex = M.prevertex; 8 | v.constant = M.constant; -------------------------------------------------------------------------------- /@hplmap/plot.m: -------------------------------------------------------------------------------- 1 | function [h,re,im] = plot(M,varargin) 2 | %PLOT Visualize a Schwarz-Christoffel half-plane map. 3 | % PLOT(M) plots the polygon associated with the Schwarz-Christoffel 4 | % half-plane map M and the images of ten evenly spaced vertical rays 5 | % and horizontal lines under the S-C transformation. 6 | % 7 | % PLOT(M,NRE,NIM) plots the images of NRE vertical rays and NIM 8 | % horizontal lines. 9 | % 10 | % PLOT(M,RE,IM) plots the vertical rays at abscissae given by the 11 | % entries of RE and horizontal lines at the ordinates specified in IM. 12 | % 13 | % PLOT(M,TOL) or PLOT(M,NRE,NIM,TOL) or PLOT(M,RE,IM,TOL) 14 | % computes the map with accuracy roughly TOL. Normally TOL defaults to 15 | % 1e-4 or the accuracy of M, whichever is greater. 16 | % 17 | % See also HPLMAP, EVAL. 18 | 19 | % Copyright 1998 by Toby Driscoll. 20 | % $Id: plot.m 7 1998-05-10 04:37:19Z tad $ 21 | 22 | p = polygon(M); 23 | w = vertex(p); 24 | beta = angle(p) - 1; 25 | z = M.prevertex; 26 | c = M.constant; 27 | 28 | if nargin == 1 29 | [a1,a2,a3] = hpplot(w,beta,z,c); 30 | elseif length(varargin) == 1 31 | % Tolerance given only 32 | [a1,a2,a3] = hpplot(w,beta,z,c,10,10,ceil(-log10(varargin{1}))); 33 | elseif length(varargin) == 2 34 | % RE,IM given only 35 | [a1,a2,a3] = hpplot(w,beta,z,c,varargin{1},varargin{2}); 36 | else 37 | % All given 38 | nqpts = ceil(-log10(varargin{3})); 39 | [a1,a2,a3] = hpplot(w,beta,z,c,varargin{1},varargin{2},nqpts); 40 | end 41 | 42 | if nargout > 0 43 | h = a1; 44 | re = a2; 45 | im = a3; 46 | end 47 | 48 | -------------------------------------------------------------------------------- /@hplmap/private/hp2disk.m: -------------------------------------------------------------------------------- 1 | function [zd,cd] = hp2disk(w,beta,z,c) 2 | %HP2DISK Convert solution from the half-plane to one from the disk. 3 | % [Z,C] = HP2DISK(W,BETA,Z,C) quickly transforms the solution Z,C of 4 | % the Schwarz-Christoffel half-plane mapping parameter problem to the 5 | % solution ZD,CD of the disk problem. 6 | % 7 | % See also DISK2HP, HPPARAM, DPARAM. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: hp2disk.m 298 2009-09-15 14:36:37Z driscoll $ 11 | 12 | n = length(w); 13 | zd = zeros(size(z)); 14 | if isinf(z(n)) 15 | zd(n) = 1; 16 | zd(1:n-1) = (z(1:n-1)-i)./(z(1:n-1)+i); 17 | else 18 | zd = (z-i)./(z+i); 19 | zd = zd/zd(n); 20 | end 21 | zd = sign(zd); 22 | 23 | % Recalculate constant from scratch. 24 | mid = (zd(1)+zd(2))/2; 25 | qdat = sctool.scqdata(beta,16); 26 | cd = (w(1) - w(2))/... 27 | (diskmap.dquad(zd(2),mid,2,zd,beta,qdat) - diskmap.dquad(zd(1),mid,1,zd,beta,qdat)); 28 | 29 | -------------------------------------------------------------------------------- /@hplmap/private/hpderiv.m: -------------------------------------------------------------------------------- 1 | function fprime = hpderiv(zp,z,beta,c) 2 | %HPDERIV Derivative of the half-plane map. 3 | % HPDERIV(ZP,Z,BETA,C) returns the derivative at the points of ZP of 4 | % the Schwarz-Christoffel half-plane map defined by Z, BETA, and C. 5 | % 6 | % See also HPPARAM, HPMAP. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: hpderiv.m 298 2009-09-15 14:36:37Z driscoll $ 10 | 11 | % Support old syntax 12 | if nargin < 4 13 | c = 1; 14 | end 15 | 16 | zf = z(~isinf(z)); 17 | beta = beta(~isinf(z)); 18 | zprow = zp(:).'; 19 | fprime = zeros(size(zp)); 20 | 21 | npts = length(zp(:)); 22 | terms = zprow(ones(length(beta),1),:) - zf(:,ones(npts,1)); 23 | fprime(:) = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 24 | -------------------------------------------------------------------------------- /@hplmap/private/hpdisp.m: -------------------------------------------------------------------------------- 1 | function hpdisp(w,beta,z,c) 2 | %HPDISP Display results of Schwarz-Christoffel half-plane parameter problem. 3 | % HPDISP(W,BETA,Z,C) displays the results of HPPARAM in a pleasant 4 | % way. 5 | % 6 | % See also HPPARAM, HPPLOT. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: hpdisp.m 298 2009-09-15 14:36:37Z driscoll $ 10 | 11 | if length(z) < length(w) 12 | z = [z(:);Inf]; 13 | end 14 | disp(' ') 15 | disp(' vertex [w] beta prevertex [z] ') 16 | disp(' --------------------------------------------------------') 17 | u = real(w); 18 | v = imag(w); 19 | for j = 1:length(w) 20 | if v(j) < 0 21 | s = '-'; 22 | else 23 | s = '+'; 24 | end 25 | disp(sprintf(' %8.5f %c %7.5fi %8.5f %20.12e',... 26 | u(j),s,abs(v(j)),beta(j),z(j))); 27 | end 28 | disp(' ') 29 | if imag(c) < 0 30 | s = '-'; 31 | else 32 | s = '+'; 33 | end 34 | disp(sprintf(' c = %.8g %c %.8gi\n',real(c),s,abs(imag(c)))) 35 | 36 | -------------------------------------------------------------------------------- /@hplmap/private/hpimapfun.m: -------------------------------------------------------------------------------- 1 | function zdot = hpimapfun(wp,yp,flag,scale,z,beta,c); 2 | % Used by HPINVMAP for solution of an ODE. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: hpimapfun.m 298 2009-09-15 14:36:37Z driscoll $ 6 | 7 | lenyp = length(yp); 8 | lenzp = lenyp/2; 9 | 10 | % Don't allow points in lower half-plane. This really messes up the 11 | % derivative calculation. 12 | zp = yp(1:lenzp) + i*max(0,yp(lenzp+1:lenyp)); 13 | 14 | f = scale./hpderiv(zp,z,beta,c); 15 | zdot = [real(f);imag(f)]; 16 | -------------------------------------------------------------------------------- /@moebius/char.m: -------------------------------------------------------------------------------- 1 | function out = char(map) 2 | %CHAR Pretty-print a Moebius transformation. 3 | 4 | % Copyright (c) 1998-2001 by Toby Driscoll. 5 | % $Id: char.m 161 2001-07-20 14:32:59Z driscoll $ 6 | 7 | % Numerator 8 | num = ''; 9 | a = map.coeff(1); 10 | if a~=0 11 | if isreal(a) 12 | num = [num num2str(a,4)]; 13 | else 14 | num = [num '(' num2str(a,4) ')']; 15 | end 16 | end 17 | a = map.coeff(2); 18 | if a~=0 19 | if ~isempty(num) 20 | if real(a) >= 0 21 | num = [num ' + ']; 22 | else 23 | num = [num ' - ']; 24 | a = -a; 25 | end 26 | end 27 | if isreal(a) & a~=1 28 | num = [num num2str(a,4) '*']; 29 | else 30 | num = [num '(' num2str(a,4) ')*']; 31 | end 32 | num = [num 'z']; 33 | end 34 | 35 | % Denominator 36 | den = ''; 37 | a = map.coeff(3); 38 | if a~=0 39 | if isreal(a) 40 | den = [den num2str(a,4)]; 41 | else 42 | den = [den '(' num2str(a,4) ')']; 43 | end 44 | end 45 | a = map.coeff(4); 46 | if a~=0 47 | if ~isempty(den) 48 | if real(a) >= 0 49 | den = [den ' + ']; 50 | else 51 | den = [den ' - ']; 52 | a = -a; 53 | end 54 | end 55 | if isreal(a) & a~=1 56 | den = [den num2str(a,4) '*']; 57 | else 58 | den = [den '(' num2str(a,4) ')*']; 59 | end 60 | den = [den 'z']; 61 | end 62 | 63 | L = [length(num),length(den)]; 64 | D = (max(L)-L)/2; 65 | num = [blanks(floor(D(1))) num blanks(ceil(D(1)))]; 66 | den = [blanks(floor(D(2))) den blanks(ceil(D(2)))]; 67 | fline = repmat('-',1,max(L)); 68 | 69 | out = sprintf('\n %s\n %s\n %s\n\n',num,fline,den); 70 | 71 | -------------------------------------------------------------------------------- /@moebius/diff.m: -------------------------------------------------------------------------------- 1 | function f = diff(map) 2 | %Differentiate a Moebius transformation. 3 | % DIFF(M) returns a callable function that evaluates to the derivative of 4 | % the Moebius transformation M. 5 | 6 | % Copyright (c) 2007 by Toby Driscoll. 7 | 8 | a = map.coeff(1); b = map.coeff(2); c = map.coeff(3); d = map.coeff(4); 9 | f = @(z) (b*c-a*d)./(d*z + c).^2; -------------------------------------------------------------------------------- /@moebius/disp.m: -------------------------------------------------------------------------------- 1 | function disp(f) 2 | 3 | disp(char(f)) -------------------------------------------------------------------------------- /@moebius/display.m: -------------------------------------------------------------------------------- 1 | function display(f) 2 | %DISPLAY Pretty-print a Moebius transformation. 3 | 4 | % Copyright (c) 1998-2001 by Toby Driscoll. 5 | % $Id: display.m 159 2001-07-20 14:26:16Z driscoll $ 6 | 7 | fprintf('\n%s =\n',inputname(1)) 8 | disp(f) 9 | -------------------------------------------------------------------------------- /@moebius/double.m: -------------------------------------------------------------------------------- 1 | function c = double(map) 2 | % Returns coefficients of the Moebius transformation. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: double.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | c = map.coeff; -------------------------------------------------------------------------------- /@moebius/eval.m: -------------------------------------------------------------------------------- 1 | function f = eval(map,z) 2 | %Evaluate Moebius transformation at point(s). 3 | % EVAL(M,Z) evaluates the Moebius transformation M at the point(s) 4 | % in Z. Infinity is a valid input. 5 | 6 | % Copyright (c) 1998 by Toby Driscoll. 7 | % $Id: eval.m 93 2000-05-24 17:57:50Z tad $ 8 | 9 | f = NaN*zeros(size(z)); 10 | atinf = isinf(z); 11 | if any(atinf) 12 | f(atinf) = map.coeff(2)/map.coeff(4); 13 | end 14 | 15 | num = map.coeff(2)*z(~atinf) + map.coeff(1); 16 | den = map.coeff(4)*z(~atinf) + map.coeff(3); 17 | 18 | toinf = abs(den) < 3*eps; 19 | den(toinf) = NaN; 20 | num(toinf) = 1; 21 | 22 | f(~atinf) = num./den; 23 | f(isnan(f)) = Inf; -------------------------------------------------------------------------------- /@moebius/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@moebius/inv.m: -------------------------------------------------------------------------------- 1 | function M2 = inv(M1) 2 | %INV Invert a Moebius transformation. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: inv.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | M2 = moebius; 8 | M2.source = M1.image; 9 | M2.image = M1.source; 10 | M2.coeff = [1 -1 -1 1].*M1.coeff([1 3 2 4]); -------------------------------------------------------------------------------- /@moebius/minus.m: -------------------------------------------------------------------------------- 1 | function M = minus(M1,M2) 2 | %MINUS Subtract a scalar from a Moebius map. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: minus.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | M = M1 + (-M2); 8 | -------------------------------------------------------------------------------- /@moebius/mrdivide.m: -------------------------------------------------------------------------------- 1 | function M = mrdivide(M1,M2) 2 | %MRDIVIDE Divide Moebius map by a scalar, or reciprocate it. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mrdivide.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | if isa(M1,'double') & length(M1)==1 8 | % Exchange numerator and denominator 9 | M2.coeff = M2.coeff([3 4 1 2]); 10 | % Multiply by scalar 11 | M = M1*M2; 12 | elseif isa(M2,'double') & length(M2)==1 13 | C = M1.coeff; 14 | C(3:4) = M2*C(3:4); 15 | M = moebius; 16 | M.coeff = C; 17 | else 18 | error('Division not defined for these operands.') 19 | end 20 | -------------------------------------------------------------------------------- /@moebius/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M1,M2) 2 | %MTIMES Multiply Moebius transformation by a scalar. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | % Make the first one moebius. 8 | if isa(M1,'double') 9 | tmp = M1; 10 | M1 = M2; 11 | M2 = tmp; 12 | end 13 | 14 | C = M1.coeff; 15 | if isa(M2,'double') & length(M2)==1 16 | C(1:2) = M2*C(1:2); 17 | M = moebius; 18 | M.coeff = C; 19 | else 20 | error('Multiplication not defined for these operands.') 21 | end 22 | -------------------------------------------------------------------------------- /@moebius/normal.m: -------------------------------------------------------------------------------- 1 | function M = normal(M) 2 | %NORMAL Normalize a Moebius transformation. 3 | % NORMAL(M), where M is a moebius object, divides the coefficients of M 4 | % by the constant term in the demoninator, or the coefficient of the 5 | % linear term in the denominator if the constant is zero. 6 | % 7 | % Copyright (c) 2004 by Toby Driscoll. 8 | % $Id: normal.m 273 2004-01-23 17:25:17Z driscoll $ 9 | 10 | c = M.coeff(3); 11 | if c==0, c = M.coeff(4); end 12 | M.coeff = M.coeff/c; 13 | 14 | -------------------------------------------------------------------------------- /@moebius/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M1,M2) 2 | %PLUS Add a scalar to a Moebius map. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: plus.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | % Make the first one moebius. 8 | if isa(M1,'double') 9 | tmp = M1; 10 | M1 = M2; 11 | M2 = tmp; 12 | end 13 | 14 | C = M1.coeff; 15 | if isa(M2,'double') & length(M2)==1 16 | C(1) = C(1) + M2*C(3); 17 | C(2) = C(2) + M2*C(4); 18 | else 19 | error('Addition not defined for these operands.') 20 | end 21 | M = moebius(C); 22 | -------------------------------------------------------------------------------- /@moebius/subsref.m: -------------------------------------------------------------------------------- 1 | function w = subsref(M,S) 2 | %SUBSREF Evaluate or compose maps. 3 | % M(Z), where M is a Moebius transformation and Z is a vector of 4 | % points, returns the image of the points in Z. This just a synonym 5 | % for EVAL(M,Z). 6 | % 7 | % M1(M2), where M1 and M2 are both Moebius transformations, returns 8 | % a new Moebius transformation that is their composition. 9 | % 10 | % See also EVAL, MOEBIUS. 11 | 12 | % Copyright (c) 1998 by Toby Driscoll. 13 | % $Id: subsref.m 44 1998-07-01 20:21:54Z tad $ 14 | 15 | if length(S) == 1 & strcmp(S.type,'()') 16 | if isa(S.subs{1},'double') 17 | w = eval(M,S.subs{1}); 18 | elseif isa(S.subs{1},'moebius') 19 | C = M.coeff; 20 | D = S.subs{1}.coeff; 21 | w = moebius; 22 | w.coeff = [C(1:2)*D([3 1]).' C(1:2)*D([4 2]).' ... 23 | C(3:4)*D([3 1]).' C(3:4)*D([4 2]).']; 24 | else 25 | error('Syntax not supported.') 26 | end 27 | else 28 | error('Only syntax for MOEBIUS is a single parenthesized subscript.') 29 | end 30 | -------------------------------------------------------------------------------- /@moebius/uminus.m: -------------------------------------------------------------------------------- 1 | function M = uminus(M) 2 | %UMINUS Negate a Moebius transformation. 3 | % Copyright (c) 1998 by Toby Driscoll. 4 | % $Id: uminus.m 44 1998-07-01 20:21:54Z tad $ 5 | 6 | M.coeff(1:2) = -M.coeff(1:2); 7 | -------------------------------------------------------------------------------- /@moebius/uplus.m: -------------------------------------------------------------------------------- 1 | function M = uplus(M) 2 | -------------------------------------------------------------------------------- /@polygon/boundingbox.m: -------------------------------------------------------------------------------- 1 | function box = boundingbox(p) 2 | %BOUNDINGBOX Smallest box that contains the polygon. 3 | % BOUNDINGBOX(P) returns the smallest box (in AXIS format) that contains 4 | % the polygon P. If P is unbounded, all the entries will be infinite. 5 | % 6 | % See also POLYGON/DIAM. 7 | % 8 | % Copyright 2003 by Toby Driscoll. 9 | % $Id: boundingbox.m 266 2003-04-25 18:46:31Z driscoll $ 10 | 11 | if ~isinf(p) 12 | z = vertex(p); 13 | box = [ min(real(z)) max(real(z)) min(imag(z)) max(imag(z)) ]; 14 | else 15 | % We might find some finite bounds. But is there any application for this? 16 | box = [ -Inf Inf -Inf Inf ]; 17 | end -------------------------------------------------------------------------------- /@polygon/cdt.m: -------------------------------------------------------------------------------- 1 | function T = cdt(p) 2 | %CDT Constrained Delaunay triangulation of polygon vertices. 3 | % T = CDT(P) returns a structure representing a constrained Delaunay 4 | % triangulation of the n polygon vertices. T has the fields: 5 | % 6 | % T.edge : 2x(2n-3) matrix of indices of edge endpoints 7 | % T.triedge : 3x(n-2) matrix of triangle edge indices 8 | % T.edgetri : 2x(2n-3) matrix of triangle membership indices for 9 | % the edges (boundary edges have a zero in 2nd row) 10 | % 11 | % See also PLOTCDT. 12 | 13 | % Copyright 1998 by Toby Driscoll. 14 | % $Id: cdt.m 7 1998-05-10 04:37:19Z tad $ 15 | 16 | w = p.vertex; 17 | if any(isinf(w)) 18 | error('CDT not possible for unbounded polygons.') 19 | end 20 | 21 | [e,te,et] = crtriang(w); 22 | [e,te,et] = crcdt(w,e,te,et); 23 | 24 | T = struct('edge',e,'triedge',te,'edgetri',et); 25 | -------------------------------------------------------------------------------- /@polygon/diam.m: -------------------------------------------------------------------------------- 1 | function d = diam(p) 2 | %DIAM Diameter of a polygon. 3 | % 4 | % DIAM(P) returns max_{j,k} |P(j)-P(k)|. This may be infinite. 5 | 6 | % Copyright 2002 by Toby Driscoll. 7 | % $Id: diam.m 194 2002-09-10 19:10:41Z driscoll $ 8 | 9 | w = vertex(p); 10 | [w1,w2] = meshgrid(w); 11 | d = max( max( abs(w1-w2) ) ); 12 | -------------------------------------------------------------------------------- /@polygon/display.m: -------------------------------------------------------------------------------- 1 | function display(p) 2 | % Pretty-print a polygon. 3 | 4 | % Copyright 1998-2003 by Toby Driscoll. 5 | % $Id: display.m 271 2003-05-08 18:11:36Z driscoll $ 6 | 7 | w = vertex(p); 8 | alpha = angle(p); 9 | n = length(w); 10 | if n==0 11 | fprintf('\n empty polygon\n\n') 12 | return 13 | end 14 | 15 | fprintf('\n%s = polygon object:\n\n',inputname(1)) 16 | 17 | % We make disp do the heavy lifting. This way the FORMAT command works 18 | % here too. 19 | 20 | vstr = evalc( 'disp(w)' ); 21 | astr = evalc( 'disp(alpha)' ); 22 | 23 | % Parse into one cell per line. 24 | for j=1:n 25 | [tmp,vstr] = strtok(vstr,sprintf('\n')); vc{j}=tmp; 26 | [tmp,astr] = strtok(astr,sprintf('\n')); ac{j}=tmp; 27 | end 28 | 29 | % Now into matrices. 30 | vm = strvcat(vc); am = strvcat(ac); 31 | 32 | % Remove leading and trailing space blocs. 33 | idx = find( ~all(vm==' ') ); 34 | vm = vm(:,min(idx):max(idx)); 35 | idx = find( ~all(am==' ') ); 36 | am = am(:,min(idx):max(idx)); 37 | 38 | wv = max(size(vm,2),6); 39 | wa = max(size(am,2),8); 40 | b1 = blanks(2+floor((wv-6)/2)); 41 | b2 = blanks(ceil((wv-6)/2)+4+floor((wa-8)/2)); 42 | fprintf( [b1 'Vertex' b2 'Angle/pi\n'] ); 43 | %fprintf( [b1 '------' b2 '--------\n'] ); 44 | 45 | uv = min(size(vm,2),6); 46 | ua = min(size(am,2),8); 47 | b1 = blanks(2+floor((6-uv)/2)); 48 | b2 = blanks(ceil((6-uv)/2)+4+floor((8-ua)/2)); 49 | str = [ repmat(b1,n,1) vm repmat(b2,n,1) am ]; 50 | 51 | fprintf([' ' repmat('-',1,wv+4+wa) '\n']); 52 | disp(str) 53 | fprintf('\n\n') 54 | -------------------------------------------------------------------------------- /@polygon/double.m: -------------------------------------------------------------------------------- 1 | function x = double(p) 2 | %DOUBLE Convert polygon to double. 3 | % If the polygon is bounded, DOUBLE returns the vertices in an Nx2 4 | % matrix. Otherwise, it returns a cell array whose first component is 5 | % the vertex matrix and whose second component is the vector of 6 | % interior normalized angles. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: double.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | if ~any(isinf(p.vertex)) 12 | x = p.vertex; 13 | x = [real(x) imag(x)]; 14 | else 15 | x = { [real(p.vertex) imag(p.vertex)] p.angle }; 16 | end 17 | -------------------------------------------------------------------------------- /@polygon/fill.m: -------------------------------------------------------------------------------- 1 | function H = fill(p,varargin) 2 | %FILL Plot a polygon with a filled interior. 3 | % FILL(P) plots the boundary of P in blue and fills the interior of the 4 | % polygon with gray. FILL(P,PROP1,VAL1,...) passes additional arguments 5 | % to the built-in FILL command. 6 | % 7 | % See also FILL. 8 | 9 | % Copyright 2003 by Toby Driscoll. 10 | % $Id: fill.m 274 2004-05-27 13:11:21Z driscoll $ 11 | 12 | v = vertex(p); 13 | vf = v(~isinf(v)); 14 | if any(isinf(v)) 15 | v = vertex(truncate(p)); 16 | end 17 | 18 | axlim = [min(real(vf)) max(real(vf)) min(imag(vf)) max(imag(vf))]; 19 | d = max([0.04,diff(axlim(1:2)),diff(axlim(3:4))]); 20 | axlim(1:2) = mean(axlim(1:2)) + 0.54*[-1 1]*d; 21 | axlim(3:4) = mean(axlim(3:4)) + 0.54*[-1 1]*d; 22 | 23 | % Use defaults, but allow overrides and additional settings. 24 | settings = { 0.75*[1 1 1],'edgecolor','b','linewidth',1.5, varargin{:} }; 25 | h = fill(real(v),imag(v),settings{:}); 26 | 27 | if ~ishold 28 | axis equal 29 | axis square 30 | axis(axlim) 31 | end 32 | 33 | if nargout > 0 34 | H = h; 35 | end 36 | -------------------------------------------------------------------------------- /@polygon/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(p,varargin) 2 | %GET Get polygon parameters. 3 | % ==> Deprecated. Please use ANGLE and VERTEX instead. 4 | % 5 | % [VAL1,VAL2,...] = GET(P,'PROP1','PROP2',...) returns the values of the 6 | % polygon P corresponding to the requested properties. Valid properties 7 | % are: 8 | % 9 | % vertex, angle 10 | 11 | % Copyright 1999-2003 by Toby Driscoll. 12 | % $Id: get.m 232 2003-01-09 14:52:16Z driscoll $ 13 | 14 | for j = 1:length(varargin) 15 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 16 | case 'ver' 17 | varargin{j} = p.vertex; 18 | case 'ang' 19 | varargin{j} = p.angle; 20 | otherwise 21 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 22 | varargin{j} = []; 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /@polygon/isempty.m: -------------------------------------------------------------------------------- 1 | function t = isempty(p) 2 | % Returns true if there are no vertices. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: isempty.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | t = isempty(p.vertex); 8 | -------------------------------------------------------------------------------- /@polygon/isinf.m: -------------------------------------------------------------------------------- 1 | function s = isinf(p) 2 | %ISINF Determine whether a polygon is unbounded. 3 | % 4 | % ISINF(P) returns logical 1 when P is unbounded and 0 otherwise. 5 | 6 | % Copyright 2002 by Toby Driscoll. 7 | % $Id: isinf.m 190 2002-09-10 17:23:26Z driscoll $ 8 | 9 | s = any(isinf(vertex(p))); -------------------------------------------------------------------------------- /@polygon/isinpoly.m: -------------------------------------------------------------------------------- 1 | function idx = isinpoly(wp,p,varargin) 2 | %ISINPOLY Identify points interior/exterior to a polygon. 3 | % ISINPOLY(WP,P) returns a logical vector the size of WP in which 4 | % nonzero means the corresponding point is inside polygon P and zero 5 | % means it is outside. 6 | % 7 | % ISINPOLY(WP,P,TOL) considers points within TOL of the boundary to be 8 | % inside P. Without this argument, points on the boundary may or may not 9 | % register as inside. 10 | % 11 | % See also POLYGON/WINDING. 12 | 13 | % Copyright 1998-2003 by Toby Driscoll. 14 | % $Id: isinpoly.m 231 2003-01-09 14:49:49Z driscoll $ 15 | 16 | idx = logical( winding(p,wp,varargin{:}) ); 17 | 18 | -------------------------------------------------------------------------------- /@polygon/length.m: -------------------------------------------------------------------------------- 1 | function n = length(p) 2 | % Returns number of vertices 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: length.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | n = length(p.vertex); 8 | -------------------------------------------------------------------------------- /@polygon/linspace.m: -------------------------------------------------------------------------------- 1 | function [z,idx] = linspace(p,m) 2 | %LINSPACE Evenly spaced points around the polygon. 3 | % LINSPACE(P,N) returns a vector of N points evenly spaced on the 4 | % polygon P, starting with the first vertex. 5 | % 6 | % LINSPACE(P,H) for H<1 instead uses H as an upper bound on the arc 7 | % length between points. 8 | % 9 | % [Z,IDX] = LINSPACE(...) returns the points and an identically sized 10 | % vector of corresponding side indices. 11 | % 12 | % If the polygon is unbounded, an error results. 13 | 14 | % Copyright 1998-2002 by Toby Driscoll. 15 | % $Id: linspace.m 182 2002-09-05 15:40:11Z driscoll $ 16 | 17 | n = length(p); 18 | w = vertex(p); 19 | dw = diff(w([1:n 1])); 20 | 21 | if any(isinf(w)) 22 | error('LINSPACE cannot be applied to unbounded polygons.') 23 | end 24 | 25 | % Arc lengths of sides. 26 | s = abs(dw); 27 | s = cumsum([0;s]); 28 | L = s(end); 29 | s = s/L; % relative arc length 30 | 31 | % Evenly spaced points in arc length. 32 | if m < 1 33 | % How many points will we need? 34 | m = ceil(L/m) + 1; 35 | end 36 | zs = (0:m-1)'/m; 37 | z = zs; 38 | done = logical(zeros(size(z))); 39 | idx = zeros(size(z)); 40 | 41 | % Translate to polygon sides. 42 | for j = 1:n 43 | mask = (~done) & (zs < s(j+1)); 44 | z(mask) = w(j) + dw(j)*(zs(mask)-s(j))/(s(j+1)-s(j)); 45 | idx(mask) = j; 46 | done = mask | done; 47 | end 48 | 49 | -------------------------------------------------------------------------------- /@polygon/minus.m: -------------------------------------------------------------------------------- 1 | function r = minus(p,q) 2 | % Translate a polygon, or subtract the vertices of two polygons. 3 | 4 | % Copyright 1999-2003 by Toby Driscoll. 5 | % $Id: minus.m 247 2003-03-03 16:28:22Z driscoll $ 6 | 7 | r = plus(p,-q); 8 | -------------------------------------------------------------------------------- /@polygon/modify.m: -------------------------------------------------------------------------------- 1 | function [p,indx] = modify(p) 2 | %MODIFY Modify a polygon graphically. 3 | % See MODPOLY for usage instructions. 4 | 5 | % Copyright 1998 by Toby Driscoll. 6 | % $Id: modify.m 7 1998-05-10 04:37:19Z tad $ 7 | 8 | [w,beta,indx] = modpoly(vertex(p),angle(p)-1); 9 | p = polygon(w,beta+1); 10 | -------------------------------------------------------------------------------- /@polygon/mrdivide.m: -------------------------------------------------------------------------------- 1 | function r = mrdivide(p,q) 2 | % Divide a polygon by a scalar. 3 | 4 | % Copyright 2003 by Toby Driscoll. 5 | % $Id: mrdivide.m 242 2003-03-03 16:17:56Z driscoll $ 6 | 7 | if ~isa(q,'double') || length(q)>1 8 | error('Function ''/'' defined only for a scalar double.') 9 | end 10 | 11 | r = p; 12 | r.vertex = r.vertex/q; 13 | -------------------------------------------------------------------------------- /@polygon/mtimes.m: -------------------------------------------------------------------------------- 1 | function r = mtimes(p,q) 2 | % Multiplication of a polygon by a scalar. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | if isa(q,'polygon') 8 | if isa(p,'polygon') 9 | error('Function ''*'' not defined for two polygon objects.') 10 | end 11 | tmp = p; 12 | p = q; 13 | q = tmp; 14 | end 15 | 16 | r = p; 17 | r.vertex = r.vertex*q; 18 | -------------------------------------------------------------------------------- /@polygon/perimeter.m: -------------------------------------------------------------------------------- 1 | function L = perimeter(p) 2 | %PERIMETER Perimeter of a polygon. 3 | 4 | % $Id: perimeter.m 243 2003-03-03 16:18:13Z driscoll $ 5 | 6 | if isinf(p) 7 | L = Inf; 8 | else 9 | w = vertex(p); 10 | L = sum( abs( diff( w([1:end 1]) ) ) ); 11 | end -------------------------------------------------------------------------------- /@polygon/plot.m: -------------------------------------------------------------------------------- 1 | function handles = plot(p,varargin) 2 | %PLOT Plot a polygon. 3 | % PLOT(P) plots the polygon P (draws the sides). 4 | % 5 | % PLOT(P,'num') or PLOT(P,'lab') also plots dots for the vertices and 6 | % numeric labels. For infinite vertices, two numeric labels are 7 | % printed. 8 | % 9 | % H = PLOT(P) returns a vector of handles to the sides drawn. H = 10 | % PLOT(P,'num') returns a structure; H.side is a vector of side 11 | % handles, and H.label is a 2-column array of vertex dot and label 12 | % handles (each vertex has two graphical objects). 13 | 14 | % Copyright 1998 by Toby Driscoll. 15 | % $Id: plot.m 138 2001-05-15 14:16:46Z driscoll $ 16 | 17 | w = vertex(p); 18 | beta = angle(p) - 1; 19 | 20 | if isempty(w) 21 | h = []; 22 | elseif nargin > 1 23 | [eh,lh] = plotpoly(w,beta,1); 24 | h.side = eh; 25 | h.label = lh; 26 | else 27 | h = plotpoly(w,beta); 28 | end 29 | 30 | if nargout > 0 31 | handles = h; 32 | end 33 | 34 | -------------------------------------------------------------------------------- /@polygon/plotcdt.m: -------------------------------------------------------------------------------- 1 | function h = plotcdt(p,T,varargin) 2 | %PLOTCDT Plot constrained Delaunay triangulation. 3 | % PLOTCDT(P,T) plots the CDT of P computed by CDT. PLOTCDT(P,T,1) labels 4 | % the edges and vertices. 5 | % 6 | % H = PLOTCDT(P,T) returns a vector of handles for the edges. 7 | % 8 | % See also CDT. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: plotcdt.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | han = sctool.plotptri(p.vertex,T.edge,varargin{:}); 14 | 15 | if nargout > 0 16 | h = han; 17 | end 18 | -------------------------------------------------------------------------------- /@polygon/plus.m: -------------------------------------------------------------------------------- 1 | function r = plus(p,q) 2 | % Translate a polygon, or add the vertices of two polygons. 3 | 4 | % Copyright 1998-2003 by Toby Driscoll. 5 | % $Id: plus.m 245 2003-03-03 16:24:51Z driscoll $ 6 | 7 | if isa(q,'polygon') 8 | tmp = p; 9 | p = q; 10 | q = tmp; 11 | end 12 | 13 | switch(class(q)) 14 | case 'polygon' 15 | if length(q)~=length(p) 16 | error('Polygons must have the same length to be added.') 17 | elseif isinf(p) || isinf(q) 18 | error('Only finite polygons may be added.') 19 | end 20 | r = polygon( vertex(p) + vertex(q) ); 21 | case 'double' 22 | if length(q) > 1 && length(q)~=length(p) 23 | error(['Only a scalar or identical-length vector may be added to a ' ... 24 | 'polygon.']) 25 | end 26 | r = polygon( vertex(p) + q(:) ); 27 | end 28 | -------------------------------------------------------------------------------- /@polygon/size.m: -------------------------------------------------------------------------------- 1 | function n = size(p,m) 2 | % Number of vertices. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: size.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | if nargin == 1 8 | n = [length(p.vertex) 1]; 9 | elseif m == 1 10 | n = length(p.vertex); 11 | else 12 | n = 1; 13 | end 14 | 15 | -------------------------------------------------------------------------------- /@polygon/subsasgn.m: -------------------------------------------------------------------------------- 1 | function p = subsasgn(p,S,data) 2 | % Allows assignment of individual vertices. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: subsasgn.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | name = fieldnames(p); 8 | 9 | % Single index reference p(idx) 10 | if length(S) == 1 & strcmp(S.type,'()') & length(S.subs) == 1 11 | p.vertex(S.subs{1}) = data; 12 | else 13 | % Field reference 14 | if strcmp(S(1).type,'.') 15 | field = S(1).subs; 16 | idx = strmatch(field,name,'exact'); 17 | if isempty(idx) 18 | error(sprintf('Unrecognized field name ''%s''.',field)); 19 | end 20 | if length(S) > 1 & strcmp(S(2).type,'()') & length(S(2).subs) == 1 21 | idx = S(2).subs{1}; 22 | else 23 | idx = ':'; 24 | end 25 | eval(sprintf('p.%s(idx) = data;',field)) 26 | end 27 | end -------------------------------------------------------------------------------- /@polygon/subsref.m: -------------------------------------------------------------------------------- 1 | function data = subsref(p,S) 2 | % Extract one or more vertices by index. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: subsref.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | name = fieldnames(p); 8 | 9 | % Single index reference p(idx) 10 | if length(S) == 1 & strcmp(S.type,'()') & length(S.subs) == 1 11 | data = p.vertex(S.subs{1}); 12 | return 13 | end 14 | 15 | % Field reference 16 | data = []; 17 | if strcmp(S(1).type,'.') 18 | field = S(1).subs; 19 | idx = strmatch(field,name,'exact'); 20 | if isempty(idx) 21 | error(sprintf('Unrecognized field name ''%s''.',field)); 22 | end 23 | eval(sprintf('data = p.%s;',field')) 24 | end 25 | 26 | % Index on the reference 27 | if length(S) > 1 & strcmp(S(2).type,'()') & length(S(2).subs) == 1 28 | data = data(S(2).subs{1}); 29 | end 30 | -------------------------------------------------------------------------------- /@polygon/uminus.m: -------------------------------------------------------------------------------- 1 | function q = uminus(p) 2 | % Negate the vertices of a polygon. 3 | % This may have surprising consequences if p is unbounded. 4 | 5 | % Copyright 2003 by Toby Driscoll (driscoll@math.udel.edu). 6 | % $Id: uminus.m 246 2003-03-03 16:28:04Z driscoll $ 7 | 8 | q = polygon( -vertex(p), angle(p) ); 9 | 10 | -------------------------------------------------------------------------------- /@polygon/vertex.m: -------------------------------------------------------------------------------- 1 | function [x,y] = vertex(p) 2 | %VERTEX Vertices of a polygon. 3 | % VERTEX(P) returns the vertices of polygon P as a complex vector. 4 | % 5 | % [X,Y] = VERTEX(P) returns the vertices as two real vectors. 6 | % 7 | % See also POLYGON. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: vertex.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | x = p.vertex; 13 | if nargout == 2 14 | y = imag(x); 15 | x = real(x); 16 | end 17 | -------------------------------------------------------------------------------- /@polygon/winding.m: -------------------------------------------------------------------------------- 1 | function idx = winding(p,wp,varargin) 2 | %WINDING Winding number of points with respect to a polygon. 3 | % WINDING(P,WP) returns a vector the size of WP of winding numbers with 4 | % respect to P. A zero value means the point is outside P; a value 5 | % greater than 1 means it lies on multiple sheets. 6 | % 7 | % WINDING(P,WP,TOL) makes the boundary of P "fuzzy" by a distance 8 | % TOL. This may be needed to compute winding number for points on the 9 | % boundary that you want to be considered "just inside." 10 | % 11 | % See also POLYGON/ISINPOLY. 12 | 13 | % Copyright 2003 by Toby Driscoll. 14 | % $Id: winding.m 230 2003-01-09 14:48:25Z driscoll $ 15 | 16 | if isinf(p) 17 | warning('SC:Truncation','Using a truncated version of the polygon.') 18 | p = truncate(p); 19 | end 20 | 21 | idx = double( sctool.isinpoly(wp,p.vertex,varargin{:}) ); 22 | -------------------------------------------------------------------------------- /@rectmap/corners.m: -------------------------------------------------------------------------------- 1 | function corner = corners(M) 2 | %CORNERS Indices of rectangle/generalized quadrilateral corners. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: corners.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | z = M.prevertex; 8 | tol = 4*eps; 9 | 10 | % Find extent of rectangle 11 | K = max(real(z)); 12 | Kp = max(imag(z)); 13 | 14 | % First corner is K + 0i 15 | dif = repmat(z,1,4) - repmat([K K+i*Kp -K+i*Kp -K],length(z),1); 16 | [tmp,corner] = min(abs(dif)); 17 | 18 | corner = corner(:); 19 | -------------------------------------------------------------------------------- /@rectmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel rectangle map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the source rectangle of M. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also RECTMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 267 2003-05-08 18:07:51Z driscoll $ 13 | 14 | p = polygon(M); 15 | n = length(p); 16 | z = M.prevertex; 17 | zr = z(corners(M)); 18 | 19 | if nargin < 3 20 | qdata = M.qdata; 21 | else 22 | qdata = tol; 23 | end 24 | 25 | wp = NaN*zp; 26 | opt = scmapopt(M); 27 | idx = find( isinpoly(zp,polygon(zr),opt.Tolerance) ); 28 | wp(idx) = ... 29 | rmap(zp(idx),vertex(p),angle(p)-1,z,M.constant,M.stripL,qdata); 30 | -------------------------------------------------------------------------------- /@rectmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel rectangle map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % rectangle map M at the points ZP. 5 | % 6 | % See also RECTMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | z = M.prevertex; 12 | c = M.constant; 13 | beta = angle(polygon(M)) - 1; 14 | 15 | fp = rderiv(zp,z,beta,M.constant,M.stripL); 16 | -------------------------------------------------------------------------------- /@rectmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@rectmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties are: 5 | % 6 | % polygon, options, prevertex, constant, L (stripL) 7 | 8 | % Copyright 1999-2003 by Toby Driscoll. 9 | % $Id: get.m 236 2003-01-15 15:29:14Z driscoll $ 10 | 11 | for j = 1:length(varargin) 12 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 13 | case 'pol' 14 | varargout{j} = map.scmap.polygon; 15 | case 'opt' 16 | varargout{j} = map.scmap.options; 17 | case 'pre' 18 | varargout{j} = map.prevertex; 19 | case 'con' 20 | varargout{j} = map.constant; 21 | case {'l','str'} 22 | varargout{j} = map.stripL; 23 | otherwise 24 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 25 | varargout{j} = []; 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /@rectmap/modulus.m: -------------------------------------------------------------------------------- 1 | function mu = modulus(M) 2 | %MODULUS Conformal modulus of the generalized quadrilateral. 3 | % Returns the conformal modulus of the polygon in the rectmap (the 4 | % aspect ratio of the source rectangle). 5 | 6 | % Copyright 1998 by Toby Driscoll. 7 | % $Id: modulus.m 7 1998-05-10 04:37:19Z tad $ 8 | 9 | z = M.prevertex; 10 | mu = max(imag(z)) / (2*max(real(z))); 11 | -------------------------------------------------------------------------------- /@rectmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 33 1998-06-29 22:35:40Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'rectmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.scmap = c*M.scmap; 16 | -------------------------------------------------------------------------------- /@rectmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.prevertex = M.prevertex; 8 | v.constant = M.constant; 9 | v.stripL = M.stripL; 10 | -------------------------------------------------------------------------------- /@rectmap/private/r2strip.m: -------------------------------------------------------------------------------- 1 | function [yp,yprime] = r2strip(zp,z,L) 2 | %R2STRIP Map from rectangle to strip. 3 | % R2STRIP(ZP,Z,L) maps from a rectangle to the strip 0 <= Im z <= 1, 4 | % with the function log(sn(z|m))/pi, where sn is a Jacobi elliptic 5 | % function and m = exp(-2*pi*L). The prevertices of the map (in the 6 | % rectangle domain) are given by Z; only the corners of the rectangle 7 | % defined by Z are used. 8 | % 9 | % The derivative of the map is returned as a second argument. 10 | % 11 | % NOTE: The functionality is NOT parallel to HP2DISK and DISK2HP. 12 | 13 | % Copyright 1998 by Toby Driscoll. 14 | % $Id: r2strip.m 298 2009-09-15 14:36:37Z driscoll $ 15 | 16 | % The built-in ellipj accepts only real arguments. The standard identity is 17 | % not helpful when m is near zero, because (1-m) loses digits of accuracy. 18 | 19 | K = max(real(z)); 20 | Kp = max(imag(z)); 21 | yp = zp; 22 | yprime = zp; 23 | 24 | [sn,cn,dn] = ellipjc(zp,L); 25 | % Make sure everything is in the upper half-plane (fix roundoff) 26 | sn = real(sn) + i*max(imag(sn),0); 27 | 28 | yp = log(sn)/pi; 29 | yprime = cn.*dn./sn/pi; 30 | 31 | % Make sure everything is in the strip (roundoff could put it outside) 32 | yp = real(yp) + i*max(0,imag(yp)); 33 | yp = real(yp) + i*min(1,imag(yp)); 34 | 35 | -------------------------------------------------------------------------------- /@rectmap/private/rcorners.m: -------------------------------------------------------------------------------- 1 | function [w,beta,z,corners,renum] = rcorners(w,beta,z) 2 | %RCORNERS (not intended for calling directly by the user) 3 | % Find corners of rectangle whose map is represented by prevertices z 4 | % on the strip, then renumber w, beta, and z (and the corners) so that 5 | % corners(1)=1. 6 | 7 | % Copyright 1998 by Toby Driscoll. 8 | % $Id: rcorners.m 298 2009-09-15 14:36:37Z driscoll $ 9 | 10 | n = length(w); 11 | 12 | % Deduce corner locations 13 | left = abs(real(z)-min(real(z))) < eps; 14 | right = abs(real(z)-max(real(z))) < eps; 15 | top = abs(imag(z)-max(imag(z))) < eps; 16 | bot = abs(imag(z)-min(imag(z))) < eps; 17 | corners = find(left+right+top+bot - 1); 18 | c1 = find(abs(z-max(real(z))) < eps); 19 | offset = find(corners==c1); 20 | corners = corners([offset:4,1:offset-1]); 21 | 22 | % Renumber vertices so that corners(1)=1 23 | renum = [corners(1):n,1:corners(1)-1]; 24 | w = w(renum); 25 | beta = beta(renum); 26 | z = z(renum); 27 | corners = rem(corners-corners(1)+1+n-1,n)+1; 28 | 29 | -------------------------------------------------------------------------------- /@rectmap/private/rderiv.m: -------------------------------------------------------------------------------- 1 | function fprime = rderiv(zp,z,beta,c,L,zs) 2 | %RDERIV Derivative of the rectangle map. 3 | % RDERIV(ZP,Z,BETA,C,L) returns the derivative at the points of ZP of 4 | % the Schwarz-Christoffel rectangle map defined by Z, BETA, C, and L. 5 | % 6 | % If a sixth argument is supplied, it is assumed to be the image of Z 7 | % on the intermediate strip; see R2STRIP. 8 | % 9 | % See also RPARAM, RMAP, R2STRIP. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: rderiv.m 298 2009-09-15 14:36:37Z driscoll $ 13 | 14 | n = length(z); 15 | 16 | if nargin < 6 17 | % Find prevertices on the strip 18 | zs = r2strip(z,z,L); 19 | zs = real(zs) + i*round(imag(zs)); % put them *exactly* on edges 20 | end 21 | 22 | % First compute map and derivative from rectangle to strip 23 | [F,dF] = r2strip(zp,z,L); 24 | 25 | % Now compute derivative of map from strip to polygon 26 | % Add in ends of strip 27 | ends = find(diff(imag(z([1:n 1])))); 28 | zs = [zs(1:ends(1));Inf;zs(ends(1)+1:ends(2));-Inf;zs(ends(2)+1:n)]; 29 | bs = [beta(1:ends(1));0;beta(ends(1)+1:ends(2));0;beta(ends(2)+1:n)]; 30 | dG = stripmap.deriv(F,zs,bs); 31 | 32 | % Put it together 33 | fprime = c*dF.*dG; 34 | 35 | -------------------------------------------------------------------------------- /@rectmap/private/rimapfun.m: -------------------------------------------------------------------------------- 1 | function zdot = rimapfun(wp,yp,flag,scale,z,beta,c,zs,L); 2 | % Used by RINVMAP for solution of an ODE. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: rimapfun.m 298 2009-09-15 14:36:37Z driscoll $ 6 | 7 | lenyp = length(yp); 8 | lenzp = lenyp/2; 9 | zp = yp(1:lenzp) + i*yp(lenzp+1:lenyp); 10 | 11 | f = scale./rderiv(zp,z,beta,c,L,zs); 12 | zdot = [real(f);imag(f)]; 13 | -------------------------------------------------------------------------------- /@rectmap/private/rptrnsfm.m: -------------------------------------------------------------------------------- 1 | function z = rptrnsfm(y,cnr) 2 | %RPTRNSFM (not intended for calling directly by the user) 3 | % Transform optimization vars to prevertices for rectangle parameter 4 | % problem. 5 | 6 | % Copyright 1997 by Toby Driscoll. Last updated 05/06/97. 7 | 8 | n = length(y)+3; 9 | z = zeros(n,1); 10 | 11 | % Fill interior of "long edges" first 12 | z(cnr(1)+1:cnr(2)-1) = cumsum(exp(y(cnr(1):cnr(2)-2))); 13 | z(cnr(4)-1:-1:cnr(3)+1) = i + cumsum(exp(y(cnr(4)-3:-1:cnr(3)-1))); 14 | 15 | % Find L 16 | xr = real( z([cnr(2)-1,cnr(3)+1]) ); 17 | z(cnr(2)) = mean(xr)+sqrt(diff(xr/2)^2+exp(2*y(cnr(2)-1))); 18 | z(cnr(3)) = i + z(cnr(2)); 19 | z(cnr(4)) = i; 20 | 21 | % Now, fill in "short edges" 22 | cp = cumprod([1;exp(-y(cnr(2):cnr(3)-2))]); 23 | x = [0;cumsum(cp)] - [flipud(cumsum(flipud(cp)));0]; 24 | x = x(2:end-1)/x(end); 25 | mask = abs(x) < eps; 26 | u = x; 27 | u(~mask) = log( x(~mask) ) / pi; 28 | u(mask) = -z(cnr(2))/eps; 29 | z(cnr(2)+1:cnr(3)-1) = i*imag(u) + real(z(cnr(2))) - real(u); 30 | 31 | idx = [cnr(4)-2:n-3 1:cnr(1)-1]; 32 | cp = cumprod([1;exp(-y(idx))]); 33 | x = [0;cumsum(cp)] - [flipud(cumsum(flipud(cp)));0]; 34 | x = x(2:end-1)/x(end); 35 | mask = abs(x) < eps; 36 | u = x; 37 | u(~mask) = log( x(~mask) ) / pi; 38 | u(mask) = -z(cnr(2))/eps; 39 | z([cnr(4)+1:n 1:cnr(1)-1]) = u; 40 | -------------------------------------------------------------------------------- /@rectmap/rectangle.m: -------------------------------------------------------------------------------- 1 | function zr = rectangle(M) 2 | %RECTANGLE Return the corners of the rectangle in the fundamental domain. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: rectangle.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | zr = prevertex(M); 8 | zr = zr(corners(M)); 9 | -------------------------------------------------------------------------------- /@riesurfmap/accuracy.m: -------------------------------------------------------------------------------- 1 | function acc = accuracy(M) 2 | %ACCURACY Apparent accuracy of a Schwarz-Christoffel map. 3 | % ACCURACY(M) estimates the accuracy of the Schwarz-Christoffel Riemann 4 | % surface map M. The technique used is to compare the differences between 5 | % successive finite vertices to the integral between the corresponding 6 | % prevertices, and return the maximum. 7 | % 8 | % See also RIESURFMAP. 9 | 10 | % Copyright 2002 by Toby Driscoll. 11 | % $Id: accuracy.m 201 2002-09-13 19:46:08Z driscoll $ 12 | 13 | % If an accuracy has been assigned, don't question it 14 | if ~isempty(M.accuracy) 15 | acc = M.accuracy; 16 | return 17 | end 18 | 19 | % Get data for low-level functions 20 | p = polygon(M); 21 | w = vertex(p); 22 | beta = angle(p) - 1; 23 | wb = M.branch; 24 | z = M.prevertex; 25 | zb = M.prebranch; 26 | c = M.constant; 27 | qdata = M.qdata; 28 | 29 | % Test accuracy by integrating between consecutive finite prevertices, and 30 | % comparing to differences of vertices. 31 | 32 | n = length(w); 33 | idx = find(~isinf(w)); 34 | wf = w(idx); % finite vertices 35 | 36 | % Two columns hold endpoint indices for integrations. 37 | idx = [idx(1:end) idx([2:end 1])]; 38 | 39 | % Do the integrations. 40 | I = rsquad(z(idx(:,1)),z(idx(:,2)),idx(:,1),idx(:,2),z,beta,zb,qdata); 41 | 42 | acc = max(abs( c*I - diff(wf([1:end 1])) )); 43 | -------------------------------------------------------------------------------- /@riesurfmap/center.m: -------------------------------------------------------------------------------- 1 | function wc = center(map,wc) 2 | %CENTER Conformal center of Schwarz-Christoffel disk map. 3 | % CENTER(M) returns the conformal center (image of 0) of the 4 | % Schwarz-Christoffel disk map represented by M. 5 | % 6 | % CENTER(M,WC) computes a map conformally equivalent to M but with 7 | % conformal center WC (provided WC is inside the polygon of M), and 8 | % returns the new map. If WC is empty, you will be asked to select it 9 | % graphically. 10 | % 11 | % See also DISKMAP. 12 | 13 | % Copyright 1998 by Toby Driscoll. 14 | % $Id: center.m 196 2002-09-10 19:12:38Z driscoll $ 15 | 16 | if nargin == 1 17 | % Return center 18 | wc = map.center; 19 | if isempty(wc) 20 | p = polygon(map); 21 | wc = rsmap(0,vertex(p),angle(p)-1,... 22 | map.prevertex,map.prebranch,map.constant,map.qdata); 23 | end 24 | 25 | else 26 | % Set center 27 | error('Recentering of RIESURF maps not supported.') 28 | end 29 | -------------------------------------------------------------------------------- /@riesurfmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel disk map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the unit disk. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also DISKMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 198 2002-09-13 18:44:12Z driscoll $ 13 | 14 | if nargin < 3 15 | qdata = M.qdata; 16 | else 17 | qdata = tol; 18 | end 19 | 20 | p = polygon(M); 21 | wp = NaN*zp; 22 | idx = abs(zp) <= 1+eps; 23 | zb = M.prebranch; 24 | wp(idx) = rsmap(zp(idx),vertex(p),angle(p)-1,M.prevertex,zb,M.constant,qdata); 25 | -------------------------------------------------------------------------------- /@riesurfmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(f,zp) 2 | %EVALDIFF Evaluate derivative of Schwarz-Christoffel Riemann surface map. 3 | % EVALDIFF(F,ZP) computes the derivative of the Schwarz-Christoffel 4 | % Riemann surface map F at the points ZP. 5 | % 6 | % See also RIESURFMAP, EVAL. 7 | 8 | % Copyright 2002 by Toby Driscoll. 9 | % $Id: evaldiff.m 203 2002-09-13 20:09:37Z driscoll $ 10 | 11 | z = f.prevertex; 12 | c = f.constant; 13 | beta = angle(polygon(f)) - 1; 14 | zb = f.prebranch; 15 | 16 | fp = rsderiv(zp,z,beta,zb,c); 17 | -------------------------------------------------------------------------------- /@riesurfmap/evalinv.m: -------------------------------------------------------------------------------- 1 | function [zp,flag] = evalinv(M,wp,tol,z0) 2 | %EVALINV Not supported for RIESURFMAPs. 3 | % Currently inversion of maps to Riemann surfaces is not supported, 4 | % primarily because of the multivalued nature of the inverse. 5 | 6 | help riesurfmap/evalinv 7 | -------------------------------------------------------------------------------- /@riesurfmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@riesurfmap/forwardpoly.m: -------------------------------------------------------------------------------- 1 | function p = forwardpoly(map) 2 | % Given a riesurfmap F, FORWARDPOLY(F) returns the polygon that is 3 | % formed using the prevertices, angles, and quadrature data of that 4 | % map. If the prevertices were found from the solution of a 5 | % parameter problem, then the result should agree closely with the 6 | % original polygon that was supplied. 7 | 8 | % Copyright 2002 by Toby Driscoll. 9 | % $Id: forwardpoly.m 203 2002-09-13 20:09:37Z driscoll $ 10 | 11 | z = map.prevertex; 12 | alpha = angle(polygon(map)); 13 | c = map.constant; 14 | zb = map.prebranch; 15 | 16 | n = length(z); 17 | 18 | % Since there is no parameter problem, use high accuracy in quadrature. 19 | qdata = scqdata(alpha-1,16); 20 | 21 | w = zeros(n,1); 22 | atinf = (alpha < eps); 23 | w(atinf) = Inf; 24 | 25 | % Endpoints of integrations 26 | idx = find(~atinf); 27 | idx = [idx(1:end-1) idx(2:end)]; 28 | 29 | % Integrations 30 | I = rsquad(z(idx(:,1)),z(idx(:,2)),idx(:,1),idx(:,2),z,alpha-1,zb,qdata); 31 | 32 | % Deduce vertices 33 | w(~atinf) = c*cumsum([0;I]); 34 | 35 | p = polygon(w,alpha); 36 | -------------------------------------------------------------------------------- /@riesurfmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright 2002 by Toby Driscoll. 5 | % $Id: mtimes.m 204 2002-09-13 20:09:50Z driscoll $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'riesurfmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.scmap = c*M.scmap; 16 | M.center = c*M.center; -------------------------------------------------------------------------------- /@riesurfmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 2002 by Toby Driscoll. 5 | % $Id: parameters.m 201 2002-09-13 19:46:08Z driscoll $ 6 | 7 | v.branch = M.branch; 8 | v.prevertex = M.prevertex; 9 | v.prebranch = M.prebranch; 10 | v.constant = M.constant; 11 | -------------------------------------------------------------------------------- /@riesurfmap/plot.m: -------------------------------------------------------------------------------- 1 | function [h,r,theta] = plot(f,varargin) 2 | %PLOT Visualize a Schwarz-Christoffel Riemann surface map. 3 | % PLOT(F) plots the polygon associated with the Schwarz-Christoffel 4 | % Riemann surface map F and the images of ten evenly spaced circles 5 | % and radii under the S-C transformation. 6 | % 7 | % PLOT(F,NR,NTHETA) plots the images of NR circles and NTHETA radii. 8 | % 9 | % PLOT(F,R,THETA) plots the circles at radii given by the entries of R 10 | % and radii at the angles specified in THETA. 11 | % 12 | % PLOT(F,TOL) or PLOT(F,NR,NTHETA,TOL) or PLOT(F,R,THETA,TOL) computes 13 | % the map with accuracy roughly TOL. Normally TOL defaults to 1e-4 or 14 | % the accuracy of F, whichever is greater. 15 | % 16 | % See also RIESURFMAP, EVAL. 17 | 18 | % Copyright 2002 by Toby Driscoll. 19 | % $Id: plot.m 298 2009-09-15 14:36:37Z driscoll $ 20 | 21 | p = polygon(f); 22 | w = vertex(p); 23 | beta = angle(p) - 1; 24 | z = f.prevertex; 25 | zb = f.prebranch; 26 | c = f.constant; 27 | 28 | if nargin == 1 29 | [a1,a2,a3] = rsplot(w,beta,z,zb,c); 30 | elseif length(varargin) == 1 31 | % Tolerance given only 32 | [a1,a2,a3] = rsplot(w,beta,z,zb,c,10,10,ceil(-log10(varargin{1}))); 33 | elseif length(varargin) == 2 34 | % R, theta given only 35 | [a1,a2,a3] = rsplot(w,beta,z,zb,c,varargin{1},varargin{2}); 36 | else 37 | % All given 38 | nqpts = ceil(-log10(varargin{3})); 39 | [a1,a2,a3] = rsplot(w,beta,z,zb,c,varargin{1},varargin{2},nqpts); 40 | end 41 | 42 | if nargout > 0 43 | h = a1; 44 | r = a2; 45 | theta = a3; 46 | end 47 | 48 | -------------------------------------------------------------------------------- /@riesurfmap/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M,a) 2 | % Add a constant to the image of a map (i.e., translate image). 3 | 4 | % Copyright (c) 2002 by Toby Driscoll. 5 | % $Id: plus.m 206 2002-09-13 20:21:47Z driscoll $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(a,'riesurfmap') 9 | tmp = M; 10 | M = a; 11 | a = tmp; 12 | end 13 | 14 | if length(a)==1 & isa(a,'double') 15 | M.center = M.center + a; 16 | M.scmap = M.scmap + a; 17 | else 18 | error('Addition is not defined for these operands.') 19 | end 20 | -------------------------------------------------------------------------------- /@riesurfmap/private/rsderiv.m: -------------------------------------------------------------------------------- 1 | function fprime = rsderiv(zp,z,beta,zb,c) 2 | %RSDERIV Derivative of the Riemann surface map. 3 | 4 | % RSDERIV(ZP,Z,BETA,ZB,C) returns the derivative at the points of ZP of 5 | % the Schwarz-Christoffel disk map defined by Z, BETA, and C. 6 | 7 | % Copyright 2002 by Toby Driscoll. 8 | % $Id: rsderiv.m 298 2009-09-15 14:36:37Z driscoll $ 9 | 10 | % Support old syntax 11 | if nargin < 4 12 | c = 1; 13 | end 14 | 15 | z = z(:); 16 | beta = beta(:); 17 | zprow = zp(:).'; 18 | fprime = zeros(size(zp)); 19 | 20 | npts = length(zp(:)); 21 | ZP = zprow(ones(length(beta),1),:); 22 | Z = z(:,ones(npts,1)); 23 | terms = 1 - ZP./Z; 24 | fp = c*exp(sum(log(terms).*beta(:,ones(npts,1)))); 25 | 26 | B = length(zb); 27 | if B > 0 28 | ZB = zb(:,ones(1,npts)); 29 | ZP = zprow(ones(B,1),:); 30 | fp = fp.*prod((ZP-ZB).*(1-ZP.*conj(ZB)),1); 31 | end 32 | 33 | fprime(:) = fp; -------------------------------------------------------------------------------- /@scmap/char.m: -------------------------------------------------------------------------------- 1 | function s = char(f) 2 | 3 | s = ' scmap object (generic)'; 4 | -------------------------------------------------------------------------------- /@scmap/diff.m: -------------------------------------------------------------------------------- 1 | function Md = diff(M) 2 | %DIFF Differentiated SC map object. 3 | % DIFF(M) returns an object formally representing the derivative of 4 | % the map M. 5 | 6 | % Copyright 1998 by Toby Driscoll. 7 | % $Id: diff.m 7 1998-05-10 04:37:19Z tad $ 8 | 9 | Md = scmapdiff(M); 10 | -------------------------------------------------------------------------------- /@scmap/diskmap.m: -------------------------------------------------------------------------------- 1 | function M = diskmap(M) 2 | %DISKMAP Convert generic Schwarz-Christoffel map object to disk map. 3 | % DISKMAP(M) creates a diskmap object based on the polygon and 4 | % options contained in M. 5 | % 6 | % See the DISKMAP class documentation. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: diskmap.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | M = diskmap(M.polygon,M.options); 12 | -------------------------------------------------------------------------------- /@scmap/disp.m: -------------------------------------------------------------------------------- 1 | function disp(f) 2 | 3 | % $Id: disp.m 156 2001-07-20 14:03:14Z driscoll $ 4 | 5 | s = char(f); 6 | if isstr(s) 7 | disp(s) 8 | elseif iscell(s) 9 | fprintf('\n SC %s:\n\n',class(f)); 10 | for n = 1:length(s) 11 | disp(s{n}) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /@scmap/display.m: -------------------------------------------------------------------------------- 1 | function display(f) 2 | 3 | % $Id: display.m 153 2001-07-20 13:46:12Z driscoll $ 4 | 5 | fprintf('\n%s =\n',inputname(1)) 6 | disp(f) 7 | -------------------------------------------------------------------------------- /@scmap/extermap.m: -------------------------------------------------------------------------------- 1 | function M = extermap(M) 2 | %EXTERMAP Convert generic Schwarz-Christoffel map object to exterior map. 3 | % EXTERMAP(M) creates a extermap object based on the polygon and 4 | % options contained in M. 5 | % 6 | % See the EXTERMAP class documentation. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: extermap.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | M = extermap(M.polygon,M.options); 12 | -------------------------------------------------------------------------------- /@scmap/hplmap.m: -------------------------------------------------------------------------------- 1 | function M = hplmap(M) 2 | %HPLMAP Convert generic Schwarz-Christoffel map object to half-plane map. 3 | % HPLMAP(M) creates a hplmap object based on the polygon and 4 | % options contained in M. 5 | % 6 | % See the HPLMAP class documentation. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: hplmap.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | M = hplmap(M.polygon,M.options); 12 | -------------------------------------------------------------------------------- /@scmap/inv.m: -------------------------------------------------------------------------------- 1 | function Mi = inv(M) 2 | %INV Inverse SC map object. 3 | % INV(M) returns an object formally representing the inverse of the 4 | % map M. 5 | 6 | % Copyright 1998 by Toby Driscoll. 7 | % $Id: inv.m 7 1998-05-10 04:37:19Z tad $ 8 | 9 | Mi = scmapinv(M); 10 | -------------------------------------------------------------------------------- /@scmap/minus.m: -------------------------------------------------------------------------------- 1 | function M = minus(M,a) 2 | % Subtract a contant from the image of an SC map. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: minus.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | M = M + (-a); 8 | 9 | -------------------------------------------------------------------------------- /@scmap/mrdivide.m: -------------------------------------------------------------------------------- 1 | function M = mrdivide(M,a) 2 | % Divide the image of an SC map by a constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mrdivide.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | if isa(a,'double') 8 | M = M * (1/a); 9 | else 10 | error('Cannot divide by an SC map.') 11 | end 12 | 13 | -------------------------------------------------------------------------------- /@scmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Usually this will be invoked by a child object, which needs to adjust 5 | % its own constant as well. 6 | 7 | % Copyright (c) 1998 by Toby Driscoll. 8 | % $Id: mtimes.m 33 1998-06-29 22:35:40Z tad $ 9 | 10 | % May need to swap arguments 11 | if isa(M,'double') & isa(c,'scmap') 12 | tmp = M; 13 | M = c; 14 | c = tmp; 15 | end 16 | 17 | M.polygon = c*M.polygon; 18 | -------------------------------------------------------------------------------- /@scmap/options.m: -------------------------------------------------------------------------------- 1 | function opt = options(M) 2 | %OPTIONS Returns an options structure for the given SC map. 3 | 4 | % Copyright 2003 by Toby Driscoll. 5 | % $Id: options.m 238 2003-01-15 15:49:10Z driscoll $ 6 | 7 | opt = M.options; 8 | -------------------------------------------------------------------------------- /@scmap/plus.m: -------------------------------------------------------------------------------- 1 | function M = plus(M,a) 2 | % Add a constant to the image of an SC map (i.e., translate image). 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: plus.m 32 1998-06-29 22:26:36Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(a,'scmap') 9 | tmp = M; 10 | M = a; 11 | a = tmp; 12 | end 13 | 14 | if length(a)==1 & isa(a,'double') 15 | M.polygon = M.polygon + a; 16 | else 17 | error('Addition is not defined for these operands.') 18 | end 19 | -------------------------------------------------------------------------------- /@scmap/polygon.m: -------------------------------------------------------------------------------- 1 | function p = polygon(M) 2 | %POLYGON Returns the polygon of a Schwarz--Christoffel map object. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: polygon.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | p = M.polygon; 8 | -------------------------------------------------------------------------------- /@scmap/prevertex.m: -------------------------------------------------------------------------------- 1 | function z = prevertex(M) 2 | %PREVERTEX Extract a vector of the prevertices of an S-C map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: prevertex.m 23 1998-05-13 23:29:29Z tad $ 6 | 7 | tmp = parameters(M); 8 | if strmatch('prevertex',fieldnames(tmp)) 9 | z = tmp.prevertex; 10 | else 11 | msg = sprintf('Prevertices not defined for map of class %s\n',class(M)); 12 | error(msg) 13 | end 14 | -------------------------------------------------------------------------------- /@scmap/scmapopt.m: -------------------------------------------------------------------------------- 1 | function opt = scmapopt(M,varargin) 2 | %SCMAPOPT Options structure for a Schwarz--Christoffel map object. 3 | % Same as the regular SCMAPOPT, but the first argument is the options 4 | % structure contained in the map M. 5 | 6 | % Copyright 1998 by Toby Driscoll. 7 | % $Id: scmapopt.m 7 1998-05-10 04:37:19Z tad $ 8 | 9 | opt = sctool.scmapopt(M.options,varargin{:}); 10 | -------------------------------------------------------------------------------- /@scmap/stripmap.m: -------------------------------------------------------------------------------- 1 | function M = stripmap(M) 2 | %STRIPMAP Convert generic Schwarz-Christoffel map object to strip map. 3 | % STRIPMAP(M) creates a stripmap object based on the polygon and 4 | % options contained in M. 5 | % 6 | % See the STRIPMAP class documentation. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: stripmap.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | M = stripmap(M.polygon,M.options); 12 | -------------------------------------------------------------------------------- /@scmap/subsref.m: -------------------------------------------------------------------------------- 1 | function wp = subsref(M,S) 2 | %SUBSREF Evaluate map by subscript notation. 3 | % M(ZP), where M is a SC map and ZP is a vector of points in the 4 | % canonical domain of the map, returns the image of the points in ZP. 5 | % 6 | % This just a synonym for EVAL(M,ZP). 7 | % 8 | % See also EVAL, SCMAP. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: subsref.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | if length(S) == 1 & strcmp(S.type,'()') 14 | wp = eval(M,S.subs{1}); 15 | else 16 | wp = builtin('subsref', M, S); 17 | end 18 | 19 | -------------------------------------------------------------------------------- /@scmap/uminus.m: -------------------------------------------------------------------------------- 1 | function M = uminus(M) 2 | % Negate the image of an SC map. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: uminus.m 44 1998-07-01 20:21:54Z tad $ 6 | 7 | M = (-1)*M; -------------------------------------------------------------------------------- /@scmap/uplus.m: -------------------------------------------------------------------------------- 1 | function M = uplus(M) 2 | -------------------------------------------------------------------------------- /@scmapdiff/disp.m: -------------------------------------------------------------------------------- 1 | function disp(fi) 2 | 3 | fprintf('\n Derivative of:\n',inputname(1)) 4 | disp(fi.themap) -------------------------------------------------------------------------------- /@scmapdiff/display.m: -------------------------------------------------------------------------------- 1 | function display(df) 2 | 3 | fprintf('\n%s = Derivative of:\n',inputname(1)) 4 | disp(df.themap) 5 | -------------------------------------------------------------------------------- /@scmapdiff/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(Md,zp) 2 | %EVAL Evaluate differentiated SC map. 3 | % EVAL(MD,ZP), where MD is an SCMAPDIFF object and ZP is a vector of 4 | % points in canonical domain of the map, returns the derivative of the 5 | % map used to create MD at the points ZP. 6 | % 7 | % See also SCMAPDIFF, SCMAPDIFF/SUBSREF. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | wp = evaldiff(Md.themap,zp); 13 | -------------------------------------------------------------------------------- /@scmapdiff/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@scmapdiff/scmapdiff.m: -------------------------------------------------------------------------------- 1 | classdef scmapdiff 2 | 3 | properties 4 | themap 5 | end 6 | 7 | methods 8 | 9 | function df = scmapdiff(f) 10 | %SCMAPDIFF Derivative of a Schwarz-Christoffel map. 11 | % SCMAPDIFF(F) returns a dummy object that represents the derivative 12 | % of the SC map F. The only thing possible with this object is to EVAL 13 | % it. 14 | % 15 | % See also SCMAPDIFF/EVAL, SCMAPDIFF/SUBSREF. 16 | 17 | % Copyright 1998-2001 by Toby Driscoll. 18 | % $Id: scmapdiff.m 160 2001-07-20 14:28:22Z driscoll $ 19 | 20 | if nargin > 0 21 | df.themap = f; 22 | else 23 | df.themap = []; 24 | end 25 | 26 | end 27 | end 28 | end -------------------------------------------------------------------------------- /@scmapdiff/subsref.m: -------------------------------------------------------------------------------- 1 | function wp = subsref(Md,S) 2 | %SUBSREF Evaluate differentiated SC map by subscript notation. 3 | % MD(ZP), where MD is an SCMAPDIFF object and ZP is a vector of 4 | % points in canonical domain of the map, returns the derivative of the 5 | % map used to create MD at the points ZP. 6 | % 7 | % This just a synonym for EVAL(MD,ZP). 8 | % 9 | % See also SCMAPDIFF, SCMAPDIFF/EVAL. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: subsref.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | if length(S) == 1 & strcmp(S.type,'()') 15 | wp = evaldiff(Md.themap,S.subs{1}); 16 | else 17 | error('Only syntax for SCMAPDIFF is a single parenthesized subscript.') 18 | end 19 | 20 | -------------------------------------------------------------------------------- /@scmapinv/disp.m: -------------------------------------------------------------------------------- 1 | function disp(fi) 2 | 3 | fprintf('\n Inverse of:\n',inputname(1)) 4 | disp(fi.themap) -------------------------------------------------------------------------------- /@scmapinv/display.m: -------------------------------------------------------------------------------- 1 | function display(fi) 2 | 3 | fprintf('\n%s = Inverse of:\n',inputname(1)) 4 | disp(fi.themap) 5 | -------------------------------------------------------------------------------- /@scmapinv/eval.m: -------------------------------------------------------------------------------- 1 | function zp = eval(Mi,wp) 2 | %EVAL Evaluate inverse SC map. 3 | % EVAL(MI,WP), where MI is an SCMAPINV object and WP is a vector of points 4 | % in the polygon of the map, returns the inverse image of WP under the 5 | % map (the forward image under MI). 6 | % 7 | % See also SCMAPINV, SCMAPINV/SUBSREF. 8 | 9 | % Copyright 1998 by Toby Driscoll. 10 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 11 | 12 | zp = evalinv(Mi.themap,wp); 13 | -------------------------------------------------------------------------------- /@scmapinv/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@scmapinv/inv.m: -------------------------------------------------------------------------------- 1 | function M = inv(Mi) 2 | %INV Original SC map from its inverse. 3 | % INV(MI) just returns the SC map that was originally inverted to 4 | % produce MI. 5 | 6 | % Copyright 1998 by Toby Driscoll. 7 | % $Id: inv.m 7 1998-05-10 04:37:19Z tad $ 8 | 9 | M = Mi.themap; 10 | -------------------------------------------------------------------------------- /@scmapinv/scmapinv.m: -------------------------------------------------------------------------------- 1 | classdef scmapinv 2 | 3 | properties 4 | themap 5 | end 6 | 7 | methods 8 | function Mi = scmapinv(M) 9 | %SCMAPINV Inverse of a Schwarz-Christoffel map. 10 | % SCMAPINV(M) returns a dummy object that represents the inverse of 11 | % the SC map M. The only things possible with this object are to EVAL 12 | % it or INV it back to the SC map. 13 | % 14 | % See also SCMAPINV/EVAL, SCMAPINV/SUBSREF, SCMAPINV/INV. 15 | 16 | % Copyright 1998 by Toby Driscoll. 17 | % $Id: scmapinv.m 155 2001-07-20 13:53:44Z driscoll $ 18 | 19 | if nargin==0 20 | Mi.themap = []; 21 | else 22 | Mi.themap = M; 23 | end 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /@scmapinv/subsref.m: -------------------------------------------------------------------------------- 1 | function zp = subsref(Mi,S) 2 | %SUBSREF Evaluate inverse map by subscript notation. 3 | % MI(WP), where MI is an SCMAPINV object and WP is a vector of points in 4 | % the polygon of the map, returns the inverse image of WP under the map. 5 | % 6 | % This just a synonym for EVAL(MI,WP), or EVALINV(INV(MI),WP). 7 | % 8 | % See also SCMAPINV, SCMAPINV/EVAL. 9 | 10 | % Copyright 1998 by Toby Driscoll. 11 | % $Id: subsref.m 7 1998-05-10 04:37:19Z tad $ 12 | 13 | if length(S) == 1 & strcmp(S.type,'()') 14 | zp = evalinv(Mi.themap,S.subs{1}); 15 | else 16 | error('Only syntax for SCMAPINV is a single parenthesized subscript.') 17 | end 18 | 19 | -------------------------------------------------------------------------------- /@stripmap/char.m: -------------------------------------------------------------------------------- 1 | function out = char(f) 2 | %CHAR Pretty-print a Schwarz-Christoffel strip map. 3 | 4 | % Copyright 1998-2001 by Toby Driscoll. 5 | % $Id: char.m 162 2001-07-20 14:33:00Z driscoll $ 6 | 7 | p = polygon(f); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = f.prevertex; 11 | c = f.constant; 12 | 13 | L = cell(2,1); 14 | L{1} = ' vertex alpha prevertex '; 15 | L{2}=' ------------------------------------------------------------'; 16 | u = real(w); 17 | v = imag(w); 18 | for j = 1:length(w) 19 | if v(j) < 0 20 | s = '-'; 21 | else 22 | s = '+'; 23 | end 24 | if ~imag(z(j)) 25 | L{end+1}=sprintf(' %8.5f %c %7.5fi %8.5f %20.12e',... 26 | u(j),s,abs(v(j)),alpha(j),z(j)); 27 | else 28 | L{end+1}=sprintf(' %8.5f %c %7.5fi %8.5f %20.12e + i',... 29 | u(j),s,abs(v(j)),alpha(j),z(j)); 30 | end 31 | end 32 | 33 | L{end+1} = ' '; 34 | if imag(c) < 0 35 | s = '-'; 36 | else 37 | s = '+'; 38 | end 39 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 40 | L{end+1} = sprintf(' Apparent accuracy is %.2e',f.accuracy); 41 | L{end+1} = ' '; 42 | 43 | out = L; 44 | -------------------------------------------------------------------------------- /@stripmap/diskmap.m: -------------------------------------------------------------------------------- 1 | function Md = diskmap(Ms) 2 | % Convert strip map to disk map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: diskmap.m 43 1998-07-01 19:12:31Z tad $ 6 | 7 | p = polygon(Ms); 8 | w = vertex(p); 9 | beta = angle(p) - 1; 10 | z = Ms.prevertex; 11 | n = length(z); 12 | 13 | % Find index of vertex at Inf 14 | idx = find(isinf(z) & (z > 0)); 15 | 16 | % Put that vertex last 17 | renum = [idx+1:n 1:idx]; 18 | w = w(renum); 19 | beta = beta(renum); 20 | z = z(renum); 21 | 22 | % Map prevertices to real axis 23 | zh = exp(pi*z); 24 | 25 | % Map -Inf correctly 26 | idx = find(isinf(z) & (z < 0)); 27 | zh(idx) = 0; 28 | 29 | % Map Inf correctly 30 | zh(n) = Inf; 31 | 32 | % Transform prevertices to disk 33 | A = moebius(zh(n-2:n),[-1 -i 1]); 34 | zd = sign(A(zh)); 35 | zd(n) = 1; 36 | 37 | % Create new map 38 | Md = diskmap(polygon(w,beta+1),zd); 39 | -------------------------------------------------------------------------------- /@stripmap/display.m: -------------------------------------------------------------------------------- 1 | function out = display(M) 2 | %DISPLAY Display parameters of a Schwarz-Christoffel strip map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: display.m 118 2001-05-03 21:18:27Z driscoll $ 6 | 7 | p = polygon(M); 8 | w = vertex(p); 9 | alpha = angle(p); 10 | z = M.prevertex; 11 | c = M.constant; 12 | 13 | L = {' '; ' stripmap object:'; ' '}; 14 | L{4} = ' vertex alpha prevertex '; 15 | L{5}=' ------------------------------------------------------------'; 16 | u = real(w); 17 | v = imag(w); 18 | for j = 1:length(w) 19 | if v(j) < 0 20 | s = '-'; 21 | else 22 | s = '+'; 23 | end 24 | if ~imag(z(j)) 25 | L{end+1}=sprintf(' %8.5f %c %7.5fi %8.5f %20.12e',... 26 | u(j),s,abs(v(j)),alpha(j),z(j)); 27 | else 28 | L{end+1}=sprintf(' %8.5f %c %7.5fi %8.5f %20.12e + i',... 29 | u(j),s,abs(v(j)),alpha(j),z(j)); 30 | end 31 | end 32 | 33 | L{end+1} = ' '; 34 | if imag(c) < 0 35 | s = '-'; 36 | else 37 | s = '+'; 38 | end 39 | L{end+1} = sprintf(' c = %.8g %c %.8gi',real(c),s,abs(imag(c))); 40 | L{end+1} = ' '; 41 | L{end+1} = sprintf(' Apparent accuracy is %.2e',M.accuracy); 42 | L{end+1} = ' '; 43 | 44 | 45 | if nargout==0 46 | fprintf('%s\n',L{:}) 47 | else 48 | out = L; 49 | end -------------------------------------------------------------------------------- /@stripmap/eval.m: -------------------------------------------------------------------------------- 1 | function wp = eval(M,zp,tol) 2 | %EVAL Evaluate Schwarz-Christoffel strip map at points. 3 | % EVAL(M,ZP) evaluates the Schwarz-Christoffel map M at the points ZP 4 | % in the strip 0<=Im z<=1. The default tolerance of M is used. 5 | % 6 | % EVAL(M,ZP,TOL) attempts to give an answer accurate to TOL. If TOL is 7 | % less than the accuracy of M, this is unlikely to be met. 8 | % 9 | % See also STRIPMAP, EVALINV. 10 | 11 | % Copyright 1998 by Toby Driscoll. 12 | % $Id: eval.m 7 1998-05-10 04:37:19Z tad $ 13 | 14 | p = polygon(M); 15 | n = length(p); 16 | 17 | if nargin < 3 18 | qdata = M.qdata; 19 | else 20 | qdata = tol; 21 | end 22 | 23 | wp = NaN*zp; 24 | idx = (imag(zp) > -eps) & (imag(zp) < 1+eps); 25 | wp(idx) = ... 26 | stmap(zp(idx),vertex(p),angle(p)-1,M.prevertex,M.constant,qdata); 27 | -------------------------------------------------------------------------------- /@stripmap/evaldiff.m: -------------------------------------------------------------------------------- 1 | function fp = evaldiff(M,zp) 2 | %EVALDIFF Derivative of Schwarz-Christoffel strip map at points. 3 | % EVALDIFF(M,ZP) computes the derivative of the Schwarz-Christoffel 4 | % strip map M at the points ZP. 5 | % 6 | % See also STRIPMAP, EVAL. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: evaldiff.m 7 1998-05-10 04:37:19Z tad $ 10 | 11 | z = M.prevertex; 12 | c = M.constant; 13 | beta = angle(polygon(M)) - 1; 14 | 15 | fp = stderiv(zp,z,beta,c); 16 | -------------------------------------------------------------------------------- /@stripmap/feval.m: -------------------------------------------------------------------------------- 1 | function varargout = feval(varargin) 2 | %FEVAL Equivalent to EVAL. 3 | 4 | if nargout 5 | varargout = cell(1,nargout); 6 | [varargout{:}] = eval(varargin{:}); 7 | else 8 | varargout{1} = eval(varargin{:}); 9 | end 10 | 11 | 12 | -------------------------------------------------------------------------------- /@stripmap/get.m: -------------------------------------------------------------------------------- 1 | function varargout = get(map,varargin) 2 | %GET Get map parameters. 3 | % [VAL1,VAL2,...] = GET(F,'PROP1','PROP2',...) returns the values of the 4 | % map F corresponding to the requested properties. Valid properties 5 | % are: 6 | % 7 | % polygon, options, prevertex, constant 8 | 9 | % Copyright 1999-2003 by Toby Driscoll. 10 | % $Id: get.m 236 2003-01-15 15:29:14Z driscoll $ 11 | 12 | for j = 1:length(varargin) 13 | switch lower(varargin{j}(1:min(3,length(varargin{j})))) 14 | case 'pol' 15 | varargout{j} = map.scmap.polygon; 16 | case 'opt' 17 | varargout{j} = map.scmap.options; 18 | case 'pre' 19 | varargout{j} = map.prevertex; 20 | case 'con' 21 | varargout{j} = map.constant; 22 | otherwise 23 | warning(sprintf('Property ''%s'' not recognized.\n',varargin{j})) 24 | varargout{j} = []; 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /@stripmap/hplmap.m: -------------------------------------------------------------------------------- 1 | function Mh = hplmap(Ms) 2 | % Convert strip map to half-plane map. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: hplmap.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | p = polygon(Ms); 8 | w = vertex(p); 9 | beta = angle(p) - 1; 10 | z = Ms.prevertex; 11 | n = length(z); 12 | 13 | % Find index of vertex at Inf 14 | idx = find(isinf(z) & (z > 0)); 15 | 16 | % Put that vertex last 17 | renum = [idx+1:n 1:idx]; 18 | w = w(renum); 19 | beta = beta(renum); 20 | z = z(renum); 21 | 22 | % Map prevertices to real axis 23 | zh = real(exp(pi*z)); 24 | 25 | % Map -Inf correctly 26 | idx = find(isinf(z) & (z < 0)); 27 | zh(idx) = 0; 28 | 29 | % Put finite ones inside [-1,1] 30 | zh = (zh-zh(1)) * 2/(zh(n-1)-zh(1)) - 1; 31 | 32 | % Map Inf correctly 33 | zh(n) = Inf; 34 | 35 | % Create new map 36 | Mh = hplmap(polygon(w,beta+1),zh); 37 | -------------------------------------------------------------------------------- /@stripmap/mtimes.m: -------------------------------------------------------------------------------- 1 | function M = mtimes(M,c) 2 | % Scale the image of a map by a complex constant. 3 | 4 | % Copyright (c) 1998 by Toby Driscoll. 5 | % $Id: mtimes.m 33 1998-06-29 22:35:40Z tad $ 6 | 7 | % May need to swap arguments 8 | if isa(M,'double') & isa(c,'stripmap') 9 | tmp = M; 10 | M = c; 11 | c = tmp; 12 | end 13 | 14 | M.constant = c*M.constant; 15 | M.scmap = c*M.scmap; 16 | -------------------------------------------------------------------------------- /@stripmap/parameters.m: -------------------------------------------------------------------------------- 1 | function v = parameters(M) 2 | %PARAMETERS Return a structure of the Schwarz-Christoffel map parameters. 3 | 4 | % Copyright 1998 by Toby Driscoll. 5 | % $Id: parameters.m 7 1998-05-10 04:37:19Z tad $ 6 | 7 | v.prevertex = M.prevertex; 8 | v.constant = M.constant; -------------------------------------------------------------------------------- /@stripmap/plot.m: -------------------------------------------------------------------------------- 1 | function [h,re,im] = plot(M,varargin) 2 | %PLOT Visualize a Schwarz-Christoffel strip map. 3 | % PLOT(M) plots the polygon associated with the Schwarz-Christoffel 4 | % strip map M and the images of ten evenly spaced vertical line 5 | % segments and horizontal lines under the S-C transformation. 6 | % 7 | % PLOT(M,NRE,NIM) plots the images of NRE vertical line segments and 8 | % NIM horizontal lines. 9 | % 10 | % PLOT(M,RE,IM) plots the vertical line segments at abscissae given by 11 | % the entries of RE and horizontal lines at the ordinates specified in 12 | % IM. 13 | % 14 | % PLOT(M,TOL) or PLOT(M,NRE,NIM,TOL) or PLOT(M,RE,IM,TOL) computes the 15 | % map with accuracy roughly TOL. Normally TOL defaults to 1e-4 or the 16 | % accuracy of M, whichever is greater. 17 | % 18 | % See also STRIPMAP, EVAL. 19 | 20 | % Copyright 1998 by Toby Driscoll. 21 | % $Id: plot.m 7 1998-05-10 04:37:19Z tad $ 22 | 23 | p = polygon(M); 24 | w = vertex(p); 25 | beta = angle(p) - 1; 26 | z = M.prevertex; 27 | c = M.constant; 28 | 29 | if nargin == 1 30 | [a1,a2,a3] = stplot(w,beta,z,c); 31 | elseif length(varargin) == 1 32 | % Tolerance given only 33 | [a1,a2,a3] = stplot(w,beta,z,c,10,10,ceil(-log10(varargin{1}))); 34 | elseif length(varargin) == 2 35 | % RE,IM given only 36 | [a1,a2,a3] = stplot(w,beta,z,c,varargin{1},varargin{2}); 37 | else 38 | % All given 39 | nqpts = ceil(-log10(varargin{3})); 40 | [a1,a2,a3] = stplot(w,beta,z,c,varargin{1},varargin{2},nqpts); 41 | end 42 | 43 | if nargout > 0 44 | h = a1; 45 | re = a2; 46 | im = a3; 47 | end 48 | 49 | -------------------------------------------------------------------------------- /@stripmap/private/stdisp.m: -------------------------------------------------------------------------------- 1 | function stdisp(w,beta,z,c) 2 | %STDISP Display results of Schwarz-Christoffel strip parameter problem. 3 | % STDISP(W,BETA,Z,C) displays the results of STPARAM in a pleasant 4 | % way. 5 | % 6 | % See also STPARAM, STPLOT. 7 | 8 | % Copyright 1998 by Toby Driscoll. 9 | % $Id: stdisp.m 298 2009-09-15 14:36:37Z driscoll $ 10 | 11 | disp(' ') 12 | disp(' vertex [w] beta prevertex [z] ') 13 | disp(' ------------------------------------------------------------') 14 | u = real(w); 15 | v = imag(w); 16 | for j = 1:length(w) 17 | if v(j) < 0 18 | s = '-'; 19 | else 20 | s = '+'; 21 | end 22 | if ~imag(z(j)) 23 | disp(sprintf(' %8.5f %c %7.5fi %8.5f %20.12e',... 24 | u(j),s,abs(v(j)),beta(j),z(j))); 25 | else 26 | disp(sprintf(' %8.5f %c %7.5fi %8.5f %20.12e + i',... 27 | u(j),s,abs(v(j)),beta(j),z(j))); 28 | end 29 | end 30 | disp(' ') 31 | if imag(c) < 0 32 | s = '-'; 33 | else 34 | s = '+'; 35 | end 36 | disp(sprintf(' c = %.8g %c %.8gi\n',real(c),s,abs(imag(c)))) 37 | -------------------------------------------------------------------------------- /@stripmap/private/stimapfun.m: -------------------------------------------------------------------------------- 1 | function zdot = stimapfun(wp,yp,flag,scale,z,beta,c); 2 | 3 | % Used by STINVMAP for solution of an ODE. 4 | 5 | % Copyright 1998 by Toby Driscoll. 6 | % $Id: stimapfun.m 298 2009-09-15 14:36:37Z driscoll $ 7 | 8 | lenyp = length(yp); 9 | lenzp = lenyp/2; 10 | zp = yp(1:lenzp) + i*yp(lenzp+1:lenyp); 11 | 12 | f = scale./stderiv(zp,z,beta,c); 13 | zdot = [real(f);imag(f)]; 14 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this software, please cite it as below." 3 | authors: 4 | - family-names: Driscoll 5 | given-names: Tobin 6 | orcid: https://orcid.org/0000-0002-1490-2545 7 | title: "Schwarz–Christoffel Toolbox for conformal mapping in MATLAB" 8 | version: 3.1.3 9 | doi: 10.5281/zenodo.5245134 10 | date-released: 2021-08-24 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Tobin A. Driscoll. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of the University of Delaware nor the names of contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sc-toolbox 2 | ========== 3 | 4 | Schwarz-Christoffel Toolbox for conformal mapping in MATLAB 5 | 6 | The SC Toolbox contains numerical routines and graphical interfaces to work with Schwarz-Christoffel conformal maps--those to regions bounded by polgons in the complex plane. Many map variations are present. The software has no requirements other than core MATLAB. 7 | 8 | You might prefer to view the [page at the File Exchange](https://www.mathworks.com/matlabcentral/fileexchange/1316-schwarz-christoffel-toolbox), where you can try the package out online without downloading and installing it. 9 | 10 | For more details on the maps, see _Schwarz Christoffel Mapping_, by Driscoll and Trefethen. For a user's guide, visit https://tobydriscoll.net/project/sc-toolbox/. 11 | -------------------------------------------------------------------------------- /drawpoly.m: -------------------------------------------------------------------------------- 1 | function [w,beta] = drawpoly(fig,cmd) 2 | %DRAWPOLY Draw a polygon with the mouse. 3 | % DRAWPOLY is obsolete. Use POLYEDIT instead. 4 | 5 | % Copyright 1998 by Toby Driscoll. 6 | 7 | error('DRAWPOLY is obsolete. Use POLYEDIT instead.') 8 | -------------------------------------------------------------------------------- /guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/guide.pdf -------------------------------------------------------------------------------- /lapsolvegui.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/lapsolvegui.fig -------------------------------------------------------------------------------- /lsprogress.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/lsprogress.fig -------------------------------------------------------------------------------- /modpoly.m: -------------------------------------------------------------------------------- 1 | function [w,beta,indx] = modpoly(w,beta) 2 | %MODPOLY Modify a polygon. 3 | % MODPOLY is obsolete. Use POLYEDIT instead. 4 | 5 | % Copyright 1998 by Toby Driscoll. 6 | 7 | error('MODPOLY is obsolete. Use POLYEDIT instead.') -------------------------------------------------------------------------------- /private/OK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/OK.png -------------------------------------------------------------------------------- /private/addexist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/addexist.png -------------------------------------------------------------------------------- /private/addseq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/addseq.png -------------------------------------------------------------------------------- /private/bullseye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/bullseye.png -------------------------------------------------------------------------------- /private/eraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/eraser.png -------------------------------------------------------------------------------- /private/floppy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/floppy.png -------------------------------------------------------------------------------- /private/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/grid.png -------------------------------------------------------------------------------- /private/gt2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/gt2.png -------------------------------------------------------------------------------- /private/gtsign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/gtsign.png -------------------------------------------------------------------------------- /private/magglass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/magglass.png -------------------------------------------------------------------------------- /private/move.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/move.png -------------------------------------------------------------------------------- /private/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/pencil.png -------------------------------------------------------------------------------- /private/pencileraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/pencileraser.png -------------------------------------------------------------------------------- /private/plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/plot.png -------------------------------------------------------------------------------- /private/polyclose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/polyclose.png -------------------------------------------------------------------------------- /private/polygon5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/polygon5.png -------------------------------------------------------------------------------- /private/prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/prompt.png -------------------------------------------------------------------------------- /private/quantang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/quantang.png -------------------------------------------------------------------------------- /private/quantlen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/quantlen.png -------------------------------------------------------------------------------- /private/quit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/quit.png -------------------------------------------------------------------------------- /private/rescale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/rescale.png -------------------------------------------------------------------------------- /private/snapxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/snapxy.png -------------------------------------------------------------------------------- /private/solve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/solve.png -------------------------------------------------------------------------------- /private/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tobydriscoll/sc-toolbox/813dddca3a7b0af5ab6ccd9796f84d0ce0d7ba8a/private/trash.png -------------------------------------------------------------------------------- /ptsource.m: -------------------------------------------------------------------------------- 1 | function ptsource(w,beta,z,c,ws,R,theta,options) 2 | %PTSOURCE Field due to point source in a polygon. 3 | % PTSOURCE plots evenly spaced equipotential and force lines for a 4 | % point source located in a polygonal region. This is equivalent to 5 | % the disk map with conformal center at the source. With no arguments 6 | % the user draws the polygon and clicks the mouse at the source. 7 | % 8 | % PTSOURCE(W,BETA) uses the polygon described by W and BETA. 9 | % 10 | % PTSOURCE(W,BETA,Z,C) assmues that Z and C comprise the solution to 11 | % the disk mapping parameter problem, as returned by DPARAM. 12 | % 13 | % PTSOURCE(W,BETA,Z,C,WS) uses WS as the source location. 14 | % 15 | % PTSOURCE(W,BETA,Z,C,WS,R,THETA,OPTIONS) uses the R, THETA, and 16 | % OPTIONS parameter as described in SCPLOTOPT. 17 | % 18 | % See also DFIXWC. 19 | 20 | % Copyright 1998 by Toby Driscoll. 21 | % $Id: ptsource.m 298 2009-09-15 14:36:37Z driscoll $ 22 | 23 | if nargin < 2 24 | [w,beta] = drawpoly; 25 | end 26 | n = length(w); 27 | if nargin < 8 28 | options = []; 29 | if nargin < 7 30 | theta = []; 31 | if nargin < 6 32 | R = []; 33 | if nargin < 5 34 | ws = []; 35 | if nargin < 4 36 | z = []; 37 | end 38 | end 39 | end 40 | end 41 | end 42 | 43 | if isempty(z) 44 | [z,c] = dparam(w,beta); 45 | end 46 | 47 | if isempty(ws) 48 | plotpoly(w,beta) 49 | disp('Click mouse at source location.') 50 | [xc,yc] = ginput(1); 51 | ws = xc+i*yc; 52 | end 53 | 54 | [z,c] = dfixwc(w,beta,z,c,ws); 55 | dplot(w,beta,z,c,R,theta,options); 56 | -------------------------------------------------------------------------------- /scdemo.m: -------------------------------------------------------------------------------- 1 | function scdemo 2 | %SCDEMO Demonstrate the Schwarz-Christoffel Toolbox. 3 | 4 | % Copyright 1997 by Toby Driscoll. 5 | % $Id: scdemo.m 298 2009-09-15 14:36:37Z driscoll $ 6 | 7 | t = {'Schwarz-Christoffel Toolbox' 'demonstrations'}; % menu title 8 | demo = { 'demtut','deminf','demlong','demmult','demfaber' }; % demos 9 | % Loop until user selects 'quit' 10 | while 1 11 | k = menu(t,'Tutorial','Infinite vertices','Elongated polygons', ... 12 | 'Faber polynomials','Quit'); 13 | if k > 4 14 | break 15 | end 16 | 17 | progname = {'scdtutor','scdinf','scdlong','scdfaber'}; 18 | eval(progname{k}) 19 | pause(5) 20 | h = findall(0,'name','Slideshow Player'); 21 | waitfor(h) 22 | end 23 | -------------------------------------------------------------------------------- /scgexprt.m: -------------------------------------------------------------------------------- 1 | function scgexprt(data) 2 | % Export data to base workspace. 3 | 4 | % Copyright 1997 by Toby Driscoll. Last updated 04/29/97. 5 | 6 | tag = {'pol','map','phy','can'}; 7 | field = {'polygon','map','phypoints','canpoints'}; 8 | 9 | for j = 1:4 10 | name = get(findobj(gcf,'tag',tag{j}),'string'); 11 | if ~isempty(name) 12 | assignin('base',name,getfield(data,field{j})) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /scgimprt.m: -------------------------------------------------------------------------------- 1 | function data = scgimprt(data) 2 | % Import data from base workspace. 3 | 4 | % Copyright 1997 by Toby Driscoll. Last updated 05/23/97. 5 | 6 | tag = {'pol','map','phy','can'}; 7 | field = {'polygon','map','phypoints','canpoints'}; 8 | 9 | for j = 1:4 10 | name = get(findobj(gcf,'tag',tag{j}),'string'); 11 | if ~isempty(name) 12 | val = evalin('base',name); 13 | data = setfield(data,field{j},val); 14 | if j == 1 15 | % New polygon means map is not current 16 | data.iscurrent = 0; 17 | data.phypoints = []; 18 | data.canpoints = []; 19 | elseif j == 2 20 | % New map is current and defines the polygon, too 21 | data.iscurrent = 1; 22 | data.polygon = polygon(data.map); 23 | data.phypoints = []; 24 | data.canpoints = []; 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /tests/dctests.m: -------------------------------------------------------------------------------- 1 | % Tests of doubly-connected maps. 2 | 3 | clf; 4 | IPOLY = 4; 5 | 6 | % In the file dscsolv.m, between line 98 and 116 7 | % nonlinear solver can use nesolve, sdogleg, or fsolve (optim toolbox). 8 | 9 | if IPOLY==1 10 | q = sqrt(2); 11 | a = 1+q; 12 | z0 = [a+a*i -a+a*i -a-a*i a-a*i]; 13 | z1 = [q q*i -q -q*i]; 14 | Q = sqrt(2); 15 | p0 = polygon(z0); 16 | p1 = polygon(z1); 17 | rgn = dscpolygons(p1,p0) 18 | elseif IPOLY==2 19 | z0 = [0.5+2.5*i 0.5+0.5*i 1+0.5*i 1+i 1+0.5*i 0.5+0.5*i 0.5+2.5*i 2.5*i 0 2 2+2.5*i]; 20 | z1 = [1+2*i 1+1.5*i 1+2*i 1.5+2*i 1.5+0.5*i 1.5+2*i]; 21 | p0 = polygon(z0); 22 | p1 = polygon(z1); 23 | rgn = dscpolygons(p1,p0) 24 | elseif IPOLY==3 25 | z0 = [-1-i 1-i 1+i -1+i]; 26 | z1 = [0.5*i 0 -0.5 0 -0.5*i -0.5-0.5*i 0.5-0.5*i 0.25-0.5*i ... 27 | 0.25-0.25*i 0.25-0.5*i -0.5*i 0 0.5 0 0.5*i 0.5+0.5*i -0.5+0.5*i]; 28 | p0 = polygon(z0); 29 | p1 = polygon(z1); 30 | rgn = dscpolygons(p1,p0) 31 | elseif IPOLY==4 32 | z0 = [-2-i 2-i 2+2*i -0.8+2*i 1+0.5*i -1+2*i -2+2*i]; 33 | z1 = [0 -1]; 34 | p0 = polygon(z0); 35 | p1 = polygon(z1); 36 | rgn = dscpolygons(p1,p0) 37 | elseif IPOLY == 5 38 | z0 = [1+i 4+i 4+4*i 1+4*i]; 39 | z1 = [2.75+1.5*i 3.25+3.25*i 1.5+3*i]; 40 | p0 = polygon(z0); 41 | p1 = polygon(z1); 42 | rgn = dscpolygons(p1,p0) 43 | end 44 | 45 | tic 46 | f = annulusmap(rgn) 47 | toc 48 | tic 49 | plot(f); 50 | toc -------------------------------------------------------------------------------- /tests/testHalfplane.m: -------------------------------------------------------------------------------- 1 | classdef testHalfplane < matlab.unittest.TestCase 2 | 3 | properties 4 | map 5 | end 6 | 7 | methods (TestClassSetup) 8 | function createMap(testCase) 9 | opt = sctool.scmapopt('trace',0,'tol',1e-12); 10 | p = polygon([4 2i -2+4i -3 -3-1i 2-2i]); 11 | testCase.map = hplmap(p,opt); 12 | end 13 | end 14 | 15 | methods (Test) 16 | 17 | function testForwardMap(testCase) 18 | result = testCase.map([-1+0.01i 2i 4+0.5i Inf]); 19 | expected = [ 20 | 3.718839996085665 - 0.046084791699413i,... 21 | 1.734612962216089 - 0.777136490010106i,... 22 | 1.179285609480821 - 1.753573737693204i,... 23 | 2.000000000000000 - 2.000000000000000i,... 24 | ]; 25 | testCase.verifyEqual(result,expected,'abstol',1e-10); 26 | end 27 | 28 | function testInverseMap(testCase) 29 | val = testCase.map([-1 -1+0.01i 2i 4+0.5i]); 30 | result = evalinv( testCase.map, val ); 31 | expected = [ -1 -1+0.01i 2i 4+0.5i ]; 32 | testCase.verifyEqual(result,expected,'abstol',1e-10); 33 | end 34 | 35 | function testPlot(testCase) 36 | fig = figure; 37 | plot(testCase.map,2,3) 38 | close(fig) 39 | end 40 | 41 | end 42 | 43 | 44 | 45 | end -------------------------------------------------------------------------------- /tests/testRectangle.m: -------------------------------------------------------------------------------- 1 | classdef testRectangle < matlab.unittest.TestCase 2 | 3 | properties 4 | map 5 | end 6 | 7 | methods (TestClassSetup) 8 | function createMap(testCase) 9 | opt = sctool.scmapopt('trace',0,'tol',1e-12); 10 | p = polygon([4 2i -2+4i -3 -3-1i 2-2i]); 11 | testCase.map = rectmap(p,1:4,opt); 12 | end 13 | end 14 | 15 | methods (Test) 16 | 17 | function testForwardMap(testCase) 18 | result = testCase.map([1.5 1.4+3i -0.6+1i 1].'); 19 | expected = [ 20 | 3.641550444027862 - 0.358449555972138i 21 | -0.005336970451055 + 1.988135598448822i 22 | -1.643459212104280 + 0.428597577267735i 23 | 1.646072527976422 - 1.929214505595285i 24 | ]; 25 | testCase.verifyEqual(result,expected,'abstol',1e-7); 26 | end 27 | 28 | function testInverseMap(testCase) 29 | val = testCase.map([1.5 1.4+3i -0.6+1i 1]); 30 | result = evalinv( testCase.map, val ); 31 | expected = [1.5 1.4+3i -0.6+1i 1]; 32 | testCase.verifyEqual(result,expected,'abstol',1e-7); 33 | end 34 | 35 | function testPlot(testCase) 36 | fig = figure; 37 | plot(testCase.map,4,3) 38 | close(fig) 39 | end 40 | 41 | end 42 | 43 | 44 | 45 | end -------------------------------------------------------------------------------- /tests/testStrip.m: -------------------------------------------------------------------------------- 1 | classdef testStrip < matlab.unittest.TestCase 2 | 3 | properties 4 | map 5 | end 6 | 7 | methods (TestClassSetup) 8 | function createMap(testCase) 9 | opt = sctool.scmapopt('trace',0,'tol',1e-12); 10 | p = polygon([4 2i -2+4i -3 -3-1i 2-2i]); 11 | testCase.map = stripmap(p,[1 4],opt); 12 | end 13 | end 14 | 15 | methods (Test) 16 | 17 | function testForwardMap(testCase) 18 | result = testCase.map([1+1i Inf -2+0.5i 0].'); 19 | expected = [ 20 | -3.000000000000000 - 0.312856946533931i 21 | -3.000000000000000 + 0.000000000000000i 22 | 3.534971699300866 - 0.074755569347609i 23 | 0.000000000000000 + 2.000000000000000i 24 | ]; 25 | testCase.verifyEqual(result,expected,'abstol',1e-10); 26 | end 27 | 28 | function testInverseMap(testCase) 29 | val = testCase.map([4 -2+0.5i 1+0.5i]); 30 | result = evalinv( testCase.map, val ); 31 | expected = [4 -2+0.5i 1+0.5i]; 32 | testCase.verifyEqual(result,expected,'abstol',1e-10); 33 | end 34 | 35 | function testPlot(testCase) 36 | fig = figure; 37 | plot(testCase.map,4,3) 38 | close(fig) 39 | end 40 | 41 | end 42 | 43 | 44 | 45 | end --------------------------------------------------------------------------------