0

I have the following SageMath code, which works perfectly in CoCalc:

def mean_x(factor, values):
    return sum([cos(2*pi*v/factor) for v in values])/len(values)

def mean_y(factor, values):
    return sum([sin(2*pi*v/factor) for v in values])/len(values)

def calculatePeriodAppeal(factor, values):
    mx = mean_x(factor, values)
    my = mean_y(factor, values)
    appeal = sqrt(mx^2+my^2)
    return appeal

def calculateBestLinear(factor, values):
    mx = mean_x(factor, values).n()
    my = mean_y(factor, values).n()
    y0 = factor*atan2(my,mx)/(2*pi).n()
    err = 1-sqrt(mx^2+my^2).n()
    return [factor*x + y0, err]

def calculateGCDAppeal(factor, values):
    mx = mean_x(factor, values)
    my = mean_y(factor, values)
    appeal = 1 - sqrt((mx-1)^2+my^2)/2
    return appeal

testSeq = [0,125,211,287,408,520,650,735,816,942,1060] 
gcd = calculateGCDAppeal(x, testSeq)
agcd = find_local_maximum(gcd,2,100)
print(agcd)
plot(gcd,(x, 2, 100))

The output is the best approximate greatest common divisor of the numbers from testSeq, along with a plot.

How can I use this code in Python?

Here is the current Python version, which does not yet work:

import numpy as np
import sage as sm

def mean_x(factor, values):
    return sum([np.cos(2*np.pi*v/factor) for v in values])/len(values)

def mean_y(factor, values):
    return sum([np.sin(2*np.pi*v/factor) for v in values])/len(values)

def calculatePeriodAppeal(factor, values):
    mx = mean_x(factor, values)
    my = mean_y(factor, values)
    appeal = np.sqrt(mx**2+my**2)
    return appeal

def calculateBestLinear(factor, values):
    mx = mean_x(factor, values).n()
    my = mean_y(factor, values).n()
    y0 = factor*np.atan2(my,mx)/(2*np.pi).n()
    err = 1-np.sqrt(mx**2+my**2).n()
    return [factor*x + y0, err]

def calculateGCDAppeal(factor, values):
    mx = mean_x(factor, values)
    my = mean_y(factor, values)
    appeal = 1 - np.sqrt((mx-1)**2+my**2)/2
    return appeal

testSeq = [0,125,211,287,408,520,650,735,816,942,1060] 
gcd = calculateGCDAppeal(x, testSeq)
agcd = sm.find_local_maximum(gcd,2,100)
print(agcd)

The errors I get are:

Traceback (most recent call last):

  File "<ipython-input-805-d2a8b405fd43>", line 30, in <module>
    gcd = calculateGCDAppeal(x, testSeq)

NameError: name 'x' is not defined

I don't understand this because because this code works in CoCalc.

Traceback (most recent call last):
    
      File "<ipython-input-803-80cdeb0485a5>", line 33, in <module>
        agcd = sm.find_local_maximum(gcd,2,100)
    
    AttributeError: module 'sage' has no attribute 'find_local_maximum'

...but I know that SageMath has the function find_local_maximum.

If I use numerical.optimize.find_local_maximum instead, I get:

Traceback (most recent call last):

  File "<ipython-input-842-949de8b03df5>", line 34, in <module>
    agcd = sm.numerical.optimize.find_local_maximum(gcd,2,100)

AttributeError: module 'sage' has no attribute 'numerical'

I don't know how to add the "numerical" attribute.

user90664
  • 75
  • 8
  • Please supply the expected [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). This includes the *entire* error message with traceback. On a quick scan, I see two references to `x` and no definition. Please link to the `sage` documentation, or other external evidence that the function exists in the version you import. – Prune Sep 08 '20 at 22:51

2 Answers2

0

First of all, there is no definition of x anywhere in this code. In addition, the syntax of find_local_maximum is sage.numerical.optimize.find_local_maximum not sage.find_local_maximum (from the SageMath documentation)

Seth
  • 2,214
  • 1
  • 7
  • 21
  • I realize that a definition of x is missing, but I don't understand why SageMath run in CoCalc doesn't require that. Also, I tried sage.numerical.optimize.find_local_maximum but that didn't work, either (see error and Traceback above. – user90664 Sep 09 '20 at 00:25
  • When I run your first snippet in CoCalc I get the same NameError that you posted in your question ([see here](https://cocalc.com/4f2b2945-0ea2-466a-897a-b7417c5c12e8/raw/2020-09-08-174428.html)). I don't know why yours is working, because it shouldn't. @user90664 – Seth Sep 09 '20 at 00:45
  • Thank you for trying. I can't access what you linked to, unfortunately. Here's a [screen shot](https://docs.google.com/document/d/1zlFbTWfmeKqZHOva7BxAdZiJ8YE-vpa4b7diiEJQJvI/edit?usp=sharing) of it working for me. – user90664 Sep 09 '20 at 01:19
  • @jmmurillo Hi jmmurillo, I got this [code](https://math.stackexchange.com/questions/914288/how-to-find-the-approximate-basic-period-or-gcd-of-a-list-of-numbers) from you. (Thank you!) Can you help me figure out how to use it in Python? – user90664 Sep 09 '20 at 01:27
0

When Sage starts, it imports a lot of things.

When using Python, you need to import them yourself.

In particular, Sage defines x when it starts.

To import it if using Python:

from sage.calculus.predefined import x

Find this out using the import_statements function in a Sage session.

The quick workaround is the catch-all

from sage.all import *

but it's good practice to import only what is needed.

See the answer to this related question

Samuel Lelièvre
  • 3,212
  • 1
  • 14
  • 27
  • Thank you, but unfortunately it still isn't working for me. I'm guessing it's for the reason mentioned [here](https://stackoverflow.com/questions/50039916/no-module-named-sage-all). – user90664 Sep 11 '20 at 18:51
  • Python code that uses Sage library code needs a Python with the Sage library installed. So far this cannot be done using pip but there is work on that. – Samuel Lelièvre Sep 12 '20 at 22:30