Expanding anonymous function into a string - string

I have a set of anonymous functions, and I want to convert them into strings. Normally I would just use func2str, but the problem is I want the variables and internal functions to be expanded out into their "true" values. The problem I'm running into is that MATLAB is keeping these by the names, but recognizing the values. Example
classdef Bclass
properties
equation
end
function obj = Bclass(inEquation, inValue)
obj.equation = #(t,y) inEquation(t,y) * inValue;
end
function out = getStr(obj)
out = func2str(obj.equation);
end
end
The problem is that the func2str call is outputting #(t,y) inEquation(t,y) * inValue, when I actually want it to output something like #(t,y) t*y * 5, if we had said b = Bclass(#(t,y) t*y, 5).
Is there a way to retrieve these variable values from MATLAB?

You can do this, but it could quickly become very difficult if your problem becomes any more complex than the example given above (i.e. more complicated anonymous functions, multiple nesting levels, etc.). You'll have to make use of the functions function to get information on the function handle, and its behavior may change between releases. Additionally, you'll have to do quite a bit of string manipulation (using functions like regexp, regexprep, strsplit, and strrep, as I do below).
I've tried to include here the most general approach I could, allowing for the following possibilities:
inEquation can be a non-anonymous function handle (i.e. #times).
inEquation can simply be passed along as is without actually being invoked.
inEquation can be called multiple times in the anonymous function.
The input arguments to inEquation can be named differently than what it is invoked with in obj.equation.
obj.equation can contain indexing operations.
First, we'll initialize some variables to mimic your example:
f1 = #(m, n) m*n; % Note the different variable names, but it will still work
inEquation = f1;
inValue = 5;
f2 = #(t, y) inEquation(t, y)*inValue; % Function constructed using workspace variables
Next, we'll get the function information for f2:
s = functions(f2);
varNames = fieldnames(s.workspace{1});
varValues = struct2cell(s.workspace{1});
out = s.function;
The workspace field holds the variable names and values that were used to construct f2, and the function field is the string you'd get by calling func2str on f2. We'll also need to compute a few things so we can correctly parse opening and closing parentheses in f2:
openIndex = (out == '(');
closeIndex = (out == ')');
parenIndex = cumsum(openIndex-[false closeIndex(1:end-1)]).*(openIndex | closeIndex);
Now, we'll loop over the workspace variables, convert their values to strings (if possible), and replace them in out:
for iVar = 1:numel(varNames)
name = varNames{iVar};
value = varValues{iVar};
if isa(value, 'function_handle') % Workspace variable is a function handle
value = func2str(value);
callIndex = strfind(out, [name, '('])+numel(name);
fcnParts = regexp(value, '#\({1}([^\)])*\){1}(\S)*', 'once', 'tokens');
if isempty(callIndex) % Function handle is not invoked
if isempty(fcnParts) % Non-anonymous function handle (i.e. #times)
value = ['#' value];
end
out = strrep(out, name, value);
elseif isempty(fcnParts) % Invoked function handle (i.e. #times)
out = strrep(out, name, value);
else % Invoked anonymous function handle
for iCall = callIndex
args = out(iCall+(1:find(parenIndex(iCall+1:end) == parenIndex(iCall), 1)-1));
value = regexprep(fcnParts{2}, ...
strcat('(?<!\w)', strsplit(fcnParts{1}, ','), '(?!\w)'), ...
strsplit(args, ','));
out = strrep(out, [name, '(', args, ')'], value);
end
end
elseif isnumeric(value) && isscalar(value) % Workspace variable is a numeric scalar
out = strrep(out, name, num2str(value));
end
end
And we get the desired result for out:
>> out
out =
#(t,y)t*y*5
Note that this will also work as expected with a non-anonymous function handle as well:
>> f1 = #times;
>> inEquation = f1;
>> inValue = 5;
>> f2 = #(t, y) inEquation(t, y)*inValue;
% Repeat above processing...
>> out
out =
#(t,y)times(t,y)*5
It will also work on some more complicated functions:
>> postVolt = #(g, V) -.05*g*(V+80);
>> preIdx = 5;
>> postIdx = 1;
>> index = 6;
>> obj.values = {};
>> f2 = #(t) postVolt(obj.values{preIdx}(index), obj.values{preIdx}(obj.voltIdx{postIdx}));
% Repeat above processing...
>> out
out =
#(t)-.05*obj.values{5}(6)*(obj.values{5}(obj.voltIdx{1})+80)

Related

Does not string.gmatch() return nil in Lua?

local str = ",23,4"
local t = {}
local i = 1
for temp in str:gmatch("[^,]+") do
t[i] = temp
i = i + 1
end
I'm a Lua newbie. Here is my code. I expected that t[1] has nil. However, gmatch() skipped it instead of returning nil. Tabel t[] has only two key-values. If I make table t[] like this
t[1] = nil
t[2] = 23
t[3] = 4
, how do I use gmatch()? Or what function do I have to use?
gmatch() didn't skip anything; it did exactly what you told it to: it found every occurrance of "[^,]+", of which there are two, and handed each of them to the loop body.
If you want to match empty strings as well, you can change your pattern to "[^,]*".
+ matches one or more
* matches zero or more
Please refer to https://www.lua.org/manual/5.3/manual.html#6.4.1

Save variables to file at runtime

I'm looking for some functionality in Julia comparable to Matlab's
save('myfile.mat', 'myvar1', 'myvar2')
For example, using HDF5.jl, it is easy to do
#write filename myvar1 myvar2
But this requires that I know exactly which variables I want to write to the file.
I'd like to be able to choose which variables to write at run time, in a function scope, and specify their names using symbols or strings.
vars = [:myvar1, :myvar2]
#write filename vars
What would be the best way to accomplish this?
EDIT
I know that I can use save from JLD.jl as save("file.jld", "myvar1", myvar1). But I want to be able to save a list of variables that are not known at compile time, allowing a single call to save (or similar):
if condition
myvar1 = 1
vars = [:myvar1]
else
myvar1 = 1
myvar2 = 2
vars = [:myvar1, :myvar2]
end
# what goes here?
save(filename, vars...)
You may want to take a look at the JLD package, which builds on HDF5 with better support of user-defined Julia types. Both HDF5 and JLD provide functions for save that take run-time names for variables.
You can use serialize and deserialize:
vars = Dict()
if condition
myvar = 1
vars[:myvar1] = myvar1
else
myvar1 = 1
myvar2 = 2
vars[:myvar1] = myvar1
vars[:myvar2] = myvar2
end
f = open( filename, "w" )
serialize( f, vars )
close( f )
to read:
f = open( filename, "r" )
vars = deserialize( f )
close( f )
if you don't need to save variable names you can use array instead of dict: vars = []

Converting a string to an expression in MATLAB

I'm writing a small MATLAB package and I'd like to ask for user input for a function. So if the user enters:
x.^2 + sin(x)
I want to use this user input to appear elsewhere in the code, but x would already be defined and so the expression above would be a vector (or scalar if length(x) is 1).
You can use the eval function for this. For example:
>> x = 5
x =
5
>> eval('x*3')
ans =
15
You can create a function handle:
% some variable you already defined
myVar = 5;
% Create an anonymous function in some z
f = str2func('#(z) z.^2 + sin(z)');
% Call function supplying the input
f(myVar)

how to extracted updated string after calling string.gsub in lua?

Problem Description:
HI there. I'm trying to figure out how to use the lua function "string.gsub". I've been reading the manual which says:
This is a very powerful function and can be used in multiple ways.
Used simply it can replace all instances of the pattern provided with
the replacement. A pair of values is returned, the modified string and
the number of substitutions made. The optional fourth argument n can
be used to limit the number of substitutions made:
> = string.gsub("Hello banana", "banana", "Lua user")
Hello Lua user 1
> = string.gsub("banana", "a", "A", 2) -- limit substitutions made to 2
bAnAna 2
Question
When it says that a pair of values is returned; how do I get the new string value?
Code
local email_filename = "/var/log/test.txt"
local email_contents_file_exists = function(filename)
file = io.open(filename, "r")
if file == nil then
return false
else
file.close(file)
return true
end
end
local read_email_contents_file = function()
print('inside the function')
if not email_contents_file_exists(email_filename) then
return false
end
local f = io.open(email_filename, "rb")
local content = f:read("*all")
f:close()
print(content)
--content = string.gsub(content, '[username]', 'myusername')
--local tmp {}
--tmp = string.gsub(content, '[username]', 'myusername')
print(string.gsub(content, '[username]', 'myusername'))
return content
end
local test = read_email_contents_file()
What I've Tried So Far:
I've tried just printing the results, as you see above. That returns a bunch of garbled text. Tried saving to original string and I've also tried saving the results to an array (local tmp = {})
Any suggestions?
> = string.gsub('banana', 'a', 'A', 2)
bAnAna 2
> = (string.gsub('banana', 'a', 'A', 2))
bAnAna
You were going pretty good with reading the Lua users wiki.
In Lua, when you a function returns more than one value, you can access them all as follows
function sth()
return 1, "hi", false
end
x, y, z, a, b, c = sth() -- x = 1; y = "hi" and z = false(boolean); a = b = c = nil
Now, coming back to string.gsub function. It returns two values. The first being the processed string and the second being the number of time gsub performed itself on the input string.
So, to get the new string value, something like this would be best:
local tempString = string.gsub(content, '[username]', 'myusername')
OR
local tempString = content:gsub( '[username]', 'myusername' )
Ofcourse, here, you need to be aware about the various patterns used in Lua which are mentioned in the Programming in Lua book.
You need to escape [ and ] because they are magic characters in Lua patterns.

MATLAB generate combination from a string

I've a string like this "FBECGHD" and i need to use MATLAB and generate all the required possible permutations? In there a specific MATLAB function that does this task or should I define a custom MATLAB function that perform this task?
Use the perms function. A string in matlab is a list of characters, so it will permute them:
A = 'FBECGHD';
perms(A)
You can also store the output (e.g. P = perms(A)), and, if A is an N-character string, P is a N!-by-N array, where each row corresponds to a permutation.
If you are interested in unique permutations, you can use:
unique(perms(A), 'rows')
to remove duplicates (otherwise something like 'ABB' would give 6 results, instead of the 3 that you might expect).
As Richante answered, P = perms(A) is very handy for this. You may also notice that P is of type char and it's not convenient to subset/select individual permutation. Below worked for me:
str = 'FBECGHD';
A = perms(str);
B = cellstr(reshape(A,7,[])');
C = unique(B);
It also appears that unique(A, 'rows') is not removing duplicate values:
>> A=[11, 11];
>> unique(A, 'rows')
ans =
11 11
However, unique(A) would:
>> unique(A)
ans =
11
I am not a matlab pro by any means and I didn't investigate this exhaustively but at least in some cases it appears that reshape is not what you want. Notice that below gives 999 and 191 as permutations of 199 which isn't true. The reshape function as written appears to operate "column-wise" on A:
>> str = '199';
A = perms(str);
B = cellstr(reshape(A,3,[])');
C = unique(B);
>> C
C =
'191'
'199'
'911'
'919'
'999'
Below does not produce 999 or 191:
B = {};
index = 1;
while true
try
substring = A(index,:);
B{index}=substring;
index = index + 1;
catch
break
end
end
C = unique(B)
C =
'199' '919' '991'

Resources