9
$\begingroup$

I have a (hopefully small) problem with some numerical integration algorithm, more specifically I want to integrate the imaginary part of a complex valued function, e.g. f[u_]:=Exp[-iuK] with $K\in\mathbb{R}$. As mentioned I am only interested in Im[f], in the example -Sin[u K].

Now if I integrate with Mathematica

NIntegrate[f, {s, Min[roots[[ 1 ]], roots[[ 2 ]]],
                Max[roots[[ 1 ]], roots[[ 2 ]]]}, AccuracyGoal->aGoal, 
                PrecisionGoal->pGoal, WorkingPrecision->wPrecision ];

I get two different results depending on f:

  1. if I use -Sin[u K], it returns somenumber
  2. if I use Im[f], it returns a list { somenumber } Those two have to be treated differently and that crashes my program. I have a few questions:

Why does Mathematica sometimes return lists, and sometimes values? How can I distinguish between a list and a value, i.e.

If xyz is a list then 
  do something 
else 
  do something else
end

Any other ideas how one could avoid these different return "types"? The manual and anything I found hasn't been useful so far.

$\endgroup$
4
  • 4
    $\begingroup$ I'm trying to understand why NIntegrate is returning a List in one case, and a simple value in another. So, what are you using for roots? $\endgroup$
    – rcollyer
    Commented Mar 1, 2012 at 19:34
  • 1
    $\begingroup$ I cannot reproduce this behavior. E.g., Clear[f]; f[u_] := Exp[-I u]; NIntegrate[Im[f[s]], {s, 0, 1}] works just fine (returning a Real value). $\endgroup$
    – whuber
    Commented Mar 1, 2012 at 21:04
  • $\begingroup$ NIntegrate will return a list when its argument is a list. Therefore I suggest you investigate under what circumstances your f is a list. With your example code, one way this could happen is if K is sometimes a list. $\endgroup$ Commented Mar 2, 2012 at 6:34
  • $\begingroup$ The simple example I gave doesn't reproduce the error, that's true. Probably some input arguments of NIntegrate cause the behavior, however, I'll use one of the answers below. Thank you all! $\endgroup$
    – user13655
    Commented Mar 2, 2012 at 8:48

5 Answers 5

10
$\begingroup$

How about putting the results in a list and then removing unneeded braces.?

a = 76.5
b = {4, 5, 12.3}
Flatten[{a}]
Flatten[{b}]

lists

That way you are always dealing with a list of values.


Or simply place braces around numbers (that are not already in a list):

If[NumericQ[x], x = {x}]
$\endgroup$
0
17
$\begingroup$

Generally speaking, you can recognize a list because it'll have List as its Head. For example:

Head[{1,2,3}]

will return List.

For your example conditional where you want to change what you do based on the Head of the resulting expression, you can use Switch, such as in:

Switch[result,
       _List, what you want to do with a list,
       _, what you want to do otherwise]

A pattern of the form _List means "only match expressions with the head List. The next pattern, _, means "match an expression with any head". Mathematica stops in a Switch at the first match, so List will be preferred over "anything else".

$\endgroup$
1
  • 1
    $\begingroup$ I need to remember that syntax. I keep using Head[result]===List.... yours is much nicer. $\endgroup$
    – tkott
    Commented Mar 1, 2012 at 21:06
11
$\begingroup$

It is useful to write functions that can handle expressions in several different forms.

Here is a function that will return 1 plus a numeric argument, or 1 plus the first element of a list, if it is given a list.

f[n_?NumericQ] := n + 1
f[{n_?NumericQ, ___}] := n + 1

This can also be written in one line using Alternatives:

f[n_?NumericQ | {n_?NumericQ, ___}] := n + 1

When using Alternatives the possibilities will be checked in the explicit order you give.
When using separate lines Mathematica attempts to intelligently order the rules by specificity.

Usage:

f[Pi]
1 + Pi
f[{1, 2, 3}]
2
f["bird"]
f["bird"]

You can use the same syntax for Replace rules if you do not want to create a function.

Pi /. n_?NumericQ | {n_?NumericQ, ___} :> n + 1

{1, 2, 3} /. n_?NumericQ | {n_?NumericQ, ___} :> n + 1
1 + Pi

2
$\endgroup$
1
  • $\begingroup$ You had my +1 with mentioning Alternatives, I can't upvote you any further. $\endgroup$
    – rcollyer
    Commented Mar 2, 2012 at 2:53
7
$\begingroup$

Some functions are intermittent about whether they wrap their results in a list. I'm not sure about NIntegrate, but Reap (for example) certainly does. For purposes of discussion, let's define such a function:

g[x_] /; OddQ[x] := {10 x}
g[x_] := -x

g[1]

{10}

g[2]

-2

We can define h to automatically "unwrap" resulting lists like this:

h[x_] := g[x] /. {n_} :> n

h[1]

10

h[2]

-2

Table[h[x], {x, 0, 10}]

{0, 10, -2, 30, -4, 50, -6, 70, -8, 90, -10}

Also, ListQ can be used to distinguish lists from other value types:

ListQ[1]

False

ListQ[{1}]

True

$\endgroup$
2
$\begingroup$

Alright, I figured out my mistake - as Mathematica distinguishes between different bracket types, one shouldn't confuse () and {}, as I did in a part of my calculations. Sorry for the puzzlement.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.