I have the following code:
s(i+1)=NRK(Dt*f(tv(i+1),x)+s(i)-x,s(i));
Where NRK=NRK(function , numeric scalar) This was the symbolic implementation, with f=symbolic function, and x a symbolic array of unknowns.
The thing is that working with symbolic expressions can solve the issue, but this goes inside a loop, and symbolic tools slow down suprisingly the performance in a ratio of 100 times! However, anonymous functions do a perfect job.
My try was the following:
h=#([arguments (i.e. a, b, c, ...])Dt*f(t(i+1),[arguments (i.e. a, b, c,...])+s(i)-[a b c ...];
s(i+1)=NRK(#h,s(i));
How can I write these arguments? Is it possible?
You can specify them in the parenthesis:
h = #( a, b, c ) Dt*f( t(ii+1), a, b, c ) + s(ii);
Then call
s(ii+1) = NRK( h, s(ii) );
Some remarks:
- You do not need to write an extra # when providing h to NRK, since h is already defined as a function handle.
- It is best not to use i as a variable name in Matlab.
Related
I've been trying to plot a graph of function f(x) on interval 0,6. For some reason maple doesn't plot the graph when I use 'f(x)' as an argument. It works fine when I substitute assigned function as an argument. What can be the reason? How can I plot it using 'f(x)' as an argument?
My code is as follows and the error is on the pictures:
mystep:=proc(x,a,b,c)
if x<a
then
b;
else
c;
end if:
end proc:
f(x):=mystep(x,3,-2,7);
plot('f(x)', x=0..6);
enter image description here
Your syntax for creation of the operator (that you hope to assign to f) is incorrect for 1D plaintext input.
Here is the usual syntax for creation of such an operator, and assignment to name f.
restart;
mystep:=proc(x,a,b,c)
if x<a then b; else c; end if:
end proc:
f:=x->mystep(x,3,-2,7);
These should now all work as you expect.
plot('f(x)', x=0..6);
plot(f, 0..6);
plot(x->mystep(x,3,-2,7), 0..6);
In recent versions of Maple the syntax that you used can work in (only) 2D Input mode. But it is a poor syntax to use, since is easily confused with the 1D syntax for assigning into the remember table of an operator (and with even more confusion ensuing). You should avoid ambiguous syntax.
The type of function you have is piecewise-defined function (see this wikipedia page https://en.wikipedia.org/wiki/Piecewise). And in Maple there is already a command for defining this type of a function, piecewise, see its help page for a complete explanation of how to use it. Now for your mysetup, you have a condition x < a, and a value for when this happens, b, and a value for otherwise, c. So you want piecewise( x < a, b, c ). I think it is better to just use this command, but if it is really necessary to define a new procedure, then your mysetup becomes like the following.
mystep := proc(x, a, b, c)
return( piecewise( x < a, b, c ) ):
end proc:
Now for your plot you can use either
plot( piecewise( x < 3, -2, 7 ), x = 0..6 );
or
f(x) := mystep(x, 3, -2, 7);
plot( f(x), x = 0..6);
Suppose I have a function f(x) defined, which gives nan when it is very large, say x>100. Fortunately, when x>100, I can replace f by another function g. So I would like to define:
h = #(x)isnan(f(x)).*f(x)+isnan(f(x)).*g(x)
However, when I substitute h(1001), it gives nan. Is it possible to define h so that it gives g(1001) instead of nan? The only restriction is that I need to have anonymous function h for later use, say I would like to use it in integration, i.e., integral(h,0,inf).
Example: Suppose I have a function:
f = #(x)x.*1./x
This function is very easy and must be 1. I construct a function:
g = #(x)isnan(f(x)).*0+isnan(f(x)).*1
How to make g to be well defined so that I can still evaluate integral(g,-1,1)? For this example, I know I can evaluate it easily, but my restriction is that I need to define anonymous function g and use integral to do it.
You would need to make a regular function and wrap it with the anonymous function.
i.e.
function r = ternary(a, b, c)
if (a)
r = b;
else
r = c;
end
end
h = #(x)ternary(isnan(f(x)), g(x), f(x));
Note that this will evaluate your function twice. A less generalized solution for your particular case that won't evaluate the function twice.
function r = avoidNAN(a, b)
if (isnan(a))
r = b;
else
r = a;
end
end
There is a solution without any additional functions:
f = #(x)x.*1./x;
g = #(x)100+x;
h= #(x)getfield(struct('a',f(x),'b',g(x)),char(isnan(f(x))+'a'))
I'd like to compare multiple, 2-dimensional logical variables with each other. I can think of solving this problem with a loop, however I suspect it could be done with inbuilt functions.
Do I need an extra function or can this be achieved using inbuilt functions?
Code:
a=logical(randi([0 1],5,5));
b=logical(randi([0 1],5,5));
c=logical(randi([0 1],5,5));
%d,e,f... etc.
and(a,b,c)
However this gives you an error:
Error using &
Too many input arguments.
Working loop solution:
%example function to solve this
function out=extended_and(varargin)
out=varargin{1};
for ind=2:numel(varargin)
out=out & varargin{ind};
end
end
If a, b, c (d, e, f) are all related, they should be in the same array. Something like:
L(:,:,1)=logical(randi([0 1],5,5));
L(:,:,2)=logical(randi([0 1],5,5));
L(:,:,3)=logical(randi([0 1],5,5));
%L(:,:,4)... etc.
%or, more simply:
% L = logical(randi([0 1], 5, 5, 327)); or however may arrays you want
Then you can use all:
R = all(L, 3);
If you have to have a, b, c, ... you can concatenate them first:
L = cat(3, a, b, c);
I am writing a program in Matlab and I have a function defined this way.
sum (i=1...100) (a*x(i) + b*y(i) + c)
x and y are known, while a, b and c are not: I need to find values for them such that the total value of the function is minimized. There is no additional constraint for the problem.
I thought of using fminsearch to solve this minimization problem, but from Mathworks I get that functions which are suitable inputs for fminsearch are defined like this (an example):
square = #(x) x.^2
So in my case I could use a vector p=[a, b, c] as the value to minimize, but then I don't know how to define the remaining part of the function. As you can see the number of possible values for the index i is huge, so I cannot simply sum everything together explicitly, but I need to represent the summation in some way. If I write the function somewhere else then I am forced to use symbolic calculus for a, b and c (declaring them with syms) and I'm not sure fminsearch would accept that.
What can I do? Of course if fminsearch turns out to be unfeasible for my situation I accept links to use something else.
The most general solution is to use x and y in the definition of the objective function:
>> objfun = #(p) sum( p(1).*x + p(2).*y + p(3) );
>> optp = fminsearch( objfun, po, ... );
Suppose I have a heavy-duty workhorse of a function:
[a b c d] = lotsOfComputation();
In some use cases, I may only need one or two of its outputs. In those cases, I ignore the output with a ~. Is it possible to detect this from within the lostOfComputation function?
(Yes, I know the more elegant solution is a refactor into separate functions. I have already done this for the immediate use-case, but the question remained in my head.)
Sure, try nargout, it returns the number of output arguments. Well, actually that will work when the argument is omitted, but it will count ~ as an argument. Here's an example:
function [a b c] = test()
a=0;b=0;c=0;
disp(nargout);
end
>> [a, b] = test();
2
>> [~, b] = test();
2
>> [~, ~, ~] = test();
3
So perhaps the answer to your exact question is no, at least not with nargout.
To answer your question directly, not that I know.
However, if you are asking this to save potentially wasted computation you could split your function into sub-functions, but retain the general syntax in your original post using deal.
For example, if you always wanted a and b from lotsOfComputation, you could remake your function as
[a b] = lotsOfComputation();
you could then have two separate computations for c and d
[c] = cComp();
[d] = dComp();
you could then write your original functions as
[a b c d] = deal(lotsOfComputation(), cComp(), dComp());
If you wanted to ignore the output of c or d, you could replace the function calls with a null value in the deal function, i.e.
[a b ~ d] = deal(lotsOfComputation(), 0, dComp());
I know that this doesn't directly answer the question, but it might be of theoretical interest :)