Error creating a function handle using str2func in a function

조회 수: 6 (최근 30일)
Joseph
Joseph 2011년 1월 20일
I have been having trouble using STR2FUNC to make a function handle for a string name in a function. It works properly if I add a break point and evaluate the same portion of code at the command line.
This problem comes about because I have created a number of different folders and generate functions of the same name in each folder (i.e FreeEnergy-> COg.m,CO2g.m ; Enthalpy-> COg.m, CO2g.m; Entropy-> COg.m, CO2g.m).
Each function each folder has different code, so I am trying to make a function handle to each and store it in a structure. I first switch the directory to the proper directory and use STR2FUNC to generate the function handle.
Example Code (in function file): cdir = pwd; ...
cd([cdir 'FreeEnergy'])
res(i).G=str2func(name);
functions(res(i).G)
Example Output:
function: 'COg'
type: 'simple'
file: ''
However, if I was to highlight "res(i).G=str2func(name); functions(res(i).G)" and evaluate it at the command line then it adds in the proper file path
Example Output:
function: 'COg'
type: 'simple'
file: 'C:Users\Joe\Documents\Matlab\FreeEnergy\COg.m'
The second is the proper output and does not generate unless I evaluate at the command line. I have no idea why this is happening. Is it a bug? If I was to run the same function again then it will also work properly, but involves a lot of time overhead for creating the individual function code from their symbolic variables. Any suggestions would be appreciated.
  댓글 수: 1
Oleg Komarov
Oleg Komarov 2011년 1월 20일
Can you post some more code...It's not obvious what you're trying to do.

댓글을 달려면 로그인하십시오.

채택된 답변

Philip Borghesani
Philip Borghesani 2011년 1월 21일
REHASH will work but it is a big hammer. A faster solution is to use exist which will force MATLAB to look on the disk for the file. WHICH will also to the job but EXIST allows a full file path to be specified.
function gencode
f=fopen('newcode.m','w');
fprintf(f,'function newcode\n');
fclose(f);
hf1=@newcode;
exist('newcode','file');
hf2=@newcode;
functions(hf1)
functions(hf2)
delete newcode.m
Output:
>> gencode
ans =
function: 'newcode'
type: 'simple'
file: ''
ans =
function: 'newcode'
type: 'simple'
file: 'h:\temp\newcode.m'
  댓글 수: 1
Joseph
Joseph 2011년 1월 21일
I appreciate your solution, it shed some light on the what was going on and was very efficient.

댓글을 달려면 로그인하십시오.

추가 답변 (3개)

Kenneth Eaton
Kenneth Eaton 2011년 1월 21일
The solution I found was to make a call to REHASH after you create each file. It appears that MATLAB needs a chance to update the list of known files before it can properly create a function handle for a newly-added function. Calling REHASH before generating each function handle will give you the proper file path, whether you are using STR2FUNC or EVAL as Walter suggested.
  댓글 수: 2
Walter Roberson
Walter Roberson 2011년 1월 21일
You are correct, that would be needed when you create a function file. The original question did not mention that the files were being generated inside of Matlab.
Joseph
Joseph 2011년 1월 21일
Thank you for your help.

댓글을 달려면 로그인하십시오.


Walter Roberson
Walter Roberson 2011년 1월 20일
Perhaps cd to where you need to and then,
res(i).G = eval(['@' name]);
I know eval() is not the greatest of tools, but if it works...
  댓글 수: 1
Joseph
Joseph 2011년 1월 20일
I tried this approach and also tried eval'ing the whole expression as "eval('res(i).G = str2func(name)')", but neither worked. However, I noticed that if I put a break point and step through the code at "res(i).G=str2func(name)" then it works properly (i.e. giving the full path name, allowing for the function call outside the scope of the original function handle evaluation). That is my reasoning that it might be a bug, because I eliminated the command line evaluation that previously showed correct results. Obviously stepping through the code every time is not a solution.

댓글을 달려면 로그인하십시오.


Joseph
Joseph 2011년 1월 21일
%res is a structure with fields (name,Cp_R,H_RT,S_R,G_RT,Cp,H,S,G)
%fields Cp_R,H_RT,S_R,G_RT are peicewise symbolic variables
%fields Cp,H,S,G are initial empty
%Generates C code, converts it to matlab code that can evaluate arrays
%of arbitrary length
funcdir = pwd;
for i=1:length(res)
for k=1:4
switch k
case 1
cd([fundir '\GibbsFreeEnergy']);
funcode = ccode(res(i).G_RT);
case 2
cd([fundir '\Enthalpy']);
funcode = ccode(res(i).H_RT);
case 3
cd([fundir '\Entropy']);
funcode = ccode(res(i).S_R);
case 4
cd([fundir '\SpecificHeat']);
funcode = ccode(res(i).Cp_R);
end
%The following code to convert the piecewise C code to the proper matlab syntax is omitted (matlabFunction doesn't work for piecewise functions).
%Write string to m-file with the name from the res(i).Name into the appropriate folder
name = res(i).Name;
fid = fopen([name '.m'],'w+');
fprintf(fid,funcode);
fclose(fid)
switch k
case 1
res(i).G=str2func(name);
functions(res(i).G)
case 2
res(i).H=str2func(name);
functions(res(i).H)
case 3
res(i).S=str2func(name);
functions(res(i).S)
case 4
res(i).Cp=str2func(name);
functions(res(i).Cp)
end
end
end
%If I put a break point at the str2func lines in the second switch-case block and step through the code it will create the required output, if I run the code with no break points then it will generate the code with " file = '' " after evaluating "functions()"

카테고리

Help CenterFile Exchange에서 Function Handles에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by