What it the best way to plot a vertical line using Octave?
So, I have two methods for this. One, I found, and the other I made up.
Method 1: From here.
%% Set x value where verticle line should intersect the x-axis.
x = 0;
%% plot a line between two points using plot([x1,x2],[y1,y2])
plot([x,x],[-10,10]);
Method 2: A slightly different approach, exact same result
%% Setup a vector of x values
x = linspace(0,0,100);
%% Setup a vector of y values
y = linspace(0,10,100);
%% Plot the paired points in a line
plot(x,y);
I think Method 2 may write more information to memory before the plot process and it's a line longer, so in my eyes, Method 1 should be the better option. If you prefer Method 2, make sure your x and y vectors are the same dimension or you'll end up with a bunch of dots where you're line should be.
Unfortunately the Octave documentation for doing obvious things can be ridiculously lousy with no working examples. Drawing a simple line on top of a plot is one.
As already mentioned, it's is very silly to plot straight lines in octave. It's a waste of memory and processing. Instead use the line() function, to draw on top of your plot.
The line() function require 2 non-standard x-values and y-values vectors, instead of the standard point-slope arguments for point A and point B, normally represented by (x1,y1) and (x2,y2). Instead, you need to write this as: X=(x1,x2) and Y=(y1,y2). Thus confusing every living soul!
Here is an example of the correct way to do this in Octave language:
pkg load statistics % Need to load the statistics package
x = randn (1,1000); % Normal Distribution of random numbers
clf; histfit(x) % Make a histogram plot of x and fit the data
ylim ([-20,100]) % Change the plot limits (to lift graph up)
% Draw the (vertical) line between (0,-10) and (0,90)
line ("xdata",[0,0], "ydata",[-10,90], "linewidth", 3)
With the result:
notation (x1,x2),(y1,y2) is really confusing and against textbooks.
Anyway, this is my way:
figure;
hold on;
% vertical line x=0
plot([0,0],[0,10]);
%horizontal line y=0
plot([0,10],[0,0]);
% vertical line x=2
plot([2,2],[0,10]);
hold off;
Related
So, I have a vector that corresponds to a given feature (same dimensionality). Is there a package in Julia that would provide a mathematical function that fits these data points, in relation to the original feature? In other words, I have x and y (both vectors) and need to find a decent mapping between the two, even if it's a highly complex one. The output of this process should be a symbolic formula that connects x and y, e.g. (:x)^3 + log(:x) - 4.2454. It's fine if it's just a polynomial approximation.
I imagine this is a walk in the park if you employ Genetic Programming, but I'd rather opt for a simpler (and faster) approach, if it's available. Thanks
Turns out the Polynomials.jl package includes the function polyfit which does Lagrange interpolation. A usage example would go:
using Polynomials # install with Pkg.add("Polynomials")
x = [1,2,3] # demo x
y = [10,12,4] # demo y
polyfit(x,y)
The last line returns:
Poly(-2.0 + 17.0x - 5.0x^2)`
which evaluates to the correct values.
The polyfit function accepts a maximal degree for the output polynomial, but defaults to using the length of the input vectors x and y minus 1. This is the same degree as the polynomial from the Lagrange formula, and since polynomials of such degree agree on the inputs only if they are identical (this is a basic theorem) - it can be certain this is the same Lagrange polynomial and in fact the only one of such a degree to have this property.
Thanks to the developers of Polynomial.jl for leaving me just to google my way to an Answer.
Take a look to MARS regression. Multi adaptive regression splines.
For example , if I want to plot Sin(z) where z is a complex variable , how I will achieve it in either Octave or Maxima?
I don't know about Octave, but here is a message about that, with some code you can try in Maxima: https://www.ma.utexas.edu/pipermail/maxima/2007/006644.html
There may be more specific information for wxMaxima -- you can try their user forum: https://sourceforge.net/p/wxmaxima/discussion/435775/
(referring Octave 4.0.0)
How do you want to try to represent the output of the function? Plotting either the real or imaginary parts of the output can be done fairly simply using a 3-dimensional graph, where the x and y axes are the real and imaginary components of z, and the vertical axis is either the real or imaginary values of sin(z). Producing those are fairly simple in Octave. Here's a link to a script you can save and run to show an example.
Simply change the g = exp(f) line to g = sin(f).
Octave-help mailing list example
Note that the imaginary part plot is commented out. Just switch the # between the different plot commands if you want to see that part.
Now, are you instead looking for options to map the Z plane (z=x+iy) to the W plane (w=u+iv) and represent closed contours mapped by w=sin(z)? in that case you'll need to do parametric plotting as described on this FIT site. There is a link to his Matlab program at the bottom of the explanation that provides one method of using color coding to match z->w plane contour mapping.
Those m-files are written for Matlab, so a few things do not work, but the basic plotting is compatible with Octave 4.0.0. (the top level ss13.m file will fail on calls to flops and imwrite)
But, if you put your desired function in myfun13.m for f, df and d2f, (sin(z), cos(z), -sin(z) respectively), then run cvplot13, you'll get color maps showing the correspondence between z and w planes.
wxMaxima has a plot3d that can do it. Since the expression to plot is in terms of x and y, I plotted the function's magnitude with abs(f(x+%i*y)):
plot3d(abs((x+%i*y-3)*(x+%i*y-5)*(x+%i*y-6)), [x,2,7], [y,-1,1], [grid,100,100], [z,0,5])$
I'd like to know how to plot power series (whose variable is x), but I don't even know where to start with.
I know it might not be possible plot infinite series, but it'd do as well plotting the sum of the first n terms.
Gnuplot has a sum function, which can be used inside the using statement to sum up several columns or terms. Together with the special file name + you can implement power series.
Consider the exponention function, which has a power series
\sum_{n=0}^\infty x^n/n!
So, we define a term as
term(x, n) = x**n/n!
Now we can plot the power series up to the n=5 term with
set xrange [0:4]
term(x, n) = x**n/n!
set samples 20
plot '+' using 1:(sum [n=0:5] term($1, n))
To plot the results when using 2 to 7 terms and compare it with the actual exp function, use
term(x, n) = x**n/n!
set xrange [-2:2]
set samples 41
set key left
plot exp(x), for [i=1:6] '+' using 1:(sum[t=0:i] term($1, t)) title sprintf('%d terms', i)
The easiest way that I can think of is to generate a file that has a column of x-values and a column of f(x) values, then just plot the table like you would any other data. A power series is continuous, so you can just connect the dots and have a fairly accurate representation (provided your dots are close enough together). Also, when evaluating f(x), you just sum up the first N terms (where N is big enough). Big enough means that the sum of the rest of the terms is smaller than whatever error you allow. (*If you want 3 good digits, then N needs to be large enough that the remaining sum is smaller than .001.)
You can pull out a calc II textbook to determine how to bound the error on the tail of the sum. A lot of calc classes briefly cover it, but students tend to feel like the error estimates are pointless (I know because I've taught the course a few times.) As an example, if you have an alternating series (whose terms are decreasing in absolute value), then the absolute value of the first term you omit (don't sum) is an upperbound on your error.
*This statement is not 100% true, it is slightly over simplified, but is correct for most practical purposes.
I made this graph in wolfram alpha by accident:
Can you write code to produce a larger version of this pattern?
Can you make similar looking patterns?
Readable code in any language is good, but something that can be run in a browser would be best (i.e. JavaScript / Canvas). If you write code in other languages, please include a screenshot.
Notes:
The input formula for the above image is: arg(sin(x+iy)) = sin^(-1)((sqrt(2) cos(x) sinh(y))/sqrt(cosh(2 y)-cos(2 x))) (link)
You don't have to use to use the above formula. Anything which produces a similar result would be cool. But "reverse engineering" Wolfram Alpha would be best
The two sides of the equation are equal (I think), So WA should have probably only returned 'true' instead of the graph
The pattern is probably the result of rounding errors.
I don't know if the pattern was generated by iterating over every pixel or if it's vector based (points and lines). My guess is with vector.
I don't know what causes this type of pattern ('Rounding errors' is the best guess.)
IEEE floating point standard does not say how sin or cos, etc should work, so trig functions vary between platforms and architectures.
No brownian motion plots please
Finally, here's another example which might help in your mission: (link)
As you asked for similar looking patterns in any language, here is the Mathematica code (really easy since Wolfram Alpha is based on Mathematica)
Edit
It is indeed a roundoff effect:
If we set:
and make a plot
Plot3D[f[x, y], {x, 7, 9}, {y, -8, -9},WorkingPrecision -> MachinePrecision]
The result is:
But if we extend the precision of the plot to 30 digits:
Plot3D[f[x, y], {x, 7, 9}, {y, -8, -9},WorkingPrecision -> 30]
We get
and the roughness is gone (which caused your scribbly pattern)
BTW, your f[x,y] is a very nice function:
So if I managed to copy your formulas without errors (which should be considered a miracle), both sides of your equation are equal only in certain periodic ranges in x, probably of the form [2 n Pi, (2 n + 1) Pi]
I have an unsorted list of noisy X, Y points. They do, however, form a path through the world. I would like an algorithm to draw an approximation of this data using line segments.
This is similar to how you would use a line -fitting algorithm to pick an approximation of linear data. My problem is only harder because the path bends and winds around the world.
alt text http://www.praeclarum.org/so/pathfinder.png
Does anyone know of any standard / robust / easy to comprehend algorithms to accomplish this?
Q&A:
What do you mean by noisy? If I had an ideal realization of the path, then my set of points would be sampled from that ideal path with gaussian noise added to the X and Y elements. I do not know the mean or standard deviation of that noise. I may be able to guess at the std dev...
Do the points lie near, but not on, some ideal but complicated path which you seek to approximate? Yes.
Do you have any a priori information about he shape of the path? Any other way to get such information? Unfortunately not.
Bezier Interpolation may fit your problem.
This does not address the ordering of the points into a path, however; there are a number of approaches to consider:
Any "optimal" type of path (e.g. smallest direction change at each point on the path, * Shortest path through all points) will likely boil down the NP complete Travelling Salesman Problem (TSP).
A "reasonable" path to cluster the nodes and then route between clusters, and within clusters. Of course, the larger the cluster, or the larger the number of clusters the more this smaller problem looks like a large n TSP.
Ordering the points by one axis. If there are much more than 2 axes, some dimensional reduction strategy may be useful. e.g. Independent Component Analysis.
With an unsorted list, you won't really know which points to include in each segment, so I guess you could just go with the closest point.
One way could be to pick a start point at random, and pick the closest point as the next point in each step. Add the first two points to a set S.
Fit a line to the points in S until the RMS exceeds some value, then clear S and start a new line.
The intersection of consecutive lines would be the end-points of the segments.
If your points are close to each other, you can normal "straight" lines (orthogonal lines). Using the normal smoothing algorithms. You can see the world as being flat.
If they are far apart, you need to compensate for the rounding of the earth, by using great circles to navigate from point to point. Otherwise your straight lines will make a longer way.
It is your choice if a point is too far to create straight lines.
Further you have to know if you need to "visit" each point, or just need to go near, and how near that near is.
If you need to send the course(s) to a plane, ship or other traveller, you probably need to visit each point. If you get the GPS data from an object, you probably just want to plot a course on a screen, and remove the noise.
After seeing your edits:
If this is an object moving some traject you want to plot, you might want to smooth the direction and speed instead of the x/y values. (Making your measured values (x) have a fixed and increasing Y-interval makes smoothing a lot easier.)
Here is a heuristic hack that might address the ordering problem for the data, if
you have enough points
the mean distance between points is small compared to the smallest radius of curvature expected of the path
the mean distance between points is not large compared to the std. dev. of the noise
the path is not self-crossing (you might get lucky, but no guarantees)
Proceed like this:
Pick (hopefully by a meaningful rather than random means) a starting point, p1.
Find all the points that lie within some clustering distance, r_c of p1. Choose r_c small compared to the expected turning radius, but large compared to the scatter.
Call this cluster C1.
Find point q1 the mean of positions in C1.
Fit a line to the points in C1 and project to (or just beyond) the edge of the cluster, and find the nearest point in your original data. Label that point p2.
Iterate steps 2-5 until you run out of data.
Now you have a new list of points q1..qn that are ordered.
Off the top of my head, very rough, and only works under pretty good conditions...
Self-crossing behavior can probably be improved by requiring in step (5) that the new projected line lie within some maximum angle of the previous one.
The problem with the Bezier curve is that is doesn't actually go though the points you have sampled and even though the points samples are distorted a little; the bezier curve might actually be miles off.
A better approximation, and a solution that seems to resemble the original image way better is a Catmull-Rom Spline because it does run though all the points in the curve.
My approach would be to first sort your list of points, then use a bezier curve.
The trick is of course the sorting. Start with one random point and find the nearest point. Assume these two are connected. With those two endpoints, find the nearest points to them. Assume that the one with the smaller distance to it's endpoint is connected to that point. Repeat until all points are connected.
I assume that there are still some problems with this approach, but maybe you can use it as a starting point (pun intended).
Edit: You can do it several times with different starting points, and then see where the results differ. That at least gives you some confidence, which points are connected to each other.
A completely different approach, that does not require another constraint, but details may depend on your application. It sghould work best if you have a "dense cloud of points" around the path.
Use a "cost" function that defines the difference between the curve and the cloud of points. Use a parametrized curve, and a standard optimization algorithm. - OR -
Start with a straight curve from start to end, then use a genetic algorithm to modify it.
The typical cost function would be to take the smallest distance between each point and the curve, and sum the squares.
I have not enough experience to suggest an optimization or genetic algorithm but I am sure it can be done :)
I could imagine a genetic algorithm as follows:
The path will be built from Waypoints. Start with putting N waypoints in a straigt line from start to end. (N can be chosen depending on the problem). Mutations could be:
For each segment, if rnd() < x, a new waypoint is introduced in the middle.
For each waypoint, the X and Y coordinate are varied slightly.
You will need to include the total length in the cost function. Splitting might not be needed, or maybe x (the "split chance") might need to decrease as more waypoints are introduced. You may or may not want to apply (2) to the start- and endpoint.
Would be fun to try that...
I take it that "unsorted list" means that while your set of points is complete, you don't know what order they were travelled through?
The gaussian noise has to be basically ignored. We're given absolutely no information that allows us to make any attempt to reconstruct the original, un-noisy path. So I think the best we can do is assume the points are correct.
At this point, the task consists of "find the best path through a set of points", with "best" left vague. I whipped up some code that attempts to order a set of points in euclidean space, preferring orderings that result in straighter lines. While the metric was easy to implement, I couldn't think of a good way to improve the ordering based on that, so I just randomly swap points looking for a better arrangement.
So, here is some PLT Scheme code that does that.
#lang scheme
(require (only-in srfi/1 iota))
; a bunch of trig
(define (deg->rad d)
(* pi (/ d 180)))
(define (rad->deg r)
(* 180 (/ r pi)))
(define (euclidean-length v)
(sqrt (apply + (map (lambda (x) (expt x 2)) v))))
(define (dot a b)
(apply + (map * a b)))
(define (angle-ratio a b)
(/ (dot a b)
(* (euclidean-length a) (euclidean-length b))))
; given a list of 3 points, calculate the likelihood of the
; angle they represent. straight is better.
(define (probability-triple a b c)
(let ([av (map - a b)]
[bv (map - c b)])
(cos (/ (- pi (abs (acos (angle-ratio av bv)))) 2))))
; makes a random 2d point. uncomment the bit for a 3d point
(define (random-point . x)
(list (/ (random 1000) 100)
(/ (random 1000) 100)
#;(/ (random 1000) 100)))
; calculate the likelihood of an entire list of points
(define (point-order-likelihood lst)
(if (null? (cdddr lst))
1
(* (probability-triple (car lst)
(cadr lst)
(caddr lst))
(point-order-likelihood (cdr lst)))))
; just print a list of points
(define (print-points lst)
(for ([p (in-list lst)])
(printf "~a~n"
(string-join (map number->string
(map exact->inexact p))
" "))))
; attempts to improve upon a list
(define (find-better-arrangement start
; by default, try only 10 times to find something better
[tries 10]
; if we find an arrangement that is as good as one where
; every segment bends by 22.5 degrees (which would be
; reasonably gentle) then call it good enough. higher
; cut offs are more demanding.
[cut-off (expt (cos (/ pi 8))
(- (length start) 2))])
(let ([vec (list->vector start)]
; evaluate what we've started with
[eval (point-order-likelihood start)])
(let/ec done
; if the current list exceeds the cut off, we're done
(when (> eval cut-off)
(done start))
; otherwise, try no more than 'tries' times...
(for ([x (in-range tries)])
; pick two random points in the list
(let ([ai (random (vector-length vec))]
[bi (random (vector-length vec))])
; if they're the same...
(when (= ai bi)
; increment the second by 1, wrapping around the list if necessary
(set! bi (modulo (add1 bi) (vector-length vec))))
; take the values from the two positions...
(let ([a (vector-ref vec ai)]
[b (vector-ref vec bi)])
; swap them
(vector-set! vec bi a)
(vector-set! vec ai b)
; make a list out of the vector
(let ([new (vector->list vec)])
; if it evaluates to better
(when (> (point-order-likelihood new) eval)
; start over with it
(done (find-better-arrangement new tries cut-off)))))))
; we fell out the bottom of the search. just give back what we started with
start)))
; evaluate, display, and improve a list of points, five times
(define points (map random-point (iota 10)))
(define tmp points)
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 10))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 100))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 1000))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
(set! tmp (find-better-arrangement tmp 10000))
(printf "~a~n" (point-order-likelihood tmp))
(print-points tmp)
It seems that you know the 'golden curve' from your answers to questions, I would suggest finding the Bezier curve of the 'golden curve' as suggested by #jamesh and drawing that.
How many points you have?
A Bezier curve, as mentioned, is a good idea if you have comparedly few points. If you have many points, buiding clusters as suggested by dmckee.
However you also need another constraint for defining the order of points. There have been many good suggestions for how to chose the points, but unless you introduce another constraint, any gives a possible solution.
Possible constraints I can think of:
shortest path
most straight segments
least total absolute rotation
directional preference (i.e. horizontal / vertical is more likely than crisscrossing)
In all cases, to meet the constraint you probably need to test all permutations of the sequence. If you start with a "good guess", you cayn terminate the others quickly.