Skip to content

Commit 35bc5cb

Browse files
committed
Some Matlab files
1 parent 23ac92d commit 35bc5cb

10 files changed

+954
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,10 @@ build*
88
compile_flags.txt
99
._*
1010
tensor_test_files
11+
12+
# MATLAB/Octave MEX files
13+
*.mex
14+
*.mexa64
15+
*.mexw32
16+
*.mexw64
17+
*.mexmaci64

bindings/matlab/README.md

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
<!--
2+
SPDX-FileCopyrightText: 2024 Binsparse Developers
3+
4+
SPDX-License-Identifier: BSD-3-Clause
5+
-->
6+
7+
# Binsparse MATLAB/Octave Bindings
8+
9+
This directory contains MATLAB and GNU Octave MEX bindings for the Binsparse C library, providing a simple interface to access Binsparse functionality from both MATLAB and Octave.
10+
11+
## Quick Start
12+
13+
### Prerequisites
14+
15+
**For MATLAB:**
16+
1. **MATLAB** with MEX compiler support
17+
2. **Binsparse C library** headers (included in this repository)
18+
19+
**For Octave:**
20+
1. **GNU Octave** with mkoctfile (usually included)
21+
2. **C compiler** (gcc recommended)
22+
3. **Binsparse C library** headers (included in this repository)
23+
24+
### Setup MEX Compiler (if needed)
25+
26+
**For MATLAB:**
27+
If you haven't configured a MEX compiler yet:
28+
29+
```matlab
30+
mex -setup
31+
```
32+
33+
Choose a compatible C compiler when prompted.
34+
35+
**For Octave:**
36+
Octave usually comes with mkoctfile pre-configured. Verify it works:
37+
38+
```bash
39+
mkoctfile --version
40+
```
41+
42+
### Build the Bindings
43+
44+
#### Option 1: MATLAB
45+
46+
1. Open MATLAB and navigate to this directory:
47+
```matlab
48+
cd('path/to/binsparse-reference-c/bindings/matlab')
49+
```
50+
51+
2. Build the MEX functions:
52+
```matlab
53+
build_matlab_bindings()
54+
```
55+
56+
3. Test the installation:
57+
```matlab
58+
test_bsp_hello()
59+
```
60+
61+
#### Option 2: Octave (from within Octave)
62+
63+
1. Open Octave and navigate to this directory:
64+
```octave
65+
cd('path/to/binsparse-reference-c/bindings/matlab')
66+
```
67+
68+
2. Build the MEX functions:
69+
```octave
70+
build_octave_bindings()
71+
```
72+
73+
3. Test the installation:
74+
```octave
75+
test_bsp_hello_octave()
76+
```
77+
78+
#### Option 3: Octave (from command line)
79+
80+
1. Navigate to this directory:
81+
```bash
82+
cd path/to/binsparse-reference-c/bindings/matlab
83+
```
84+
85+
2. Build using the shell script:
86+
```bash
87+
./compile_octave.sh
88+
```
89+
90+
3. Test the installation:
91+
```bash
92+
octave --eval "test_bsp_hello_octave()"
93+
```
94+
95+
## Usage Examples
96+
97+
### Basic Usage
98+
99+
**In MATLAB or Octave:**
100+
101+
```matlab
102+
% Simple greeting
103+
result = bsp_hello()
104+
% Output: 'Binsparse MEX binding is working!'
105+
106+
% Get Binsparse version
107+
[version, success] = bsp_hello('version')
108+
% Output: version = '0.1', success = true
109+
```
110+
111+
### Error Handling
112+
113+
The MEX functions include proper error handling:
114+
115+
```matlab
116+
try
117+
result = bsp_hello('invalid_mode')
118+
catch ME
119+
fprintf('Error: %s\n', ME.message)
120+
end
121+
```
122+
123+
## Files Description
124+
125+
| File | Description |
126+
|------|-------------|
127+
| `bsp_hello.c` | Simple MEX function demonstrating Binsparse integration |
128+
| `build_matlab_bindings.m` | Main build script for MATLAB MEX functions |
129+
| `build_octave_bindings.m` | Main build script for Octave MEX functions |
130+
| `compile_bsp_hello.m` | Simple compilation script for the demo function (MATLAB) |
131+
| `compile_octave.sh` | Shell script for building Octave MEX functions |
132+
| `test_bsp_hello.m` | Test script to verify functionality (MATLAB) |
133+
| `test_bsp_hello_octave.m` | Test script to verify functionality (Octave) |
134+
| `README.md` | This documentation file |
135+
136+
## Technical Details
137+
138+
### MEX Function Structure
139+
140+
The `bsp_hello` MEX function demonstrates:
141+
142+
1. **Header inclusion**: Proper inclusion of `<binsparse/binsparse.h>`
143+
2. **Error handling**: Using Binsparse error types (`bsp_error_t`)
144+
3. **Memory management**: Safe allocation and cleanup
145+
4. **MATLAB interface**: Proper MEX function structure
146+
147+
### Build Process
148+
149+
**MATLAB build process:**
150+
151+
1. Locates Binsparse include directory (`../../include/`)
152+
2. Compiles MEX functions using MATLAB's `mex` command
153+
3. Links against MATLAB MEX libraries
154+
4. Validates compilation with test functions
155+
156+
**Octave build process:**
157+
158+
1. Locates Binsparse include directory (`../../include/`)
159+
2. Compiles MEX functions using `mkoctfile --mex`
160+
3. Links against Octave MEX libraries
161+
4. Validates compilation with test functions
162+
163+
## Extending the Bindings
164+
165+
To add new Binsparse functionality:
166+
167+
1. Create a new `.c` file with MEX function structure
168+
2. Include `<binsparse/binsparse.h>` and relevant headers
169+
3. Add the filename to `mex_files` list in `build_matlab_bindings.m`
170+
4. Create corresponding test functions
171+
172+
### Example MEX Function Template
173+
174+
```c
175+
#include "mex.h"
176+
#include <binsparse/binsparse.h>
177+
178+
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
179+
// Input validation
180+
if (nrhs != 1) {
181+
mexErrMsgIdAndTxt("BinSparse:InvalidInput", "Expected 1 input argument");
182+
}
183+
184+
// Call Binsparse functions
185+
bsp_error_t error = /* your_binsparse_function() */;
186+
187+
// Handle errors
188+
if (error != BSP_SUCCESS) {
189+
mexErrMsgIdAndTxt("BinSparse:Error", "%s", bsp_get_error_string(error));
190+
}
191+
192+
// Return results to MATLAB
193+
plhs[0] = /* create_matlab_output() */;
194+
}
195+
```
196+
197+
## Troubleshooting
198+
199+
### Common Issues
200+
201+
1. **MEX compiler not found**
202+
- **MATLAB**: Run `mex -setup` to configure a compiler
203+
- **Octave**: Install mkoctfile (usually comes with Octave)
204+
- Ensure you have a compatible C compiler installed
205+
206+
2. **Include paths not found**
207+
- Verify you're running from the `bindings/matlab` directory
208+
- Check that `../../include/binsparse/binsparse.h` exists
209+
210+
3. **Compilation errors**
211+
- **MATLAB**: Try building with verbose output: `build_matlab_bindings('verbose')`
212+
- **Octave**: Try building with verbose output: `build_octave_bindings('verbose')` or `./compile_octave.sh --verbose`
213+
- Check compiler compatibility with your MATLAB/Octave version
214+
215+
### Platform-Specific Notes
216+
217+
- **Windows**:
218+
- MATLAB: Microsoft Visual Studio or compatible compiler
219+
- Octave: MinGW-w64 (often included with Octave installer)
220+
- **macOS**: Xcode command line tools required for both MATLAB and Octave
221+
- **Linux**: GCC or compatible compiler should work for both MATLAB and Octave
222+
223+
## Development Status
224+
225+
This is a minimal demonstration of MATLAB/Octave bindings for Binsparse. Currently implemented:
226+
227+
- ✅ Basic MEX function structure
228+
- ✅ Binsparse header inclusion
229+
- ✅ Error handling with Binsparse error types
230+
- ✅ Build system and testing framework
231+
- ⏳ Matrix reading/writing functions (future work)
232+
- ⏳ Advanced Binsparse features (future work)
233+
234+
## License
235+
236+
This code is licensed under the BSD-3-Clause license, same as the main Binsparse project.

bindings/matlab/bsp_hello.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Binsparse Developers
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
/**
8+
* bsp_hello.c - Simple Binsparse MEX function demonstration
9+
*
10+
* This is a minimal MEX function that demonstrates how to:
11+
* 1. Include Binsparse headers
12+
* 2. Use basic Binsparse types and error handling
13+
* 3. Return information to Matlab
14+
*
15+
* Usage in Matlab:
16+
* info = bsp_hello();
17+
* [version, success] = bsp_hello('version');
18+
*/
19+
20+
#include "mex.h"
21+
#include <binsparse/binsparse.h>
22+
#include <string.h>
23+
24+
/**
25+
* Dummy function that demonstrates basic Binsparse functionality
26+
*/
27+
bsp_error_t dummy_binsparse_function(char** version_out) {
28+
// Simulate some basic Binsparse operation
29+
// In a real function, this might read/write matrices, etc.
30+
31+
if (!version_out) {
32+
return BSP_ERROR_INVALID_INPUT;
33+
}
34+
35+
// Allocate memory for version string
36+
*version_out = (char*) malloc(strlen(BINSPARSE_VERSION) + 1);
37+
if (!*version_out) {
38+
return BSP_ERROR_MEMORY;
39+
}
40+
41+
strcpy(*version_out, BINSPARSE_VERSION);
42+
return BSP_SUCCESS;
43+
}
44+
45+
/**
46+
* Main MEX function entry point
47+
*/
48+
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
49+
char* mode = NULL;
50+
char* version_str = NULL;
51+
bsp_error_t error;
52+
53+
// Handle different calling modes
54+
if (nrhs == 0) {
55+
// Default mode: return basic info
56+
plhs[0] = mxCreateString("Binsparse MEX binding is working!");
57+
return;
58+
}
59+
60+
if (nrhs == 1) {
61+
// Get input argument
62+
if (!mxIsChar(prhs[0])) {
63+
mexErrMsgIdAndTxt("BinSparse:InvalidInput", "Input must be a string");
64+
}
65+
66+
mode = mxArrayToString(prhs[0]);
67+
if (!mode) {
68+
mexErrMsgIdAndTxt("BinSparse:MemoryError",
69+
"Failed to convert input string");
70+
}
71+
72+
if (strcmp(mode, "version") == 0) {
73+
// Call our dummy Binsparse function
74+
error = dummy_binsparse_function(&version_str);
75+
76+
if (nlhs >= 1) {
77+
if (error == BSP_SUCCESS) {
78+
plhs[0] = mxCreateString(version_str);
79+
} else {
80+
plhs[0] = mxCreateString(bsp_get_error_string(error));
81+
}
82+
}
83+
84+
if (nlhs >= 2) {
85+
plhs[1] = mxCreateLogicalScalar(error == BSP_SUCCESS);
86+
}
87+
88+
// Clean up
89+
if (version_str) {
90+
free(version_str);
91+
}
92+
} else {
93+
mexErrMsgIdAndTxt("BinSparse:InvalidMode",
94+
"Unknown mode. Valid modes: 'version'");
95+
}
96+
97+
// Clean up mode string
98+
mxFree(mode);
99+
} else {
100+
mexErrMsgIdAndTxt("BinSparse:TooManyInputs",
101+
"Too many input arguments. Expected 0 or 1.");
102+
}
103+
}

0 commit comments

Comments
 (0)