- You will see updates in your activity feed.
- You may receive emails, depending on your notification preferences.

108 views (last 30 days)

Show older comments

Alphonce Owayo
on 2 Mar 2021

Edited: Alphonce Owayo
on 8 Mar 2021

[Below is my code its meant to do as follows, as long as k<NoS, it shall form Equations that at the end of the day are equivalent to k =NoS. Afterwards, it should sum them up, and do fminsearch for Xcal Ycal Zcal and t0. My problem is however I declare the variables Xcal,Ycal,Zcal and t0 whether using syms Xcal, Ycal,Zcal, t0 or Xcal=(1,1,'double') ...etc. Matlab always displays the following "error Conversion to double from function_handle is not possible.". I am new to matlab, but I think there are just too many rules about multiplication and division. Whichever way I do it, there are always errors chiefly '.*' is not allowed for cell variables or sometimes '*' operand is not allowed for this kind of variable and so on and so forth. I've written a separate function on a different.m.file which can run, but I am just hoping to keep things simple and operate within one script, using an anonymous function as indicated. Also I am not very farmiliar with how to call functions or variables across scripts. I am not sure if what I am doing is correct or could someone let me know what I am not doing right thanks]

.....

while k<NoS;

k=1:NoS;

Xcal={};

Ycal={};

Zcal={};

t0={};

eqn=zeros(1,NoS);

eqn(k)=........

@(Xcal,Ycal,Zcal,t0)(sqrt(xj*xj-2*xj*Xcal+Xcal*Xcal+yj*yj-2*yj*Ycal+Ycal*Ycal+zj*zj-2*zj*Zcal+Zcal*Zcal)-c*tj+c*t0)

x0=[500,1000,50,5];

s2=sum(eqn(k));

soln =fminsearch(s2,x0)

break;

end

.....

Alphonce Owayo
on 2 Mar 2021

Walter Roberson
on 2 Mar 2021

@(Xcal,Ycal,Zcal,t0)(sqrt(xj*xj-2*xj*Xcal+Xcal*Xcal+yj*yj-2*yj*Ycal+Ycal*Ycal+zj*zj-2*zj*Zcal+Zcal*Zcal)-c*tj+c*t0)

does not appear to vary with k?

Alphonce Owayo
on 2 Mar 2021

Walter Roberson
on 2 Mar 2021

You are trying to construct a vector of function handles. You cannot do that in MATLAB. This is because in MATLAB, () indicates both indexing and function invocation. If you had a vector eqn of function handles, would eqn(1) indicate indexing to retrieve the first function handle, or would it indicate that each element of the vector was to be invoked with parameter value 1?

Because of this, function handles must be stored in cell arrays, and then it becomes clear that {} indexes which one.

You also try to sum() the function handles. What is your expectation when you add function handles? Especially ones that might not have the same number of parameters or the same parameter names or which might have bound in different values of variables

A=1

f1 = @(x)x+A

A=2

f2 = @(x)x+A

f1+f2

is what exactly? It could not be value, but if it is a function handle then it has to bind in two different A simultaneously.

Alphonce Owayo
on 2 Mar 2021

Walter Roberson
on 2 Mar 2021

NoS = 8;

A1 = randi(9, NoS, 1);

B1 = randi(9, NoS, 1);

C1 = randi(9, NoS, 1);

D1 = randi(9, NoS, 1);

c = randi(20)/20;

syms Xcal Ycal Zcal t0

xj = B1(:);

yj = C1(:);

zj = D1(:)

zj = 8×1

3
3
2
3
2
9
1
2

tj = A1(:);

eqns = (sqrt(xj.*xj-2*xj*Xcal+Xcal*Xcal+yj.*yj-2*yj*Ycal+Ycal*Ycal+zj.*zj-2*zj*Zcal+Zcal*Zcal)-c*tj+c*t0)

eqns =

s2 = sum(eqns);

F = matlabFunction(s2, 'vars', {[Xcal, Ycal, Zcal, t0]}, 'file', 's2.m', 'optimize', false)

F = function_handle with value:

@s2

x0=[500,1000,50,5];

opts = optimset('fminsearch');

opts.MaxFunEvals = 1e5;

opts.MaxIter = 1e5;

[best, fval] = fminsearch(F, x0, opts);

Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: -127680188996661018802776340601204504679739116743394470870553834000417957237043402105822935744474258656269534029514841447587798499464869380073561353531424768.000000

You might notice that the current function value is rather negative. This is correct: if you lok at your equations, you can see that you can get arbitrarily negative values when t0 is negative.

Furthermore, we can see that the t0 contribution is the same for every equation, and appears only outside the sqrt(). Therefore you can split the sum into two pieces, one contributed by (NoS * c) * t0 and the other piece with the square roots and the -c*sum(tj). You can mininimize the two pieces independently.

Alphonce Owayo
on 3 Mar 2021

Alphonce Owayo
on 3 Mar 2021

Walter Roberson
on 3 Mar 2021

If you use fmincon() instead of fminsearch() then you can put in bounds.

If you are trying to minimize the sum, then that can be done too:

format long g

NoS = 8;

A1 = randi(9, NoS, 1);

B1 = randi(9, NoS, 1);

C1 = randi(9, NoS, 1);

D1 = randi(9, NoS, 1);

c = randi(20)/20;

syms Xcal Ycal Zcal t0

xj = B1(:);

yj = C1(:);

zj = D1(:)

zj = 8×1

4
8
9
5
5
1
2
7

tj = A1(:);

eqns = (sqrt(xj.*xj-2*xj*Xcal+Xcal*Xcal+yj.*yj-2*yj*Ycal+Ycal*Ycal+zj.*zj-2*zj*Zcal+Zcal*Zcal)-c*tj+c*t0)

eqns =

s2 = sum(eqns);

F = matlabFunction(s2.^2, 'vars', {[Xcal, Ycal, Zcal, t0]}, 'file', 's2.m', 'optimize', false)

F = function_handle with value:

@s2

x0=[500,1000,50,5];

opts = optimset('fminsearch');

opts.MaxFunEvals = 1e5;

opts.MaxIter = 1e5;

[best, fval] = fminsearch(F, x0, opts);

best

best = 1×4

5.28673078857011 6.11901306252565 5.51087556249405 -4.35285398925722

fval

fval =

1.56106356119392e-13

Alphonce Owayo
on 4 Mar 2021

{x1 =

-0.281080673516821

y1 =

19.0054637291946

z1 =

-9.49765205419143

ts =

-7.05830717920742e-09}

These are the typical range of my values except I realised fval =

354229770.329462 is very high.

Is it because of my inputs ?

typical xj; -25 -30 25 20 25 28 -25 -20

typical yj; 45 20 55 15 15 45 25 50

typicalzj; 0 0 0 0 40 40 40 40

typical tj; 0.000244 -0.00049 0 0.000732 0.070068 0.001221 -0.00049 0.054443

c= 4.3*10^6

Walter Roberson
on 4 Mar 2021

format long g

NoS = 8;

syms Xcal Ycal Zcal t0

xj = [-25 -30 25 20 25 28 -25 -20];

yj = [45 20 55 15 15 45 25 50];

zj = [0 0 0 0 40 40 40 40];

tj = [0.000244 -0.00049 0 0.000732 0.070068 0.001221 -0.00049 0.054443];

c= 4.3*10^6

c =

4300000

eqns = (sqrt(xj.*xj-2*xj*Xcal+Xcal*Xcal+yj.*yj-2*yj*Ycal+Ycal*Ycal+zj.*zj-2*zj*Zcal+Zcal*Zcal)-c*tj+c*t0)

eqns =

s2 = sum(eqns);

F = matlabFunction(s2.^2, 'vars', {[Xcal, Ycal, Zcal, t0]}, 'file', 's2.m', 'optimize', false)

F = function_handle with value:

@s2

x0=[1,2,3,4];

opts = optimset('fminsearch');

opts.MaxFunEvals = 1e5;

opts.MaxIter = 1e5;

[best, fval] = fminsearch(F, x0, opts);

best

best = 1×4

1.05770074278451 2.89375508854424 3.52918424078698 0.0157047849691125

fval

fval =

2.49306076911199e-05

Alphonce Owayo
on 8 Mar 2021

Alphonce Owayo
on 8 Mar 2021

Alphonce Owayo
on 8 Mar 2021

Walter Roberson
on 8 Mar 2021

You said that the above, where we found XCal, YCal, ZCal, t0, represented just one point, and that you now have 1.5 million data points. I am not at all clear how the equations generalize? Are you looking for N objects, so finding XCal(N,1), YCal(N,1), ZCalk(N,1), t0(N,1), based upon best fit for the 1.5 million inputs?

If you are, then that would probably be a clustering task, possibly with a non-euclidean distance matrix.

Do you need to determine the optimum number of objects based upon the 1.5 million points? (Because theory says that the optimum number of clusters is equal to the number of unique points, unless there is a per-object cost.)

Alphonce Owayo
on 8 Mar 2021

You said that the above, where we found XCal, YCal, ZCal, t0, represented just one point, and that you now have 1.5 million data points. Yes this is correct, see the code below dp=ne=1.05 million. Its automatic it reads the input from an excel file specially organized, then outputs it in a text file. Everything is fine I am quite happy with the solutions except the speed of calculations.

prompt0 = 'enter the No. of Data points... dp=';

dp = input(prompt0)

prompt1 = 'enter the No. of Sensors..NoS=';

NoS = input(prompt1)

ne=dp;

if NoS < 1;

disp ('Error,please check your input');

else

disp ('Input looks good,please proceed');

end

%A = 1:NoS;

i=1

i=1;ne;

while i<ne;

for i=1:ne;

NoS==NoS;

% Input sensor signal receipt time

disp("Import the times the sensor received the signals from 1 to NoS--");

ATM=[];

x=importdata('C:\Users\Alphonce\Desktop\J C& G Submission\Book2.xlsx');

ATM = x(i,1:NoS);

disp('Press enter two times to exit from Senszpos--');

while true

% str=input('','s');

% if isempty(str)

if NoS-1==NoS-1;

break;

end

[row,~,errmsg]=sscanf(str,'%f'); % getting row in column vector

if ~isempty(errmsg)

error(errmsg);

end

ATM=[ATM row]; % column catenation

end

ATM=ATM'; % transpose for desired result

disp(ATM);

A1=ATM

A2 = [A1];

% input sensor x position

disp("Import sensor x pos from 1 to NoS--");

Sensxpos=[];

x1=importdata('C:\Users\Alphonce\Desktop\J C& G Submission\Book2.xlsx');

Sensxpos = x1(1:NoS,NoS+1);

while true

%str=input('','s');

%if isempty(str)

if NoS-1==NoS-1;

break;

end

[row,~,errmsg]=sscanf(str,'%f'); % getting row in column vector

if ~isempty(errmsg)

error(errmsg);

end

Sensxpos=[Sensxpos row]; % column catenation

end

Sensxpos=Sensxpos'; % transpose for desired result

disp(Sensxpos);

B=Sensxpos

B1 = [B];

% input sensor y position

disp("Import sensor y pos from 1 to NoS--");

Sensypos=[];

x2=importdata('C:\Users\Alphonce\Desktop\J C& G Submission\Book2.xlsx');

Sensypos = x2(1:NoS,NoS+2);

while true

%str=input('','s');

%if isempty(str)

if NoS-1==NoS-1;

break;

end

[row,~,errmsg]=sscanf(str,'%f'); % getting row in column vector

if ~isempty(errmsg)

error(errmsg);

end

Sensypos=[Sensypos row]; % column catenation

end

Sensypos=Sensypos'; % transpose for desired result

disp(Sensypos);

C=Sensypos

C1 = [C];

% input sensor z position

disp("Import sensor z pos from 1 to NoS--");

Senszpos=[];

x3=importdata('C:\Users\Alphonce\Desktop\J C& G Submission\Book2.xlsx');

Senszpos = x3(1:NoS,NoS+3);

while true

% str=input('','s');

% if isempty(str)

if NoS-1==NoS-1;

break;

end

[row,~,errmsg]=sscanf(str,'%f'); % getting row in column vector

if ~isempty(errmsg)

error(errmsg);

end

Senszpos=[Senszpos row]; % column catenation

end

Senszpos=Senszpos'; % transpose for desired result

disp(Senszpos);

D=Senszpos

D1 = [D];

% speed of sound in concrete. (longitudinal)

Ela = 40.4e15; den= 2190; % nu = 0.17; % E in Gpa den in Kg/m^3

c = sqrt(Ela/den);

c

syms Xcal Ycal Zcal t0

xj = B1(:);

yj = C1(:);

zj = D1(:)

tj = A1(:);

s2 = sum(eqns);

F = matlabFunction(s2.^2, 'vars', {[Xcal, Ycal, Zcal, t0]}, 'file', 's2.m', 'optimize', false)

x0=[0,0,0,0.01];

lb=[-35,-35,-20,-10];

ub=[35,35,20,10];

options = optimoptions('simulannealbnd','Display','Iter');

x = simulannealbnd(F,x0,lb,ub)

[x,fval,exitflag,output] = simulannealbnd(F,x0,lb,ub,options)

x1=x(1,1);

y1=x(1,2);

z1=x(1,3);

ts=x(1,4);

x1

y1

z1

ts

fid=fopen('myresult4.txt','a');

fprintf(fid,'%s\t',x1);

fprintf(fid,'%s\t',y1);

fprintf(fid,'%s\t',z1);

fprintf(fid,'%s\n',ts);

fclose(fid);

if i>=ne;

break;

end

end

end

Alphonce Owayo
on 8 Mar 2021

Walter Roberson
on 8 Mar 2021

Your code is confused

i=1

i=1;ne;

while i<ne;

for i=1:ne;

NoS==NoS;

At the end of the for i loop, i will be left as the last value it is assigned. Unless you modify i within the loop, that means that after for i=1:ne that i will be left as ne and then while i<ne would be false because i would equal ne. What is the point of having that while loop?

What is the point of having

i=1;ne;

which assigns 1 to i and prints nothing because of the semi-colon, then recalls ne and does no calculation with it, and then prints nothing because of the semi-colon ? The line could easily be mistaken for

i=1:ne;

but that would not be correct code because then i<ne would fail in the while

NoS==NoS;

What is the point of that?

if NoS-1==NoS-1;

What is the point of that test? The only time the test can fail is if NoS is empty, or NoS is NaN.

Alphonce Owayo
on 8 Mar 2021

Well I am still learning some of these things, thanks for pointing this out.

The idea is to set up a counter i from 1 to 1.5million

such that as long as i is less than 1.5 million it executes the while loop .

NoS==NoS; This is to ensure that while executing the loop you do not have to keep entering the value of NoS indicated in the input prompt1, once you start running its automatic.

if NoS-1==NoS-1; This is meant to let it know when to stop creating the array. Since the size of the array is determined by NoS. (its meant to say that if Columns(NoS-1) = NoS-1); stop picking the values and continue executing the rest of the code. For example if NoS is 8, it will pick from col 1 to col 8, it requires a condition such that it doesnt proceed to pick to col.9....

Alphonce Owayo
on 8 Mar 2021

Alphonce Owayo
on 8 Mar 2021

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

Select web siteYou can also select a web site from the following list:

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

- América Latina (Español)
- Canada (English)
- United States (English)

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)