finding intersection point using scilab

北慕城南 提交于 2019-12-11 04:28:42

问题


How can I find intersection points in the graph shown below using fsolve function (from scilab)?

Here is what I've tried so far:

function y=f(x)
    y = 30 + 0 * x;
endfunction


function y= g(x)
    y=zeros(x)
    k1 = find(x >= 5 & x <= 11); 
    if  k1<>[]  then
        y(k1)= -59.535905 +24.763399*x(k1) -3.135727*x(k1)^2+0.1288967*x(k1)^3;
    end;
    k2=find(x >= 11 & x <= 12); 
    if  k2 <> []    then 
        y(k2)=1023.4465 - 270.59543 * x(k2) + 23.715076 * x(k2)^2 - 0.684764 * x(k2)^3; 
    end;
    k3 = find(x >= 12 & x <= 17);    
    if  k3 <> [] then
        y(k3) =-307.31448 + 62.094807 *x(k3) - 4.0091108 * x(k3)^2 + 0.0853523 * x(k3)^3;
    end;
    k4 = find(x >= 17 & x <= 50); 
    if k4 <> [] then 
        y(k4) = 161.42601 - 20.624104 *x(k4) + 0.8567075 * x(k4)^2 - 0.0100559 * x(k4)^3;
    end;
endfunction

t=[5:50];
plot(t, g(t));
plot2d(t, f(t));
deff('res = fct', ['res(1) = f(x)'; 'res(2) = g(x)']);
k1=[5, 45];
xsol1 = fsolve(k1, f, g)


回答1:


Your original post was utterly unreadable and chaotic. It took me while to edit it and understand what you are trying to achieve. However I will try to help you. Lets go step by step:

  1. I am not sure why you have used find function this way. probably you were trying to vectorize the g function? Please consider that Scilab does not broadcast functions over arrays by default. You need to either vectorize them or use feval to do so. Please read this other answer I have written before. find is a vectorized operation applying on an array, a Boolean operation and a scalar, finding the elements of the array which satisfy the operation. For example from the find page:
beers = ["Desperados", "Leffe", "Kronenbourg", "Heineken"];
find(beers == "Leffe")

returns 2 and

A = rand(1, 20);
w = find(A < 0.4)

returns those elements of array A which are smaller than 0.4.

  1. Please learn about conditionals and specifically if, then, elsif, else, end statements. If you learn this you will not use the find function in that way. Sometimes you have so many ifs in a row, then try to use select, case, else, end instead. Your second function could be written as:
function y = g(x)
  if x < 5 | 50 < x then
    error("Out of range");
  elseif x <= 11 then
    y = -59.535905 + 24.763399 * x - 3.135727 * x^2 + 0.1288967 * x^3;
    return;
  elseif x <= 12 then
    y = 1023.4465 - 270.59543 * x + 23.715076 * x^2 - 0.684764 * x^3;
    return;
  elseif x <= 17 then
    y = -307.31448 + 62.094807 * x - 4.0091108 * x^2 + 0.0853523 * x^3;
    return;
  else
    y = 161.42601 - 20.624104 * x + 0.8567075 * x^2 - 0.0100559 * x^3;
  end
endfunction
  1. Now apparently you want to find the points on this curve which have a value of 30. Although there are methods to find these points automatically plotting can be very helpful to find the proper range:
t = [5:50];
plot(t, feval(t, g) - 30)

showing that the the two solutions are in the range of 20 < x1 < 30 and 40 < x < 50.

  1. Now if we use fsolve with the proper initial values it gives us good results:
--> deff('[y] = g2(x)', 'y = g(x) - 30');

--> fsolve([25; 45], g2)
 ans  =

   26.67373
   48.396547
  1. The third parameter of the fsolve function is the Jacobin / derivative of the g(x) function. You either should calculate the derivatives of the above polynomials manually (or use a proper symbolic software like Maxima), or define them as polynomials using poly function. See this tutorial for example. Then differentiate them, defining a new function like dgdx.


来源:https://stackoverflow.com/questions/55223387/finding-intersection-point-using-scilab

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!