Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

multiple outputs from a function

3,161 views
Skip to first unread message

Ben Barrowes

unread,
Dec 11, 2004, 6:08:01 AM12/11/04
to
I feel I must be missing something fundamental...

How do you write a function (or ?) in Mathematica which produces more
than one output?

Let's say I have some data and I want a single function to calculate the
mean, variance, std, etc, more than one thing and return those? I know
that there are builtin functions for those parameters, but the point is
I want to define functions with more than one output.

The only examples I can find are along the lines of:

f[x_,y_]:=x^2+y^2;

which have only a single result.

Is there a different structure altogether, such as a Subroutine, which
allows multiple results from a single subunit?

One thought I had was that because Mathematica treats everything as
global unless defined specifically local (e.g. in a module), that
variables used in a procedure would be accessible and would thus be a
"result", but it seems scoping problems would arise if this was used too
often. For example:

In[67]:=
t1[x_,y_]:=(a1=x^2+y;a2=x+y^2;x+y)

In[68]:=
t2=t1[5,6]

Out[68]=
11

In[69]:=
a1

Out[69]=
31

In[70]:=
a2

Out[70]=
41

Is this the accepted method for extracting multiple results from one
function definition?


Ben Barrowes

David Bailey

unread,
Dec 13, 2004, 4:40:30 AM12/13/04
to
Hi,

It is sometimes useful to arrange for data to come back in global
variables, as you have done - although it would be best to use more
distinctive names to avoid confusion. In most situations it is best to
return a list of items, or a structure - using a head with no
definition. Thus, in your case you might return something like

myStatics[5.2,1.1]

where the first number is the mean and the other is the standard
deviation. Obviously, you can extend this to return as much information
as you like.

Regards,

David Bailey

dbaileyconsultancy.co.uk

Dr. Wolfgang Hintze

unread,
Dec 13, 2004, 4:43:37 AM12/13/04
to
Ben,

just put the output in a list.
Here's an example which gives the first three powers of a variale x

Definition

In[9]:=
pow[x_] := {x, x^2, x^3}

Execution

In[10]:=
y = pow[8]

Result

Out[10]=
{8, 64, 512}

The specific components of the list can then be extracted one by one
using Part, or [[]]. Example: the second value is

In[13]:=
y[[2]]

Out[13]=
64

Hope this helps,
Wolfgang

Bob Hanlon

unread,
Dec 13, 2004, 4:46:48 AM12/13/04
to
Use a list.

stats[data_] := {mu -> Mean[data], sigma->StandardDeviation[data]}

data=Table[Random[],{100}];

stats[data]

{mu -> 0.5086542300219064, sigma -> 0.2993179460132339}


Bob Hanlon

Bill Rowe

unread,
Dec 13, 2004, 4:56:08 AM12/13/04
to
On 12/11/04 at 5:22 AM, barr...@alum.mit.edu (Ben Barrowes) wrote:

>I feel I must be missing something fundamental...

>How do you write a function (or ?) in Mathematica which produces
>more than one output?

>Let's say I have some data and I want a single function to
>calculate the mean, variance, std, etc, more than one thing and
>return those? I know that there are builtin functions for those
>parameters, but the point is I want to define functions with more
>than one output.

>The only examples I can find are along the lines of:

>f[x_,y_]:=x^2+y^2;

>which have only a single result.

>Is there a different structure altogether, such as a Subroutine,
>which allows multiple results from a single subunit?

The way I would do this is to return the results in a list.

>One thought I had was that because Mathematica treats everything as
>global unless defined specifically local (e.g. in a module), that
>variables used in a procedure would be accessible and would thus be
>a "result", but it seems scoping problems would arise if this was
>used too often. For example:

>In[67]:= t1[x_,y_]:=(a1=x^2+y;a2=x+y^2;x+y)

Instead try

t1[x_,y_]:={x^2+y, x+y^2, x+y}
{a1,a2,t2}=t1[5,6];

t2
11

a1
31

a2
41
--
To reply via email subtract one hundred and four

yehuda ben-shimol

unread,
Dec 13, 2004, 4:58:13 AM12/13/04
to
A function can return only one expression.
In order to use an expression that holds several results it should be a
List (not necessarily, but a common practice)
So, for a function f operating on a list of data elements use something
similar to
f[mydata_List]:={Mean[mydata], Var[mydata], Sqrt/@mydata, ...... (*as
many as you wish*) }

yehuda

Ben Barrowes wrote:

>I feel I must be missing something fundamental...
>
>How do you write a function (or ?) in Mathematica which produces more
>than one output?
>
>Let's say I have some data and I want a single function to calculate the
>mean, variance, std, etc, more than one thing and return those? I know
>that there are builtin functions for those parameters, but the point is
>I want to define functions with more than one output.
>
>The only examples I can find are along the lines of:
>
>f[x_,y_]:=x^2+y^2;
>
>which have only a single result.
>
>Is there a different structure altogether, such as a Subroutine, which
>allows multiple results from a single subunit?
>

>One thought I had was that because Mathematica treats everything as
>global unless defined specifically local (e.g. in a module), that
>variables used in a procedure would be accessible and would thus be a
>"result", but it seems scoping problems would arise if this was used too
>often. For example:
>
>In[67]:=
>t1[x_,y_]:=(a1=x^2+y;a2=x+y^2;x+y)
>

David Park

unread,
Dec 13, 2004, 5:00:21 AM12/13/04
to
Ben,

Just output a list.

squareandcube[x_] := {x^2, x^3}

If you want to further use the results you can use the function this way.

{x2, x3} = squareandcube[5]
{25, 125}

x3/x2
5

For a complicated calculation you can use a Module, assemble the various
results and then return them in a list.

f[x_]:=
Module[{result1, result2, result3},
result1 = (calculation);
result2 = (calculation);
result3 = (calculation);
{result1, result2, result3}]

Setting some of the results as a side effect is probably a poor method.

David Park
dj...@earthlink.net
http://home.earthlink.net/~djmp/

DrBob

unread,
Dec 13, 2004, 5:03:25 AM12/13/04
to
A function can't evaluate to more than one value, but it can evaluate to a List of values:

data = RandomArray[BinomialDistribution[12, .1], 12]
stats[s_] := {Mean@s, Variance@s, StandardDeviation@s}
stats@data

{0, 0, 3, 1, 0, 1, 1, 2, 2, 2, 2, 2}
{4/3, 32/33, 4*Sqrt[2/33]}

or

stats[s_] := Through[{Mean, Variance, StandardDeviation}@s]
stats@data

{4/3, 32/33, 4*Sqrt[2/33]}

or

stats[s_] := Thread[{Mean,
Variance, StandardDeviation} -> Through[{Mean,
Variance, StandardDeviation}@s]]
stats@data
Mean /. %

{Mean -> 4/3, Variance -> 32/33, StandardDeviation -> 4*Sqrt[2/33]}
4/3

Bobby

--
Dr...@bigfoot.com
www.eclecticdreams.net

Ben Kovitz

unread,
Dec 13, 2004, 5:14:53 AM12/13/04
to
On Dec 11, 2004, at 2:22 AM, Ben Barrowes wrote:

> How do you write a function (or ?) in Mathematica which produces more
> than one output?
>
> Let's say I have some data and I want a single function to calculate
> the
> mean, variance, std, etc, more than one thing and return those? I know
> that there are builtin functions for those parameters, but the point is
> I want to define functions with more than one output.

Perhaps you want to return a list. For example:

polarToXY[r_, c_] := {r Cos[c], r Sin[c]}

A list, indicated by braces, is "one thing" but it can contain as many
things as you like.


Ben Kovitz
Humboldt State University


David Annetts

unread,
Dec 13, 2004, 5:15:54 AM12/13/04
to
Hi Ben,

> I feel I must be missing something fundamental...
>

> How do you write a function (or ?) in Mathematica which
> produces more than one output?
>
> Let's say I have some data and I want a single function to
> calculate the mean, variance, std, etc, more than one thing
> and return those? I know that there are builtin functions for
> those parameters, but the point is I want to define functions
> with more than one output.
>

> The only examples I can find are along the lines of:
>
> f[x_,y_]:=x^2+y^2;
>
> which have only a single result.
>
> Is there a different structure altogether, such as a
> Subroutine, which allows multiple results from a single subunit?

Why not define your function

Needs["Statistics`"] (* to be safe ...*)
stats[x_List] := Module[
{local variables},

(* function body *)

Return[{mean, variance, std}];
];

Ie. A function that accepts a list and returns another list. The return
list has three elements, mean variance & std deviation of the original list.
Rephrasing this

mean = First[stats[yourList]];
var = stats[yourList][[2]];
std = Last[stats[yourList]];

Regards,

Dave.

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.296 / Virus Database: 265.5.0 - Release Date: 9/12/2004

John Jowett

unread,
Dec 14, 2004, 6:14:41 AM12/14/04
to
Hello,

As several people have pointed out, returning a list of values is probably
the most straightforward thing to do. It's fine as long as you know what the
elements in the list are supposed to be.

But another technique that is often useful is to return a list of rules. To
give a trivial example:

In[2]:=
f[x_,y_]:={sum->x+y,difference->x-y,product->x y, quotient-> x/y}

In[3]:=
f[1,2]

Out[3]=
{sum -> 3, difference -> -1, product -> 2, quotient -> 1/2}

These results can then be used in other expressions:

In[5]:=
(difference/sum)/.f[1,2]

Out[5]=
-1/3

For less trivial examples see the built-in function Solve or functions like
LocationReport in the standard package Statistics`DescriptiveStatistics`.

This is a way to provide a number of "named" results without worrying about
order in the list (in some other programming languages something similar is
achieved with so-called "associative arrays").

John Jowett

"Ben Barrowes" <barr...@alum.mit.edu> wrote in message
news:cpekeh$744$1...@smc.vnet.net...

DrBob

unread,
Dec 14, 2004, 6:22:50 AM12/14/04
to
Return is almost never needed, certainly not in this kind of function:

stats[x_List] := Module[{local variables},

(* function body *);
{mean, variance, std}
];

Bobby

On Mon, 13 Dec 2004 04:23:23 -0500 (EST), David Annetts <davida...@ihug.com.au> wrote:

>
>
> Hi Ben,


>
>> I feel I must be missing something fundamental...
>>
>> How do you write a function (or ?) in Mathematica which
>> produces more than one output?
>>
>> Let's say I have some data and I want a single function to
>> calculate the mean, variance, std, etc, more than one thing
>> and return those? I know that there are builtin functions for
>> those parameters, but the point is I want to define functions
>> with more than one output.
>>
>> The only examples I can find are along the lines of:
>>
>> f[x_,y_]:=x^2+y^2;
>>
>> which have only a single result.
>>
>> Is there a different structure altogether, such as a
>> Subroutine, which allows multiple results from a single subunit?
>

> Why not define your function
>
> Needs["Statistics`"] (* to be safe ...*)
> stats[x_List] := Module[
> {local variables},
>
> (* function body *)
>
> Return[{mean, variance, std}];
> ];
>
> Ie. A function that accepts a list and returns another list. The return
> list has three elements, mean variance & std deviation of the original list.
> Rephrasing this
>
> mean = First[stats[yourList]];
> var = stats[yourList][[2]];
> std = Last[stats[yourList]];
>
> Regards,
>
> Dave.
>

--
Dr...@bigfoot.com
www.eclecticdreams.net

David Annetts

unread,
Dec 14, 2004, 6:32:07 AM12/14/04
to
Insofar as Mathematica is concerned, no, it is not needed. Indeed, as others have
pointed out, the entire Module[] can also be avoided.

As a clear statement that a list (or any other variable) is returned from a
Module[] or Block[], it is invaluable. In my experience, simple defensive
things like this save hours (or worse) trying to debug code. Leave it out
if you want.

Dave.

> -----Original Message-----
> From: DrBob [mailto:dr...@bigfoot.com]
> Sent: Tuesday, 14 December 2004 07:55
> To: David Annetts; math...@smc.vnet.net
> Subject: Re: multiple outputs from a function
>
> Return is almost never needed, certainly not in this kind of function:
>
> stats[x_List] := Module[{local variables},
> (* function body *);
> {mean, variance, std}
> ];
>
> Bobby

--

No virus found in this outgoing message.
Checked by AVG Anti-Virus.

Version: 7.0.296 / Virus Database: 265.5.2 - Release Date: 13/12/2004

pa...@cwgsy.net

unread,
Dec 15, 2004, 4:32:10 AM12/15/04
to
Don't know if you have a solution already, but i would use:

t1[x_,y_]:={x^2+y,x+y^2,x+y};

{a1,a2,a3}=t1[var1,var2]
This will set a1, a2 and a3 as parts 1,2 and 3 in the list.

DrBob

unread,
Dec 15, 2004, 4:43:19 AM12/15/04
to
>> Indeed, as others have pointed out, the entire Module[] can also be avoided.

On the contrary, Module is often totally necessary; it controls scoping so that we can avoid conflicts with Global variables.

But Return is never necessary, and it allows (even encourages) writing spaghetti code with multiple return points. You may avoid that pitfall, but Return is a temptation that will lure others into the trap.

>> As a clear statement that a list (or any other variable) is returned

In any Block or Module I write, it's very easy to pick out the last expression. Nothing can be clearer than that.

Bobby

On Tue, 14 Dec 2004 18:09:49 +1100, David Annetts <davida...@ihug.com.au> wrote:

> Insofar as Mathematica is concerned, no, it is not needed. Indeed, as others have
> pointed out, the entire Module[] can also be avoided.
>
> As a clear statement that a list (or any other variable) is returned from a
> Module[] or Block[], it is invaluable. In my experience, simple defensive
> things like this save hours (or worse) trying to debug code. Leave it out
> if you want.
>
> Dave.
>
>> -----Original Message-----
>> From: DrBob [mailto:dr...@bigfoot.com]
>> Sent: Tuesday, 14 December 2004 07:55
>> To: David Annetts; math...@smc.vnet.net
>> Subject: Re: multiple outputs from a function
>>
>> Return is almost never needed, certainly not in this kind of function:
>>
>> stats[x_List] := Module[{local variables},
>> (* function body *);
>> {mean, variance, std}
>> ];
>>
>> Bobby
>

--
Dr...@bigfoot.com
www.eclecticdreams.net

yehuda ben-shimol

unread,
Dec 15, 2004, 4:53:28 AM12/15/04
to

This does not change the basic idea: The external header is still List.
You may replace the list with an arbitrary header of your own, as long
as it does not try to modify its content. The usage of rules prevents
you to remember the position of the results but enforces you to remember
their names as appear in the rule.
yehuda

John Jowett wrote:

--Boundary_(ID_zhw7Zg8IIxMmPWqsLSw1dQ)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
This does not change the basic idea: The external header is still List.
You may replace the list with an arbitrary header of your own, as long
as it does not try to modify its content. The usage of rules prevents
you to remember the position of the results but enforces you to
remember their names as appear in the rule.<br>
yehuda<br>
<br>
John Jowett wrote:
<blockquote cite="mid200412141...@smc.vnet.net" type="cite">
<pre wrap="">Hello,

As several people have pointed out, returning a list of values is probably
the most straightforward thing to do. It's fine as long as you know what the
elements in the list are supposed to be.

But another technique that is often useful is to return a list of rules. To
give a trivial example:

In[2]:=
f[x_,y_]:={sum-&gt;x+y,difference-&gt;x-y,product-&gt;x y, quotient-&gt; x/y}

In[3]:=
f[1,2]

Out[3]=
{sum -&gt; 3, difference -&gt; -1, product -&gt; 2, quotient -&gt; 1/2}

These results can then be used in other expressions:

In[5]:=
(difference/sum)/.f[1,2]

Out[5]=
-1/3

For less trivial examples see the built-in function Solve or functions like
LocationReport in the standard package Statistics`DescriptiveStatistics`.

This is a way to provide a number of "named" results without worrying about
order in the list (in some other programming languages something similar is
achieved with so-called "associative arrays").

John Jowett

"Ben Barrowes" <a class="moz-txt-link-rfc2396E" href="mailto:barr...@alum.mit.edu">&lt;barr...@alum.mit.edu&gt;</a> wrote in message
<a class="moz-txt-link-freetext" href="news:cpekeh$744$1...@smc.vnet.net">news:cpekeh$744$1...@smc.vnet.net</a>...
</pre>
<blockquote type="cite">
<pre wrap="">I feel I must be missing something fundamental...

f[x_,y_]:=x^2+y^2;

Out[68]=
11

In[69]:=
a1

Out[69]=
31

In[70]:=
a2

Out[70]=
41


Ben Barrowes

</pre>
</blockquote>
<pre wrap=""><!---->

</pre>
</blockquote>
</body>
</html>

--Boundary_(ID_zhw7Zg8IIxMmPWqsLSw1dQ)--

0 new messages