Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a list of this form:

$ lst =\left\{\left\{q_1,x_1,y_1,z_1\right\},\left\{q_2,x_2,y_2,z_2\right\},\text{...},\left\{q_n,x_n,y_n,z_n\right\}\right\} $

I want to use this list in the function:

$V(\{x,y,z\})=\sum _{i=1}^n \frac{q_i}{\sqrt{\left(x_i-x\right){}^2+\left(y_i-y\right){}^2+\left(z_i-z\right){}^2}}$

Where n is the lenght of the list n = Length[lst]. I am not sure how i get this into a inpute code. I have tried the following with the list lst and function v2 :

lst= {{1, 0, 0, 0}, {1, -1, 0, 0}, {1, 1, 0, 0}}; 

$ \text{V2}(\{\text{x$\_$},\text{y$\_$},\text{z$\_$}\},\text{lst$\_$})\text{:=}\sum _{i=1}^n \frac{\text{lst}[[\text{All},1]]}{\sqrt{\left(\text{lst}[[\text{All},2]]_i-x\right){}^2+\left(\text{lst}[[\text{All},3]]_i-y\right){}^2+\left(\text{lst}[[\text{All},4]]_i-z\right){}^2}}$

    V2[{x_, y_, z_}, lst_] := 
       Sum[lst[[All,1]]/Sqrt[(Subscript[lst[[All,2]], i] - x)^2 + (Subscript[lst[[All,3]], i] - y)^2 + 
           (Subscript[lst[[All,4]], i]- z)^2], {i, 1, n}]; 

    Apply[V2, {{x, y, z}, lst}]

Gives : $ \left.\frac{1}{\sqrt{\left(\{0,-1,1\}_2-x\right){}^2+\left(\{0,0,0\}_2-y\right){}^2+\left(\{0,0,0\}_2-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_3-x\right){}^2+\left(\{0,0,0\}_3-y\right){}^2+\left(\{0,0,0\}_3-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_1-x\right){}^2+\left(\{0,0,0\}_1-y\right){}^2+\left(\{0,0,0\}_1-z\right){}^2}},\frac{1}{\sqrt{\left(\{0,-1,1\}_2-x\right){}^2+\left(\{0,0,0\}_2-y\right){}^2+\left(\{0,0,0\}_2-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_3-x\right){}^2+\left(\{0,0,0\}_3-y\right){}^2+\left(\{0,0,0\}_3-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_1-x\right){}^2+\left(\{0,0,0\}_1-y\right){}^2+\left(\{0,0,0\}_1-z\right){}^2}},\frac{1}{\sqrt{\left(\{0,-1,1\}_2-x\right){}^2+\left(\{0,0,0\}_2-y\right){}^2+\left(\{0,0,0\}_2-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_3-x\right){}^2+\left(\{0,0,0\}_3-y\right){}^2+\left(\{0,0,0\}_3-z\right){}^2}}+\frac{1}{\sqrt{\left(\{0,-1,1\}_1-x\right){}^2+\left(\{0,0,0\}_1-y\right){}^2+\left(\{0,0,0\}_1-z\right){}^2}}\right\}$

But i am expecting to get $\frac{1}{\sqrt{x^2+y^2+z^2}}+\frac{1}{\sqrt{(x+1)^2+y^2+z^2}}+\frac{1}{\sqrt{(x-1)^2+y^2+z^2}} $

What am i doing wrong?

share|improve this question
    
Please don't use $\LaTeX$ for Mathematica code... edit your question to convert the code to something that's copy-pastable (use InputForm). –  rm -rf Jan 5 at 17:28
    
@rm-rf I already left such a comment and I believe the OP has put all the necessary input in code (as well as TeX). Makes the formatting look a little messy I suppose. –  Michael E2 Jan 5 at 17:42

5 Answers 5

Yet another method

#/Sqrt[(#2 - x)^2 + (#3 - y)^2 + (#4 - z)^2] & @@@ lst // Total

enter image description here

share|improve this answer

Here's a straightforward way. First, break apart the list into the xyz parts and the q parts. The denominators are just the Norm which are summed uing Total.

list = {{q1, x1, y1, z1}, {q2, x2, y2, z2}, {q3, x3, y3, z3}, {q4, x4, y4, z4}}; 
xyz = list[[All, 2 ;; 4]];
q = list[[All, 1]];
Sum[q[[i]]/Norm[xyz[[i]]], {i, Length[list]}]

q1/Sqrt[Abs[x1]^2 + Abs[y1]^2 + Abs[z1]^2] + q2/Sqrt[Abs[x2]^2 + Abs[y2]^2 + Abs[z2]^2] 
  + q3/Sqrt[Abs[x3]^2 + Abs[y3]^2 + Abs[z3]^2] + q4/Sqrt[Abs[x4]^2 + Abs[y4]^2 + Abs[z4]^2]

which is the desired sum.

share|improve this answer

Ignoring the subscripts, this definition for V2 yields the desired answer:

V2[{x_, y_, z_}, lst_] := 
 Total[
  lst[[All, 1]] /
   Sqrt[(lst[[All, 2]] - x)^2 + (lst[[All, 3]] - y)^2 + (lst[[All, 4]] - z)^2]
  ]

This takes advantage of the Listable attribute of the standard arithmetical operations and other functions such as Sqrt. Total is a better way to add up a list than Sum.

share|improve this answer

To answer your question, "what am I doing wrong", I'd say that you are using the wrong syntax to access elements in a list. It's easier to start from scratch than to correct your code. (Edited to explain when it is better to use delayed rule assignment)

This, for example, will do what you want

Plus @@ (lst /. {qn_, xn_, yn_, zn_} -> qn/Sqrt[(xn - x)^2 + (yn - y)^2 + (zn - z)^2])

What I have done here is to use a replacement rule to turn each list {qk,xk,yk,zk} contained in lst into the corresponding contribute to the field. Then I sum all the contributes by changing the head of lst from List to Plus.

You can enclose the above code in a procedure that accepts the {x,y,z} vector and the list lst, if you wish:

v2[{x_, y_, z_}, lst_] := Plus @@ (lst /. 
    {qn_, xn_, yn_, zn_} -> qn/Sqrt[(xn - x)^2 + (yn - y)^2 + (zn - z)^2]
)

But if you choose to code the rule in a separate portion of code and then applying it manually, you'd be better off with a delayed rule assignment like this:

toFieldContribute = {qn_, xn_, yn_, zn_} :> qn/Sqrt[(xn - x)^2 + (yn - y)^2 + (zn - z)^2]

in this way, even if you had values associated with x,y or z (it is not uncommon, given the names), they would not show up in the definition of the above rule, because the evaluation will take place only when the rule is applied, like in

Total[ lst /. toFieldContribute ]

In this way only the actual values of x, y or z would be used. try with a fresh kernel by evaluating x=2, then the rule definition, then x=5 and then apply it as above. You will get different results with -> and :>

To show yet another approach, and to make the answer more similar to your tentative solution, you could do code your procedure in this way

v2[{x_, y_, z_}, lst_] := Block[n = Length[lst], 
    Sum[lst[[k, 1]]/Sqrt[
        (lst[[k, 2]] - x)^2 + (lst[[k, 3]] - y)^2 + (lst[[k, 4]] - z)^2],
    {k, 1, n}
    ]
]

(here I have used Block to limit the scope of n, and I used the index k to refer to the k-th element of lst, while 1,2,3 and 4 refer to the elements in each sublist {qk,xk,yk,zk}). But I believe my former approach to be faster (and somewhat tidier).

share|improve this answer
    
Thanks for the fast reply and explanation. I had one question, why do you need to use a RuleDelayed in your first method? –  Jan vos Jan 5 at 16:13
    
In this case, since the rule is defined and applied in the same line, there strictly is no reason to do that. But I usually like to write my code in pieces and if you define toFieldRule={qn_, xn_, yn_, zn_} -> qn/Sqrt[(xn - x)^2 + (yn - y)^2 + (zn - z)^2]) you might end up with a rule definition tainted by values previously assigned to x, y or z so that when you apply it later in lst/.toFieldRule you will get results with those values and not the actual values of x,y and z. –  Peltio Jan 5 at 16:41

Also:

v[x_, y_, z_, list_] := 
 Total[#1/Sqrt[({##2} - {x, y, z}).({##2} - {x, y, z})] & @@@ list]

Applying to

lst = {{1, 0, 0, 0}, {1, -1, 0, 0}, {1, 1, 0, 0}};
v[x, y, z, lst]

yields:

1/Sqrt[(-1 - x)^2 + y^2 + z^2] + 1/Sqrt[(1 - x)^2 + y^2 + z^2] + 1/Sqrt[x^2 + y^2 + z^2]

If you don't mind the Abs then this could be done more compactly:

v2[x_, y_, z_, list_] := Total[#1/Norm[{##2} - {x, y, z}] & @@@ list]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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