0
$\begingroup$

I am trying to input more than two list arguments into a function. For example, I have written the following code:

g[xList_, yList_] := 
 For[ϕ = 1;  j = 2, j <= 6, j++, 
  For[i = 1, i < j, 
   i++, ϕ = ϕ*((x[i])^2 + (x[j])^2 - (2*x[i])*(x[j])*Cos[y[i] - y[j]])]];

xList = Array[x, 6];
yList = Array[y, 6];
g[xList, yList]
ϕ

Here, each of x[i] and y[i] is a variable of the function g. However, in the above code, it seems that g is really not a function of xlist and ylist because by varying the list of arguments, I am not getting the desired output. In particular, I can't input a new set of list arguments wlist=Array[w, 6] , zlist=Array[z, 6] into the function g.

Is there a way to input two sets of list arguments as input variables to a function?

$\endgroup$
2
  • 1
    $\begingroup$ Why should I avoid the For loop in Mathematica? $\endgroup$
    – Roman
    Oct 9, 2023 at 10:24
  • 1
    $\begingroup$ You appear to have some syntax errors. To declare a variable as a specific type you need x_List not xList_. Next Part shorthand is with two square brackets; x[[i]] , not x[i]. You also have "side-effects" with ϕ as it is not localised; see Module for help. $\endgroup$
    – Edmund
    Oct 9, 2023 at 21:22

1 Answer 1

3
$\begingroup$

When you use a construct like

g[xList_, yList_] := ...

it is presumed that the symbols xList and yList will appear in the right hand side. That's sort of what it means to be an argument. Your definition for g doesn't reference xList or yList. You could have just written g := ... or g[] := and achieved the same thing.

The "arguments" that g does reference, x, y, \[Phi], are not localized to g, so g operates via side effects. g also doesn't produce any output. So, g isn't really a function, but just a fancy way of assigning a constant expression to \[Phi]. So, really, you could have just written \[Phi] = ....

But, of course, you aren't deliberately trying to just assign a value to \[Phi], and you do want your g to depend on some arguments.

Here's an alternate definition that corrects these problems, but it's not particularly good style:

g2[x_, y_] :=
  Module[
    {\[Phi] = 1},
    For[j = 2, j <= 6, j++,
      For[i = 1, i < j, i++,
        \[Phi] = \[Phi]*((x[[i]])^2 + (x[[j]])^2 - (2*x[[i]])*(x[[j]])*Cos[y[[i]] - y[[j]]])]];
    \[Phi]]

Notice the double square brackets for accessing elements of a list. Now, x and y will take on the values of whatever arguments you pass in to g2.

One reason this isn't good stye is because of the "magic numbers" that show up in j=2 and i<=6. These should really depend on the arguments. Also, you can probably avoid the For loops by using regular list-based operations. And there's the gratuitous \[Phi]. But, I didn't take the time to reverse engineer your code to apply these fixes.

$\endgroup$
2
  • $\begingroup$ Could you please tell what are the regular list based operations instead of "For"? $\endgroup$
    – Rakesh
    Oct 9, 2023 at 17:02
  • $\begingroup$ @Rakesh Have a look at guide/FunctionalProgramming. For your example, Table probably does what you want. $\endgroup$
    – user87932
    Oct 9, 2023 at 17:43

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.