0

Edit

To clarify. I have a function f that takes in 5 arguments z,x,y,n,m. The order of events should go as follows:

  1. Upon calling the function test, the variable z is assigned, say z = 1.

  2. A linear combination is created by adding f with with each of elements of ni inserted and the result is stored in fn, as such (z = 1, so no more z variable):

fn = x + 2.*y + exp(0) - sqrt(m) + x + 2.*y + exp(2) - sqrt(m) + x + 2.*y + exp(4) - sqrt(m) + x + 2.*y + exp(6) - sqrt(m) + x + 2.*y + exp(8) - sqrt(m) + x + 2.*y + exp(10) - sqrt(m) = 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(m) = 6*x + 12*y + 25473.8 - 6*sqrt(m)

  1. A linear combination is created by adding fn with each of elements of mi inserted and the result is stored in fnm. (I don't know how to do 1. and 2. simultaneously. If you do, please let me know):

fnm = 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(0) + 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(2) + 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(4) + 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(6) + 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(8) + 6*x + 12*y + 1 + exp(2) + exp(4) + exp(6) + exp(8) + exp(10) - 6*sqrt(10) = 6*x + 12*y + 25453.1

  1. A surface is plotted by plugging in x and y from arrays xi and yi into fnm

and of Edit

I'm having trouble with the double summation over the function f. I tried to follow the example in the last answer presented here, but it's not working for some reason. Because my variables x and y are not defined beforehand, I included them into @() in the arrayfun. I was first getting the error Z must be a matrix, not a scalar or vector. , so I changed the function handle fnm to a symbolic function after reading about it here. But now the whole thing exploded ... I don't know what's going on. Why is it saying there aren't enough inputs? fn should only be a function of x, y, m on line 11 since z is already defined to be some number (lets say 1) and n's just got summed over.

    function test(z)

f = @(z,x,y,n,m) z.*x + 2.*y + exp(n) - sqrt(m);

    function s(z)
        ni = 0:2:10;
        mi = 0:2:10;
        xi = -5:5;
        yi = -5:5;
        fn = @(n) arrayfun(@(z, x, y, ni, m) sum(f(z, x, y, ni, m)),n);
        fnm = @(m) arrayfun(@(x, y, mi) sum(fn(x, y, mi)),m);
        zz = sym(fnm);

        [xx,yy] = meshgrid(xi,yi);
        surf(xx,yy,zz)
    end

s
end

so many errors :(

    Error using test2>@(x,y,mi)sum(fn(x,y,mi)) (line 11)
Not enough input arguments.

Error in test2>@(m)arrayfun(@(x,y,mi)sum(fn(x,y,mi)),m) (line 11)
        fnm = @(m) arrayfun(@(x, y, mi) sum(fn(x, y, mi)),m);

Error in sym>funchandle2ref (line 1209)
    S = x(S{:});

Error in sym>tomupad (line 1114)
    x = funchandle2ref(x);

Error in sym (line 151)
                S.s = tomupad(x);

Error in test2/s (line 12)
        zz = sym(fnm);

Error in test2 (line 18)
s
Community
  • 1
  • 1
Raksha
  • 1,572
  • 2
  • 28
  • 53
  • Not quite sure what you are trying to do here, but `f()` takes 5 arguments, while in `fn()` you only give it four. Also, `sym(fnm)` makes no sense (1. fnm. requires an argument; 2. sym will try to turn the output if the function into a symbolic variable.). Could you explain what you're trying to do here? – Tamás Szabó May 25 '15 at 06:39
  • How many arguments do you want to enter yourself in this line: `fn = @(n) arrayfun(@(x, y, ni, m) sum(f(x, y, ni, m)),n);`? It seems as if you require 5 inputs, but you only ask for one. So you may want something more like `fn = @(n,x,y,ni,m) arrayfun(@(x, y, ni, m) sum(f(x, y, ni, m)),n);` and similar for the other function. – patrik May 25 '15 at 08:48
  • This row is also quite weird `zz = sym(fnm);`. Are you trying to work with numbers or symbols? – patrik May 25 '15 at 08:52
  • @patrik I updated my question to explain a bit more of what I'm trying to do. I'm trying to plug in numbers for variables in a symbolic expression. For some reason it wasn't working so well with a function handle. As far as plotting the surface, I was following an example here: https://www.youtube.com/watch?v=NkxRM6VbmW8 – Raksha May 25 '15 at 15:25
  • @TamásSzabó hm, I think you're right. I added `z`, but in line 11, function `fnm` should only have 3 variables since `z` and `n` are now assigned, right? I added a description of what I'm trying to do too. – Raksha May 25 '15 at 15:30
  • 1
    @Solarmew What I mean is that a call `@(n) arrayfun(@(z, x, y, ni, m) sum(f(z, x, y, ni, m)),n);` makes matlab expect to read 1 variable `n`. However, inside that function you have another function where Matlab expects to read another set of variables, `z, x, y, ni, m`. With this you explicitly say that in the call to `arrayfun` I will call 5 variables by using 5 inputs. However you only use 1 input `n`. This means that you have four undefined variables. Further, since `fnm` will be numeric unless you do `sym(fnm)` you do that. Then you use a function that assumes `zz` to be a discrete grid. – patrik May 25 '15 at 17:54
  • 1
    @Solarmew What you need to clarify is first if you want to use numerical calculations or symbolic calculations. Then you need to make sure that a variable defined with `@` will assume the variables within the parenthesis to be provided by the developer, `x=1; y=1; f1 = @(x,y,z) x*y*z; q=f1(1);%syntax error, too few input arguments; f2 = @(z) x*y*z; w=f2(1); %valid, assumes x to be 1 and y to be 1, w==1` – patrik May 25 '15 at 18:00
  • @patrik, I don't know :( I guess numeric? What's the difference if in the end I'm supposed to still get all numbers to plot? I added the extra variables fn = @(z, x, y, n, m) arrayfun(@(z, x, y, ni, m) sum(f(z, x, y, ni, m)),n); fnm = @(x, y, m) arrayfun(@(x, y, mi) sum(fn(x, y, mi)),m); but now the error is "Too many input arguments." – Raksha May 25 '15 at 18:09
  • Sorry I'm not getting it :( I learn better by example. Could someone please show me what the right code would look like? – Raksha May 25 '15 at 19:10
  • 1
    @Solarmew the "right code" is only right when used for the right purpose and your purpose is unfortunately a bit ambiguous, could you give a bit more details about what result you expect (expected output). Anyway, I am not sure why you get this error. Where do you get the error (edit the example)? Further, even if you actually gives more input arguments to the anonymous function, you need to give more information to `arrayfun` as well. You only define gives `z`. Do you know how `arrayfun` works? It would also be of help to give an example input. Also can nested functions be used that way? – patrik May 25 '15 at 20:07
  • 1
    @Solarmew Are you sure that a nested function is optimal here? It seems to me that you could define `f` inside `s`, or write `s` as a sub function to `test` instead. Regarding the sum, what is wrong with a for loop? You can also use `bsxfun` or a 3-dimensional matrix. All these are easier to use. It does also seem as if you have more than two dimensions before you sum so if you are unwilling to use a for loop you may get a higher dimensional matrix anyway. And by the way, I guess that `z` is not really the z-coordinate? This is hard to read since you use the z-axis in the plot. – patrik May 25 '15 at 20:22
  • @patrik, you're right, I wrote some nested for loops and it worked just fine. I guess I'm just so used to Mathematica and its shortcuts, I was hoping there was a more elegant, quick and dirty way to implement here as well. But for loops work as well. Thanks for bearing with me! – Raksha May 25 '15 at 21:05
  • 1
    @Solarmew there are of course other ways to do this if you try to do what I think you are. The problem is that sometimes it is easier to implement the brute force solution rather than spending a lot of time on vectorization for a doubtful gain (`arrayfun` is more or less a for loop in disguise). One for loop is not that bad. – patrik May 25 '15 at 21:48

1 Answers1

1

Are you trying to do this?. I am not optimizing anything, for you to understand it clearly....

function test(zi)
syms z x y n m fn fnm;
f0=symfun(z.*x + 2.*y + exp(n) - sqrt(m),[z x y n m]);
z=zi;
ni=0:2:10;
mi=0:2:10;
fn=0;
for i=1:length(ni);
    fn=symfun(fn+f0(z,x,y,ni(i),m),[x y m]);
end
fnm=0;
for i=1:length(mi)
    fnm=symfun(fnm+fn(x,y,mi(i)),[x y]);
end

xi=-5:5;
yi=-5:5;
for i=1:length(xi)
    for j=1:length(yi)
        zz(i,j)=eval(fnm(xi(i),yi(j)));
    end
end

[xx,yy]=meshgrid(xi,yi);
mesh(xx,yy,zz);

So, test(1) produces this:

enter image description here

Beware of the symfun calls, which shall be put there in order every summation keeps onto a "symbolic" framework. The arrayfun could be used, though they are neat, they could be not necesarily efficient... Let that exercise as homework!! XD..

Brethlosze
  • 1,533
  • 1
  • 22
  • 41