Can I express an abstract, symbolic range of reals?

Hello, I'm very new at sage. I'd like to express a range like range(-3.0,3.0,0.02) but with symbols for all the parameters, like range(a,b,delta), that displays nicely with show(). I would like to be able to substitute in floats at some later stage.

a. I'm not sure what a conventional symbolic expression for a range of floats is

b. Not sure how to express it in SageMath.

My goal is to be able to express constructing a chain rule over a finite input range. I seem to be able to express the chaining of functions ok, but am getting stuck with what i'm calling the constant function which is this range. If I use the range(-3.0,3.0,0.02) I get swamped by the output.

P.S. I don't want to use a built-in differentiate, I'm going to use finite differences.

Cheers...

edit retag close merge delete

In Jupyter notebook I'm up to here, could be horribly unconventional:

from typing import List, Dict, Callable
# A Function takes in an ndarray as an argument and produces an ndarray
Array_Function = Callable[[ndarray], ndarray]
Chain = List[Array_Function]

identity_function(x) = SR('x')

def compose(chain: Chain)-> Callable:
if not chain:
return identity_function
else:
return chain[0](compose(chain[1:]))

input_range = np.arange(-3, 3, 0.02)

c0: Chain = [x ** 2, max(0.2 * x,x), 1 / (1 + exp(-x))]
sigmoid,lru,square = c0
show([sigmoid,lru,square])

show(compose(c0))

( 2020-06-13 04:47:42 +0100 )edit

"If I use the range(-3.0,3.0,0.02) I get swamped by the output."

In that case, I usually do L=range(-3.0,3.0,0.02) to avoid to be swamped by the output.

( 2020-06-16 09:53:15 +0100 )edit

Sort by » oldest newest most voted

This is not an abstract symbolic expression for a range - which I would still like, but this answer uses numpy to provide its default output summary with ellipses for large arrays. Solves my practical problem of too much output.
ref: https://doc.sagemath.org/html/en/thematic_tutorials/numerical_sage/numpy.html

  import numpy as np

l = np.array(srange(-3.0, 3.0, 0.002))
show(l)

[⎯𝟹.⎯𝟸.𝟿𝟿𝟾⎯𝟸.𝟿𝟿𝟼...𝟸.𝟿𝟿𝟺𝟸.𝟿𝟿𝟼𝟸.𝟿𝟿𝟾]

more

The answer from @Sebastien displayed ellipses in its output summary, maybe this feature is broken in sage's jupyter notebook implementation?

( 2020-06-15 06:26:14 +0100 )edit
1

( 2020-06-16 08:59:31 +0100 )edit

I don't know for the symbolic range, but note that sage provides srange which takes floats as input:

sage: srange(-3.0,3.0,0.02)
[-3.00000000000000,
-2.98000000000000,
-2.96000000000000,
-2.94000000000000,
...
2.96000000000000,
2.98000000000000]


EDIT:

Above, the ellipse "..." replacing the long output was done by hand. To have the ellipse to appear automatically, the best is to create your own class. For example:

sage: class MyRange(SageObject):
....:     def __init__(self, start, stop, step):
....:         self._start = start
....:         self._stop = stop
....:         self._step = step
....:     def to_srange(self):
....:         return srange(self._start, self._stop, self._step)
....:     def __iter__(self):
....:         return iter(self.to_srange())
....:     def __repr__(self):
....:         L = self.to_srange()
....:         if len(L) < 10:
....:             return repr(L)
....:         else:
....:             Lellipse = L[:3] + ["..."] + L[-3:]
....:             return '['+', '.join(str(a) for a in Lellipse)+']'
....:
....:
sage: MyRange(-3,3,1)      # short list no ellipse
[-3, -2, -1, 0, 1, 2]
sage: MyRange(-3,3,0.02)    # long list with ellipse
[-3.00000000000000, -2.98000000000000, -2.96000000000000, ..., 2.94000000000000, 2.96000000000000, 2.98000000000000]
sage: sum(a^2 for a in MyRange(-3,3,0.02))
900.020000000001
sage: sum(a^2 for a in srange(-3,3,0.02))   # confirms that MyRange considers the whole list
900.020000000001


To learn how to use classes in Python/Sage, you may also look at this fruit.py example available in my optional package.

more

Thanks, Have already tried that. Same swamped output. Want to be able to have symbolic parameters to the range expression. Or equivalent - with a compact show() output.

srange( a, b, delta)

( 2020-06-14 21:44:14 +0100 )edit

I think you want to create a Python class and write your own __repr__ method. Let me update my answer...

( 2020-06-16 09:43:19 +0100 )edit

Thanks @Sebastien - I think you are right. Though I found numpy arrays seem to do the ellipses nicely. Maybe I really need to write a class for a symbolically parameterised range, which can be realised. Seems weird not to have one. I keep feeling I’ve missed something obvious.

Very hard to work out which way to do things when starting out - unsurprisingly :-)

( 2020-06-19 01:25:15 +0100 )edit

When I work with long ranges, I usually don't need to look at them. I just store them in a variable and that's it. But, it is true that such feature is useful. For example, the string representation of a pandas dataframe containing millions of lines will print only the few first and few last lines.

( 2020-06-19 14:36:15 +0100 )edit