Extracting coordinates from a Mathematica spline graphics - wolfram-mathematica

How can one extract the coordinates of all the points which make up the following graphics (here just an example)?
spl = BSplineCurve[{{-.4, -.3}, {0, -.6}, {.4, -.3}, {0, -1.2}},
SplineClosed -> True] ;
Graphics[{Red, Thick, spl}]
The problem is that if I add //FullForm to the last line there is no point coordinates in the output, so no pattern to use to make that extraction:
With a Plotor CoutourPlot output I would have coded Flatten[Cases[Normal#output, Line[x_] :> x, Infinity], 1]
which is not possible here.

The b-spline is itself a graphics primitive so you cant pull out the "line" like that.
You need to use the related BSplineFunction to generate your points:
pts=BSplineFunction[{{-.4, -.3}, {0, -.6}, {.4, -.3}, {0, -1.2}},
SplineClosed -> True] /# Range[0, 1, .01];
Graphics#Line#pts
If you need to extract from a graphic you can do this:
Cases[graphics, BSplineCurve[a__] :> BSplineFunction[a], Infinity]
but you still need to feed it a table of parameter values to get your points.

To extract just the control points you can go:
curveData=Cases[graphics, BSplineCurve[a__] :> a, Infinity]
how many BSplineCurves were found in the graphic?
Length[curveData]
here are the control points of one of them
curveData// First // MatrixForm
If you have a list of BSplineFunctions you can find out much more
so first convert the BSplineCurves to BSplineFunctions as the previous post
bfs =Cases[graphics, BSplineCurve[a__] :> BSplineFunction[a], Infinity]
then you could just go
Inputform[bfs]
and parse the result, but it is cleaner to go:
cdata = Cases[bfs, BSplineFunction[a__] :> a, Infinity];
d = Partition[cdata, 9];
This is Mathematica 11. other versions may need different partitioning
each element of d will be something like:
d[[1]] // MatrixForm
1
{{0.,1.}}
{3}
{False}
{{{0.,0.,0.},{0.,298.986,167.077},{0.,497.083,497.459},{0.,503.603,839.898}},Automatic}
{{0.,0.,0.,0.,1.,1.,1.,1.}}
{0}
MachinePrecision
Unevaluated
The 5th element contains the control point coordinates. The sixth corresponds to the knots. The other elements look familiar but let us not post our guesses!

Related

Wolfram Mathematica 9.0 Generate vertical table

I'm new in system Wolfram Mathematica 9.0 and I want to make table with horizontal approaches. And I had made only vertical ones. Now I will show you:
You did not show the input that produced the undesired output, but I assume it is something like this:
xx = {4, 16};
yy = {3, 5};
TableForm[{{xx}, {yy}}, TableHeadings -> {{"x", "y"}, None}]
To get the output you desire you merely need to leave out the extraneus set of List brackets ({}) around each expression. You can also omit None as this is inferred.
TableForm[{xx, yy}, TableHeadings -> {{"x", "y"}}]
You could also expressly specify the directions with TableDirections:
TableForm[{{xx}, {yy}},
TableHeadings -> {{"x", "y"}},
TableDirections -> {Column, Row, Row}
]
This earlier answer of mine illustrates the way that TableForm formats nested lists:
https://stackoverflow.com/a/5011242/618728

Find the 1st intersection of 2 PDF functions with Mathematica

With Mathematica 8.0.1.0, I have used FindRoot[] to identify the intersection of two 2 pdf functions.
But if I have pdf functions that intersect at more than one point, and I have the upper limit of the x axis range beyond the second intersection, FindRoot[] only returns the second intersection.
pdf1 = 1/x 0.5795367855565214` (E^(
11.170058830053032` (-1.525439351903338` - Log[x]))
Erfc[1.6962452696714152` (-0.5548887795964352` - Log[x])] +
E^(1.2932713057519` (2.60836043407439` + Log[x]))
Erfc[1.6962452696714152` (2.720730943938539` + Log[x])]);
pdf2 = 1/x 0.4648445097126269` (E^(
5.17560914275408` (-2.5500941338198615` - Log[x]))
Erfc[1.7747318880142482` (-2.139288893723375` - Log[x])] +
E^(1.1332542415053757` (3.050849516581922` + Log[x]))
Erfc[1.7747318880142482` (3.1407996592474956` + Log[x])]);
Plot[{pdf1, pdf2}, {x, 0, 0.5}, PlotRange -> All] (* Shows 1st intersection *)
Plot[{pdf1, pdf2}, {x, 0.4, 0.5}, PlotRange -> All] (* Shows 2nd intersection *)
{x /. FindRoot[pdf1 == pdf2, {x, 0.00001, 0.5}],
x /. FindRoot[pdf1 == pdf2, {x, 0.00001, 0.4}]}
The above plots show the issue. When plotted they intersect at two points:
{0.464719, 0.0452777}
respectively.
As I can't know before hand if I'll have a second intersection and I don't know where it might fall on the x axis if I did, can anyone suggest a way to have FindRoot[] only return the first intersection rather than the second?
If not, can anyone suggest another way to go about it?
With FindRoot[], you can only get a single root for a given starting point. Iterating through different options is cumbersome and you might not even get the desired result for certain edge cases unless you hit upon the right choice of starting point.
In this case, something like NSolve or Reduce might be a better option. If you know that your expressions decay, using a reasonable upper bound for possible values of x, you can use the following, which is pretty quick and will give you all roots.
NSolve[{pdf1 == pdf2, 0 < x < 1}, x] // Timing
Out[1]= {0.073495, {{x -> 0.0452777}, {x -> 0.464719}}}
How about the following:
First you have to find all roots in one step. I do this with
roots=Reduce[pdf1==pdf2&&0.000001<x<0.5,x]
And then you could take the minimum (first root on the x axis in your special case).
rootMin=Min[N[x/.{ToRules[roots]}]]

Prevent auto-layout of Graph[] objects in Mathematica 8

Some types of objects have special input/output formatting in Mathematica. This includes Graphics, raster images, and, as of Mathematica 8, graphs (Graph[]). Unfortunately large graphs may take a very long time to visualize, much longer than most other operations I'm doing on them during interactive work.
How can I prevent auto-layout of Graph[] objects in StandardForm and TraditionalForm, and have them displayed as e.g. -Graph-, preferably preserving the interpretability of the output (perhaps using Interpretation?). I think this will involve changing Format and/or MakeBoxes in some way, but I was unsuccessful in getting this to work.
I would like to do this in a reversible way, and preferably define a function that will return the original interactive graph display when applied to a Graph object (not the same as GraphPlot, which is not interactive).
On a related note, is there a way to retrieve Format/MakeBoxes definitions associated with certain symbols? FormatValues is one relevant function, but it is empty for Graph.
Sample session:
In[1]:= Graph[{1->2, 2->3, 3->1}]
Out[1]= -Graph-
In[2]:= interactiveGraphPlot[%] (* note that % works *)
Out[2]= (the usual interactive graph plot should be shown here)
Though I do not have Mathematica 8 to try this in, one possibility is to use this construct:
Unprotect[Graph]
MakeBoxes[g_Graph, StandardForm] /; TrueQ[$short] ^:=
ToBoxes#Interpretation[Skeleton["Graph"], g]
$short = True;
Afterward, a Graph object should display in Skeleton form, and setting $short = False should restore default behavior.
Hopefully this works to automate the switching:
interactiveGraphPlot[g_Graph] := Block[{$short}, Print[g]]
Mark's concern about modifying Graph caused me to consider the option of using $PrePrint. I think this should also prevent the slow layout step from taking place. It may be more desirable, assuming you are not already using $PrePrint for something else.
$PrePrint =
If[TrueQ[$short], # /. _Graph -> Skeleton["Graph"], #] &;
$short = True
Also conveniently, at least with Graphics (again I cannot test with Graph in v7) you can get the graphic with simply Print. Here, shown with Graphics:
g = Plot[Sin[x], {x, 0, 2 Pi}]
(* Out = <<"Graphics">> *)
Then
Print[g]
I left the $short test in place for easy switching via a global symbol, but one could leave it out and use:
$PrePrint = # /. _Graph -> Skeleton["Graph"] &;
And then use $PrePrint = . to reset the default functionality.
You can use GraphLayout option of Graph as well as graph-constructors to suppress the rendering. A graph can still be visualized with GraphPlot. Try the following
{gr1, gr2, gr3} = {RandomGraph[{100, 120}, GraphLayout -> None],
PetersenGraph[10, 3, GraphLayout -> None],
Graph[{1 -> 2, 2 -> 3, 3 -> 1}, GraphLayout -> None]}
In order to make working easier, you can use SetOptions to set GraphLayout option to None for all graph constructors you are interested in.
Have you tried simply suppressing the output? I don't think that V8's Graph command does any layout, if you do so. To explore this, we can generate a large list of edges and compare the timings of graph[edges];, Graph[edges];, and GraphPlot[edges];
In[23]:= SeedRandom[1];
edges = Union[Rule ### (Sort /#
RandomInteger[{1, 5000}, {50000, 2}])];
In[25]:= t = AbsoluteTime[];
graph[edges];
In[27]:= AbsoluteTime[] - t
Out[27]= 0.029354
In[28]:= t = AbsoluteTime[];
Graph[edges];
In[30]:= AbsoluteTime[] - t
Out[30]= 0.080434
In[31]:= t = AbsoluteTime[];
GraphPlot[edges];
In[33]:= AbsoluteTime[] - t
Out[33]= 4.934918
The inert graph command is, of course, the fastest. The Graph command takes much longer, but no where near as long as the GraphPlot command. Thus, it seems to me that Graph is not, in fact, computing the layout, as GraphPlot does.
The logical question is, what is Graph spending it's time on. Let's examine the InputForm of Graph output in a simple case:
Graph[{1 -> 2, 2 -> 3, 3 -> 1, 1 -> 4}] // InputForm
Out[123]//InputForm=
Graph[{1, 2, 3, 4},
{DirectedEdge[1, 2],
DirectedEdge[2, 3],
DirectedEdge[3, 1],
DirectedEdge[1, 4]}]
Note that the vertices of the graph have been determined and I think this is what Graph is doing. In fact, the amount of time it took to compute Graph[edges] in the first example, comparable to the fastest way that I can think to do this:
Union[Sequence ### edges]; // Timing
This took 0.087045 seconds.

Telling Plot to style vector-valued black-box functions in Mathematica

Suppose I write a black-box functions, which evaluates an expensive complex valued function numerically, and then returns real and imaginary part.
fun[x_?InexactNumberQ] := Module[{f = Sin[x]}, {Re[f], Im[f]}]
Then I can use it in Plot as usual, but Plot does not recognize that the function returns a pair, and colors both curves the same color. How does one tell Mathematica that the function specified always returns a vector of a fixed length ? Or how does one style this plot ?
EDIT: Given attempts attempted at answering the problem, I think that avoiding double reevalution is only possible if styling is performed as a post-processing of the graphics obtained. Most likely the following is not robust, but it seems to work for my example:
gr = Plot[fun[x + I], {x, -1, 1}, ImageSize -> 250];
k = 1;
{gr, gr /. {el_Line :> {ColorData[1][k++], el}}}
One possibility is:
Plot[{#[[1]], #[[2]]}, {x, -1, 1}, PlotStyle -> {{Red}, {Blue}}] &# fun[x + I]
Edit
If your functions are not really smooth (ie. almost linear!), there is not much you can do to prevent the double evaluation process, as it will happen (sort of) anyway due to the nature of the Plot[] mesh exploration algorithm.
For example:
fun[x_?InexactNumberQ] := Module[{f = Sin[3 x]}, {Re[f], Im[f]}];
Plot[{#[[1]], #[[2]]}, {x, -1, 1}, Mesh -> All,
PlotStyle -> {{Red}, {Blue}}] &#fun[x + I]
I don't think there's a good solution to this if your function is expensive to compute. Plot will only acknowledge that there are several curves to be styled if you either give it an explicit list of functions as argument, or you give it a function that it can evaluate to a list of values.
The reason you might not want to do what #belisarius suggested is that it would compute the function twice (twice as slow).
However, you could use memoization to avoid this (i.e. the f[x_] := f[x] = ... construct), and go with his solution. But this can fill up your memory quickly if you work with real valued functions. To prevent this you may want to try what I wrote about caching only a limited number of values, to avoid filling up the memory: http://szhorvat.net/pelican/memoization-in-mathematica.html
If possible for your actual application, one way is to allow fun to take symbolic input in addition to just numeric, and then Evaluate it inside of Plot:
fun2[x_] := Module[{f = Sin[x]}, {Re[f], Im[f]}]
Plot[Evaluate[fun2[x + I]], {x, -1, 1}]
This has the same effect as if you had instead evaluated:
Plot[{-Im[Sinh[1 - I x]], Re[Sinh[1 - I x]]}, {x, -1, 1}]

Mathematica: reconstruct an arbitrary nested list after Flatten

What is the simplest way to map an arbitrarily funky nested list expr to a function unflatten so that expr==unflatten##Flatten#expr?
Motivation:
Compile can only handle full arrays (something I just learned -- but not from the error message), so the idea is to use unflatten together with a compiled version of the flattened expression:
fPrivate=Compile[{x,y},Evaluate#Flatten#expr];
f[x_?NumericQ,y_?NumericQ]:=unflatten##fPrivate[x,y]
Example of a solution to a less general problem:
What I actually need to do is to calculate all the derivatives for a given multivariate function up to some order. For this case, I hack my way along like so:
expr=Table[D[x^2 y+y^3,{{x,y},k}],{k,0,2}];
unflatten=Module[{f,x,y,a,b,sslot,tt},
tt=Table[D[f[x,y],{{x,y},k}],{k,0,2}] /.
{Derivative[a_,b_][_][__]-> x[a,b], f[__]-> x[0,0]};
(Evaluate[tt/.MapIndexed[#1->sslot[#2[[1]]]&,
Flatten[tt]]/. sslot-> Slot]&) ]
Out[1]= {x^2 y + y^3, {2 x y, x^2 + 3 y^2}, {{2 y, 2 x}, {2 x, 6 y}}}
Out[2]= {#1, {#2, #3}, {{#4, #5}, {#5, #7}}} &
This works, but it is neither elegant nor general.
Edit: Here is the "job security" version of the solution provided by aaz:
makeUnflatten[expr_List]:=Module[{i=1},
Function#Evaluate#ReplaceAll[
If[ListQ[#1],Map[#0,#1],i++]&#expr,
i_Integer-> Slot[i]]]
It works a charm:
In[2]= makeUnflatten[expr]
Out[2]= {#1,{#2,#3},{{#4,#5},{#6,#7}}}&
You obviously need to save some information about list structure, because Flatten[{a,{b,c}}]==Flatten[{{a,b},c}].
If ArrayQ[expr], then the list structure is given by Dimensions[expr] and you can reconstruct it with Partition. E.g.
expr = {{a, b, c}, {d, e, f}};
dimensions = Dimensions[expr]
{2,3}
unflatten = Fold[Partition, #1, Reverse[Drop[dimensions, 1]]]&;
expr == unflatten # Flatten[expr]
(The Partition man page actually has a similar example called unflatten.)
If expr is not an array, you can try this:
expr = {a, {b, c}};
indexes = Module[{i=0}, If[ListQ[#1], Map[#0, #1], ++i]& #expr]
{1, {2, 3}}
slots = indexes /. {i_Integer -> Slot[i]}
{#1, {#2, #3}}
unflatten = Function[Release[slots]]
{#1, {#2, #3}} &
expr == unflatten ## Flatten[expr]
I am not sure what you are trying to do with Compile. It is used when you want to evaluate procedural or functional expressions very quickly on numerical values, so I don't think it is going to help here. If repeated calculations of D[f,...] are impeding your performance, you can precompute and store them with something like
Table[d[k]=D[f,{{x,y},k}],{k,0,kk}];
Then just call d[k] to get the kth derivative.
I just wanted to update the excellent solutions by aaz and Janus. It seems that, at least in Mathematica 9.0.1.0 on Mac OSX, the assignment (see aaz's solution)
{i_Integer -> Slot[i]}
fails. If, however, we use
{i_Integer :> Slot[i]}
instead, we succeed. The same holds, of course, for the ReplaceAll call in Janus's "job security" version.
For good measure, I include my own function.
unflatten[ex_List, exOriginal_List] :=
Module[
{indexes, slots, unflat},
indexes =
Module[
{i = 0},
If[ListQ[#1], Map[#0, #1], ++i] &#exOriginal
];
slots = indexes /. {i_Integer :> Slot[i]};
unflat = Function[Release[slots]];
unflat ## ex
];
(* example *)
expr = {a, {b, c}};
expr // Flatten // unflatten[#, expr] &
It might seem a little like a cheat to use the original expression in the function, but as aaz points out, we need some information from the original expression. While you don't need it all, in order to have a single function that can unflatten, all is necessary.
My application is similar to Janus's: I am parallelizing calls to Simplify for a tensor. Using ParallelTable I can significantly improve performance, but I wreck the tensor structure in the process. This gives me a quick way to reconstruct my original tensor, simplified.

Resources