diff --git a/.github/workflows/doc_checks.yml b/.github/workflows/doc_checks.yml index c7b51470..29209fb8 100644 --- a/.github/workflows/doc_checks.yml +++ b/.github/workflows/doc_checks.yml @@ -2,6 +2,13 @@ name: Documentation check on: - pull_request +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: doc_checks: runs-on: ubuntu-latest @@ -9,10 +16,8 @@ jobs: QISKIT_SETTINGS: ${{github.workspace}}/docs/qiskit_settings.conf steps: - - name: Cancel Workflow Action - uses: styfle/cancel-workflow-action@0.11.0 - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: sQUlearn/sphinx-action@master with: diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 23f3a7be..20598994 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -2,23 +2,27 @@ name: Formatting check on: - pull_request +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: black: runs-on: ubuntu-latest steps: - - name: Cancel Workflow Action - uses: styfle/cancel-workflow-action@0.11.0 - - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: - python-version: 3.9 + python-version: 3.13 - name: Install dependencies run: pip install black[jupyter] - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Run Black run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6ec40e08..105a81bb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,14 +14,14 @@ jobs: id-token: write steps: - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v6 with: python-version: 3.9 - name: Install dependencies run: pip install flit - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Build run: flit build diff --git a/.github/workflows/publish_docs.yml b/.github/workflows/publish_docs.yml index 0cf92ce5..1239f70b 100644 --- a/.github/workflows/publish_docs.yml +++ b/.github/workflows/publish_docs.yml @@ -12,9 +12,9 @@ jobs: QISKIT_SETTINGS: ${{github.workspace}}/docs/qiskit_settings.conf steps: - name: Checkout Source Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Checkout GH Pages - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: sQUlearn/squlearn.github.io fetch-depth: 0 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 07b2b6e0..135c8d96 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,21 +4,30 @@ on: schedule: - cron: '23 1 * * *' +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${ + (github.event_name == 'pull_request' && github.event.pull_request.number || github.ref_name) + } + cancel-in-progress: true + jobs: pytest_minimal_requirements: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.9' - name: Install dependencies run: | - python -m pip install --upgrade pip python -m venv venv_minimal source venv_minimal/bin/activate + python -m pip install --upgrade pip pip install toml autoray==0.7.2 matplotlib-inline==0.1.7 python3 install_lowest_dependencies.py - name: Test with pytest @@ -26,15 +35,6 @@ jobs: source venv_minimal/bin/activate pip install pytest pytest tests/ - - name: Install example dependencies - run: | - source venv_minimal/bin/activate - python3 install_lowest_dependencies.py --examples - - name: Test examples - run: | - source venv_minimal/bin/activate - pip install nbmake - pytest --nbmake --nbmake-timeout 600 examples/ - name: clean run: | rm -rf venv_minimal @@ -43,27 +43,22 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.9' - name: Install dependencies run: | - python -m pip install --upgrade pip python -m venv venv_qiskit_0_46 source venv_qiskit_0_46/bin/activate - pip install .[examples] qiskit==0.46.3 qiskit-ibm-runtime==0.20.0 autoray==0.7.2 + python -m pip install --upgrade pip + pip install . qiskit==0.46.3 qiskit-ibm-runtime==0.20.0 autoray==0.7.2 - name: Test with pytest run: | source venv_qiskit_0_46/bin/activate pip install pytest pytest tests/ - - name: Test examples - run: | - source venv_qiskit_0_46/bin/activate - pip install nbmake - pytest --nbmake --nbmake-timeout 600 examples/ - name: clean run: | rm -rf venv_qiskit_0_46 @@ -72,47 +67,54 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.9' - name: Install dependencies run: | - python -m pip install --upgrade pip python -m venv venv_qiskit_1 source venv_qiskit_1/bin/activate - pip install .[examples] qiskit==1.1.2 qiskit-algorithms==0.3.0 qiskit-ibm-runtime==0.27.1 autoray==0.7.2 + python -m pip install --upgrade pip + pip install . qiskit==1.1.2 qiskit-algorithms==0.3.0 qiskit-ibm-runtime==0.27.1 autoray==0.7.2 - name: Test with pytest run: | source venv_qiskit_1/bin/activate pip install pytest pytest tests/ - - name: Test examples - run: | - source venv_qiskit_1/bin/activate - pip install nbmake - pytest --nbmake --nbmake-timeout 600 examples/ - name: clean run: | rm -rf venv_qiskit_1 - pytest_latest: + pytest_full: + name: Tests + Examples on ubuntu-latest with Python ${{ matrix.python-version }} runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: | - 3.12 + ${{ + matrix.python-version + }} - name: Install dependencies run: | - python -m pip install --upgrade pip python -m venv venv_latest source venv_latest/bin/activate + python -m pip install --upgrade pip pip install .[examples] + - name: Install old autoray + if: matrix.python-version == '3.9' + run: | + source venv_latest/bin/activate + pip install autoray==0.7.2 - name: Test with pytest run: | source venv_latest/bin/activate @@ -126,3 +128,74 @@ jobs: - name: clean run: | rm -rf venv_latest + + pytest_windows: + name: Test on windows-latest with Python ${{ matrix.python-version }} + runs-on: windows-latest + + strategy: + matrix: + python-version: ["3.9", "3.12"] + + steps: + - uses: actions/checkout@v5 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: | + ${{ + matrix.python-version + }} + - name: Install dependencies + run: | + python -m venv venv_latest + .\venv_latest\Scripts\python.exe -m pip install --upgrade pip + .\venv_latest\Scripts\pip.exe install . + - name: Install old autoray + if: matrix.python-version == '3.9' + run: | + .\venv_latest\Scripts\pip.exe install autoray==0.7.2 + - name: Test with pytest + run: | + .\venv_latest\Scripts\pip.exe install pytest + .\venv_latest\Scripts\pytest.exe tests/ + - name: clean + run: | + rm -Recurse -Force venv_latest + + pytest_macos: + name: Test on macos-latest with Python ${{ matrix.python-version }} + runs-on: macos-latest + + strategy: + matrix: + python-version: ["3.9", "3.12"] + + steps: + - uses: actions/checkout@v5 + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: | + ${{ + matrix.python-version + }} + - name: Install dependencies + run: | + python -m venv venv_latest + source venv_latest/bin/activate + python -m pip install --upgrade pip + pip install . + - name: Install old autoray + if: matrix.python-version == '3.9' + run: | + source venv_latest/bin/activate + pip install autoray==0.7.2 + - name: Test with pytest + run: | + source venv_latest/bin/activate + pip install pytest + pytest tests/ + - name: clean + run: | + rm -rf venv_latest diff --git a/pyproject.toml b/pyproject.toml index c5e47b8b..bcf6a9d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dependencies = [ "tqdm>=4.1.0", "qulacs>=0.6.0", ] -requires-python = ">=3.9,<3.13" +requires-python = ">=3.9" dynamic = ["version", "description"] [project.optional-dependencies] diff --git a/src/squlearn/kernel/loss/ode_loss.py b/src/squlearn/kernel/loss/ode_loss.py index 0c65f47a..f5891a93 100644 --- a/src/squlearn/kernel/loss/ode_loss.py +++ b/src/squlearn/kernel/loss/ode_loss.py @@ -95,14 +95,14 @@ def __init__( ode_functional: Union[sp.Expr, Callable], initial_values: Union[Sequence, np.ndarray], symbols_involved_in_ode: Optional[Sequence[sp.Basic]] = None, - eta: float = np.float64(1.0), + eta: float = 1.0, ode_order: Optional[int] = None, ): super().__init__() # normalize initial_values to a 1D numpy array self.initial_values = np.asarray(initial_values).ravel() - self.eta = float(eta) + self.eta = eta if isinstance(ode_functional, sp.Expr): if symbols_involved_in_ode is None: diff --git a/src/squlearn/qnn/loss/ode_loss.py b/src/squlearn/qnn/loss/ode_loss.py index a4acec55..53118cbd 100644 --- a/src/squlearn/qnn/loss/ode_loss.py +++ b/src/squlearn/qnn/loss/ode_loss.py @@ -82,7 +82,7 @@ def __init__( ode_functional=None, symbols_involved_in_ode=None, initial_values: np.ndarray = None, - eta=np.float64(1.0), + eta: float = 1.0, ): super().__init__() self._verify_size_of_ivp_with_order_of_ode(initial_values, symbols_involved_in_ode) diff --git a/tests/kernel/ml/test_qkode.py b/tests/kernel/ml/test_qkode.py index f988d970..51781cc4 100644 --- a/tests/kernel/ml/test_qkode.py +++ b/tests/kernel/ml/test_qkode.py @@ -1,5 +1,6 @@ import numpy as np from packaging import version +from platform import system import pytest from scipy import __version__ as scipy_version import sympy as sp @@ -9,7 +10,7 @@ from squlearn.kernel import ProjectedQuantumKernel, FidelityKernel from squlearn.kernel.loss import ODELoss from squlearn.kernel import QKODE -from squlearn.optimizers import LBFGSB +from squlearn.optimizers import SLSQP @pytest.fixture(params=["expr", "callable"]) @@ -43,45 +44,28 @@ def test_qkode_pqk(self, ode_loss): ) # Create the QKODE instance - qkode = QKODE(q_kernel, loss=ode_loss, optimizer=LBFGSB()) + qkode = QKODE(q_kernel, loss=ode_loss, optimizer=SLSQP()) x_train = np.linspace(0, 0.9, 9).reshape(-1, 1) labels = np.zeros((len(x_train), 1)) qkode.fit(x_train, labels) - if version.parse(scipy_version) < version.parse("1.16"): - regressor_result = np.array( - [ - 0.99663332, - 1.12030422, - 1.2525221, - 1.39952847, - 1.56866833, - 1.75470725, - 1.96290259, - 2.19701171, - 2.46206022, - ] - ) - else: - regressor_result = np.array( - [ - 0.9973879, - 1.12113415, - 1.25344976, - 1.40061217, - 1.56992748, - 1.7561082, - 1.96445327, - 2.19875868, - 2.46402581, - ] - ) - assert qkode._loss.order_of_ode == 1 assert np.allclose( qkode.predict(x_train), - regressor_result, + np.array( + [ + 0.99673544, + 1.12042196, + 1.25265393, + 1.39967403, + 1.56883119, + 1.75490046, + 1.96312582, + 2.19726599, + 2.46239031, + ] + ), atol=1e-3, ) @@ -96,7 +80,7 @@ def test_qkode_fqk(self, ode_loss): ) # Create the QKODE instance - qkode = QKODE(q_kernel, loss=ode_loss, optimizer=LBFGSB()) + qkode = QKODE(q_kernel, loss=ode_loss, optimizer=SLSQP()) x_train = np.linspace(0, 0.9, 9).reshape(-1, 1) labels = np.zeros((len(x_train), 1))