Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ jobs:
yes | "$sdkmanager" --licenses >/dev/null || true
"$sdkmanager" "platforms;android-36" "build-tools;36.0.0"

- name: Validate native packaging scripts
shell: bash
run: |
python3 native/verify-engine-apk.py --self-test
python3 native/verify-octave-runtime.py --lock-only
python3 native/verify-octave-apk.py --self-test
python3 native/verify-elf-page-size.py --help >/dev/null
bash -n native/*.sh

- name: Run unit tests
shell: bash
run: |
Expand All @@ -57,10 +66,9 @@ jobs:
shell: bash
run: ./gradlew --no-daemon -Pmaxmath.buildNative=false :app:assembleDebug

# 暂不阻断:lint 从未在本仓库跑过,先让历史问题可见,基线清理干净后
# 去掉 continue-on-error 变成硬门禁。
# Lint errors are release blockers. Dependency update notices remain
# visible as warnings without weakening the gate.
- name: Android Lint
continue-on-error: true
shell: bash
run: ./gradlew --no-daemon -Pmaxmath.buildNative=false :app:lintDebug

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
.externalNativeBuild/
captures/
*.iml
__pycache__/
*.py[cod]

# Machine-local SDK and signing configuration
local.properties
Expand All @@ -20,6 +22,7 @@ keystore/
# Native toolchain workspace and generated runtime payloads
.build/
app/src/main/assets/engine/
app/src/main/assets/octave/
app/src/main/jniLibs/

# Packaged outputs
Expand Down
63 changes: 53 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MaxMath (Higher Algebra Calculator)
# MaxMath (Higher Algebra Calculator / MATLAB on the phone)

[![CI](https://github.com/ParuhParhat/MaxMath/actions/workflows/ci.yml/badge.svg)](https://github.com/ParuhParhat/MaxMath/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/ParuhParhat/MaxMath?label=release)](https://github.com/ParuhParhat/MaxMath/releases/latest)
Expand All @@ -9,20 +9,25 @@
<a href="README.zh-CN.md"><strong>简体中文</strong></a>
</p>

[Download MaxMath 1.1.1 APK](https://github.com/ParuhParhat/MaxMath/releases/download/v1.1.1/MaxMath-v1.1.1-arm64-v8a.apk)
· [Release notes](https://github.com/ParuhParhat/MaxMath/releases/tag/v1.1.1)
[Download MaxMath 2.0.1 APK](https://github.com/ParuhParhat/MaxMath/releases/download/v2.0.1/MaxMath-v2.0.1-arm64-v8a.apk)
· [Release notes](https://github.com/ParuhParhat/MaxMath/releases/tag/v2.0.1)

MaxMath is an offline Android app for higher-algebra computation and interactive
plotting, powered by GNU Maxima. Its interface is built with Kotlin and Jetpack
Compose, mathematical input is handled by a pure Kotlin parser, and complex
symbolic computations run in a separate engine process.
MaxMath is an offline Android app for higher-algebra computation, numeric
computation and interactive plotting, powered by GNU Maxima and GNU Octave. Its
interface is built with Kotlin and Jetpack Compose, mathematical input is
handled by a pure Kotlin parser, and complex computations run in separate
engine processes.

> Current release: 1.1.1. Minimum supported version: Android 8.0 (API 26).
> Current release: 2.0.1. Minimum supported version: Android 8.0 (API 26).
> The native computation engine currently provides an `arm64-v8a` build
> workflow only.

## Features

- Octave console: MATLAB-style command line, workspace browser, .m script
editing/import/export, interactive plot/plot3/surf/contour/subplot/colormap/
colorbar rendering and a LaTeX toggle for results (numeric engine is the
Termux build of GNU Octave 11.3.0, fully offline)
- Matrices: determinant, inverse, transpose, rank, trace, eigenvalues, and eigenvectors
- Systems of equations: natural syntax such as `x+y=1; 2x-y=3`, plus raw Maxima input
- Polynomials: factorization, greatest common divisor, root finding, expansion, and simplification
Expand All @@ -42,7 +47,7 @@ symbolic computations run in a separate engine process.
| Path | Responsibility |
| --- | --- |
| `parser/` | Lexing, AST construction, expression evaluation, and Maxima/NumPy code generation |
| `engine/` | Typed computation tasks, Maxima scripts, JNI subprocesses, the isolated process service, and 2D plotting |
| `engine/` | Typed computation tasks, Maxima scripts, JNI subprocesses, isolated process services, 2D plotting, and the Octave interactive subprocess (:octave) |
| `app/` | Compose screens, state management, LaTeX output, and interactive OpenGL 3D/contour rendering |
| `native/` | Android cross-compilation and runtime packaging scripts for ECL and Maxima |
| `docs/` | Product specifications and implementation constraints |
Expand All @@ -52,6 +57,8 @@ through Android Messenger to the isolated `:engine` process. Cancellation or a
timeout terminates the corresponding Maxima subprocess. Maxima assists with 2D
plot analysis before Matplotlib renders the image; 3D surfaces and contour plots
are sampled locally from the same expression AST and rendered with OpenGL.
The Octave console runs in its own `:octave` process; its plot commands are
exported as plot_spec.json by the bridge layer and rendered by Compose/OpenGL.

## Getting the Source

Expand Down Expand Up @@ -111,6 +118,13 @@ cd ..
./gradlew :app:assembleDebug
~~~

`package-engine.sh` writes one `assets/engine/runtime.zip` plus a content-addressed
manifest. Installation uses full hash verification, staging, and an atomic runtime
switch while keeping `user/` and `work/` separate. After assembling, run
`python3 native/verify-engine-apk.py app/build/outputs/apk/debug/app-debug.apk` to
verify the nested archive file set, `linearalgebra`, ECL data, and Maxima/ECL JNI
hashes at the final APK boundary.

The current scripts target a Linux x86_64 host and the NDK's `linux-x86_64`
toolchain. See [native/README.md](native/README.md) for complete dependency,
environment-variable, and troubleshooting information.
Expand All @@ -119,8 +133,37 @@ Generated directories that must not be committed include:

- `.build/`
- `app/src/main/assets/engine/`
- `app/src/main/assets/octave/`
- `app/src/main/jniLibs/`

## Octave console engine

The console uses the official Termux GNU Octave 11.3.0 runtime and supports
`arm64-v8a` only. Every Termux package version, filename and SHA-256 is pinned in
`native/octave-termux.lock`; fetching never resolves a mutable latest package.
Recreate and package the runtime with:

~~~bash
./native/download-octave-termux.sh arm64-v8a
./native/build-octave-16k-overrides.sh
./native/package-octave-engine.sh arm64-v8a
~~~

The download step rebuilds a clean stage from only the locked archives. The
packager follows `DT_NEEDED` from the CLI entry and arm64 `.oct` modules, keeps
the matching Termux `libc++_shared.so`, removes stale/non-arm64 Octave assets,
verifies the complete payload before transactionally switching it, and writes a
deterministic `assets/octave/runtime-manifest.json`. The complex-math and WebP
packages which still ship 4 KiB-aligned ELF segments are rebuilt from pinned
official Android/WebM sources for 16 KiB Android page compatibility. It finishes by
running `native/verify-octave-runtime.py`, which checks architecture, dependency
and strong C++ symbol closure, locked libc++ identity, file hashes and the
manifest `runtimeId`. After assembling the APK, run
`python3 native/verify-octave-apk.py app/build/outputs/apk/debug/app-debug.apk` to
confirm that AAPT retained every manifest-owned file, including `.oct-config`,
and that every packaged native ELF has 16 KiB-compatible LOAD alignment.
See [native/README.md](native/README.md) for prerequisites.

## Project Documentation

- [Product and implementation specification](docs/SPEC.md)
Expand All @@ -133,7 +176,7 @@ Generated directories that must not be committed include:

## Known Limitations

- The native computation engine currently targets `arm64-v8a` only; the `x86_64` build scripts still need further verification.
- The packaged Maxima and Octave computation runtimes support `arm64-v8a` only.
- A fresh source checkout does not include a prebuilt Maxima/ECL runtime. Generate it as described above before running full computations.
- Results come from computer algebra and numerical algorithms and should not be treated as formal proofs.

Expand Down
53 changes: 44 additions & 9 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# MaxMath(高代计算器)
# MaxMath(高代计算器 / 手机端 MATLAB

[![CI](https://github.com/ParuhParhat/MaxMath/actions/workflows/ci.yml/badge.svg)](https://github.com/ParuhParhat/MaxMath/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/ParuhParhat/MaxMath?label=release)](https://github.com/ParuhParhat/MaxMath/releases/latest)
Expand All @@ -9,18 +9,21 @@
<strong>简体中文</strong>
</p>

[下载 MaxMath 1.1.1 APK](https://github.com/ParuhParhat/MaxMath/releases/download/v1.1.1/MaxMath-v1.1.1-arm64-v8a.apk)
· [发布说明](https://github.com/ParuhParhat/MaxMath/releases/tag/v1.1.1)
[下载 MaxMath 2.0.1 APK](https://github.com/ParuhParhat/MaxMath/releases/download/v2.0.1/MaxMath-v2.0.1-arm64-v8a.apk)
· [发布说明](https://github.com/ParuhParhat/MaxMath/releases/tag/v2.0.1)

基于 GNU Maxima 的离线 Android 高等代数计算与交互式绘图应用。界面使用
Kotlin 与 Jetpack Compose,数学输入由纯 Kotlin 解析器处理,复杂符号计算在独立
引擎进程中执行
基于 GNU Maxima 与 GNU Octave 的离线 Android 高等代数计算、数值计算与交互式
绘图应用。界面使用 Kotlin 与 Jetpack Compose,数学输入由纯 Kotlin 解析器处理,
复杂符号计算与 Octave 控制台在独立引擎进程中执行

> 当前版本 1.1.1;最低系统 Android 8.0(API 26);原生计算引擎目前仅提供
> 当前版本 2.0.1;最低系统 Android 8.0(API 26);原生计算引擎目前仅提供
> `arm64-v8a` 构建流程。

## 功能

- Octave 控制台:MATLAB 风格命令行、工作区变量列表、.m 脚本编辑/导入/导出,
支持 plot/plot3/surf/contour/subplot/colormap/colorbar 实时交互绘图与 LaTeX
结果切换(数值引擎为 Termux 预编译的 GNU Octave 11.3.0,完全离线)
- 矩阵:行列式、逆、转置、秩、迹、特征值与特征向量
- 方程组:支持 `x+y=1; 2x-y=3` 一类自然写法,也支持原始 Maxima 输入
- 多项式:因式分解、最大公因式、求根、展开与化简
Expand All @@ -39,14 +42,16 @@ Kotlin 与 Jetpack Compose,数学输入由纯 Kotlin 解析器处理,复杂
| 路径 | 职责 |
| --- | --- |
| `parser/` | 词法分析、AST、表达式求值,以及 Maxima/NumPy 代码生成 |
| `engine/` | 类型化计算任务、Maxima 脚本、JNI 子进程、独立进程服务和 2D 绘图 |
| `engine/` | 类型化计算任务、Maxima 脚本、JNI 子进程、独立进程服务、2D 绘图,以及 Octave 交互子进程与 :octave 服务 |
| `app/` | Compose 页面、状态管理、LaTeX 输出及 OpenGL 3D/等高线交互 |
| `native/` | ECL 与 Maxima 的 Android 交叉编译和运行时打包脚本 |
| `docs/` | 产品规格与实现约束 |

轻量操作在 UI 进程执行;耗时操作通过 Android Messenger 转发到 `:engine` 独立
进程。取消或超时会终止对应的 Maxima 子进程。2D 图像由 Maxima 辅助分析并交给
Matplotlib 渲染;3D 曲面和等高线由同一表达式 AST 在本地采样并交给 OpenGL 绘制。
Octave 控制台由独立的 `:octave` 进程承载,绘图命令经桥接层导出为 plot_spec.json
后交给 Compose/OpenGL 渲染,与 Maxima 引擎互不干扰。

## 获取源码

Expand Down Expand Up @@ -104,15 +109,45 @@ cd ..
./gradlew :app:assembleDebug
~~~

`package-engine.sh` 会生成单文件 `assets/engine/runtime.zip` 和内容寻址清单;安装器用
暂存目录、完整哈希校验和原子切换升级,保留独立的 `user/`、`work/`。构建后运行
`python3 native/verify-engine-apk.py app/build/outputs/apk/debug/app-debug.apk`,确认最终
APK 中 `linearalgebra`、ECL 数据、归档文件集合和 Maxima/ECL JNI 哈希全部一致。

当前脚本以 Linux x86_64 主机和 NDK 的 `linux-x86_64` 工具链为目标。完整依赖、
环境变量与故障说明见 [native/README.md](native/README.md)。

生成但不提交的目录包括:

- `.build/`
- `app/src/main/assets/engine/`
- `app/src/main/assets/octave/`
- `app/src/main/jniLibs/`

## Octave 控制台引擎

控制台使用 Termux 官方 GNU Octave 11.3.0 运行时,仅支持 `arm64-v8a`。
`native/octave-termux.lock` 严格锁定每个 Termux 包的版本、文件名与 SHA-256,
下载过程不会在构建时解析可变的“最新版”。重新生成与打包命令为:

~~~bash
./native/download-octave-termux.sh arm64-v8a
./native/build-octave-16k-overrides.sh
./native/package-octave-engine.sh arm64-v8a
~~~

下载脚本只使用锁定归档重建干净 stage。打包脚本从 CLI 入口与 arm64 `.oct`
模块沿 `DT_NEEDED` 收集实际闭包,保留匹配的 Termux `libc++_shared.so`,清理旧版
及非 arm64 Octave 资产;新载荷在临时目录通过验证后才事务切换,并生成确定性的
`assets/octave/runtime-manifest.json`。官方 Termux 包中仍为 4 KiB 对齐的 complex-math
与 WebP 库会从锁定的 Android/WebM 官方源码重建为 16 KiB 兼容版本。
最后由 `native/verify-octave-runtime.py` 校验架构、依赖与强 C++ 符号闭包、锁定
libc++、逐文件哈希和清单 `runtimeId`。APK 构建后再运行
`python3 native/verify-octave-apk.py app/build/outputs/apk/debug/app-debug.apk`,从最终
制品确认 AAPT 没有过滤 `.oct-config` 等清单文件,并扫描每个 native ELF 的
16 KiB LOAD 对齐。主机依赖见
[native/README.md](native/README.md)。

## 项目文档

- [产品与实现规格](docs/SPEC.md)
Expand All @@ -125,7 +160,7 @@ cd ..

## 已知限制

- 原生计算引擎当前只面向 `arm64-v8a`;`x86_64` 构建脚本仍需进一步验证
- Maxima 与 Octave 原生计算运行时目前均只支持 `arm64-v8a`。
- 新检出的源码仓库不含预编译 Maxima/ECL 运行时,必须按上文生成后才能执行完整计算。
- 计算结果来自计算机代数与数值算法,不应被视为形式化证明。

Expand Down
49 changes: 49 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,52 @@
# MaxMath 2.0.1

手机端 MATLAB 修复版(2026-08-16):加固 Maxima 矩阵计算与 Octave 三维交互。

## 本版改进

- 修复矩阵“迹”调用 `mat_trace` 时触发未预编译 `linearalgebra` 自动加载、长时间
停在“计算中”;现直接遍历主对角线求和,并保留非方阵的明确错误。
- Octave 三维曲面取消仰角 0–180°硬限位,水平和垂直方向均可连续环绕;同时
修正上下拖动方向,使模型跟随手指旋转。
- 将占满绘图区高度且方向错误的彩色色标改成紧凑水平渐变图例,最小值、最大值
与颜色方向保持一致,不再遮挡坐标与曲面。

# MaxMath 2.0.0

手机端 MATLAB 升级版(2026-08-12):新增基于 GNU Octave 11.3.0 的控制台模式。

## 本版改进

- 修复 Maxima 交叉编译时误读取外层 MaxMath 仓库 Git 标签,导致二进制搜索
`share/maxima/v1.1.0_...` 而打包目录实际为 `5.49.0`、所有计算均报启动失败;
构建、运行时清单和最终 APK 现在都会校验编译版本与资源目录版本一致。
- 修复 Octave `surf(X,Y,Z)` 把完整 `meshgrid` 的 Y 矩阵当一维向量读取、使各行
Y 坐标相同并把三维曲面压成平面;曲面与等高线渲染同时兼容完整网格和坐标向量。
- Maxima 运行时改为确定性的单文件归档与内容清单;同版本缺失或损坏
`linearalgebra` 会自动重装,升级使用暂存、完整哈希校验和原子回滚,并保留
独立的 `user/`、`work/`。
- 所有 Maxima 计算统一进入 `:engine` 服务,新增请求 ID、Preparing/Running 进度、
90 秒准备上限、130 秒客户端执行上限、请求级取消及断连终态,避免永久“计算中”。
- Octave 变量改用独立详情页;图表从控制台大画布改为轻量结果卡片,点按后进入
纵向滚动的独立多子图页面;命令输入框不再显示可见提示词。
- 新增 Octave 控制台模式:MATLAB 风格命令行、命令历史、实时流式输出、取消与
120 秒超时;单个数值结果可在 MATLAB 文本与 LaTeX 渲染之间切换。
- 新增工作区面板:列出变量名称、类型、维数与大小,点按预览、单删或清空。
- 新增 .m 脚本编辑器:新建/导入/导出(系统文件选择器)、运行/停止、错误定位。
- 新增绘图桥:控制台里的 plot/plot3/surf/contour/subplot/hold/axis/grid/
legend/colormap/colorbar 等高层命令导出为 plot_spec.json,由 Compose/OpenGL
实时渲染,2D 可平移缩放、3D/等高线可旋转缩放,支持多子图布局。
- 引擎架构:Octave 运行在独立 `:octave` 进程,与 Maxima `:engine` 互不干扰;
常驻会话、哨兵协议、RSS 1.5GB 内存保护与空闲回收。
- 原生运行时:严格锁定 Termux GNU Octave 11.3.0 及全部 arm64-v8a 包的版本与
SHA-256;从 CLI 与 `.oct` 根节点收集实际 ELF 闭包,使用匹配的 Termux libc++,
生成稳定运行时清单并通过依赖、架构、C++ 符号与文件哈希静态门禁。
- 16 KiB 页面:从锁定的 Android/WebM 官方源码重建 complex-math 与 WebP,ECL、
Maxima 和应用 JNI 统一使用 16 KiB 链接参数,最终 APK 逐 ELF 检查 LOAD 对齐。
- 运行链路加固:运行时事务安装与崩溃回滚、请求 ID 全链路校验、即时取消、
异常退出自动恢复、1 MiB 输出上限,以及 typed preview/绘图制品的有界传输。
- 符号计算仍由 Maxima 模式承担,控制台首版聚焦数值计算。

# MaxMath 1.1.1

3D/等高线绘图性能、交互与坐标可读性更新(2026-08-08)。
Expand Down
Loading
Loading