Matlab: how to work with different outputs of function - matlab

I've got the function
function [imag2] = sumIntegral(x,w,a,b,c,p)
imag2 = zeros(p-1,p);
for k = 1:p-1
f = #(t)(1:p-1==k)*Integrand[1](t,x,w,a,b,c);
imag2(k,:) = quadv(f,x(k),x(k+1));
end
whereas
Integrand[1] should be real2 of this function
[real2,real3,imag2,imag3] = Integrand(t,x,w,a,b,c,p);
The problem is, if I define the Integrand function before, I get an error, as t is undefined. Do you know how to write real2 as a function in t?

Simply define your quick function out of the for loop
function [imag2] = sumIntegral(x,w,a,b,c,p)
imag2 = zeros(p-1,p);
f = #(t)(1:p-1==k)*Integrand[1](t,x,w,a,b,c);
for k = 1:p-1
imag2(k,:) = quadv(f,x(k),x(k+1));
end
end

You could just make a dummy proxy function that only outputs the first argument:
function real2 = MyIntergrand(t,x,w,a,b,c)
real2 = Integrand(t,x,w,a,b,c);
end

Related

how to use colfilt\ bloc_proc my own function

I'm trying to use colfilt but instead using one line function I want to apply some condition, for example:
I2 = colfilt(I,[50 50],'sliding',own_func);
function own_func(block_struct)
mean(block_struct.data);
if(block_struct.data<6000)
block_struct.data=0;
else block_struct.data=255;
end
end
Is that possible?
function foo()
I = imread('tire.tif');
function y = complicated_function(x)
%column to number
y=mean(x);
end
I2 = uint8(colfilt(I,[5 5],'sliding',#complicated_function));
end

Matlab - Function taking no arguments within a class

As I do not seem to be able to edit my old question (Matlab - Function taking no arguments but not static), here it is again:
I am trying to implement the following:
classdef asset
properties
name
values
end
methods
function AS = asset(name, values)
AS.name = name;
AS.values = values;
end
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
end
But I am getting the error that somefunction1 should be static. But if it's static then it can't access the properties anymore. How would I resolve this issue?
Basically I want to be able to write something like this:
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
as opposed to writing
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1(AS);
For accessing the properties of an object in a method, you need to pass that object as argument to the method. If you don't need a specific object in order to perform a function, then make it static (belongs to the class, but does not operate on a specific object).
So, compare the original code:
methods
% ...
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end;
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
with the correct code:
methods
% ...
% this function needs an object to get the data from,
% so it's not static, and has the object as parameter.
function out = somefunction1(obj)
ret = asset.somefunction2(obj.values);
out = mean(ret);
end;
end;
methods(Static)
% this function doesn't depend on a specific object,
% so it's static.
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end;
end;
end;
To call the method, you'd write indeed (please test):
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
because, in MATLAB, this is 99.99% of cases equivalent to:
AS = asset('testname',[1 2 3 4 5]);
output = somefunction1(AS);
The differences appear when you're overriding subsref for the class, or when the object passed to the method is not the first in the argument list (but these are cases that you should not concern with for now, until you clarify the MATLAB class semantics).

matlab function inside while loop

I've created this small program just for simplicity of the question, I am having some trouble using my function inside a while loop
this is the script;
x = 1;
y = 1;
while x<10
y = func(x,y);
x = x + 1;
this is the function, func;
function [] = func(x,y)
y- exp(-x)
end
I get the error of
Error using func
Too many output arguments.
what am I doing wrong
When you declare the function:
function [] = func(x,y)
You have specified that there will be no return values, yet when you call it you require a return value:
y = func(x,y);
To fix this issue you must alter your function declaration, e.g.:
function y_out = func(x,y)
Also, within your function declaration you have y- exp(-x), which will not change the value of y; did you intend to have y=exp(-x)?

First input must be function handle error using arrayfun()

I'm trying to use arrayfun() to map a function over a cell array. The following is happening:
>> arrayfun(solveFunc, equArray)
Error using arrayfun
First input must be a function handle.
Error in solve>genGuess (line 33)
funcVals = abs(arrayfun(inFunc, xValues));
Error in solve (line 8)
x = genGuess(inFunc, varargin{1}, varargin{2});
Error in makeSolveFunc>#(func)solve(func,start,stop) (line 3)
sFunc = #(func) solve(func, start, stop);
But, the first input IS a function handle. Also... if I manually apply the function to each element of the provided cell array, everything works fine:
>> solveFunc(equArray{1})
ans =
4.7335
>> solveFunc(equArray{2})
ans =
4.7356
Does anyone know why this would be happening? I assumed that if I could manually apply the function to each element of my array, and the return type of the function was consistent and one of the allowed types (you can't for example have arrayfun return an array of function handles... I already tried doing that), it should work. Perhaps that is not the only requirement.
Here is some code that generates this error:
solve.m
function solution = solve(inFunc, start, stop)
%SOLVE solve an equation using Newton's Method
x = genGuess(inFunc, start, stop);
for i = 1:100
m = getSlope(inFunc, x);
x = (m*x - inFunc(x))/m;
end
solution = x;
end
function slope = getSlope(inFunc, x)
%SLOPE calculate the slope at a given point
inc = 1e-5;
if x ~= 0
inc = inc * x;
end
slope = (inFunc(x + inc) - inFunc(x - inc))/(2*inc);
end
function guess = genGuess(inFunc, start, stop)
%GENGUESS get an initial guess to the solution
xValues = linspace(start, stop, 101);
funcVals = abs(arrayfun(inFunc, xValues));
[~, minIndex] = min(funcVals);
guess = xValues(minIndex);
end
charEqu.m
function equ = charEqu(a)
%CHAREQU create a KP model characteristic equation with provided p
equ = #(x) x + a;
end
makeSolveFunc.m
function sFunc = makeSolveFunc(start, stop)
%MAKESOLVEFUNC return a function that solves an equation
sFunc = #(func) solve(func, start, stop);
end
test.m
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = arrayfun(solveFunc, equArray);
I have narrowed down the error to something in genGuess(). For some reason, in the line funcVals = abs(arrayfun(inFunc, xValues)); the variable inFunc is a 1x1 cell array containing a function handle. I have no idea why that would be the case. I traced this back to the anonymous function call #(func) solve(func, start, stop); in the makeSolveFunc() function. There it is still a 1x1 cell array containing a function handle. I'm not really sure where that cell array is coming from as that function is getting called from arrayfun().
Background information on what I'm trying to do in case someone wants to suggest a better way:
I'm trying to solve equations using Newton's method. I have written a function that can solve an equation given an initial guess range. This function is the solve() function you can see in the first error message. It takes a function, and the guess range and returns a function that I'm calling solveFunc(). solveFunc() takes a function and solves it using the initial guess range previously provided.
Maybe I'm just too used to functional programming and should just use a loop.
If the arguments passed to the function handle are contents of elements of a cell array, you need to use cellfun instead of arrayfun:
cellfun(solveFunc, equArray)
This is equivalent to
for i=1:length(equArray)
out(i) = solveFunc(equArray{i});
end
since solveFunc is already a function handle.
Check where the error comes from. This line causes the error:
funcVals = abs(arrayfun(inFunc, xValues));
The first input argument is a 1x1 cell containing one function handle. This is caused because equArray is a cell, thus use cellfun as Jonas already mentioned:
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = cellfun(solveFunc, equArray);

Function handler

I'm using two distinct functions on matlab: function1 and function2 (each written in a different script).
In the script of function1, I have something like:
function result = function1(y,z)
result = function2(#(x)do_this(x,y,z), #(f)do_that(f,y,z))
function f = do_this(x,y,z)
f = operationOn(x,y,z)
end
function d = do_that(f,x,z)
d = operationOn(f,y,z)
end
end
and in function2's script, I have:
function otherResult = function2(do_this, do_that)
m = matrix;
p = do_this(m)
otherResult = do_that(p)
end
I found that I have a problem in function2, since whenever I try to display p (the result of the function do_this defined in the script1), the value I get is NaN.
I can't see where is the problem? Am I using function handlers in an incorrect way?
Thanks for your help