How can I get exactly 5 logarithmic divisions of an interval?

Writing one wouldn't be that hard. You can convert it to Log10 and then let FindDivisions do all the work in log space before converting it back. For example:

findLogDivisions[{xmin_, xmax_}, n_Integer] := 10^FindDivisions[Log10@{xmin, xmax}, n]

Then, to find 4 "nice" divisions in log space between 1 and 1000, you simply need to do:

findLogDivisions[{1, 1000}, 5] 
(* {1, 10, 100, 1000} *)

EDIT:

After 3 years, it has been discovered that this oft-linked-to answer doesn't truly space logarithmically. It's close, which was all I was going for at the time (and handles zeros), but it's not quite right. Anyway, thanks to @Pickett's careful moderation, here's a better version...

logspace[increments_, start_?Positive, end_?Positive] :=
 Exp@Range[Log@start, Log@end, Log[end/start]/increments]

This one, by the stodgy nature of Logs, won't handle non-positive numbers, so I'll leave the old answer. Sorry to all that lost millions in the stock market using the old function. :)

OLD FUNCTION

I built a function that calculates log spaced increments for a job at work. I've added a catch where it will handle log spacing from 0 to a number.

logspace [increments_, start_, end_] := Module[{a}, (
   a = Range[0, increments];
   Exp[a/increments*Log[(end - start) + 1]] - 1 + start
   )]

To try it out:

N@logspace[5,1,1000]

(*{1., 3.98107, 15.8489, 63.0957, 251.189, 1000.}*)

To view it on a number line:

a = N@logspace[10, 0, 10];
Graphics[Point@Transpose[{a, ConstantArray[.5, 11]}], Axes -> {True, False}, 
   AxesStyle -> Arrowheads[.05]]

enter image description here

And if you want to find the distances between divisions, use Differences:

Differences[a]

(*{0.270982, 0.344413, 0.437742, 0.556362, 0.707126, 0.898744, 1.14229, 1.45183, 1.84524, 2.34527}*)

Here's a mathematically simple approach, assuming that exactly n divisions are sought, no matter how nice or not.

This produces exactly n intervals:

Clear[logDiv];
logDiv[{x_?Positive, y_?Positive}, n_Integer /; n > 0] := 
  x (y/x)^Range[0, 1, 1/n]

logDiv[{10, 10000}, 3]
(* {10, 100, 1000, 10000} *)

If you want n "fence posts", use

Clear[logDiv];
logDiv[{x_?Positive, y_?Positive}, n_Integer /; n > 1] := 
  x (y/x)^Range[0, 1, 1/(n-1)]

If you want n interior division points, change n to n+1 in the first version.


Comparisons. Kuba's method produces the same output as logDiv mutatis mutandis​*. Below I use the first version of logDiv and omit Kuba's output.

Comparison 1:

N @ logDiv[{1/10, 100000}, 3]           (* same output as Kuba *)
N @ logspace[3, 1/10, 100000]           (* kale *)
N @ findLogDivisions[{1/10, 100000}, 3] (* rm -rf *)
(*
  {0.1, 10., 1000., 100000.}
  {0.1, 45.516, 2153.55, 100000.}
  {0.01, 1., 100., 10000., 1.*10^6}
*)

Comparison 2:

N @ logDiv[{10, 100000}, 5]
N @ logspace[5, 10, 100000]
N @ findLogDivisions[{10, 100000}, 5]
(*
  {10., 63.0957, 398.107, 2511.89, 15848.9, 100000.}
  {10., 18.9998, 108.996, 1008.95, 10008.3, 100000.}
  {10., 100., 1000., 10000., 100000.}
*)

Note the outputs vary; in particular logspace does something quite different than the others when start is different than 1. Depending on the application, one or the other might be desired.


*In honor of the language survey.