# Commit 5ded279e2722608b5b1876581cd88d71d1795bc0

- fzeros_complex.m 140 --------------------------------------------------++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

- Diff rendering mode:
- inline
- side by side

#### fzeros_complex.m

3 | % USAGE: | 3 | % USAGE: |
---|---|---|---|

4 | % my_zeros = fzeros_complex(f, z, [optional: print_output]) | 4 | % my_zeros = fzeros_complex(f, z, [optional: print_output]) |

5 | % | 5 | % |

6 | |||

6 | % f = function handle to a mathematical function C -> C (or R -> C) | ||

7 | % z = if a column vector of complex numbers, use them (and nothing else) as initial guesses; | 7 | % z = if a column vector of complex numbers, use them (and nothing else) as initial guesses; |

8 | % if a row vector of length 4, use them as [re_min re_max im_min im_max] of the range | 8 | % if a row vector of length 4, use them as [re_min re_max im_min im_max] of the range |

9 | % in which initial guesses will be generated. | 9 | % in which initial guesses will be generated. |

10 | % To find zeros of a function R -> C, set im_min = im_max = 0. | ||

10 | % print_output = if this parameter exists, the routine will print some info messages and plot the zeroes found. | 11 | % print_output = if this parameter exists, the routine will print some info messages and plot the zeroes found. |

11 | % | 12 | % |

12 | % JJ 2011-01-27 | 13 | % JJ 2011-01-27 |

… | … | ||

21 | % parameters | 21 | % parameters |

22 | % ------------------------------------------- | 22 | % ------------------------------------------- |

23 | 23 | ||

24 | |||

24 | mode = '2d'; | ||

25 | if size(zig) == [1,4] | ||

25 | minx = zig(1); | 26 | minx = zig(1); |

26 | maxx = zig(2); | 27 | maxx = zig(2); |

27 | miny = zig(3); | 28 | miny = zig(3); |

… | … | ||

31 | have_igs = 1; | 31 | have_igs = 1; |

32 | have_range = 1; | 32 | have_range = 1; |

33 | 33 | ||

34 | |||

35 | |||

36 | |||

37 | |||

38 | |||

34 | % R -> C | ||

35 | if miny == 0 && maxy == 0 | ||

36 | mode = '1d'; | ||

37 | k = 30; | ||

38 | zig = linspace(minx,maxx,k); | ||

39 | n_points = k; | ||

40 | else % C -> C | ||

41 | k = 10; % boxes for sudoku (per coordinate axis) | ||

42 | [zig,m] = sudoku_lhs(2,k,1); % N,k,m k*m = n*(k^N) | ||

43 | n_points = k*m; | ||

44 | zig(:,1) = minx + (maxx - minx) * ( (zig(:,1) - 1) / (n_points - 1) ); | ||

45 | zig(:,2) = miny + (maxy - miny) * ( (zig(:,2) - 1) / (n_points - 1) ); | ||

46 | end | ||

39 | 47 | ||

40 | % n_points = 300; % for random initial guess generator | 48 | % n_points = 300; % for random initial guess generator |

41 | else | 49 | else |

42 | have_igs = 1; | 50 | have_igs = 1; |

43 | have_range = 0; | 51 | have_range = 0; |

44 | |||

45 | |||

46 | 52 | ||

53 | m = min(imag(zig(:))); | ||

54 | M = max(imag(zig(:))); | ||

55 | if m == 0 && M == 0 | ||

56 | mode = '1d'; | ||

57 | end | ||

58 | |||

59 | n_points = length(zig); | ||

60 | end | ||

61 | |||

47 | if nargin < 3 | 62 | if nargin < 3 |

48 | print_output = 0; | 63 | print_output = 0; |

49 | else | 64 | else |

… | … | ||

82 | k = 1; | 82 | k = 1; |

83 | 83 | ||

84 | % ||f||^2 = f * conj(f) | 84 | % ||f||^2 = f * conj(f) |

85 | |||

85 | normf = @(xy) f(xy(1) + 1i*xy(2)).*conj(f(xy(1) + 1i*xy(2))); | ||

86 | 86 | ||

87 | % ||f||^2, f : R -> C | ||

88 | normf_real = @(x) f(x).*conj(f(x)); | ||

89 | |||

87 | % TolX must be really small so that this works even for good initial guesses. | 90 | % TolX must be really small so that this works even for good initial guesses. |

88 | % (See failures, if any, reported by the "candidate" DEBUG message below to find out if the value here is not small enough.) | 91 | % (See failures, if any, reported by the "candidate" DEBUG message below to find out if the value here is not small enough.) |

89 | % | 92 | % |

… | … | ||

106 | end | 106 | end |

107 | 107 | ||

108 | % Minimize ||f||^2 = f * conj(f) | 108 | % Minimize ||f||^2 = f * conj(f) |

109 | |||

110 | |||

109 | if strcmp(mode,'1d') | ||

110 | [S, sv, EXITFLAG] = fminsearch(normf_real, x, OPTIONS); | ||

111 | s = S(1); | ||

112 | else | ||

113 | [S, sv, EXITFLAG] = fminsearch(normf, [x y], OPTIONS); | ||

114 | s = S(1) + 1i * S(2); | ||

115 | end | ||

111 | 116 | ||

112 | % DEBUG | 117 | % DEBUG |

113 | if have_igs ~= 0 && sv > my_tol && print_output ~= 0 | 118 | if have_igs ~= 0 && sv > my_tol && print_output ~= 0 |

… | … | ||

124 | % (The EXITFLAG condition checks that the algorithm found a local minimum, | 124 | % (The EXITFLAG condition checks that the algorithm found a local minimum, |

125 | % and the second check verifies that it is a zero.) | 125 | % and the second check verifies that it is a zero.) |

126 | % | 126 | % |

127 | |||

127 | if EXITFLAG == 1 && sv <= my_tol | ||

128 | % Aesthetic fix: filter smaller-than-epsilon components out from s. | 128 | % Aesthetic fix: filter smaller-than-epsilon components out from s. |

129 | % | 129 | % |

130 | if(abs(real(s)) < my_tol) | 130 | if(abs(real(s)) < my_tol) |

131 | |||

131 | s = imag(s) * 1i; | ||

132 | end | 132 | end |

133 | if(abs(imag(s)) < my_tol) | 133 | if(abs(imag(s)) < my_tol) |

134 | s = real(s); | 134 | s = real(s); |

… | … | ||

141 | % Always save the first zero. | 141 | % Always save the first zero. |

142 | % Otherwise, save if this zero is farther than my_tol from any known ones. | 142 | % Otherwise, save if this zero is farther than my_tol from any known ones. |

143 | % | 143 | % |

144 | |||

144 | if k == 1 || abs(my_zeros(match_index) - s) > my_tol | ||

145 | if print_output ~= 0 | 145 | if print_output ~= 0 |

146 | fprintf(1, 'Found zero at z = %0.6g + %0.6g i\n', real(s), imag(s)); | 146 | fprintf(1, 'Found zero at z = %0.6g + %0.6g i\n', real(s), imag(s)); |

147 | end | 147 | end |

… | … | ||

165 | if print_output ~= 0 | 165 | if print_output ~= 0 |

166 | fprintf(1, 'Plotting zeroes...\n'); | 166 | fprintf(1, 'Plotting zeroes...\n'); |

167 | 167 | ||

168 | |||

169 | |||

170 | |||

171 | |||

172 | |||

173 | |||

174 | |||

175 | |||

176 | |||

177 | |||

178 | |||

179 | |||

180 | % plot ||f||^2 | 168 | % plot ||f||^2 |

181 | if have_range | 169 | if have_range |

182 | figure(2); | 170 | figure(2); |

… | … | ||

177 | miny = min(miny, min(imag(my_zeros))); | 177 | miny = min(miny, min(imag(my_zeros))); |

178 | maxy = max(maxy, max(imag(my_zeros))); | 178 | maxy = max(maxy, max(imag(my_zeros))); |

179 | 179 | ||

180 | |||

181 | |||

182 | |||

180 | if strcmp(mode,'1d') | ||

181 | xx = linspace(minx, maxx, nx); | ||

182 | plot(xx, normf_real(xx), 'k-'); | ||

183 | 183 | ||

184 | |||

185 | |||

186 | |||

187 | |||

188 | |||

184 | title('||f||^2'); | ||

185 | xlabel('x'); | ||

186 | ylabel('||f||^2'); | ||

189 | 187 | ||

190 | |||

191 | |||

192 | |||

193 | |||

194 | |||

188 | hold on; | ||

189 | plot(my_zeros, zeros(size(my_zeros)), 'ko'); | ||

190 | hold off; | ||

195 | 191 | ||

196 | |||

197 | |||

198 | |||

192 | axis tight; | ||

193 | else | ||

194 | figure(1); | ||

195 | clf; | ||

196 | plot(real(my_zeros), imag(my_zeros), 'ko'); | ||

197 | grid on; | ||

198 | if have_range | ||

199 | axis([minx maxx miny maxy]); | ||

200 | end | ||

201 | my_title = sprintf('Zeroes of f'); | ||

202 | title(my_title); | ||

203 | xlabel('Re(z)'); | ||

204 | ylabel('Im(z)'); | ||

199 | 205 | ||

200 | |||

206 | xx = linspace(minx, maxx, nx); | ||

207 | yy = linspace(miny, maxy, ny); | ||

208 | [X,Y] = meshgrid(xx,yy); | ||

201 | 209 | ||

202 | |||

210 | Z = nan(size(X)); | ||

211 | maxj = prod(size(X)); | ||

212 | for j = 1:maxj | ||

213 | Z(j) = normf([X(j) Y(j)]); | ||

214 | end | ||

215 | |||

216 | surf(X,Y, Z, 'EdgeColor', 'none'); | ||

217 | view(0,90); | ||

218 | title('||f||^2'); | ||

219 | xlabel('Re(z)'); | ||

220 | ylabel('Im(z)'); | ||

221 | |||

222 | hold on; | ||

223 | plot3(real(my_zeros), imag(my_zeros), 0.1+zeros(size(my_zeros)), 'wo'); | ||

224 | hold off; | ||

225 | |||

226 | colorbar; | ||

227 | |||

228 | axis tight; | ||

229 | end | ||

203 | end | 230 | end |

204 | 231 | ||

205 | fprintf(1, 'Done.\n'); | 232 | fprintf(1, 'Done.\n'); |