Closed ghost closed 1 year ago
Thanks for your suggestions Barry! I've changed the title a bit.
Is anyone working on this? I'd love to take a crack at it.
Thanks for your offer Rishi! There is currently no one working on this so you're very welcome. I think before you implement something it would be good to make a concrete list with functions how they will look like. Can you make a proposal?
Hey @josdejong ! here's how I want to create a function for calculations of areas. the function needs two parameters:
EXAMPLES: area("square", { s: 5 }); -------> 25 area("rectangle", { b: 5, h: 6 }); -------> 30 area("parallelogram", { b: 5, h: 6 }); -------> 30 area("trapezoid", { a: 4, b: 5, h: 6 }); -------> 27 area("triangle", { b: 5, h: 6 }); -------> 15 area("circle", { r: 5 }); -------> 78.53981633974483 area("ellipse", { a: 4, b: 5 }); -------> 62.83185307179586
That's a nice starting point for a proposal. The original concept suggested we might want to compute other attributes as well, such as perimeter or in the case of 3D shapes, volume. I am not suggesting that you would need to implement those things to submit an area calculator, just that we should think about a design that will morph nicely to those other characteristics when someone does want to implement them.
So would we want different functions like perimeter("square", {s: 4))
or volume("sphere", {r: 3})
? Or would we want an interface like find(QUANTITY. CONTEXT, KNOWNS)
e.g. find("volume", "cube", {s: 2cm})
? An advantage of the latter is that it could at some point be extended to turn things around, e.g. find('base', 'triangle', {area: 10, height: 2})
. It could even be extended to other common equations like find('pressure', 'ideal gas', {volume: 10L, n: 3mol, T: 300K})
. But of course, this is all about interface; your starting implementation could just do areas of familiar shapes.
Also, should there be some flexibility in the attribute names? I.e allowing base or b, height or h, etc, and maybe also dealing with the fact that often people write length×width for area of a rectangle?
Finally, of course we need @josdejong's thoughts on the interface, and also about whether this is a functionality that belongs bundled within mathjs or whether this would be better as an optional add-on package. Thanks for getting this discussion going again!
These are great, well-explained suggestions. I definitely prefer the interface approach.
Regarding the flexibility of the attribute names I think we should allow one specific name and its abbreviation, e.g. length or L. But some shapes' formulas like the ellipse uses a and b to represent major radius and minor radius. In this case should we just follow the formula?
I also think the KNOWNS object values should be numbers only not strings that includes metric units.
May I send you a codepen link? Still incomplete(restricted to area calculation) but I'd like to know your opinion first.
Ultimately Jos will weigh in, we are just discussing options here. I think it would be great to support both full names of attributes and abbreviations, like 'radius' and 'r'. But I am a bit unclear what should be done when there are multiple common terms that are used for a given shape. Such as the area of a rectangle being either length times width or base times height... I agree that a and b are pretty standard for ellipses; the full names are "major semiaxis" and "minor semiaxis", not sure if those should be allowed?
As for the object values, there is a longstanding design principle for mathjs to try to accept as many types of arguments as possible, and Unit is a first-class type in mathjs, and it makes perfect sense in the context of perimeter and area, so i would say that if this is going to be implemented it should definitely accept Unit values and perform the proper unit propagation.
And of course you are welcome to post pointers to any code examples you think will be helpful.
Thanks for working out a concrete proposal @saad-jad!
My thoughts:
width
and height
over abbreviations like a
, b
, h
. perimeter
and volume
can use the same kind of API, so you can define like const mySquare = { size: 5 }
and use it straight into every function: area('square', mySquare)
and volume('square', mySquare
).find(QUANTITY, CONTEXT, KNOWNS)
feels a bit too generic to my taste, and will bundle all of the functionality in one function also if you only need area
for example. We can always build such a utility function on top of explicit functions like area()
and volume()
though if there is need for it.Another thought (I'm not sure if we should go that direction): how about making shapes first class classes? I.e.:
const mySquare = new Square({ size: 5 })
const myArea = area(mySquare)
const myVolume = volume(mySquare)
It would remove the need to specify the type of shape separately from its properties, and would make it impossible to accidentally use the wrong shape name. If you go that route, it also begs the question on whether to implement area
and volume
as methods of the shape classes. In general, I have a preference for separating data and functions and limit the number of methods so I would say let's not do that.
To elaborate some of my thinking behind my comments above, mathjs already has an extensive "library" of units that are used in a wide variety of areas. The heart of this proposal seemed to be to develop a complementary library of well-known equations such as "area = (short base + long base) height/2" for a trapezoid. And if so, why not physics equations too like "pressure volume = R number temperature" or "energy = mass lightspeed^2" etc. And the other part of this thinking is that in most case when you have an equation like "volume = (2tau/3)*radius^3" it's just as easy/sensible to solve for radius given volume as volume given radius. So it seems like something is really missing unless there's an interface that's symmetric among all the quantities in that you can supply all but one of the quantities in any equation and ask for the remaining quantity. And so since I imagined that the library of equations would be easy to add to and would accumulate naturally over time and ultimately be quite large, it didn't seem quite reasonable that there would be a top-level mathjs function for every name of every quantity in every equation...
So that's where the "find(QUANTITY, CONTEXT, GIVEN)" interface idea came from. But to your point of requiring lots of extraneous implementation even if you just want area, again I liken it to the Unit case: if you (want to) use any Unit, you get the entire library of units, including say coulombs even if you have no idea what one is. By the same token, I assumed that the collection of equations is just some data structure, and yes you get that whole data structure if you want to solve any of the equations, but the actual implementation of 'find' would be quite compact based on that data structure. And that implementation of find would be quite short indeed based on a generic equation solver, which is another oft-requested mathjs feature.
Note that in the above comment I am not trying to say that the "find()" interface is the right interface for this purpose, just that there are concerns with a list of functions like "area()", "height()", "volume()", "radius()", etc. as well. So maybe we don't have the correct interface yet. Possibly objects like Square and Circle could help devise an even better interface, but then I am unclear how they would address instances like the ideal gas law that I raised above; what is the "object" associated with an instance of the ideal gas law? It's a "ConfinedQuantityOfIdealGas" which doesn't make a great class name ;-)
Ahhh, really interesting way of looking at it, seeing these shapes and attributes/properties (like area, volume, ...) as an extension on top of the system of units 🤔 .
Since this is pretty wide-ranging, open-ended, and has not ever focused to a specific plan, moving it to Discussions.
Add 2 and 3 dimensional objects such as triangles, trapezoids, squares, other regular polygons, spheres, cones, etc, and formulas relating to their area, volume, circumference length, eccentricity, etc.
Add functions to convert between coordinate systems (Cartesian to spherical to cylindrical, etc).