3

I'm using SpherePoints and it would be helpful if the resulting points be expressed like 1.0000000000000000e-00f. AFAIK, that's IEEE double precision, but I don't know how to write the SpherePoints to directly obtain this type of output. TIA!

Edit I want to use SpherePoints, but its standard output is not formatted the way I need, which is single precision float written like 0.0000000000000000e+00f. How can I obtain this?

  • 5
    The question is unclear. Do you really want to display numbers this way by default, and if so, why? Or do you want to export the number so that they can be imported by some other software? What exactly are the requirements of that other software? – Szabolcs Dec 28 '22 at 18:26
  • 3
    You can specify how a number is displayed with NumberForm. It has a NumberFormat option, and with that you can display a number pretty much however you want. But this will create a little display "object", making it tricky to use in later computations. So, I'll second @Szabolcs here and suggest you be more specific about your use case. – lericr Dec 28 '22 at 18:46
  • It's for a "file.h" use in C++, pre-compilation. Like this one https://git.iem.at/audioplugins/IEMPluginSuite/-/blob/master/AllRADecoder/Source/tDesign5200.h – Daniel Courville Dec 28 '22 at 19:05
  • 1
    There is CForm but it will not give that specific format. Maybe these are related https://mathematica.stackexchange.com/q/209239/86543 or https://mathematica.stackexchange.com/q/175094/86543 – userrandrand Dec 28 '22 at 19:15
  • 1
    CForm should be sufficient though, as it preserves enough digits for a double precision number. However, what you show, with an f suffix, is not double precision, but single precision. – Szabolcs Dec 28 '22 at 20:11
  • To continue @Szabolcs's comment: number-strings generated by CForm are double-precision and can be assigned to either float or double because the compiler will figure out the correct conversion if needed. If you want to go further and make sure that every last bit of your number is transferred to C, you can use a binary floating-point literal that you'd need to construct somehow in Mathematica. – Roman Dec 28 '22 at 20:34
  • Thanks everybody for the various tips. @Szabolcs, I'm surprised by your comment about the single precision, since on this page https://web.maths.unsw.edu.au/~rsw/Sphere/EffSphDes/ss.html the points sets are are said to be "within the limits of IEEE double precision". – Daniel Courville Dec 28 '22 at 20:35
  • Or you could write the numbers into a binary file and then use xxd to convert them to a C header file. But this way lies madness and endianness-problems, so I'd not recommend this route if you can avoid it at all. – Roman Dec 28 '22 at 20:36
  • @DanielCourville An f suffix in C indicates the float type, i.e. single precision floating point. Please edit the question and update it to address the questions in the comments. It looks like the question is not actually asking what you said you wanted to do in the comments. If you want to produce a C header file, ask about that. Please take a look at https://xyproblem.info/ – Szabolcs Dec 28 '22 at 22:29
  • @Szabolcs, I'm sorry about my the imprecision of my question. The long version is: I want to use SpherePoint, but its standard output is not formatted the way I need, which is single precision float written like 0.0000000000000000e+00f. How can I obtain this? – Daniel Courville Dec 29 '22 at 13:54
  • Please just add that information to the question, to make sure that it fits will the eventual answer. The gist is that you should probably use CForm and some string processing functions to construct a C header file. No need to worry about single-vs-double precision for the constant—it's sufficient to assign to a float [] variable. – Szabolcs Dec 29 '22 at 16:52

3 Answers3

5

In Mathematica, you can use the NumberForm function to format the output of your SpherePoints as a string in the desired format.

For example, if you have a list of SpherePoints called points, you can use NumberForm as follows:

NumberForm[#, {Infinity, 20}, ExponentFunction -> (If[# =!= 0, #, Null] &), 
  NumberFormat -> (Row[{"1.", StringJoin[ConstantArray["0", 19]], "e-00f"}])] & /@ points

This will apply the formatting to all elements of the points list, and return a list of formatted strings.

Alternatively, you can use NumberForm to directly format the output of a command such as SpherePoints, like this:

NumberForm[SpherePoints[3], {Infinity, 20}, ExponentFunction -> (If[# =!= 0, #, Null] &), 
  NumberFormat -> (Row[{"1.", StringJoin[ConstantArray["0", 19]], "e-00f"}])]

This will format the output of SpherePoints[3] as a string in the desired format.

Jan Eerland
  • 2,001
  • 10
  • 17
  • I understand that my question is not clear, and I apologize for that. It seems that the combination of SpherePoints and NumberForm will get me what I want which is, as an example:

    {0.0000000000000000e+00f, 0.0000000000000000e+00f, 1.0000000000000000e+00f}, {1.5761817249325915e-02f, 0.0000000000000000e+00f, 9.9987577484255452e-01f}, {1.0157555473482039e-02f, 1.4310204560850257e-02f, 9.9984600919953159e-01f}, {-3.5874636993705696e-03f, 1.9604752254683097e-02f, 9.9980137217011167e-01f}

    – Daniel Courville Dec 29 '22 at 13:39
2

As I understand, you want to generate some C code which represents an array of 3D coordinates, created with SpherePoints. You can do this with string processing and CForm.

Example:

coordsToC3D[coord_] := "float coord[][3] = {\n\t\t" <>
  StringRiffle[
   ToString /@ Map[CForm, coord, {2}],
   ",\n\t\t"
   ] <>
  "\n};\n"
coordsToC3D[SpherePoints[10]]
"float coord[][3] = {
        {-0.8944271909999157, 0., -0.44721359549995787},
        {0.8944271909999157, 0., 0.44721359549995787},
        {-0.7236067977499789, -0.5257311121191336, 0.44721359549995787},
        {-0.7236067977499789, 0.5257311121191336, 0.44721359549995787},
        {-0.276393202250021, -0.85065080835204, -0.44721359549995787},
        {-0.276393202250021, 0.85065080835204, -0.44721359549995787},
        {0.276393202250021, -0.85065080835204, 0.44721359549995787},
        {0.276393202250021, 0.85065080835204, 0.44721359549995787},
        {0.7236067977499789, -0.5257311121191336, -0.44721359549995787},
        {0.7236067977499789, 0.5257311121191336, -0.44721359549995787}
};
"

This produces numbers with enough digits for double precision (double), which means that it's also sufficient for float.

You can export this to a file using Export, picking the "String" format.

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
1

I finally settled for ScientificForm[SpherePoints[960000],17,NumberFormat->(Row[{#1,"e",#3}]&)] which gave (1st two points as example)

{-1.843418834797695e-3,1.688722657253876e-3,-9.9999687500651e-1},{2.82164651892168e-4,-3.215120673928504e-3,-9.99994791677517e-1}

Followed by a few search & replace in BBEdit, which gave what I needed

{-1.843418834797695e-03f, 1.688722657253876e-03f, -9.9999687500651e-01f},
{2.82164651892168e-04f, -3.215120673928504e-03f, -9.99994791677517e-01f},

Thanks everybody!