can I use a compiled (.exe) file to generate my objective functions while running optimisation in MATLAB?

I have developed a Fortran code which simulates a thermodynamic cycle. I want to optimise the cycle for few objectives (like cost, efficiency etc.). My Fortran program reads design variables [X] from a file and writes the objectives values F[X] in a separate file. I can call the .exe file of my program in MATLAB and it communicates with the input and output files without problem. I want to see whether it is possible to call this .exe file to generate objective functions from [X] in each iteration of optimisation procedure? If yes, which types of optimisation solvers I may choose?

 Akzeptierte Antwort

Optimization functions like fminunc simply need a MATLAB function of the form y = f(x) to operate on. To interface with your external code, you should create a MATLAB function similar to the one below:
function y = myfun(x)
%write the x data
xh = fopen('x.txt', 'w');
fprintf(xh, '%f', x);
fclose(xh);
%run your program
system('yourProgram.exe');
%read the f data
fh = fopen('f.txt');
y = fscanf(fh, '%f');
fclose(fh);
Then use fminunc:
minunc(@myfun,x0);

6 Kommentare

Thanks Andrew, but when I use the function as you suggested, it returns an error:
At line 9 of file ../test2.f (unit = 11, file = 'x.txt')
Fortran runtime error: Bad real number in item 1 of list input
Error using fminunc (line 341)
User supplied objective function must return a scalar value.
I tested the function below as a sample to see if I can replace it with a compiled fortran program.
function f = myfun(x)
f = 3*x(1)^2 + 2*x(1)*x(2) + x(2)^2; % Cost function
This is the fortran program (test2.exe) to read x1 and x2 from x.txt and write the function result to f.txt:
program test2
implicit none
real y
real x
dimension x(2)
open (unit = 11, file = "x.txt", status= "old")
open (unit = 21, file = "f.txt", status= "replace")
read(11,*) x(1)
read(11,*) x(2)
y = 3*x(1)**2 + 2*x(1)*x(2) + x(2)**2
write(21,*) y
end program test2
and then used it as you suggested:
function y = myfun(x)
%write the x data
xh = fopen('x.txt', 'w');
fprintf(xh, '%f', x);
fclose(xh);
%run your program
system('test2.exe');
%read the f data
fh = fopen('f.txt');
y = fscanf(fh, '%f');
fclose(fh);
Any ideas what should I do?
Thanks Walter,
Changed it as:
fprintf(xh, '%10.6f %10.6f', x);
and also the read statement in Fortran program as:
read(11,*) x(1),x(2)
and it solved the problem. Your suggestion should also work. However, when I run fminunc, it stops after the first iteration saying that it has has reached the minimum.
Initial point is a local minimum.
Optimization completed because the size of the gradient at the initial point
is less than the default value of the function tolerance.
I know that this is not the minimum point. Can anyone advise please?
This message is not related to the use of the Fortran function, but instead the mathematical function and initial starting point of [0 0] that you chose. Notice that the same message appears when using the MATLAB function. Avoiding local minima solutions is one of the mathematical challenges in optimization problems.
Try some of the suggestions listed on the following page such as specifying a different starting point and checking nearby points. You also may want to look into the Global Optimization Toolbox which uses multistart solves to try and avoid converging on local minima.
Thanks
I used fminsearch instead and it worked with no problem either defining the function in MATLAB or calling a compiled Fortran .exe file. I also ran a two objective function optimisation and used "gamultiobj" (the example function given in MATLAB help). No problems and it works properly. Just two questions are still remaining:
1. why I can get correct answer with fminunc regardless of x0 value when define the function directly in MATLAB, but it has problems when calling .exe file? It only gives correct minimum when I choose x0 close enough.
2. Using .exe file increased the calculation time, especially in "gamultiobj". How can I reduce the time?
I'm going to ask this in a separate question.
fminunc is a local solver - thus it gets stuck in local minima, that is why you would need to have the initial conditions very close to the solution to actually find it in a non-convex problem. gamultiobj uses a genetic algorithm. They just inherently take quite a long time. Try ParetoSearch and see how that works, probably faster than gamultiobj

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Fortran with MATLAB finden Sie in Hilfe-Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by