arclength.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. function [x_L1,f,Param_out] = arclength(fun_name,x0,sign,Mission_Param, Environment_Param)
  2. Param_0 = 0;
  3. Param_1 = 1;
  4. ArcLenParam.atol = 1e-10;
  5. ds_default =1;
  6. gg = 40000;
  7. epsilon = sqrt(eps);
  8. try
  9. val = ArcLenParam.ds;
  10. catch
  11. ArcLenParam.ds = ds_default;%;
  12. end
  13. try
  14. val = ArcLenParam.max_iter;
  15. catch
  16. ArcLenParam.max_iter = 900000000;
  17. end
  18. try
  19. val = ArcLenParam.max_corr;
  20. catch
  21. ArcLenParam.max_corr =40;
  22. end
  23. try
  24. val = ArcLenParam.atol;
  25. catch
  26. ArcLenParam.atol = 1e-8;
  27. end
  28. %存储文件
  29. % datas = sprintf('.\\data\\data-%s.txt',int2str(200));%创建文件
  30. % fid_sim = fopen(datas,'a+t');%保存文件索引
  31. if(nargout >= 5)
  32. ido_stab = 1;
  33. else
  34. ido_stab = 0;
  35. end
  36. N = length(x0);
  37. count_pts = 0;
  38. Param_old1 = Param_0;
  39. Param_old2 = Param_0;
  40. Options_fsolve = optimset('TolX',1e-12','TolFun',1e-12,'MaxIter',1000,...
  41. 'MaxFunEvals',10000,'FunValCheck ','on' ,'LargeScale','off',...
  42. 'Algorithm','trust-region-dogleg','Display','iter',...
  43. 'PrecondBandWidth',1,'UseParallel',true);
  44. [x,f] = fsolve(fun_name,x0,Options_fsolve,Param_0,Mission_Param, Environment_Param);
  45. % 利用差分计算雅可比矩阵
  46. Jac = ac_calc_Jac(fun_name,x,Param_0,f,epsilon,Mission_Param, Environment_Param);
  47. x_c(:,1) = x;
  48. lambda = 0;
  49. Param = (1-lambda)*Param_0 + lambda*Param_1;
  50. if(ido_stab)
  51. stab_c(1) = ac_calc_stab(Jac);
  52. end
  53. temp_x = [count_pts,ArcLenParam.ds,Param,x(1:7)'];
  54. % fprintf(fid_sim,'%4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f \n',temp_x);
  55. figure(2);
  56. plot(Param,x(N),'ro');
  57. hold on
  58. Param_out = Param;
  59. x_L1 = x;
  60. count_pts = count_pts + 1; % increment counter
  61. x1 = x;
  62. x2=x;
  63. lambda_old = lambda;
  64. lambda_old2=lambda;
  65. f_old = f;
  66. f_old2 = f;
  67. c_rand = rand(1,N+1);
  68. icomplete_arclength = 0;
  69. icorr_OK=0;
  70. nCount =1;
  71. nx6 = 0;
  72. for iter = 1:ArcLenParam.max_iter
  73. %判断迭代是否种植
  74. if(lambda >= 1)
  75. icomplete_arclength = 1;
  76. break;
  77. end
  78. norm_x = norm(x);
  79. if nCount == 1
  80. ArcLenParam.ds = norm_x/10;%迭代步长
  81. bound = norm_x/1;
  82. end
  83. df_dlambda = ac_calc_df_dlambda(fun_name,x,lambda,Param_0,Param_1,f,epsilon,Mission_Param, Environment_Param);%fun对lambda的微分
  84. % construct matrix for solving dz/ds
  85. A = zeros(N+1,N+1);
  86. A(1:N,1:N) = Jac;
  87. A(1:N,N+1) = df_dlambda;
  88. A(N+1,1:N+1) = c_rand;
  89. b = zeros(N+1,1);
  90. b(N+1) = 1;
  91. v = A\b;
  92. dz_ds = sign*v / norm(v,2);
  93. % 修正迭代方向
  94. dz_old = zeros(N+1,1);
  95. dz_old(1:N) = x - x2;
  96. dz_old(N+1) = lambda - lambda_old2;
  97. if(dot(dz_ds,dz_old) < 0)
  98. dz_ds = -dz_ds;
  99. end
  100. if iter == 1 && dz_ds(N+1)<0
  101. sign = -sign;
  102. end
  103. % 显示欧拉得到下一时刻
  104. x1 = x; lambda_old = lambda;
  105. f_old = f;
  106. x = x + dz_ds(1:N)*ArcLenParam.ds;
  107. nx6 = 0;
  108. for kkk = 1:N
  109. if abs(imag(x(kkk)))>0 || isnan(x(kkk))
  110. nx6 = 1;
  111. break;
  112. end
  113. end
  114. if x(7) > gg || nx6 == 1 || x(7) < 0 || (abs(abs(x1(7)) - abs(x(7))) > bound)
  115. icorr_OK = 0;
  116. else
  117. lambda = lambda + dz_ds(N+1)*ArcLenParam.ds;
  118. Param = (1-lambda)*Param_0 + lambda*Param_1;
  119. if abs(Param) > 1
  120. icorr_OK = 0;
  121. else
  122. f = feval(fun_name,x,Param,Mission_Param, Environment_Param);
  123. icorr_OK = 0;
  124. A(N+1,:) = dz_ds';
  125. [L,U,P] = lu(A);
  126. if rank(A(1:N,1:N)) < N
  127. rank(A(1:N,1:N))
  128. disp('limit point!')
  129. pause
  130. end
  131. for k_corr = 1:ArcLenParam.max_corr
  132. if(norm(f,2) <= ArcLenParam.atol )
  133. icorr_OK = 1;
  134. x_L1 = x;
  135. break;
  136. end
  137. % 获得delta_z
  138. nn = [-f;0];
  139. v = L\(P*nn);
  140. delta_z= U\v;
  141. if abs(imag(delta_z(7))) > 0
  142. icorr_OK = 0;
  143. break;
  144. end
  145. x = x + delta_z(1:N);
  146. nx6 = 0;
  147. lambda = lambda + delta_z(N+1);
  148. % 新函数值
  149. Param = (1-lambda)*Param_0 + lambda*Param_1;
  150. for kkk=1:N
  151. if abs(imag(x(kkk)))>0 || isnan(x(kkk))
  152. nx6 = 1;
  153. break;
  154. end
  155. end
  156. xx1=dot([Param_old2,x2(7)],[Param_old1,x1(7)])/(norm([Param_old2,x2(7)])*norm([Param_old1,x1(7)]));
  157. xx2=dot([Param_old1,x1(7)],[Param,x(7)])/(norm([Param_old1,x1(7)])*norm([Param,x(7)]));
  158. xx3 = abs(abs(acos(xx1)) - abs(acos(xx2)));
  159. xx4 = (x1(7) - x2(7))/(Param_old1 -Param_old2 );
  160. xx5 = (x(7) - x1(7))/(Param -Param_old1 );
  161. xx6 = abs(atan(xx4) - atan(xx5));
  162. if x(7) > gg || nx6 == 1 || x(7) < 0 || (abs(abs(x1(7)) - abs(x(7))) > bound) || xx3 > pi/10 || xx6 > pi/10 %|| atan(xx4)*atan(xx5) < 0
  163. icorr_OK = 0;
  164. break;
  165. end
  166. f = feval(fun_name,x,Param,Mission_Param, Environment_Param);
  167. end
  168. end
  169. end
  170. if(icorr_OK==0)
  171. if nCount >7
  172. fclose(fid_sim);
  173. return;
  174. else
  175. lambda=lambda_old;
  176. x = x1;
  177. f=f_old;
  178. Param = (1-lambda)*Param_0 + lambda*Param_1;
  179. Jac = ac_calc_Jac(fun_name,x,Param,f,epsilon,Mission_Param, Environment_Param);
  180. ArcLenParam.ds = ArcLenParam.ds/5;
  181. nCount = nCount+1;
  182. end
  183. elseif icorr_OK==1
  184. x2 = x1;
  185. lambda_old2=lambda_old;
  186. f_old2 = f_old;
  187. % 有限差分计算雅可比
  188. Jac = ac_calc_Jac(fun_name,x,Param,f,epsilon,Mission_Param, Environment_Param);
  189. nCount = 1;
  190. x_c(:,1) = x;
  191. lambda_c(:,1) = lambda;
  192. Param_c(:,1) = Param;
  193. fnorm_c(:,1) = norm(f,inf);
  194. Param_old2 = Param_old1;
  195. Param_old1 = Param;
  196. temp_x = [count_pts,ArcLenParam.ds,Param,x(1:7)'];
  197. % fprintf(fid_sim,'%4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f \n',temp_x);
  198. sprintf('%4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f %4.11f \n',temp_x)
  199. figure(2);
  200. plot(Param,x(N),'ro');
  201. hold on
  202. Param_out = Param;
  203. x_L1 = x;
  204. if Param > 99 || Param< -99
  205. flag = 666
  206. fclose(fid_sim);
  207. return;
  208. end
  209. if(ido_stab)
  210. stab_c(1) = ac_calc_stab(Jac);
  211. end
  212. count_pts = count_pts + 1;
  213. end
  214. end
  215. fclose(fid_sim);%关闭文件
  216. return;
  217. function Jac = ac_calc_Jac(fun_name,x,theta,f,epsilon,Mission_Param, Environment_Param)
  218. N = length(x); Jac = zeros(N,N);
  219. x_new = zeros(N,1);
  220. f_new = zeros(N,1);
  221. for k=1:N
  222. x_new = x;
  223. x_new(k) = x(k) + epsilon;
  224. f_new = feval(fun_name,x_new,theta,Mission_Param, Environment_Param);
  225. Jac(:,k) = (f_new-f)/epsilon;
  226. end
  227. return;
  228. % 计算对lambda的积分
  229. function df_dlambda = ac_calc_df_dlambda(fun_name,x,lambda,Param_0,Param_1,f,epsilon,Mission_Param, Environment_Param)
  230. Param0 = (1-lambda)*Param_0 + lambda*Param_1;
  231. lambda_new = lambda + epsilon;
  232. Param_new = (1-lambda_new)*Param_0 + lambda_new*Param_1;
  233. f_new = feval(fun_name,x,Param_new,Mission_Param, Environment_Param);
  234. df_dlambda = (f_new-f)/epsilon;
  235. return;
  236. %计算是否稳定
  237. function istable = ac_calc_stab(Jac)
  238. % 计算雅可比的特征值
  239. eig_vals_real = real(eig(Jac));
  240. % 是否大于0
  241. iunstable = length(find(eig_vals_real > 0));
  242. if(iunstable)
  243. istable = 0;
  244. else
  245. istable = 1;
  246. end
  247. return;