PageRenderTime 29ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/DIRECT/Direct.m

http://optimization-on-matlab.googlecode.com/
Objective C | 779 lines | 717 code | 62 blank | 0 comment | 112 complexity | f111989aca78c2188caac1bea85cd68b MD5 | raw file
  1. function [history,HistData] = Direct...
  2. (Problem_name,problem_bounds,opts,varargin)
  3. % function [ret_minval,final_xatmin,history,HistData] = Direct...
  4. % (Problem,problem_bounds,opts,varargin)
  5. % Function : Direct Version 4.0
  6. % Written by : Dan Finkel (definkel@unity.ncsu.edu)
  7. % Created on : 01/27/2003
  8. % Last Update: 06/21/2004
  9. % Purpose : Direct optimization algorithm.
  10. %
  11. % This code comes with no guarantee or warranty of any kind
  12. %
  13. % If unfamiliar with DIRECT, user is recommended to manual
  14. % that accompanies this code, and can be found at:
  15. % www4.ncsu.edu/~definkel/research/index.html
  16. %
  17. %
  18. % [x,fmin,history] = Direct(Problem,bounds,opts,varargin)
  19. %
  20. % Parameters:
  21. % IN: Problem - Structure containing problem
  22. % Problem.f = Objective function handle
  23. %
  24. % NOTE: If you problem has no constraints (other than
  25. % those on the bounds, this is the only field you
  26. % need to add to Problem
  27. %
  28. % Problem.numconstraints = number of constraints
  29. % Problem.constraint(i).func = i-th constraint handle
  30. % Problem.constraint(i).penalty = penalty parameter for
  31. % i-th constraint
  32. % Note: If f returns objective function AND constraints
  33. % then set Problem.constraint(1).func = Problem.f
  34. % bounds - an n x 2 vector of the lower and upper bounds.
  35. % The first column is the lower bounds, and the second
  36. % column contains the upper bounds
  37. % opts - (optional) MATLAB structure.
  38. % opts.ep = Jones factor (default is 1e-4)
  39. % opts.maxevals = max. number of function evals (default is 20)
  40. % opts.maxits = max. number of iterations (default is 10)
  41. % opts.maxdeep = max. number of rect. divisions (default is 100)
  42. % opts.testflag = 1 if globalmin known, 0 otherwise (default is 0)
  43. % opts.showits = 1 if disp. stats shown, 0 oth.
  44. % (default is 1)
  45. % opts.globalmin = globalmin (if known)
  46. % (default is 0)
  47. % opts.tol = tolerance for term. if tflag=1
  48. % (default is 0.01)
  49. % opts.impcons = turns on implicit constraint capability
  50. % (default is 0)
  51. % If set to one, objective function
  52. % is expected to return a flag which represents
  53. % the feasibility of the point sampled
  54. % varargin - (optional) additional arguements to be passed to
  55. % objective function
  56. %
  57. % NOTE: If opts.tflag == 0, maxevals, maxevals and maxdeep are ignored.
  58. % DIRECT will stop when the absolute error is less
  59. % than tol. Also, preallocation will not occur, and the algorithm
  60. % can run slower than if opts.tflag == 1
  61. % NOTE: opts.maxevals is an approximate stopping condition. DIRECT will
  62. % exceed this budget by a slight amount
  63. %
  64. % OUT: minval - minimum value found
  65. % xatmin - (optional) location of minimal value
  66. % history - (optional) array of iteration historyory, useful for tables and plots
  67. % The three columns are iteration, fcn evals, and min value found.
  68. %
  69. % Direct may be called by
  70. %
  71. % minval = Direct(Problem,bounds);
  72. % or
  73. % with any variation of the optional arguments
  74. %------------------------------------------------------------------%
  75. %
  76. % Implementation taken from:
  77. % D.R. Jones, C.D. Perttunen, and B.E. Stuckman. "Lipschitzian
  78. % Optimization Without the Lipschitz Constant". Journal of
  79. % Optimization Theory and Application, 79(1):157-181, October 1993
  80. %
  81. %------------------------------------------------------------------%
  82. %-- Initialize the variables --------------------------------------%
  83. Problem.f = Problem_name;
  84. [n,variables] = size(problem_bounds);
  85. lengths = [];c = [];fc = [];
  86. con = [];szes = [];feas_flags=[];
  87. om_lower = zeros(1,variables)';
  88. om_upper = ones(1,variables)';
  89. bounds = [om_lower,om_upper];
  90. fcncounter = 0;
  91. perror = 0;
  92. itctr = 1;
  93. done = 0;
  94. g_nargout = 3; %nargout;
  95. n = size(bounds,1);
  96. % Determine option values
  97. if nargin<3, opts=[]; end
  98. if (nargin>=3) & (length(opts)==0), opts=[]; end
  99. getopts(opts, ...
  100. 'maxits', 100,... % maximum of iterations
  101. 'maxevals', 500,... % maximum # of function evaluations
  102. 'maxdeep', 100,... % maximum number of side divisions
  103. 'testflag', 0,... % terminate if within a relative tolerence of f_opt
  104. 'globalmin', 0,... % minimum value of function
  105. 'ep', 1e-4,... % global/local weight parameter.
  106. 'tol', 0.01,... % allowable relative error if f_reach is set
  107. 'showits', 1,... % print iteration stats
  108. 'impcons', 0,... % flag for using implicit constraint handling
  109. 'pert', 1e-6); % pertubation for implicit constraint handling
  110. % 'maxflag', 0, ... % set to 1 for max problems, 0 for min problems
  111. % 'sizeconst', 0.5,... % constant on rectangle size function
  112. % 'distance', 1,... % 1/0 for distance/volume measure of size
  113. % 'minlength', 1e-4,... % stop if best rectangle has all sides 1ess than this
  114. % 'minevals', 0,... % but must evaluate at least this many points
  115. theglobalmin = globalmin;
  116. tflag = testflag;
  117. %-- New 06/08/2004 Pre-allocate memory for storage vectors
  118. if tflag == 0
  119. lengths = zeros(n,maxevals + floor(.10*maxevals));
  120. c = lengths;
  121. fc = zeros(1,maxevals + floor(.10*maxevals));
  122. szes = fc;
  123. con = fc;
  124. feas_flags = fc;
  125. end
  126. %-- Call DIRini ---------------------------------------------------%
  127. [thirds , lengths, c , fc, con, feas_flags minval,xatmin,perror,...
  128. history,szes,fcncounter,calltype] =...
  129. DIRini(problem_bounds,Problem,n,bounds(:,1),bounds(:,2),...
  130. lengths,c,fc,con, feas_flags, szes,...
  131. theglobalmin,maxdeep,tflag,g_nargout, impcons, varargin{:});
  132. ret_minval = minval;
  133. ret_xatmin = xatmin;
  134. %-- MAIN LOOP -----------------------------------------------------%
  135. minval = fc(1) + con(1);
  136. while perror > tol
  137. %-- Create list S of potentially optimal hyper-rectangles
  138. S = find_po(fc(1:fcncounter)+con(1:fcncounter),...
  139. lengths(:,1:fcncounter),minval,ep,szes(1:fcncounter));
  140. %-- Loop through the potentially optimal hrectangles -----------%
  141. %-- and divide -------------------------------------------------%
  142. for i = 1:size(S,2)
  143. [lengths,fc,c,con,feas_flags,szes,fcncounter,success] = ...
  144. DIRdivide(problem_bounds,bounds(:,1),bounds(:,2),Problem,S(1,i),thirds,lengths,...
  145. fc,c,con,feas_flags,fcncounter,szes,impcons,calltype,varargin{:});
  146. end
  147. %-- update minval, xatmin --------------------------------------%
  148. costvalue = fc(1:fcncounter)+con(1:fcncounter);
  149. [minval,fminindex] = min(fc(1:fcncounter)+con(1:fcncounter));
  150. penminval = minval + con(fminindex);
  151. xatmin = (om_upper - om_lower).*c(:,fminindex) + om_lower;
  152. if (con(fminindex) > 0)|(feas_flags(fminindex) ~= 0)
  153. %--- new minval is infeasible, don't do anything
  154. else
  155. %--- update return values
  156. ret_minval = minval;
  157. ret_xatmin = xatmin;
  158. end
  159. %--see if we are done ------------------------------------------%
  160. if tflag == 1
  161. %-- Calculate error if globalmin known
  162. if theglobalmin ~= 0
  163. perror = 100*(minval - theglobalmin)/abs(theglobalmin);
  164. else
  165. perror = 100*minval;
  166. end
  167. else
  168. %-- Have we exceeded the maxits?
  169. if itctr >= maxits
  170. disp('Exceeded max iterations. Increase maxits')
  171. done = 1;
  172. end
  173. %-- Have we exceeded the maxevals?
  174. if fcncounter > maxevals
  175. disp('Exceeded max fcn evals. Increase maxevals')
  176. done = 1;
  177. end
  178. if done == 1
  179. perror = -1;
  180. end
  181. end
  182. if max(max(lengths)) >= maxdeep
  183. %-- We've exceeded the max depth
  184. disp('Exceeded Max depth. Increse maxdeep')
  185. perror = -1;
  186. end
  187. if g_nargout == 3
  188. %-- Store History
  189. maxhist = size(history,1);
  190. history(maxhist+1,3) = fminindex;
  191. history(maxhist+1,1) = itctr;
  192. history(maxhist+1,2) = fcncounter;
  193. history(maxhist+1,4) = minval;
  194. history(maxhist+1,5) = minval;
  195. end
  196. %-- New, 06/09/2004
  197. %-- Call replaceinf if impcons flag is set to 1
  198. if impcons == 1
  199. fc = replaceinf(lengths(:,1:fcncounter),c(:,1:fcncounter),...
  200. fc(1:fcncounter),con(1:fcncounter),...
  201. feas_flags(1:fcncounter),pert);
  202. end
  203. %-- show iteration stats
  204. if showits == 1
  205. if (con(fminindex) > 0) | (feas_flags(fminindex) == 1)
  206. fprintf('Iter: %4i f_min: %15.10f* fn evals: %8i\n',...
  207. itctr,minval,fcncounter);
  208. else
  209. fprintf('Iter: %4i f_min: %15.10f fn evals: %8i\n',...
  210. itctr,minval,fcncounter);
  211. end
  212. end
  213. itctr = itctr + 1;
  214. end
  215. %-- Return values
  216. if g_nargout == 2
  217. %-- return x*
  218. final_xatmin = ret_xatmin;
  219. elseif g_nargout == 3
  220. %-- return x*
  221. final_xatmin = ret_xatmin;
  222. %-- chop off 1st row of history
  223. history(1:size(history,1)-1,:) = history(2:size(history,1),:);
  224. history = history(1:size(history,1)-1,:);
  225. end
  226. [HistData] = HistDataFunc(costvalue,history);
  227. function [HistData] = HistDataFunc(costvalue,history)
  228. costvalue =costvalue';
  229. [m,n] = size(costvalue);
  230. j = 1;
  231. for i = 1:m
  232. HistData(i,3) = costvalue(i,1);
  233. HistData(i,2) = i;
  234. HistData(i,1) = history(j,1);
  235. if i == history(j,2)
  236. j = j+1;
  237. end
  238. end
  239. return
  240. %------------------------------------------------------------------%
  241. % Function: DIRini %
  242. % Written by: Dan Finkel %
  243. % Created on: 10/19/2002 %
  244. % Purpose : Initialization of Direct %
  245. % to eliminate storing floating points %
  246. %------------------------------------------------------------------%
  247. function [l_thirds,l_lengths,l_c,l_fc,l_con, l_feas_flags, minval,xatmin,perror,...
  248. history,szes,fcncounter,calltype] = DIRini(bounds,Problem,n,a,b,...
  249. p_lengths,p_c,p_fc,p_con, p_feas_flags, p_szes,theglobalmin,...
  250. maxdeep,tflag,g_nargout,impcons,varargin)
  251. l_lengths = p_lengths;
  252. l_c = p_c;
  253. l_fc = p_fc;
  254. l_con = p_con;
  255. l_feas_flags = p_feas_flags;
  256. szes = p_szes;
  257. %-- start by calculating the thirds array
  258. %-- here we precalculate (1/3)^i which we will use frequently
  259. l_thirds(1) = 1/3;
  260. for i = 2:maxdeep
  261. l_thirds(i) = (1/3)*l_thirds(i-1);
  262. end
  263. %-- length array will store # of slices in each dimension for
  264. %-- each rectangle. dimension will be rows; each rectangle
  265. %-- will be a column
  266. %-- first rectangle is the whole unit hyperrectangle
  267. l_lengths(:,1) = zeros(n,1);
  268. %01/21/04 HACK
  269. %-- store size of hyperrectangle in vector szes
  270. szes(1,1) = 1;
  271. %-- first element of c is the center of the unit hyperrectangle
  272. l_c(:,1) = ones(n,1)/2;
  273. %-- Determine if there are constraints
  274. calltype = DetermineFcnType(Problem,impcons);
  275. %-- first element of f is going to be the function evaluated
  276. %-- at the center of the unit hyper-rectangle.
  277. %om_point = abs(b - a).*l_c(:,1)+ a;
  278. %l_fc(1) = feval(f,om_point,varargin{:});
  279. [l_fc(1),l_con(1), l_feas_flags(1)] = ...
  280. CallObjFcn(bounds,Problem,l_c(:,1),a,b,impcons,calltype,varargin{:});
  281. fcncounter = 1;
  282. %-- initialize minval and xatmin to be center of hyper-rectangle
  283. xatmin = l_c(:,1);
  284. minval = l_fc(1);
  285. if tflag == 1
  286. if theglobalmin ~= 0
  287. perror = 100*(minval - theglobalmin)/abs(theglobalmin);
  288. else
  289. perror = 100*minval;
  290. end
  291. else
  292. perror = 2;
  293. end
  294. %-- initialize history
  295. if g_nargout == 3
  296. history(1,1) = 0;
  297. history(1,2) = 0;
  298. history(1,3) = 0;
  299. history(1,4) = 0;
  300. history(1,5) = 0;
  301. end
  302. %------------------------------------------------------------------%
  303. % Function : find_po %
  304. % Written by : Dan Finkel %
  305. % Created on : 10/19/2002 %
  306. % Purpose : Return list of PO hyperrectangles %
  307. %------------------------------------------------------------------%
  308. function rects = find_po(fc,lengths,minval,ep,szes)
  309. %-- 1. Find all rects on hub
  310. diff_szes = sum(lengths,1);
  311. tmp_max = max(diff_szes);
  312. j=1;
  313. sum_lengths = sum(lengths,1);
  314. for i =1:tmp_max+1
  315. tmp_idx = find(sum_lengths==i-1);
  316. [tmp_n, hullidx] = min(fc(tmp_idx));
  317. if length(hullidx) > 0
  318. hull(j) = tmp_idx(hullidx);
  319. j=j+1;
  320. %-- 1.5 Check for ties
  321. ties = find(abs(fc(tmp_idx)-tmp_n) <= 1e-13);
  322. if length(ties) > 1
  323. mod_ties = find(tmp_idx(ties) ~= hull(j-1));
  324. hull = [hull tmp_idx(ties(mod_ties))];
  325. j = length(hull)+1;
  326. end
  327. end
  328. end
  329. %-- 2. Compute lb and ub for rects on hub
  330. lbound = calc_lbound(lengths,fc,hull,szes);
  331. ubound = calc_ubound(lengths,fc,hull,szes);
  332. %-- 3. Find indeces of hull who satisfy
  333. %-- 1st condition
  334. maybe_po = find(lbound-ubound <= 0);
  335. %-- 4. Find indeces of hull who satisfy
  336. %-- 2nd condition
  337. t_len = length(hull(maybe_po));
  338. if minval ~= 0
  339. po = find((minval-fc(hull(maybe_po)))./abs(minval) +...
  340. szes(hull(maybe_po)).*ubound(maybe_po)./abs(minval) >= ep);
  341. else
  342. po = find(fc(hull(maybe_po)) -...
  343. szes(hull(maybe_po)).*ubound(maybe_po) <= 0);
  344. end
  345. final_pos = hull(maybe_po(po));
  346. rects = [final_pos;szes(final_pos)];
  347. return
  348. %------------------------------------------------------------------%
  349. % Function : calc_ubound %
  350. % Written by : Dan Finkel %
  351. % Created on : 10/19/2002 %
  352. % Purpose : calculate the ubound used in determing potentially %
  353. % optimal hrectangles %
  354. %------------------------------------------------------------------%
  355. function ub = calc_ubound(lengths,fc,hull,szes)
  356. hull_length = length(hull);
  357. hull_lengths = lengths(:,hull);
  358. for i =1:hull_length
  359. tmp_rects = find(sum(hull_lengths,1)<sum(lengths(:,hull(i))));
  360. if length(tmp_rects) > 0
  361. tmp_f = fc(hull(tmp_rects));
  362. tmp_szes = szes(hull(tmp_rects));
  363. tmp_ubs = (tmp_f-fc(hull(i)))./(tmp_szes-szes(hull(i)));
  364. ub(i) = min(tmp_ubs);
  365. else
  366. ub(i)=1.976e14;
  367. end
  368. end
  369. return
  370. %------------------------------------------------------------------%
  371. % Function : calc_lbound %
  372. % Written by : Dan Finkel %
  373. % Created on : 10/19/2002 %
  374. % Purpose : calculate the lbound used in determing potentially %
  375. % optimal hrectangles %
  376. %------------------------------------------------------------------%
  377. function lb = calc_lbound(lengths,fc,hull,szes)
  378. hull_length = length(hull);
  379. hull_lengths = lengths(:,hull);
  380. for i = 1:hull_length
  381. tmp_rects = find(sum(hull_lengths,1)>sum(lengths(:,hull(i))));
  382. if length(tmp_rects) > 0
  383. tmp_f = fc(hull(tmp_rects));
  384. tmp_szes = szes(hull(tmp_rects));
  385. tmp_lbs = (fc(hull(i))-tmp_f)./(szes(hull(i))-tmp_szes);
  386. lb(i) = max(tmp_lbs);
  387. else
  388. lb(i) = -1.976e14;
  389. end
  390. end
  391. return
  392. %------------------------------------------------------------------%
  393. % Function : DIRdivide %
  394. % Written by : Dan Finkel %
  395. % Created on : 10/19/2002 %
  396. % Purpose : Divides rectangle i that is passed in %
  397. %------------------------------------------------------------------%
  398. function [lengths,fc,c,con,feas_flags,szes,fcncounter,pass] = ...
  399. DIRdivide(bounds,a,b,Problem,index,thirds,p_lengths,p_fc,p_c,p_con,...
  400. p_feas_flags,p_fcncounter,p_szes,impcons,calltype,varargin)
  401. lengths = p_lengths;
  402. fc = p_fc;
  403. c = p_c;
  404. szes = p_szes;
  405. fcncounter = p_fcncounter;
  406. con = p_con;
  407. feas_flags = p_feas_flags;
  408. %-- 1. Determine which sides are the largest
  409. li = lengths(:,index);
  410. biggy = min(li);
  411. ls = find(li==biggy);
  412. lssize = length(ls);
  413. j = 0;
  414. %-- 2. Evaluate function in directions of biggest size
  415. %-- to determine which direction to make divisions
  416. oldc = c(:,index);
  417. delta = thirds(biggy+1);
  418. newc_left = oldc(:,ones(1,lssize));
  419. newc_right = oldc(:,ones(1,lssize));
  420. f_left = zeros(1,lssize);
  421. f_right = zeros(1,lssize);
  422. for i = 1:lssize
  423. lsi = ls(i);
  424. newc_left(lsi,i) = newc_left(lsi,i) - delta;
  425. newc_right(lsi,i) = newc_right(lsi,i) + delta;
  426. [f_left(i), con_left(i), fflag_left(i)] = CallObjFcn(bounds,Problem,newc_left(:,i),a,b,impcons,calltype,varargin{:});
  427. [f_right(i), con_right(i), fflag_right(i)] = CallObjFcn(bounds,Problem,newc_right(:,i),a,b,impcons,calltype,varargin{:});
  428. fcncounter = fcncounter + 2;
  429. end
  430. w = [min(f_left, f_right)' ls];
  431. %-- 3. Sort w for division order
  432. [V,order] = sort(w,1);
  433. %-- 4. Make divisions in order specified by order
  434. for i = 1:size(order,1)
  435. newleftindex = p_fcncounter+2*(i-1)+1;
  436. newrightindex = p_fcncounter+2*(i-1)+2;
  437. %-- 4.1 create new rectangles identical to the old one
  438. oldrect = lengths(:,index);
  439. lengths(:,newleftindex) = oldrect;
  440. lengths(:,newrightindex) = oldrect;
  441. %-- old, and new rectangles have been sliced in order(i) direction
  442. lengths(ls(order(i,1)),newleftindex) = lengths(ls(order(i,1)),index) + 1;
  443. lengths(ls(order(i,1)),newrightindex) = lengths(ls(order(i,1)),index) + 1;
  444. lengths(ls(order(i,1)),index) = lengths(ls(order(i,1)),index) + 1;
  445. %-- add new columns to c
  446. c(:,newleftindex) = newc_left(:,order(i));
  447. c(:,newrightindex) = newc_right(:,order(i));
  448. %-- add new values to fc
  449. fc(newleftindex) = f_left(order(i));
  450. fc(newrightindex) = f_right(order(i));
  451. %-- add new values to con
  452. con(newleftindex) = con_left(order(i));
  453. con(newrightindex) = con_right(order(i));
  454. %-- add new flag values to feas_flags
  455. feas_flags(newleftindex) = fflag_left(order(i));
  456. feas_flags(newrightindex) = fflag_right(order(i));
  457. %-- 01/21/04 Dan Hack
  458. %-- store sizes of each rectangle
  459. szes(1,newleftindex) = 1/2*norm((1/3*ones(size(lengths,1),1)).^(lengths(:,newleftindex)));
  460. szes(1,newrightindex) = 1/2*norm((1/3*ones(size(lengths,1),1)).^(lengths(:,newrightindex)));
  461. end
  462. szes(index) = 1/2*norm((1/3*ones(size(lengths,1),1)).^(lengths(:,index)));
  463. pass = 1;
  464. return
  465. %------------------------------------------------------------------%
  466. % Function : CallConstraints %
  467. % Written by : Dan Finkel %
  468. % Created on : 06/07/2004 %
  469. % Purpose : Evaluate Constraints at pointed specified %
  470. %------------------------------------------------------------------%
  471. function ret_value = CallConstraints(Problem,x,a,b,varargin)
  472. %-- Scale variable back to original space
  473. point = (b - a).*x+ a;
  474. ret_value = 0;
  475. if isfield(Problem,'constraint')
  476. if ~isempty(Problem.constraint)
  477. for i = 1:Problem.numconstraints
  478. if length(Problem.constraint(i).func) == length(Problem.f)
  479. if double(Problem.constraint(i).func) == double(Problem.f)
  480. %-- Dont call constraint; value was returned in obj fcn
  481. con_value = 0;
  482. else
  483. con_value = feval(Problem.constraint(i).func,point,varargin{:});
  484. end
  485. else
  486. con_value = feval(Problem.constraint(i).func,point,varargin{:});
  487. end
  488. if con_value > 0
  489. %-- Infeasible, punish with associated pen. param
  490. ret_value = ret_value + con_value*Problem.constraint(i).penalty;
  491. end
  492. end
  493. end
  494. end
  495. return
  496. %------------------------------------------------------------------%
  497. % Function : CallObjFcn %
  498. % Written by : Dan Finkel %
  499. % Created on : 06/07/2004 %
  500. % Purpose : Evaluate ObjFcn at pointed specified %
  501. %------------------------------------------------------------------%
  502. function [fcn_value, con_value, feas_flag] = ...
  503. CallObjFcn(bounds,Problem,x,a,b,impcon,calltype,varargin)
  504. con_value = 0;
  505. feas_flag = 0;
  506. %-- Scale variable back to original space
  507. point = (b - a).*x+ a;
  508. point = point';
  509. if calltype == 1
  510. %-- No constraints at all
  511. point = bounds(1,:) + (bounds(2,:)-bounds(1,:)).*point;
  512. fcn_value = feval(Problem.f,point,varargin{:});
  513. elseif calltype == 2
  514. %-- f returns all constraints
  515. point = bounds(1,:) + (bounds(2,:)-bounds(1,:)).*point;
  516. [fcn_value, cons] = feval(Problem.f,point,varargin{:});
  517. for i = 1:length(cons)
  518. if cons > 0
  519. con_value = con_value + Problem.constraint(i).penalty*cons(i);
  520. end
  521. end
  522. elseif calltype == 3
  523. %-- f returns no constraint values
  524. point = bounds(1,:) + (bounds(2,:)-bounds(1,:)).*point;
  525. fcn_value = feval(Problem.f,point,varargin{:});
  526. con_value = CallConstraints(Problem,x,a,b,varargin{:});
  527. elseif calltype == 4
  528. %-- f returns feas flag
  529. point = bounds(1,:) + (bounds(2,:)-bounds(1,:)).*point;
  530. [fcn_value,feas_flag] = feval(Problem.f,point,varargin{:});
  531. elseif calltype == 5
  532. %-- f returns feas flags, and there are constraints
  533. point = bounds(1,:) + (bounds(2,:)-bounds(1,:)).*point;
  534. [fcn_value,feas_flag] = feval(Problem.f,point,varargin{:});
  535. con_value = CallConstraints(Problem,x,a,b,varargin{:});
  536. end
  537. if feas_flag == 1
  538. fcn_value = 10^9;
  539. con_value = 0;
  540. end
  541. return
  542. %------------------------------------------------------------------%
  543. % Function : replaceinf %
  544. % Written by : Dan Finkel %
  545. % Created on : 06/09/2004 %
  546. % Purpose : Assign R. Carter value to given point %
  547. %------------------------------------------------------------------%
  548. function fcn_values = replaceinf(lengths,c,fc,con,flags,pert)
  549. %-- Initialize fcn_values to original values
  550. fcn_values = fc;
  551. %-- Find the infeasible points
  552. infeas_points = find(flags == 1);
  553. %-- Find the feasible points
  554. feas_points = find(flags == 0);
  555. %-- Calculate the max. value found so far
  556. if ~isempty(feas_points)
  557. maxfc = max(fc(feas_points) + con(feas_points));
  558. else
  559. maxfc = max(fc + con);
  560. end
  561. for i = 1:length(infeas_points)
  562. if isempty(feas_points)
  563. %-- no feasible points found yet
  564. found_points = [];found_pointsf = [];
  565. index = infeas_points(i);
  566. else
  567. index = infeas_points(i);
  568. %-- Initialize found points to be entire set
  569. found_points = c(:,feas_points);
  570. found_pointsf = fc(feas_points) + con(feas_points);
  571. %-- Loop through each dimension, and find points who are close enough
  572. for j = 1:size(lengths,1)
  573. neighbors = find(abs(found_points(j,:) - c(j,index)) <= ...
  574. 3^(-lengths(j,index)));
  575. if ~isempty(neighbors)
  576. found_points = found_points(:,neighbors);
  577. found_pointsf = found_pointsf(neighbors);
  578. else
  579. found_points = [];found_pointsf = [];
  580. break;
  581. end
  582. end
  583. end
  584. %-- Assign Carter value to the point
  585. if ~isempty(found_pointsf)
  586. %-- assign to index the min. value found + a little bit more
  587. fstar = min(found_pointsf);
  588. if fstar ~= 0
  589. fcn_values(index) = fstar + pert*abs(fstar);
  590. else
  591. fcn_values(index) = fstar + pert*1;
  592. end
  593. else
  594. fcn_values(index) = maxfc+1;
  595. maxfc = maxfc+1;
  596. end
  597. end
  598. return
  599. %------------------------------------------------------------------%
  600. % Function : DetermineFcnType %
  601. % Written by : Dan Finkel %
  602. % Created on : 06/25/2004 %
  603. % Purpose : Determine how constraints are handled %
  604. %------------------------------------------------------------------%
  605. function retval = DetermineFcnType(Problem,impcons)
  606. retval = 0;
  607. if (~isfield(Problem,'constraint'))&(~impcons)
  608. %-- No constraints at all
  609. retval = 1;
  610. end
  611. if isfield(Problem,'constraint')
  612. %-- There are explicit constraints. Next determine where
  613. %-- they are called
  614. if ~isempty(Problem.constraint)
  615. if length(Problem.constraint(1).func) == length(Problem.f)
  616. %-- Constraint values may be returned from objective
  617. %-- function. Investigate further
  618. if double(Problem.constraint(1).func) == double(Problem.f)
  619. %-- f returns constraint values
  620. retval = 2;
  621. else
  622. %-- f does not return constraint values
  623. retval = 3;
  624. end
  625. else
  626. %-- f does not return constraint values
  627. retval = 3;
  628. end
  629. else
  630. if impcons
  631. retval = 0;
  632. else
  633. retval = 1;
  634. end
  635. end
  636. end
  637. if (impcons)
  638. if ~retval
  639. %-- only implicit constraints
  640. retval = 4;
  641. else
  642. %-- both types of constraints
  643. retval = 5;
  644. end
  645. end
  646. %------------------------------------------------------------------%
  647. % GETOPTS Returns options values in an options structure
  648. % USAGE
  649. % [value1,value2,...]=getopts(options,field1,default1,field2,default2,...)
  650. % INPUTS
  651. % options : a structure variable
  652. % field : a field name
  653. % default : a default value
  654. % OUTPUTS
  655. % value : value in the options field (if it exists) or the default value
  656. %
  657. % Variables with the field names will be created in the caller's workspace
  658. % and set to the value in the option variables field (if it exists) or to the
  659. % default value.
  660. %
  661. % Example called from a function:
  662. % getopts(options,'tol',1e-8,'maxits',100);
  663. % where options contains the single field 'tol' with value equal to 1
  664. % The function have two variable defined in the local workspace, tol with a
  665. % value of 1 and maxits with a value of 100.
  666. %
  667. % If options contains a field name not in the list passed to getopts, a
  668. % warning is issued.
  669. %
  670. %
  671. % Many thanks to the author of this function,
  672. % Paul Fackler (pfackler@ncsu.edu)
  673. %
  674. %
  675. %------------------------------------------------------------------%
  676. function varargout=getopts(options,varargin)
  677. K=fix(nargin/2);
  678. if nargin/2==K
  679. error('fields and default values must come in pairs')
  680. end
  681. if isa(options,'struct'), optstruct=1; else, optstruct=0; end
  682. varargout=cell(K,1);
  683. k=0;
  684. ii=1;
  685. for i=1:K
  686. if optstruct & isfield(options,varargin{ii})
  687. assignin('caller',varargin{ii},getfield(options,varargin{ii}));
  688. k=k+1;
  689. else
  690. assignin('caller',varargin{ii},varargin{ii+1});
  691. end
  692. ii=ii+2;
  693. end
  694. if optstruct & k~=size(fieldnames(options),1)
  695. warning('options variable contains improper fields')
  696. end
  697. return
  698. %------------------------------------------------------------------%
  699. % Versions : 1.0 - 1st successful implemenation of DIRect
  700. % : 2.0 - Removed floating point arithmetic
  701. % duplicated Table 5 of Jones et al.
  702. % : 2.1 - increased speed by storing size calcs.
  703. % : 2.2 - utitilized linked lists to increase speed
  704. % : 2.3 - rewrote ubound to increase speed
  705. % : 2.4 - rewrote lbound to increase speed
  706. % : 2.5 - removed call to calcsize
  707. % : 2.6 - added check_for_ties
  708. % : 2.7 - rewrote check_for_ties to compare fp correctly
  709. % : 2.8 - changed output arguments, rewrote help
  710. % : 3.0 - simplified input/output. Put on web.
  711. % : 3.1 - Performanced Tuned! Tremendous speed increase
  712. % : 3.2 - Removed llists; performance tuned
  713. % Many thanks to Ray Muzic and Paul Fackler
  714. % for their suggestions to improve this code
  715. % : 4.0 - Sped up code, and added 2 constraint handling
  716. % mechanisms.
  717. %------------------------------------------------------------------%