OO Programming in Physics

Would physics majors benefit from learning how to do Object Oriented programming?
 

Buckethead

Gold Member
454
20
Object Oriented programming is a very clean way to program (as perhaps you are already aware) in that an object can both have properties and functions that modify those properties locally. I recommend learning the concept behind object oriented programming and why it's such a good advancement in the way programming is done for this reason: It is not difficult to learn the concept and why it's a good thing and once you learn it, it's kind of an ahha! moment where it all just seems so logical. As far as your question is concerned, I would say yes, given this example: Let's say you wanted to do an n body simulation. You could program the object (n) in your study as an OOP object and give it properties and functions you could call to manipulate it. It's very clean this way. Will it be computationally the most efficient? That depends on the compiler, but modern compilers are very good at this. Bottom line, understanding the simple concept of OOP gives you another tool in your toolbox, so I'd say go for it. Other's may disagree.
 

wle

289
112
Object Oriented programming is a very clean way to program (as perhaps you are already aware) in that an object can both have properties and functions that modify those properties locally.
It's not really clean since the way OOP is done in most programming languages is only a special case of a more general idea. Most OO languages only support something called "single-dispatch" OO. What this means has to do with class methods and how they differ from regular functions. In a single-dispatch language, a class method is basically the same as a function except that its first parameter is treated specially and differently from its other parameters in certain ways. The details differ depending on the language but the following is typical:
  • You use a special syntax for method calls like x.foo(y, z) rather than foo(x, y, z) that makes it clear the first parameter, x, is handled in a special way.
  • You're allowed to define multiple methods all sharing the same name foo, each one specialised on a different type of x.
  • Which version of foo gets called depends on the data type of x. Importantly, the exact type of x typically doesn't have to be known until runtime. (In C++, only if you specify that the method is "virtual".)
  • x is passed by reference while, depending on the language, the other parameters might be passed by value.
  • In some programming languages, foo might have special permission to access the internal properties of x but not the other arguments. This is true in the C++/Java/C# family but not, for example, in Python.
Multiple dispatch is a generalisation where you can define a bunch of different methods foo(x, y, z) with the same name but specialised for different types of all the parameters, and which version of foo is called is decided depending on all the argument types at runtime. (In C++-speak, you can have a method/function that is "virtual" with respect to all of its parameters.) Not many programming languages support this. A couple that people on this forum might have heard of are Common Lisp and Julia.

That said a lot of important languages, including languages used in physics such as C++ and Python, use and depend on single-dispatch OO, so you might be forced to deal with it. But I wouldn't see it as anything to get excited about.
 
The advantage of OOP is: you can link the scrap of several programmers together and every individual piece of code is not capable to disrupt the operation of an other piece of code.
 
10,334
3,865
I work in the scientific program development field and we use Java OO methodology for everything.

Simulation-wise OO provides a means to more easily simulate a physical system by describing its components and attributes in term of classes. As an example, in a solar system simulation you could define a Planet class that contains the planet's attributes:
- a position vector, and
- a velocity vector
- planetary mass
- ...other relevant attributes

and the position and velocity attributes would be described by a vector class containing these spherical coordinate attributes:
- radial distance for the origin
- theta angle
- phi angle
- ...
with methods to get and set these attributes, methods to get the x,y,z equivalents of these attributes for display and methods to update them based on running the ODE calculations to simulate motion.

Your simulation program(ie class) would then perform the necessary ODE computations using an array of planet objects which in turn rely on vector attributes ie classes within classes within classes each one testable independently.

You can learn more about OO based physical system simulation from Open Source Physics:


www.compadre.org/osp/

They provide many working examples including this generic Galaxy simulation:

OSP Galaxy Simulation:
/*
* Open Source Physics software is free software as described near the bottom of this code file.
*
* For additional information and documentation on Open Source Physics please see:
* <http://www.opensourcephysics.org/>
*/

package org.opensourcephysics.sip.ch19;
import org.opensourcephysics.controls.*;
import org.opensourcephysics.frames.*;
import org.opensourcephysics.display.*;
import java.awt.*;

/**

* GalaxyApp models evolution of a galaxy using percolation ideas

* Model proposed by Schulman and Seiden

* @version 1.0

* @author J. Tobochnik  3/25/05

*

*/
public class GalaxyApp extends AbstractSimulation implements Drawable {
  DisplayFrame frame = new DisplayFrame("Galaxy");
  final static double twoPi = 2.0*Math.PI;
  final static double twoPiOver6 = twoPi/6;
  double p, v, dt, t;
  int numberOfRings, numberOfActiveCells, numberOfCells;
  int[] starLifeTime, cellR, cellA, activeCellLabel;

  public GalaxyApp() {
    frame.addDrawable(this);
  }

  public void initialize() {
    t = 0;
    numberOfRings = control.getInt("Number of rings");
    numberOfActiveCells = control.getInt("Initial number of active cells");
    p = control.getDouble("star formation probability");
    v = control.getDouble("cell velocity");
    dt = control.getDouble("time step");
    frame.setPreferredMinMax(-numberOfRings-1.0, numberOfRings+1.0, -numberOfRings-1.0, numberOfRings+1.0);
    numberOfCells = 3*numberOfRings*(numberOfRings+1);
    cellR = new int[numberOfCells];
    cellA = new int[numberOfCells];
    int cellLabel = 0;
    // initial values of r and a for each cell label
    for(int r = 1;r<=numberOfRings;r++) {
      for(int a = 0;a<r*6;a++) {
        cellR[cellLabel] = r;
        cellA[cellLabel] = a;
        cellLabel++;
      }
    }
    starLifeTime = new int[numberOfCells];
    activeCellLabel = new int[numberOfCells];
    initializeGalaxy();
  }

  public void initializeGalaxy() {
    int i = 0;
    while(i<numberOfActiveCells) {
      int label = (int) (Math.random()*numberOfCells);
      if(starLifeTime[label]!=15) {
        starLifeTime[label] = 15; // activate region for 15 time steps
        activeCellLabel[i] = label;
        i++;
      }
    }
  }

  public void formNewStars() {
    // copy list of active cells into another array
    int[] currentActiveCellLabel = activeCellLabel.clone();
    int currentNumberOfActiveCells = numberOfActiveCells;
    numberOfActiveCells = 0;
    for(int i = 0;i<currentNumberOfActiveCells;++i) {
      int cellLabel = currentActiveCellLabel[i];
      int r = cellR[cellLabel];
      int a = cellA[cellLabel];
      // activate neighboring cells in same ring
      createStars(r, pbc(a+1, r));
      createStars(r, pbc(a-1, r));
      // activate cells in next larger ring
      if(r<numberOfRings-1) {
        int ap = aForOtherRadius(a, r, r+1);
        createStars(r+1, pbc(ap, r+1));
        createStars(r+1, pbc(ap+1, r+1));
      }
      // activate cells in next smaller ring
      if(r>1) {
        int am = aForOtherRadius(a, r, r-1);
        createStars(r-1, pbc(am, r-1));
        createStars(r-1, pbc(am+1, r-1));
      }
    }
  }

  public int pbc(int a, int r) {
    return(a+6*r)%(6*r);
  }

  public int aForOtherRadius(int a, int r, int rOther) {
    // angle corresponding to a at time t
    double angle = twoPiOver6*a/r+((v*t)/r);
    angle -= twoPi*(int) (angle/twoPi);
    // change in angle for cell at other r
    double angleChange = ((v*t)/rOther);
    angleChange -= twoPi*(int) (angleChange/twoPi);
    // return value of a for cell at other r
    return(int) ((rOther/twoPiOver6)*(angle-angleChange));
  }

  public void createStars(int r, int a) {
    int label = a+3*r*(r-1);
    if((Math.random()<p)&&(starLifeTime[label]!=15)) {
      activeCellLabel[numberOfActiveCells] = label;
      numberOfActiveCells++;
      starLifeTime[label] = 15;
    }
  }

  public void doStep() {
    t += dt;
    formNewStars();
    frame.setMessage("t = "+decimalFormat.format(t)+" #active = "+numberOfActiveCells);
  }

  public void reset() {
    control.setValue("Number of rings", 50);
    control.setValue("Initial number of active cells", 200);
    control.setValue("star formation probability", 0.18);
    control.setValue("cell velocity", 1.0);
    control.setValue("time step", 10.0);
  }

  public void draw(DrawingPanel panel, Graphics g) {
    g.setColor(Color.black);
    g.fillRect(0, 0, panel.getWidth(), panel.getHeight()); // color background black
    g.setColor(Color.yellow);
    for(int label = 0;label<numberOfCells;label++) {
      if(starLifeTime[label]>0) {
        int r = cellR[label];
        int a = cellA[label];
        double angle = twoPiOver6*a/r+(v*t)/r; // angle for cell at time t
        double x = r*Math.cos(angle);
        double y = r*Math.sin(angle);
        double ds = starLifeTime[label]/15.0;
        int leftPixels = panel.xToPix(x);
        int topPixels = panel.yToPix(y);
        int heightPixels = (int) (panel.getYPixPerUnit()*ds);
        int widthPixels = (int) (panel.getXPixPerUnit()*ds);
        g.fillOval(leftPixels, topPixels, widthPixels, heightPixels);
        starLifeTime[label]--;                 // decrease star cluster lifetime
      }
    }
  }

  public static void main(String[] args) {
    SimulationControl.createApp(new GalaxyApp());
  }
}

/*
* Open Source Physics software is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License (GPL) as
* published by the Free Software Foundation; either version 2 of the License,
* or(at your option) any later version.

* Code that uses any portion of the code in the org.opensourcephysics package
* or any subpackage (subdirectory) of this package must must also be be released
* under the GNU GPL license.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA
* or view the license online at http://www.gnu.org/copyleft/gpl.html
*
* Copyright (c) 2007  The Open Source Physics project
*                     http://www.opensourcephysics.org
*/
Development-wise OO provides a better means of organizing your code into packages, classes and methods. Because of this you can build larger programs without losing sight of what you are developing. Prior to OO techniques, programmers would write very large simulation programs and would package their functions into libraries and use those libraries to develop their applications.

A library is akin to a Java jar file, a program is akin to a java class and a function is akin to a class method. In java then my code is organized in jars of packages and in classes within each package so that Java provides and additional level of organization with packages. Packaging allows you to bring together classes of the same name made unique by the packaging name.

Having come from a background of writing mostly fortran code where variables were either local to a function or global in scope and optionally organized in common blocks, I find the OO methodology to be better for code refactoring and for making classes that are testable individually and then again when combined to make a program.

Other OO languages that have a lot of traction today are Python and C++. I always preferred Java to C++ and now that I've played enough with python and its OO features prefer Python to Java for some projects especially any kind of data analysis or machine learning work using numpy, pandas and matplotlib.

However as a programmer, you're always looking for the next great language that will solve all the world's problems or at least your own and that includes Clojure, Kotlin, Groovy, Scala and Julia.


and to see these languages in action:



Lastly, many scientific projects use Matlab as the language of choice and it too has evolved to use OO methodology although you can still write plain old function and workspace based matlab code.

 

anorlunda

Mentor
Insights Author
Gold Member
6,292
3,498
Would physics majors benefit from learning how to do Object Oriented programming?
Wow. Too broad a question. It depends on what kind of programming you'll be doing. An it applies to anyone doing that kind of programming, no matter what their field.

I'm thinking for example, of microcode for special hardware for an experiment. One doesn't use high level languages there. Or someone who wants to make a DB query.
 

FactChecker

Science Advisor
Gold Member
2018 Award
4,719
1,613
Although OO is sometimes oversold and overused, there are situations that scream for OOD. A good example is in a computer simulation where objects of different types (classes) are entering and leaving the simulation. With OOD, each object knows how to create itself, have properties, behavior, data collection, and removal; all appropriate for the type of object that it is. It can even redefine what basic operations like addition, subtraction, assignment, etc. means for those classes of objects. And this knowledge is all conveniently located in the definition of the class of the object, not scattered around in the larger program.
 
1,562
189
Multiple dispatch is a generalisation where you can define a bunch of different methods foo(x, y, z) with the same name but specialised for different types of all the parameters, and which version of foo is called is decided depending on all the argument types at runtime.
Isn't that just method overloading?
 

wle

289
112
Isn't that just method overloading?
No. The difference is that the method selection is deferred until run time.

As an example, in Julia you can write code like this:
Code:
struct Dog
    name
end

struct Car
    make
end


# Different ways Dogs and Cars can attack each other.

function attack(x::Dog, y::Dog)
    println(x.name, " chases ", y.name)
end

function attack(x::Dog, y::Car)
    println(x.name, " steals bumper from ", y.make)
end

function attack(x::Car, y::Dog)
    println(x.make, " runs over ", y.name)
end

function attack(x::Car, y::Car)
    println(x.make, " crashes into ", y.make)
end


# Make a heterogeneous array containing a few Dogs and Cars.

objects = [Dog("Max"), Car("Ford"), Car("Audi"), Dog("Bruno")]


# Make all these things attack each other.

pairs = [(x, y) for x in objects for y in objects if x != y]

for (x, y) in pairs
    attack(x, y)
end
Running this produces this output:
Code:
Max steals bumper from Ford
Max steals bumper from Audi
Max chases Bruno
Ford runs over Max
Ford crashes into Audi
Ford runs over Bruno
Audi runs over Max
Audi crashes into Ford
Audi runs over Bruno
Bruno chases Max
Bruno steals bumper from Ford
Bruno steals bumper from Audi
The important thing (and the difference with overloaded functions in C++) is that both arguments x and y in the loop are obtained from an array containing different types of objects (Dogs and Cars), so which version of attack() needs to be called can only be decided in the loop at run time.

I think you need something called the Visitor Pattern to simulate this using single-dispatch OO.
 
Last edited:

.Scott

Homework Helper
2,197
698
Would physics majors benefit from learning how to do Object Oriented programming?
They would clearly benefit.
But the primary reason you would need to learn "how to do" it would be to understand what it is and what kind of tool it is.
The feature of the object-oriented model that I find most useful is the clean, well-defined, easy-to-support interface you can create between your class and the outside world. When working with a software component that consists of tens of thousands of lines of code (or more), it is important that the project be segmented into separated parts that can each have is own specified requirements and be independently testable. The OO model shines in this area.
 
32,344
4,130
Although OO is sometimes oversold and overused, there are situations that scream for OOD.
And by implication, I think we can say that there are situations that don't scream for OOD. I've seen a fair amount of really bad Fortran and C/C++ code posted by people who are physicists or are working toward some degree in that discipline. If all your program needs to do is to crank out a bunch of calculations, either by itself or by using some third-party library, and this isn't a team effort, you probably don't really need objects in your code.

In cases like this, I would be happy if the code used good programming practices such as:
  • informative variable names (i.e., NOT names like xxbjar or other gobbledy-gook)
  • informative function names that convey to the reader what the function is supposed to do
  • comments along the way to aid a reader in discovering what the code is supposed to be doing
  • efforts at indenting the code to reflect the control structures (e.g. loops, if ... else blocks, and so on)
Just these four things would go a long way in helping some poor schmuck who's looking at the code try to figure out what it's supposed to be doing, and why it's not working correctly.

My sense is that some of these physics students have never taken a programming class in their lives, but then they are suddenly tasked with writing some code by their research advisor, and they cobble up something that sort of works (maybe). Or they are tasked with updating some ancient, poorly written code written by some other poor schlub with exactly the same programming expertise. There are some basic ideas covered in CS classes about writing maintainable code that never got pounded into the heads of some of the people who have posted code here at PF.
 
14,873
4,545
Wow. Too broad a question. It depends on what kind of programming you'll be doing. An it applies to anyone doing that kind of programming, no matter what their field.
what he said (very small).jpg


OO is sometimes a good idea, sometimes a waste of time, and sometimes isn't even applicable. It doesn't have to do with physics, it has to do with what kind of programming you are doing
 

FactChecker

Science Advisor
Gold Member
2018 Award
4,719
1,613
And by implication, I think we can say that there are situations that don't scream for OOD.
I agree. Like any appealing idea, people can really get carried away. Simple code can be made unnecessarily complicated if all data is hidden and every data change requires calling a method.
 
10,334
3,865
One practice i think is just as useful as OO is functional programming where function inputs are arguments and outputs are done via returns. There is no hidden state or global variables to mess things up. Given the same inputs you get the same outputs.

FP makes debugging easier and encourages better programming. But it can be harder/ nuisance for experienced programmers versed in storing hidden state to make richer functions with less arguments and cleaner outputs.

 
624
142
As I see it OO is only really applicable to a mathematical model, not directly to physics. Many physical systems can be modeled in several ways, and only some of those models are amenable to OO.

So yes, iff it is appropriate!
 
32,344
4,130
As I see it OO is only really applicable to a mathematical model, not directly to physics.
No, OOD isn't applicable just only to mathematical models. It's used all the time in many arenas that aren't mathematical in nature, such as in accounting, inventory, optimizing delivery routes, and too many others to list.
 
624
142
I don't disagree with you, but the OP (and my reply) specifically mentioned physics, not those other things!

In any case, Physics did very nicely thank you before the arrival of OO.

BTW, I used to use OO by default, but I now use it only when it is useful (operator overloading is a good example).
 

FactChecker

Science Advisor
Gold Member
2018 Award
4,719
1,613
OOD has significant advantages in anything where a set of tools will be widely used. There are often problems using libraries of tools where the names of functions might conflict with names in other libraries. That is a very common occurrence when multiple libraries are relevant to the same subject. OOD allows better control of which tool-set will be used at any particular time. Conflicts are so easily avoided that tool-sets programmed using OOD can virtually always be downloaded and used without problems. In my experience, libraries usually have conflicts.
 
10,334
3,865
Well I think this thread has run its course and the OP has gotten many good answers here and so it’s time to close the thread before we run astray.

Thank you all for contributing here.

The thread is now closed.

Jedi
 

Physics Forums Values

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving
Top