1
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ Please don't use $\LaTeX$ for Mathematica code... edit your question to convert the code to something that's copy-pastable (use InputForm). $\endgroup$
    – rm -rf
    Jan 5, 2014 at 17:28
  • $\begingroup$ @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. $\endgroup$
    – Michael E2
    Jan 5, 2014 at 17:42

4 Answers 4

1
$\begingroup$

Yet another method

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

enter image description here

$\endgroup$
0
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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).

$\endgroup$
2
  • $\begingroup$ Thanks for the fast reply and explanation. I had one question, why do you need to use a RuleDelayed in your first method? $\endgroup$
    – Jan vos
    Jan 5, 2014 at 16:13
  • $\begingroup$ 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. $\endgroup$
    – Peltio
    Jan 5, 2014 at 16:41
0
$\begingroup$

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]
$\endgroup$

Your Answer

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

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