Main Content

Results for

Introduction
This article describes how I have used MATLAB, MCP, and other tools to enable AI desktop apps to communicate with and share information between multiple AIs in performing research and code development. I describe how Claude desktop app (for example) can orchestrate AI-related setups of itself and other AI dektop apps using system calls through MATLAB, access multiple local and cloud AIs to develop and test code, and share with and evaluate results from multiple AIs. If you have been copy-pasting between MATLAB and an AI application or browser page, you may find this helpful.
Warning
When connected to MATLAB App via MCP, an AI desktop application acquires MATLAB App's command line privileges, possibly full system privileges. Be careful what commands you approve.
Setup
Experiments with Claude code and MATLAB MCP Core Server describes how to link Claude App via MCP to a local MATLAB to create MATLAB scripts in your file system, operate MATLAB App to test them, collect errors sent to standard output, view created files, and iterate. Other AI apps can similarly configured as described here.
My setup is an APPLE M1 MacBook with MATLAB v2025a and ollama along with MATLAB MCP Core Server, ollama MCP, filesystem MCP, fetch MCP to access web pages, and puppeteer MCP to navigate and operate webpages like MATLAB Online. I have similarly Claude App, Perplexity App (which requires the PerplexityXPC helper for MCP since it's sandboxed as a Mac App Store app), and LM Studio App. As of this writing, ChatGPT App support for MCP connectors is currently in beta and possibly available to Pro users if setup enabled via a web browser. It is not described here.
The available MCP commands are:
filesystem MCP `read_text_file`, `read_media_file`, `write_file`, `edit_file`, `list_directory`, `search_files`, `get_file_info`, etc.
matlab MCP `evaluate_matlab_code`, `run_matlab_file`, `run_matlab_test_file`, `check_matlab_code`, `detect_matlab_toolboxes`
fetch MCP ‘fetch_html`, `fetch_markdown`, `fetch_txt`, `fetch_json` | Your Mac |
puppeteer MCP `puppeteer_navigate`, `puppeteer_screenshot`, `puppeteer_click`, `puppeteer_fill`, `puppeteer_evaluate`, etc.
ollama MCP ‘ollama_list’, ‘ollama_show’, ’ollama_pull’, ’ollama_push’, ’ollana_copy’, ’ ollama-create’, ’ollama_copy’, ’ollama_delete’, ’ollama_ps’, ’ollama_chat’, ’ollama_web_search’, ’ollama_web_fetch’
Claude App (for example) can help you find, download, install, and configure MCP services for itself and for other Apps. Claude App requires for this setup a json configuration file like
{
"mcpServers": {
"ollama": {
"command": "npx",
"args": ["-y", "ollama-mcp"],
"env": {
"OLLAMA_HOST": "http://localhost:11434"
}
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/duncancarlsmith/Documents/MATLAB"
]
},
"matlab": {
"command": "/Users/duncancarlsmith/Developer/mcp-servers/matlab-mcp-core-server",
"args": ["--matlab-root", "/Applications/MATLAB_R2025a.app"]
},
"fetch": {
"command": "npx",
"args": ["-y", "mcp-fetch-server"]
},
"puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
}
}
}
Various options for these services are available through Claude App’s Settings=>Connectors. If you first install and set up the MATLAB MCP with Claude App, then Claude can find and edit its own json file using MATLAB and help you (after quitting and restarting) to complete the installations of all of the other tools. I highly recommend using Claude App as a command post for installations although other desktop apps like Perplexity may serve equally well.
Perplexity App is manually configured using Settings=>Connectors and adding server names and commands as above. Perplexity XPC is included with the Perplexity App download . When you create connectors with Perplexity App, you are prompted to install Perplexity XPC to allow Perplexity App to spawn proceses outside its container. LM Studio is manually configured via its righthand sidebar terminal icon by selecting Install-> Edit mcp.json. The json is like Claude’s. Claude can tell/remind you exactly what to insert there.
One gotcha in this setup concerns the Ollama MCP server. Apparently the default json format setting fails and one must tell the AIs to use “markdown” when commuicating with it. This instruction can be made session by session but I have made it a permanent preference in Claude App by clicking my initials in the lower left of Claude App, selecting settings, and under “What preferences should claude consider in responses,” adding “When using ollama MCP tools (ollama_chat, ollama_generate), always set format="markdown" - the default json format returns empty responses.”
LM Studio by default points at an Open.ai API. Claude can tell you how to download a model, point LM Studio at a local Ollama model and set up LM Studio App with MCP. Be aware that the default context setting in LM Studio is too small. Be sure to max out the context slider for your selected model or you will experience an AI with a very short term memory and context overload failures. When running MATLAB, LM Studio will ask for a project directory. Under presets you can enter something like “When using MATLAB tools, always use /Users/duncancarlsmith/Documents/MATLAB as the project_path unless the user specifies otherwise.” and attach that to the context in any new chat. An alternate ollama desktop application is Ollama from ollama.com which can run large models in the cloud. I encountered some constraints with Ollama App so focus on LM Studio.
I have installed Large Language Models (LLMs) with MATLAB using the recommended Add-on Browser. I had Claude configure and test it. This package helps MATLAB communicate with external AIs via API and also with my native ollama. See the package information. To use it, one must define tools with MATLAB code. A tool is a function with a description that tells an LLM what the function does, what parameters it takes, and when to call it. FYI, Claude discovered my small ollama default model had not been trained to support tool and hallucinated a numerical calculaton rather than using a tool we set up to perform such a calculation with MATLAB with machine precision. Claude suggested and then orchestrated the download of the 7.1 GB model mistral-nemo model which supports tool calling so if using you are going to use tools be sure to use a tool aware model.
To interact with Ollama, Claude can use the MATLAB MCP server to execute MATLAB commands to use ollamaChat() from the LLMs-with-MATLAB package like “chat = ollamaChat("mistral-nemo");response = generate(chat, "Your question here”);” The ollamaChat function creates an object that communicates with Ollama's HTTP API running on localhost:11434. The generate function sends the prompt and returns the text response. Claude can also communicate with Ollama using the Ollama MCP server. Similarly, one can ask Claude to create tools for other AIs.
The tool capability allows one to define and suggest MATLAB functions that the Ollama model can request to use to, for example, to make exact numerical calculations in guiding its response. I have also the MATLAB Add-on MATLAB MCP HTTP Client which allows MATLAB to connect with cloud MCP servers. With this I can, for example, connect to an external MCP service to get JPL-quality (SPICE generated) ephemeris predictions for solar system objects and, say, plot Earth’s location in solar system barycentric coordinates and observe the deviations from a Keplerian orbit due of lunar and other gravitational interactions.
To connect with an external AI API such as openAI or Perplexity, you need an account and API key and this key must be set as an environmental variable in MATLAB. Claude can remind you how to create the environmental variable by hand or how you can place your key in a file and have Claude find and extract the key and define the environmental variable without you supplying it explicitly to Claude.
It should be pointed out that conversations and information are NOT shared between Desktop apps. For example, if I use Claude App to, via MATLAB, make an API transaction with ChatGPT or Perplexity in the cloud, the corresponding ChatGPT App or Perplexity App has no access the the transaction, not even to a log file indicating it occured. There may be various OS dependent tricks to enable communication between AI desktop apps (e.g. AppleScript/AppleEvents copy and paste) but I have not explored such options.
AI<->MATLAB Communication
WIth this setup, I can use any of the three desktop AI apps to create and execute a MATLAB script or to ask any supported LLM to do this. Only runtime standard output text like error messages generated by MATLAB are fed back via MCP. Too evaluate the results of a script during debugging and after successful execution, an AI requires more information.
Perplexity App can “see and understand” binary graphical output files (presented as inputs to the models like other data) without human intervention via screen sharing, obviating the need to save or paste figures. Perplexity and Claude can both “see” graphical output files dragged and dropped manually into their prompt interface. With MacOS, I can use Shift-Command-5 to capture a window or screen selection and paste it into the input field in either App. Can this exchange of information be accomplished programmatically? Yes, using MCP file services.
To test what binary image file formats are supported by Claude with the file server connection, I asked Claude to use MATLAB commands to make and convert a figure to JPEG, PNG, GIF, BMP, TIFF, and WebP and found the filesytem: read_media_file command of the Claude file server connection supported the first three. The file server MCP transmits the file using JSON and base64 text strings. A 64-bit encoding adds an additonal ~30 percent to a bitmap format and there is overhead. A total tranmission limit of 1MB is imposed by Anthropic so the maximum bitmap file size appears to be about 500 KB. If your output graphic file is larger, you may ask Claude to use MATLAB to compress it before reading it via the file service.
BTW, interestingly, the drag and drop method of image file transfer does not have this 500 KB limit. I dragged and dropped an out of context (never shared in my interactions with Claude) 3.3 MB JPEG and received a glowing, detailed description of my cat.
So in in generating a MATLAB script via AI prompts, we can ask the AI to make sure MATLAB commands are included in the script that save every figure in a supported and possibly compressed bitmap format so the command post can fetch it. Claude, for example, can ‘see’ an an annotated plot and and accurately describe the axes labels, understand the legend, extract numbers in an annotation, and also derive approximate XY values of a plotted function. Note that Claude (given some tutoring and an example) can also learn to parse and find all of the figures saved as PNG inside a saved .mlx package and, BTW, create a .mlx from scratch. So an alternate path is to generate a Live Script or ask the AI to convert a .m script to Live Script using a MATLAB command and to save the executed .mlx. Another option is for the AI to ask MATLAB to loop over figures and execute for each issue a command like exportgraphics(fig, ‘figname.png', 'Resolution', 150); and then itself upload the files for processing.
With a sacrifiice of security, other options are available. With the APPLE OS, it is possible to approve matlab_mcp_core_server (and or your Claude App or Perplexity App) to access screen and audio recording. Then for example, Claude can ask MATLAB to issue a system command system('screencapture -x file.png') to capture the entire screen or java.awt.Robot().createScreenCapture() to capture a screen window. I have demonstrated with Claude App capturing a screenshot showing MATLAB App and figures, and, for fun, sending that via API to ChatGPT, and receiving back an analysis of the contents. (Sending the screenshot to Perplexity various ways via API failed for unknown reasons despite asking Perplexity for help.)
One might also try to execute a code like
robot = java.awt.Robot();
toolkit = java.awt.Toolkit.getDefaultToolkit();
screenSize = toolkit.getScreenSize();
rectangle = java.awt.Rectangle(0, 0, screenSize.width, screenSize.height);
bufferedImage = robot.createScreenCapture(rectangle);
% ... convert to MATLAB array and save with imwrite()
to capture and transmit a certain portion of your screen. Going down this path further, according to Claude, it is possible to create a MacOS virtual Desktop containing only say MATLAB, Claude, and Perplexity apps so a screen capture does not accidentally transmit a Mail or Messages window. Given accessiblity permission, one could capture windows by ID and stitch them together with a MATLAB command like composite = [matlab_img; claude_img; perplexity_img]; imwrite(composite, 'ai_workspace.png');
One must be careful an AI does not fake an analysis of an image based on context. Use a prompt preface like ‘Based solely on this image,… .” Note that AI image analysis is useful if you want suggestions for how to improve a figure by say moving a legend location from some default ‘best location’ to another location where it doesn’t hide something important.
What about communicating exact numerical results from MATLAB to an AI? A MATLAB .fig format file contains all of the exact data values used to create the figure. It turns out, Claude can receive a .fig through the manually-operated attach-file option in Claude App. Claude App of course sends received data to Anthropic and can parse the .fig format using python in its Docker container. In this way it can access the exact values behind plot data points and fitted curves and, for example, calculate a statistic describing agreement between a model curve and the data, assess outliers, and in principle suggest actions like smoothing or cleaning. Perplexity App’s manual attach-file handler does not permit upload of this format. There seem to be workarounds to 64-bit encode output files like .fig and transfer them to the host (Anthropic or Perplexity) but are there simpler ways to communicate results of the script execution? Yes.
Unless one has cleared variables during execution, all numerical and other results are contained in workspace variables in MATLAB’s memory. The values of these variables if saved can be accessed by an AI using MATLAB commands. The simplest way to ensure these values are available is to ask the AI that created and tested the script to include in the script itself a command like save('workspace.mat’) or to ask MATLAB to execute this command after executing the script. Then any AI connected to MATLAB can issue a request for variable values by issuing a MATLAB command like ‘data=load(‘workspace.mat’);fprintf(‘somevariablename’);and receive the response as text. An AI connected to MATLAB can also garner data embedded in a saved figure using MATLAB with a command like fig = openfig('MassPlots.fig', 'invisible'); h = findall(fig, 'Type', 'histogram'); data = h.Values .
Example work flow
The screenshot below illustrates a test with this setup. On the right is Perplexity App. I had first asked Perplexity to tell me about Compact Muon Solenoid (CMS) open data at CERN. The CERN server provides access to several data file types through a web interface. I decided to analyze the simplest such files, namely, Higgs boson decay candidate csv files containing the four-momentum vectors of four high energy leptons (two electrons and two muons) in select events recorded in the early years 2011 and 2012. (While the Higgs boson was discovered via its top-quark/W-boson loop-mediated decay to two photons, it can also decay to two Z bosons and each of these to a lepton+antilepton pair of any flavor.)
Screenshot showing Claude App, MATLAB, and Perplexity App
I asked Perplexity to create a new folder and write a MATLAB code to download those two files into the folder. Perplexity asked me to mouse over and copy the URLs of the download links on the appropriate page as these were hidden behind java applications, and voila. (As a test, I asked Claude in vague terms to find and download these files and it just figured it out without my manual intervention.) Next I asked Perplexity to “write and execute a MATLAB script to histogram the invariant mass of the electron pairs, of the muon pairs, and of the entire system of leptons, and to overlay fits of each dilepton mass distribution to a Lorentzian peak near the Z-boson mass (~90 GeV) plus a smooth background, save the script in the same folder, and run it.” It turns out that uncorrelated Z-boson pairs can be created by radiation from uncorrelated processes, that virtual Z bosons and photons with the “wrong” mass can be created, so one does not expect to necessary see a prominence in the 4-lepton invariant mass at the Higgs mass. For this reason I did not ask for a fit to the 4-lepton mass distribution. I did provide the starting estimated value for the location of the peak based on my experience of such nonlinear fits going off the rails.
After approving a few fixes of minor errors, voila. Sweet. In the middle of the screen shot are MATLAB App and the figure created. The format of the figure was all invented by the AI. On the left is Claude App’s analysis of the data, extracted from the manually uploaded figure in .fig format. The prompt was “Extract the histogram and fit values bin by bin an calculate the chisq per degree of freedom using the data in that .fig upload” .
I manually saved the workspace using the MATLAB Command line ( I could have asked Claude to do that) and I issued to Claude App the prompt “OK, I just saved workspace.mat in MATLAB/CMS. List the contents and the fit results.” Below is an image of the response of Claude analyzing the workspace .mat file.
Screenshot of Claude App .fig analysis
I then asked Claude to ask my local Ollama model for a 2nd opinion with the prompt “I want you to ask mistral-nemo for a 2nd opinion on the results on its own, based on all it knows, and to ask it for information about related resources. ” Claude first formulated and sentthe following prompt to the local LLM: “I measured the Z boson in the dimuon channel and got: Mass = 92.46 GeV Width = 12.44 GeV. The PDG values are M_Z = 91.19 GeV and Gamma_Z = 2.50 GeV. Based on your knowledge of particle physics and detector effects, what do you think is going on with my measurement? What could cause the width to be 5x larger than the natural width?” It’s mention of the width discrepency inparticular indicated it knew more about the physics than it had divulged.
Claude used MATLAB to call the local Ollama's REST API to get mistral-nemo's opinion with the path MATLAB MCP webwrite() Ollama Server (localhost:11434) mistral-nemo% calling Ollama's API from MATLAB with the pattern url = 'http://localhost:11434/api/generate';body = struct('model', 'mistral-nemo', 'prompt', 'Your question...', 'stream', false);response = webwrite(url, body, weboptions('MediaType', 'application/json'));
The received response was:
Your measured results for the Z boson mass and width differ significantly from the Particle Data Group (PDG) values. Here's a possible explanation for these discrepancies:
1. **Mass:**
The measured mass of 92.46 GeV is about 1.3 GeV higher than the PDG value of 91.19 GeV. This could be due to:
- **Detector calibration issues**: If your detector's energy scale is slightly miscalibrated, it could lead to an apparent shift in the measured mass.
- **Systematic effects**: Unaccounted-for systematic uncertainties might contribute to this difference.
- **New Physics**: While less likely, if new physics processes affect the Z boson, they could cause a resonant rise or other deviations from the expected behavior.
2. **Width:**
The measured width of 12.44 GeV is roughly five times larger than the natural width (Gamma_Z = 2.50 GeV). This significant difference is concerning and suggests potential issues:
- **Resonance tail**: If there's an unknown resonance near the Z boson mass, it could contribute to a large apparent width.
- **Misestimation of experimental resolution**: If you have underestimated your detector's energy resolution, it might result in a broader observed peak. The difference here seems quite large compared to typical experimental uncertainties (~1-2%).
- **Backgrounds and pile-up**: Higher backgrounds or pile-up events could artificially broaden the width.
- **Analysis method**: There might be an issue with your analysis method leading to a biased estimation of the Z boson width.
Given the discrepancy in both mass and width, it's crucial to perform thorough checks and validations:
- Review detector calibration data.
- Evaluate systematic uncertainties.
- Check for potential instrumental effects or electronic issues with the detector.
- Verify background models and consider alternative fitting methods or techniques like sideband subtraction.
- Re-evaluate your analysis pipeline to ensure no steps lead to biases in the measurements.
- Consult colleagues or experts to help identify possible causes of the discrepancy.
If these checks don't resolve the issue, it might warrant a cautionary note on potential new physics processes affecting the Z boson. However, without solid evidence and careful validation, it would be premature to claim such findings at this stage.
Claude then prompted the Ollama model with “I’m analyzing CMS HZZ4 data to measure Z boson properties. Can you recommend:1. Key papers I should read on Z boson measurements at the LHC 2. Standard analysis techniques for handling detector resolution 3. Any publicly available CMS or ATLAS open data resources 4. Software tools commonly used for this type of analysis” and received a long list of resources.
As Claude pointed out, the local Ollama model operates purely from memory and is subject to URL hallunciation so I asked Claude to check each of the many (too many to list here) URLs that Ollama provided. Claude has several options to accomplish such a task in my setup:
1. web_fetch (Anthropic tool)
2. fetch MCP server (installed on my Mac) commands fetch_html, fetch_markdown, fetch_text, fetch_jason.
3. puppeteer MCP server (installed on my Mac) which can navigate to a URL and take a screen shot and handle JavaScript-rendered pages.
4. web_search (Anthropic tool)
5. MATLAB web access tools including webread, websave, and shell commands
Claude first chose to test Ollama’s references using my installed fetch MCP server and found Mistral-nemo's URL accuracy to be: 5 valid: opendata.cern.ch, root.cern.ch, opendata.atlas.cern, pythia.org (concept, wrong URL), cms-sw.github.io; 6 invalid/hallucinated: atlas-open-data.org, pythia8.hep.yorku.ca, aida.hep.com, mc-code.eu/sherpa, www.cms.gov; 2 exist but WRONG CONTENT: arxiv URLs exist but are completely unrelated papers!
However, as Claude pointed out, use of one tool alone is subject to gotcha’s due to the variety of webpage content and deployment, robot rejection methods, and ability to check the content is valid if the URL is in fact reachable so a more detailed winnowing of the supplied resources ensued, combining results from using all tools.
Puppeteer
So what does the puppeteer server bring to the table? Puppeteer allows an app to access a website and exercise its interface. I used it with Claude App to explore and understand the interactive tools for creating an article submission on this website. Rather than create this submission, based on my own experience and Claude’s help, decided tht rather than have Claude build the submission interactively, it was easiest this time to create the submission in formatted .rtfd and paste that manually into the article submission field retaining all formating, and possibly use MATLAB to downsize the graphics a bit before insertion. WIth more experience, all this could be automated.
Like Perplexity Comet and the new Claude Chrome Extension, with puppeteer, your desktop AI App can presumably operate MATLAB Online but I’ve yet to explore that. If you do, let me know how it goes.
Conclusion
I hope this article encourages you to explore for yourself the use of AI apps connected to MATLAB, your operating system, and to cloud resources including other AIs. I am more and more astounded by AI capabilities. Having my “command post” suggest, write, test, and debug code, anwser my questions, and explore options was essential for me. I could ot have put this together unasisted. Appendix 1 (by Claude) delves deeper into the communications processes and may be helpful. Appendix 2 provides example AI-agent code generated by Claude. A much more extensive one was generated for interaction with Claude. To explore this further, ask Claude to just build and test such tools.
References
Appendix 1 Understanding the Architecture (Claude authored)
What is MCP?
Model Context Protocol (MCP) is an open standard developed by Anthropic that allows AI applications to connect to external tools through a standardized interface. To understand how it works, you need to know where each piece runs and how they communicate.
Where Claude Actually Runs
When you use Claude Desktop App, the AI model itself runs on Anthropic's cloud servers — not on your Mac. Your prompts travel over HTTPS to Anthropic, Claude processes them remotely, and responses return the same way. This raises an obvious question: how can a remote AI interact with your local MATLAB installation?
The Role of Claude Desktop App
Claude Desktop App is a native macOS application that serves two roles:
  1. Chat interface: The window where you type and read responses
  2. MCP client: A bridge that connects the remote Claude model to local tools
When you launch Claude Desktop, macOS creates a process for it. The app then reads its configuration file (~/Library/Application Support/Claude/claude_desktop_config.json) and spawns a child process for each configured MCP server. These aren't network servers — they're lightweight programs that communicate with Claude Desktop through Unix stdio pipes (the same mechanism shell pipelines use).
┌─────────────────────────────────────────────────────────────────┐
Your Mac
Claude Desktop App (parent process)
──[stdio pipe]── node ollama-mcp (child process)
──[stdio pipe]── node server-filesystem (child)
──[stdio pipe]── matlab-mcp-core-server (child)
──[stdio pipe]── node mcp-fetch-server (child)
└──[stdio pipe]── node server-puppeteer (child)
└─────────────────────────────────────────────────────────────────┘
When you quit Claude Desktop, all these child processes terminate with it.
The Request/Response Flow
Here's what happens when you ask Claude to run MATLAB code:
  1. You type your request in Claude Desktop App
  2. Claude Desktop Anthropic (HTTPS): Your message travels to Anthropic's servers, along with a list of available tools from your MCP servers
  3. Claude processes (on Anthropic's servers): The model decides to use the evaluate_matlab_code tool and generates a tool-use request
  4. Anthropic Claude Desktop (HTTPS): The response arrives containing the tool request
  5. Claude Desktop MCP Server (stdio pipe): The app writes a JSON-RPC message to the MATLAB MCP server's stdin
  6. MCP Server executes: The server runs your code in MATLAB and captures the output
  7. MCP Server Claude Desktop (stdio pipe): Results written to stdout
  8. Claude Desktop Anthropic (HTTPS): Tool results sent back to Claude
  9. Claude formulates response (on Anthropic's servers)
  10. Anthropic Claude Desktop You: Final response displayed
The Claude model never directly touches your machine. It can only "see" what MCP servers return, and it can only "do" things by requesting tool calls that your local app executes on its behalf.
MCP Servers vs. Backend Services
It's important to distinguish MCP servers from the services they connect to:
Component
What It Is
Lifecycle
Ollama MCP server
A Node.js process that translates MCP requests into Ollama API calls
Spawned by Claude Desktop, dies when app quits
Ollama server
The actual LLM runtime serving models like mistral-nemo
Runs independently (started manually or via launchd)
MATLAB MCP server
A process that translates MCP requests into MATLAB Engine commands
Spawned by Claude Desktop
MATLAB
The full MATLAB application
Runs independently; MCP server connects to it
If the Ollama server isn't running, the Ollama MCP server has nothing to talk to — its commands will fail. Similarly, the MATLAB MCP server needs MATLAB to be running (or may launch it, depending on implementation).
What About Other AI Apps?
If you run both Claude Desktop and Perplexity App with MCP configurations, each app spawns its own set of MCP server processes:
Claude Desktop (PID 1001) Perplexity App (PID 2001)
── ollama-mcp (PID 1002) ── ollama-mcp (PID 2002)
── server-filesystem (PID 1003) ── server-filesystem (PID 2003)
└── matlab-mcp-server (PID 1004) └── matlab-mcp-server (PID 2004)
HTTP to same endpoints
└────────────────────────────────────┘
┌────────────────────┐
Shared Services
• Ollama Server
• MATLAB Engine
└─────────────────────┘
Key points:
  • No cross-talk: Claude Desktop cannot communicate with Perplexity's MCP servers (or vice versa). Each app only talks to its own children via stdio pipes.
  • Shared backends: Both apps' MCP servers can make requests to the same Ollama server or MATLAB instance — they're just independent clients of those services.
  • No app launching: Claude cannot launch, control, or send commands to Perplexity App. They are peer applications, not parent-child.
How Claude "Talks To" Perplexity
When I say Claude can query Perplexity, I mean Claude calls Perplexity's cloud API — not Perplexity App. The path looks like this:
Claude model (Anthropic servers)
│ requests tool use
Claude Desktop App
│ stdio pipe
MATLAB MCP Server
│ MATLAB Engine API
MATLAB running webwrite() or perplexityAgent()
│ HTTPS
api.perplexity.ai (Perplexity's cloud)
Perplexity App isn't involved at all. The same applies to OpenAI, Anthropic's own API (for nested calls), or any other service with an HTTP API.
One App to Rule Them All?
Claude Desktop doesn't control other apps, but it can:
  1. Orchestrate local tools via MCP servers it spawns and controls
  2. Call any cloud API (Perplexity, OpenAI, custom services) via HTTP through fetch MCP or MATLAB
  3. Share backend services (Ollama, MATLAB) with other apps that happen to use them
  4. Coordinate multi-AI workflows by sending prompts to local models (via Ollama) and cloud APIs, then synthesizing their responses
The "ruling" is really about Claude serving as a command post that can dispatch requests to many AI backends and tools, not about controlling other desktop applications.
Appendix 2 Example AI agent (Claude authored)
The following is an example of Claude-generated code generated for an AI agent to handle requests to access Perplexity. It receives the users prompt, if needed, discovers the users Perplexity API key hidden in a local text file, posts a message to Perplexity API, and then receives and returns the response.
function response = perplexityAgent(prompt)
%PERPLEXITYAGENT Query Perplexity AI using their Sonar API
% response = perplexityAgent(prompt)
%
% Requires: PERPLEXITY_API_KEY environment variable
% Get your key at: https://www.perplexity.ai/settings/api
apiKey = getenv('PERPLEXITY_API_KEY');
if isempty(apiKey)
% Try to load from file
keyFile = fullfile(userpath, 'PERPLEXITY_API_KEY.txt');
if isfile(keyFile)
fid = fopen(keyFile, 'r');
raw = fread(fid, '*char')';
fclose(fid);
match = regexp(raw, 'pplx-[a-]+', 'match');
if ~isempty(match)
apiKey = match{1};
setenv('PERPLEXITY_API_KEY', apiKey);
end
end
end
if isempty(apiKey)
error('PERPLEXITY_API_KEY not set. Get one at perplexity.ai/settings/api');
end
url = 'https://api.perplexity.ai/chat/completions';
% Build request
data = struct();
data.model = 'sonar';
msg = struct('role', 'user', 'content', prompt);
data.messages = {msg};
jsonStr = jsonencode(data);
% Use curl for reliability
curlCmd = sprintf(['curl -s -X POST "%s" ' ...
'-H "Authorization: Bearer %s" ' ...
'-H "Content-Type: application/json" ' ...
'-d ''%s'''], url, apiKey, jsonStr);
[status, result] = system(curlCmd);
if status == 0 && ~isempty(result)
resp = jsondecode(result);
if isfield(resp, 'choices')
response = resp.choices(1).message.content;
elseif isfield(resp, 'error')
response = sprintf('API Error: %s', resp.error.message);
else
response = result;
end
else
response = sprintf('Request failed with status %d', status);
end
end
The Cody Contest 2025 has officially wrapped up! Over the past 4 weeks, more than 700 players submitted over 20,000 solutions. In addition, participants shared 20+ high-quality Tips & Tricksarticles—resources that will benefit Cody users for years to come.
Now it’s time to announce the winners.
🎉 Week 4 winners:
Weekly Prizes for Contest Problem Group Finishers:
Weekly Prizes for Contest Problem Group Solvers:
Weekly Prizes for Tips & Tricks Articles:
This week’s prize goes to @WANG Zi-Xiang. See the comments from our judge and problem group author @Matt Tearle:
‘We had a lot of great tips for solving Cody problems in general and the contest problems specifically. But we all know there are those among us who, having solved the problem, still want to tinker and make their code better. There are different definitions of "better", but code size remains the base metric in Cody. Enter Wang Zi-Xiang who compiled a list of many tips for reducing Cody size. This post also generated some great discussion (even prompting our insane autocrat, Lord Ned himself, to chime in). I particularly like the way that, while reducing Cody size often requires some arcane tricks that would normally be considered bad coding practice, the intellectual activity of trying to "game the system" makes you consider different programming approaches, and sometimes leads you to learn corners of MATLAB that you didn't know.’
🏆 Grand Prizes for the Main Round
Team Relentless Coders:
1st Place: @Boldizsar
2nd Place: @Roberto
Team Creative Coders:
1st Place: @Mehdi Dehghan
2nd Place: @Vasilis Bellos
3rd Place: @Alaa
Team Cool Coders
1st Place: @Hong Son
2nd Place: @Norberto
3rd Place: @Maxi
Congratulations to all! Securing a top position on the leaderboard requires not only advanced MATLAB skills but also determination and consistency throughout the four-week contest. You will receive Amazon gift cards.
🥇 Winning Team
The competition was incredibly tight—we even had to use the tie-breaker rule.
Both Team Cool Coders and Team Relentless Coders achieved 16 contest group finishers. However, the last finisher on Cool Coders completed the problem group at 1:02 PM on Dec 7, while the last finisher on Relentless Coders finished at 9:47 PM the same day.
Such a close finish! Congratulations to Team Cool Coders, who have earned the Winning Team Finishers badge.
🎬 Bonus Round
Invitations have been sent to the 6 players who qualified for the Bonus Round. Stay tuned for updates—including the Big Watch Party afterward!
Congratulations again to all winners! We’ll be reaching out after the contest ends. It has been an exciting, rewarding, and knowledge-packed journey.
See you next year!
Over the past three weeks, players have been having great fun solving problems, sharing knowledge, and connecting with each other. Did you know over 15,000 solutions have already been submitted?
This is the final week to solve Cody problems and climb the leaderboard in the main round. Remember: solving just one problem in the contest problem group gives you a chance to win MathWorks T-shirts or socks.
🎉 Week 3 Winners:
Weekly Prizes for Contest Problem Group Finishers:
Weekly Prizes for Contest Problem Group Solvers:
@森緒, @R, @Javier, @Shubham Shubham, @Jiawei Gong
Weekly Prizes for Tips & Tricks Articles:
This week’s prize goes to @Cephas. See the comments from our judge and problem group author @Matt Tearle:
'Some folks have posted deep dives into how to tackle specific problems in the contest set. But others have shared multiple smaller, generally useful tips. This week, I want to congratulate the cumulative contribution of Cool Coder Cephas, who has shared several of my favorite MATLAB techniques, including logical indexing, preallocation, modular arithmetic, and more. Cephas has also given some tips applying these MATLAB techniques to specific contest problems, such as using a convenient MATLAB function to vectorize the Leaderboard problem. Tip for Problem 61059 – Leaderboard for the Nedball World Cup:'
Congratulations to all Week 3 winners! Let’s carry this momentum into the final week!
In just one week, we have hit an amazing milestone: 500+ players registered and 5000+ solutions submitted! We’ve also seen fantastic Tips & Tricks articles rolling in, making this contest a true community learning experience.
And here’s the best part: you don’t need to be a top-ranked player to win. To encourage more casual and first-time players to jump in, we’re introducing new weekly prizes starting Week 2!
New Casual Player Prizes:
  • 5 extra MathWorks T-shirts or socks will be awarded every week.
  • All you need to qualify is to register and solve one problem in the Contest Problem Group.
Jump in, try a few problems, and don’t be shy to ask questions in your team’s channel. You might walk away with a prize!
Week 1 Winners:
Weekly Prizes for Contest Problem Group Finishers:
Weekly Prizes for Tips & Tricks Articles:
Week 1 winner for best Tips & Tricks Articles is @Vasilis Bellos.
Contest problems author @Matt Tearle commented:
We had a lot of people share useful tips (including some personal favorite MATLAB tricks). But Vasilis Bellos went *deep* into the Bridges of Nedsburg problem. Fittingly for a Creative Coder, his post was innovative and entertaining, while also cleverly sneaking in some hints on a neat solution method that wasn't advertised in the problem description.
Congratulations to all Week 1 winners! Prizes will be awarded after the contest ends. Let’s keep the momentum going!
This week's Graphics and App Building blog article guides chart authors and app builders through the process of designing for a specific theme or creating theme-responsive charts and apps.
  • Learn how dark theme may impacts charts and apps
  • Discover best practices for theme-adaptive workflows
  • Step-by-step examples for both script-based plots and advanced custom charts and UI components
  • Discover new tools like ThemeChangedFcn, getTheme, and fliplightness
We are thrilled to announce the grand prize winners of our MATLAB Shorts Mini Hack contest! This year, we invited the MATLAB Graphics and Charting team, the authors of the MATLAB functions used in every entry, to be our judges. After careful consideration, they have selected the top three winners:
1st place - Tim
Judge comments: Realism & detailed comments; wowed us with Manta Ray
2nd place – Jenny Bosten
Judge comments: Topical hacks : Auroras & Wind turbine; beautiful landscapes & nightscapes
3rd place - Vasilis Bellos
Judge comments: Nice algorithms & extra comments; can’t go wrong with Pumpkins
There is also an Honorable Mention - William Dean
Judge comments: Impressive spring & cubes!
In addition, after validating the votes, we are pleased to announce the top 10 participants on the leaderboard:
Congratulations to all! Your creativity and skills have inspired many of us to explore and learn new skills, and make this contest a big success!
Dear MATLAB contest enthusiasts,
Welcome to the third installment of our interview series with top contest participants! This time we had the pleasure of talking to our all-time rock star – @Jenny Bosten. Every one of her entries is a masterpiece, demonstrating a deep understanding of the relationship between mathematics and aesthetics. Even Cleve Moler, the original author of MATLAB, is impressed and wrote in his blog: "Her code for Time Lapse of Lake View to the West shows she is also a wizard of coordinate systems and color maps."
The interview has been published on the MATLAB Community Blog. We highly encourage
you to read it to learn more about Jenny’s journey, her creative process, and her favorite entries.
Question: Who would you like to see featured in our next interview? Let us know your thoughts in the comments!
Sonesson
Sonesson
Last activity on 5 Nov 2024

About a year ago, I made a rubix cube solver with the goal of solving a cube faster than I could in real life. It was a fun and educating project, and while it is a long way from optimal, I finished with satisfying results.
How the solver is made is a story for another time, but I always wanted to have a 3D illustration of how the moves are performed to reach the solved state. Lacking the motivation at the time, the illustrative part was forgotten... Untill a couple of weeks ago when I found out about the MATLAB Shorts Mini Hack. It was the perfect motivation to finish up!
This post will detail my entry and remixes (you should check them out before reading!) in this years mini hack. I am not a man to spare any detail, and I've recently saved up a bunch of characters from being limited to 2000, so it may be a bit wordy, but I'll try to keep it entertaining. How it works, lessons learned, sidetracks, pitfalls found, and everything in between is detailed here. So feel free to peruse the sections and pick the ones that sound interesting!
How can I make it move?
Intuativly one would use standard rubix notation to determine the moves, but due to the character limitation and me wanting the ability to rotate the middle rows and the cube as a whole I decided against this.
At the tippy top, there is an 3xn character array, MS, containing the movement sequence of the cube. The three rows contains:
  1. The axis to rotate around. - Defined by character x, y, z, or p (none of them).
  2. The row to rotate. - Defined by character 1, 2, 3, or 4 (all of them)
  3. The direction of the rotation. - Defined by character n, or p (negative or positive)
The rows are ordered from largest to smallest coordinate value along the axis of rotation. If a pause is selected, the program does not really care which character is chosen for the row and direction.
"But how many moves can I make within the time?" As many, or few, as you want.
Well... As long as you want 96 or less moves that is. The function alters the angular speed of the rotations to fit them all within the 96 frame window. But since we iterate through the cube (more on that later) we need to ensure that a move has completely finished before starting another move, or the cube will start looking like a contortionist.
If there is remaining time before the 96 frames are up (due to the timing of the angular speed), the cube politely pauses and waits for the last coule of frames to pass.
The hardest part is finding a sequence short enough to not look like the cube is flailing wildly during its 4 seconds of fame, but long enough to make some interesting pattern like the tetris shuffle in my original entry! Preferably while still being a perfect loop.
I would go on about good seamless loop mechanics, but Vasilis Bellos already made the great post "Creating seamless loop animations by zooming in" last week so I'll just sum it up to make sure to end right before the place you start.
Easy, right? Now go make your own!
Tip: Use the camera rotation to your advantage! Wanting to showcase all sides of the Mathworks cube for as long as possible, I needed a short movement sequence which gives lower angular speed. I cut out two moves from the sequence by making the camera rotate 180 degrees to finish my perfect loop at a different set of coordinates from where I started!
How did you make the cube so beautiful (MathWorks motive)?
A lot of credit should go to Tomoaki Takagi and his entry. I am a sucker for utilizing things for purposes they were not intended to be used for, and he did just that.
We are not allowed to upload images or data in the contest. But we are allowed to optionally upload some background audio for the video. The key is to realise that this audio is stored in the same place as the contest entry. Meaning we can access the "audio.wav" file we just uploaded to the contest.
An audio file is really just a long row of values between -1 and 1. So... if one were to take a picture of every side of a MathWorks cube laying around on the desk, splice the images into 54 seperate textures, scale the intensities between 0 and 1, reshape them to a row, and save it as an .wav file using the audiowrite() function... One would have a bit too much free time, but also a terrible sounding audio file with image data encoded.
There is one small problem however. As you might have noticed, the audio of most entries sound... rough. This is because of an file compression (or something of the like) applied to files over a certain length when you upload them to the contest. This also applies to audio files filled with image data that does not take particularly well to getting squeezed.
The solution? Compress it yourself (carefully)! Again I looked at Tomoaki's entry, to see what length worked for him. His entry contained a 150x150x3 image upscaled by a factor 4. His image is not exactly sharp, and with 54 different textures needed for a cube, each side would be... about 3x3x3. While a bit poetic, we can not bring such dishonour to such a beautiful object! Luckily Tomoaki had not used the entire audio file for image storage. And he used mono sound (1 audio channel) for his entry and .wav files support stereo sound (2 aoudio channels) meaning I could utilize twice as much space netting me a neat, decent resolution of 28x28 pixels per face!
Don't forget to overwrite the audio on the last frame using audiowrite() however! Most people don't appreciate the sound of images. You should explore Tomoaki's entry for more information on this. The entry is short and easy to understand.
Summary: The audio file uploaded can be used to store image data instead of sound data. Just be careful about file length and size as compression won't treat you kindly!
How did you build the cube?
Excellent question, my dear watsson. Surfaces. Lots and lots of surfaces. This part is takes the most computation time. If anyone has some forbidden knowledge I don't know about here, feel free to correct and enlighten me!
We want to be able to assign each face of the cube a seperate texture, and to be able to move each face seperately without it morphing itself or other parts of the cube. Because of this, they can't be part of a meshgrid connecting each other. Instead we have to construct each surface individually. This takes a second, but is much better in my latest version (See more in the I crave speed section). Which in my earlier entries was a big deal because I was yet to learn about our lord and saviour, persistent variables through Timothy's beautiful entry: Refraction.
One could think a rubix cube has 54 faces, 9 on each side, but alas that is but an illusion. A rubix cube is infact 27 (26 if not counting the center) smaller cubes in a trench coat. Each with 6 sides. (As illustrated by William Dean's entry Is this cheating? posted while I'm writing this, thanks for the assist!).
Patch objects are all good and well when creating faces if you only want colors, which is the case in my first submission. But MATLAB surface objects are also 3D and have a property that allows them to be textured which we use in the later versions.
Thinking about the trench coat covered cubes, we can tell that on a physical cube we have 6 planes in each coordinate direction. 2 for each row of cubes. The faces pointing outward are textured and the faces pointing inward are typically black. That is how we will model our cube as well.
The above image shows how the cube looks during the process of building each face. You may think to yourself "Why do you only have 4 planes in a direction? Do we really need all 6 that you mentioned?" Yes. and if you could enhance and zoom the image like the movies, you would see a tiny gap between the "2" black central planes (this is a surprise tool that will help us later!). The 6 planes are necessary to cover up the cube's hollow interior from multiple viewing angles so we can not compromise it down to 4. Imagine flippnig the cube in the first image of this section and looking into the cube. If we had 4 planes, we would be able to see through the cube from one of the angles.
Summary: We imagine the cube as 3x3x3 smaller cubes. We build each side, inwards pointing or not. We make each face of these smaller cubes seperately using surface() to avoid morphing behavior and to allow the surfaces to be textured individually.
How does it move?
The trick is all about coordinates. Firstly, to make the cube move we need a couple of things:
  • Some indicator of how and what to move (a movement sequence, MS)
  • The speed at which it should move
  • A way to separate what verticies should and should not move
  • An operation to transform the coordinates of said verticies so they move
  • And of course we need to update the existing data and plot.
We are already familliar with the movement sequence from the first section, so I will spare you the repetition.
The speed of rotation is fairly simple, we have a number of moves defined in MS, and a number of frames to play with, 96. Simply find how many frames we can afford to allocate each move, and since each "rotation" of the cube is a quarter turn () we get . Pretty straight forward.
Now we need to know which verticies should and should not move. Here we use our surprise tool from the previous section! When building the cube, we add a slight offset separating the central planes. We can use this coordinate shift to separate the different planes from eachother. This would not be entierly possible if the central planes shared coordinates.
As an example, let's say the movement sequence dictates that we should rotate around x and we should choose the first row. Since the cube is centered around 0 and the planes have coordinates:
in all directions where δ is the small offset, we can easily seperate the first row by checking which faces have x coordinates higher than 0.5 in all 4 verticies. Simmilarly we check for 4 verticies in between ±0.5 for the 2nd row and values lower than -0.5 for the 3rd row. For rotating the entire cube, we can just select all faces. This works for all coordinate axis due to the symmetry that occurs when being centered around 0.
Now we need an operation to transform the coordinates of the verticies. We want to rotate some 3D coordinates around a specified coordinate axis. Sounds like the perfect job of a rotational matrix for me. This is why you stay in school kids.
In case someone has never heard of a rotation matrix before, on the assumption that anyone using Matrix Laboratory is probably familliar with matrix math and basic linear algebra I'll keep this short. Basically, there are some standard matrices that will rotate a point [x,y,z] arount the origin of an axis. such that
=
Where the subscripts r denotes the rotated coordinates and ax the axis to rotate around.
These matricies are as follows:
Where θ is the angle with which you rotate the point. In our case the Angular speed.
Now, I define my own rotation matrices. This is because of one of three reasons:
  1. MATLAB does not have rotation function which rotates a point around a specified axis (this would baffle me)
  2. I am blind and could not see the correct function in the documentation (plausible)
  3. I am illiterate and can not read the documentation (improbable)
So we have everything we need! We just update the coordinate data of the affected surface objects, slap down a drawnow command for good measure, and call it an iteration!
But I'd like to shine light on something that is both feature and flaw before we move on. 24 frames per second looks decent enough, but trained eyes can tell it is a bit choppy. Especially when things move fast. So we would like our movement as slow as possible. "Then why does the angular speed as defined above not always utilize all 96 frames to finish the movement sequence?" Because to a trained eye, what looks even more choppy is a rotation not finishing before another starts as the image shows below with a frame by frame on this effect.
By matching the angular speed to an integer number of frames (by using floor()) for each rotation, we will always complete the entire rotation before starting the next move.This is good because of the reason mentioned above (it looks better), but also because we will base the next rotation on the coordinates of the current position. So it also saves us having to do some extra math to get everything aligned and in position to select the correct faces every time we swap move.
Summary: We use a combination between clever choice of coordinates and some standard rotational matricies to shift the relevant verticies as dictated by the movement sequence by an angle. Being carefull to make each rotation precisely end on an integer number of frames so that the same method works next time.
I crave speed!
Well buckle up then bucko! Best part about programming is that the instant after you spend time making something, you learn something that trivialises it. Persistent variables were that for me this project. My 3rd remix is all about making it faster (in the works as we speak)! You know what they say; "Make it work, make it good, make it fast".
My biggest qualm about my earlier versions was the execution speeds. Every call of drawframe, I would have to rebuild all my surface object to make the cube and re-iterate all the movement of the cube up untill the current frame to ensure the rotations of all verticies, and thus faces, are correct.
Defining a variable as persistent allocates it's memory in a way that it is not removed between function calls. Perfect for being limited by 96 calls to the same function that does not accept iterative input.
Without persistent variables, we needed to remake the surfaces each call to drawframe. Worse still; since we dont know the positions of the surfaces in the previous frame, we also had to re-iterate all the movement of the cube. You may ask yourself "why could you not just calculate the surface position based on the frame, angular speed of rotation and previous moves?". While the position of each face is possible to anticipate effectively with a look up table (which would not fit in the character limit but could have been snuck in with the image data), the rotation of each face is a bit more complex to keep track of. Not an issue with plain colors, but a challange when using textured faces.
Using persistent variables as in my latest version solves theese two issues and makes the code run silky smooth compared to earlier. It now
  1. Removes the most time consuming part (creating surfaces) 95 out of 96 times, and
  2. Removes the need of re-iterating through all movement to catch up with all the rotations previously made.
It does however remove a neat function of the code; frame independency. The competition calls drawframe 96 times with the numbers 1:96, so frame independency it is not an issue as the previous frame is always the previous frame. However, if we now were to call the drawframe function with the values 1, 5 ,and 96, we would not recieve frame number 1, 5, and 96 of the animation as we would have before. Now there is an implicit need to call the function in with the frames in order.
An interesting thought that occured to me was; "If I can store the surface object in a variable, why could i not just copy it to another variable and edit it's properties instead of making a gazillion calls to surface()?" Well, turns out that is not possible because the surface object as stored in the workspace is really more of a pointer to the memory storing the object in the figure window rather than the value in the memory itself. If you copy surface_1 to surface_2 and change surface_2: you get the same change in surface_1.
Also, you might think;
"EWWW... I see nested for loops."
Yep. Is creating the coordinates for the surfaces vectorizable? Absolutely. Not even that hard either. Use combinations() with the possible x, y, and z coordinates and you got yourself the coordinates to every vertice of the cube. Use some fancy logic to determine which vertice goes where and vóila: all verticies neatly ordered ready to be made into surface objects. You could probably even use meshgrid() instead if that is more to your liking. The issue lies in the "made into surface objects" part. As stated, the repeated surface call is still needed to obtain seperate parts of memory to store the surface objects. You would still need as many loop iterations, though not nested. So I decided to leave the nested loops, as a treat, because it made it easier to determine the order and orientations of the textures when encoding them into the audio. After all, efficient coding is not only about the execution speed of the code, it is also about the writing speed of the coder. Or as textbook authors would say: "This is left as an excercise to the reader".
"Are all the inner planes necessary?"
Almost. We need 6 planes for the cube to not look hollow, but since the entire inside plane is black could we not just make it one big surface? No. Different part of the planes move with different rotations, and so can eventually end up as a part of another plane. To avoid morphing, they can not be connected. Also if the planes were solid, we would rotate into still standing planes when a row is angled (kind of like the black parts of the contorted cube earlier). However, we technically do not need the center of the 27 cubes in any scenario, and we could write some logic to not include those specific faces. This was not done for character limitation purposes. I figured that the slight tank in speed would be outweighed by the clean looks and the potential that you, the reader, could achieve when remixing this entry with those sweet sweet roughly 30 extra characters.
"Wait, are you looping... backwards?"
Yes! Looping backwards is a pretty neat trick. In this application it is mainly used to save characters, but runs in roughly the same time as a typical explicit preallocation would.
It works bacause we allocate the first loop value in the last variable element. It is the same principle as writing:
a(5) = 5
a = 1×5
0 0 0 0 5
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
As you can see MATLAB will allocate memory for a 5 element vector despite us only specifying one element. So if we start from the back, MATLAB will do the front for us!
And here you can see how it holds up to not preallocating/typical allocation. Plus it gives the same result!
% No preallocation
tic
for i=1:1:10000
x(i) = i;
end
toc
Elapsed time is 0.012242 seconds.
% Typical Preallocation
tic
y=zeros(10000,1);
for i=1:1:10000
y(i) = i;
end
toc
Elapsed time is 0.005438 seconds.
% Backwards looping
tic
for i=10000:-1:1
z(i) = i;
end
toc
Elapsed time is 0.001842 seconds.
% And produces the same results!
all(z==x)
ans = logical
1
Summary: Persistent variables are really neat They keep their values between calls to functions. In terms of this contest they remove the need to re-iterate things, or for you to keep the state of the last frame without the need for rebuilding it every time.
Surface objects in the workspace are really just pointers to the surface objects in the figure window. This means that we unforttunately must call surface() for each face we want to create.
While initiating the surfaces, I use nested loops. Unnesting these loops is very doable with combination() and left as an excercise to the reader. You will still need the same total number of loop iterations to create all the surface objects, and the loops make texturing more convinient.
All 6 planes are necessary, but the central face of each "inside" plane is redundant and could be skipped at the cost of some additional logic.
Looping backwards is a cool trick to make MATLAB perform the preallocation of memory for you when iterating through a variable.
You get a cube, and you get a cube, and...
As earlier stated, in the "I crave speed!" section my 3 entries happen to follow the "Make it, make it good, make it fast" rule. But I did not just want to upload something that did not add more than just having cleaner code. There is a whole artistic and visual part to it all. So I thought to myself, why not use the speed? Now that the thing is running smooth, why not just run it twice? So i did just that. Except, simmilar results could be achived with much less grief if I just... Made the illusion that I ran it several times in parallel. I wanted to show of the improved speed with making more cubes, but... Why not just copy the cube? So I did that insead!
The figure window i really just an interactive image. using getframe()and frame2im() we can quickly turn whatever is shown in the current figure into an image stored in a workspace variable. From here we just need to display that same image multiple times in a sort of array. repmat() in combination with imshow() could have been used here (and would probably have been a bit more flexible in deciding how the cubes are displayed) but I opted for storing the image in a cell array of desired size and using montage() instead.
Most people being character limited in this competition keep everyting to a minimum including the figure windows. Yet I have two of those in my last entry despite only one being shown. As stated in the previous section, surface objects in the workspace is really more of a pointer to the object in the figure, so to keep all my surfaces in between runs I need the figure window containing my surface objects undisturbed. which is why I place the montage in a seperate figure. and display that at the end instead.
An interesting feature *cough* bug *cough* is the swapping between the figure windows that appear in the video generated. This is because of using return as various points in the code in order to skip computations if the move is a 'pause'. The code then does not reach the point where the figure is swaped and montage is made. I thought this to be visually interesting and is therefore dubbing this bug a feature and leaving it in!
Summary:
Multiple cubes were achived by taking the 'image' displayed by the plot window and creating a montage with several of them in a seperate figure window. The swapping between the single and multiple cube view is made by selecting the active figure window before the end of the drawframe call!
Bye for now!
I have yapped on for far too long. Hope you learned something, and thank you all for the kind words and positive response to my entry. This project has been a blast!
Over the past week, we have seen many creative and compelling short movies! Now, let the voting begin! Cast your votes for the short movies you love. Authors, share your creations with friends, classmates, and colleagues. Let's showcase the beauty of mathematics to the world!
We know that one of the key goals for joining the Mini Hack contest is to LEARN! To celebrate knowledge sharing, we have special prizes—limited-edition MATLAB Shorts—up for grabs!
These exclusive prizes can only be earned through the MATLAB Shorts Mini Hack contest. Interested? Share your knowledge in the Discussions' general channel (be sure to add the tag 'contest2024') to earn opportunities to win the coveted MATLAB Shorts. You can share various types of content, such as tips and tricks for creating animations, background stories of your entry, or learnings you've gained from the contest. We will select different types of winners each week.
We also have an exciting feature announcement: you can now experiment with code in MATLAB Online. Simply click the 'Open in MATLAB Online' button above the movie preview section. Even better! ‘Open in MATLAB Online’ is also available in previous Mini Hack contests!
We look forward to seeing more amazing short movies in Week 2!
Let's say you have a chance to ask the MATLAB leadership team any question. What would you ask them?
Kindly link me to the Channel Modeling Group.
I read and compreheneded a paper on channel modeling "An Adaptive Geometry-Based Stochastic Model for Non-Isotropic MIMO Mobile-to-Mobile Channels" except the graphical results obtained from the MATLAB codes. I have tried to replicate the same graphs but to no avail from my codes. And I am really interested in the topic, i have even written to the authors of the paper but as usual, there is no reply from them. Kindly assist if possible.

Hello MathWorks Community,

I am excited to announce that I am currently working on a book project centered around Matrix Algebra, specifically designed for MATLAB users. This book aims to cater to undergraduate students in engineering, where Matrix Algebra serves as a foundational element.

Matrix Algebra is not only pivotal in understanding complex engineering concepts but also in applying these principles effectively in various technological solutions. MATLAB, renowned for its powerful computational capabilities, is an excellent tool to explore and implement these concepts, making it a perfect companion for this book.

As I embark on this journey to create a resource that bridges theoretical matrix algebra with practical MATLAB applications, I am looking for one or two knowledgeable individuals who have a firm grasp of both subjects. If you have experience in teaching or applying matrix algebra in engineering contexts and are familiar with MATLAB, your contribution could be invaluable.

Collaborators will help in shaping the content to ensure it is educational, engaging, and technically robust, making complex concepts accessible and applicable for students.

If you are interested in contributing to this project or know someone who might be, please reach out to discuss how we can work together to make this book a valuable resource for engineering students.

Thank you and looking forward to your participation!

First, I felt that the three answers provided by a user in this thread might have been generated by AI. How do you think?
Second, I found that "Responsible usage of generative AI tools, such as ChatGPT, is allowed in MATLAB Answers."
If the answers are indeed AI generated, then the user didn't do "clearly indicating when AI generated content is incorporated".
That leads to my question that how do we enforce the guideline.
I am not against using AI for answers but in this case, I felt the answering text is mentioning all the relevant words but missing the point. For novice users who are seeking answers, this would be misleading and waste of time.
Mathworks has always had quality documentation but in 2023, the documentation quality fell. Will this improve in 2024?
Adam Danz
Adam Danz
Last activity on 6 Mar 2024

I'm curious how the community uses the hold command when creating charts and graphics in MATLAB. In short, hold on sets up the axes to add new objects to the axes while hold off sets up the axes to reset when new objects are added.
When you use hold on do you always follow up with hold off? What's your reasoning on this decision?
Can't wait to discuss this here! I'd love to hear from newbies and experts alike!
The 2022 community contests have concluded! During the 4 weeks, we hope you had a lot of fun and learned some MATLAB skills. Together, we've achieved amazing milestones:
  • 500+ entries and 5,000+ votes created in the Mini Hack 2022 contest.
  • 100,000+ solutions submitted in Cody 10th Anniversary contest
  • 2,000+ participants in both contests
Now, it's time to announce weekly winners and grand prize winners!
Mini Hack - Pick of the MATLAB Graphics Team
We invited the MATLAB Graphics team, the authors of the MATLAB functions used in every entry, to be our Mini Hack judges. Here are their picks in 3 categories:
  • Our Top 3:
Rising Hand by Augusto Mazzei
Object used: fill; Judge comments: Clever code, nice metaphor, kind comments
Object used: patch (via VOXview); Judge comments: Very pretty, looks like it could be in a video game
Monocular rivalry by Jenny Bosten
Object used: Image; Judge comments: We spent a too much time trying to figure out what this illusion was doing to our brains
  • Clever use of Charts:
Object used: Bar3; Judge comments: Cute! Nice fireworks!
Ship by Shanshan Wang
Object used: histogram2; Judge comments: We didn't realize there was a ship in the flow data set
A fish for fun by Shanshan Wang
Object used: plot; Judge comments: Nifty and very different from other entries.
Colorful Fibonacci Spiral #3 by Basil Imoberdorf
Object used: scatter; Judge comments: Overlapping markers make for a very cool tunnel-like effect
  • Things we still loved:
Sandstone by Tim
Object used: image; Judge comments: Domain Warping FTW
Jellyfish by Tim
Object used: surface; Judge comments: Clever use of transparency
Congratulations and you should be very proud of yourself! It's a huge achievement that your entry is recognized by the MATLAB Graphics team!
Mini Hack - special category for Week 4
Our Week 4 special category is ‘Holiday’. The winner is Christmas snowman by Simon Thor
Mini Hack - grand prize winners
After an intensive (and very time-consuming) review of votes on winning entries, we have finalized the list of grand prize winners. Huge congratulations! We appreciate the time and effort you spent and the awesome entries you created. Each of you won an Amazon gift card.
Anton Kogios, Brandon Caasenbrood, KARUPPASAMYPANDIYAN M, Teodo, Jenny Bosten, MvLevi, Abdullah Caliskan, Stewart Thomas, Jonas Schlatter, and Tim Davis
Cody 10th Anniversary - surprise prize for 28-day streak winners
We are thrilled to see that 37 players have built a streak of 28 days! Coming back every day to solve problems is an incredible achievement. We decided to show our appreciation by awarding a surprise prize to those 37 players. Congratulations! Each of you will get a MathWorks T-shirt.
Christian Schröder, Stefan Abendroth, Mohammed, Victoria, Vasileios Pasialis, Gerardo Domínguez Ramírez, HH, Anton Kogios, Lizhi Zhu, Marco Fuscà, Armando Longobardi, Monica, Rithik KRT, Ayman, Teodo, Lincoln Poon, Elijah Keifert, siranjeevi gurumani, kazuyoshi kouno, Ryan Koh, Manuela Kaiser, Mehmet OZC, Dyuman Joshi, KOTHAPALLI SRI BRINDA, Gergely Patay, abyss, Takumi, Keita Abe, Petr Cerny, Shubham Shubham, Meredith, Andrew K, Atsushi Ueno, Peter Orthmann, Armando Longobardi, Chuang Tao, and David Romero
Cody 10th Anniversary winners – Week 4
The top 3 players for solving the most problems in week 4 are Christian Schröder, Gerardo Dominguez Ramirez, and Stefan Abendroth, Congratulations! Each of you won an Amazon gift card.
Week 4 lucky winners are Qingrui Liu and Basant Ale.
Cody 10th Anniversary winners – grand prize winners
We know how hard it is to be a top-10 leader in the contest leaderboard! It requires a huge time commitment and advanced MATLAB skills. Congratulations! Each of you will win an Amazon gift card.
Christian Schröder, Stefan Abendroth, Mohammed, Victoria, Vasileios Pasialis, Gerardo Domínguez Ramírez, HH, Anton Kogios, Lizhi Zhu, and Marco Fuscà
Lucky voters and participants
Thank you for your participation in our 2022 contests. You don’t need to be on the top of the leaderboards to win. As we announced, we would give out 20 MathWorks T-shirts to lucky voters and participants of the 2 contests.
Ismail Bera Altan, Robin Stolz, Michael Mellin, Kellan Smith, Neha Shaah, Siranjeevi gurumani, Paul Villain, Andrew Horchler, Meg Noah, Saurabh Chaudhary, Pakize erdogmus, Godfrey Ojerheghan, Selena Mastrodonato, Damir Rasic, Thomas Kjeldsen, Meredith, John Noah Ramiterre, Patience Oliveira, Panda, and Sujeet Kumar Choudhary
On behalf of the MATLAB Central community team, we thank you for joining our celebration of the MATLAB Central community 2022 contests. We hope you enjoyed these contests and look forward to seeing you in next year’s contests.
Two fun community contests: MATLAB Mini Hack 2022 and Cody 10th Anniversary start today on Oct. 3rd!
Participants across all skill levels are welcome to join! Even if you have limited time, you still have opportunities to win as long as you participate.
Want to challenge yourself and win Amazon gift Cards and limited-edition Badges?
1. MATLAB Mini Hack 2022: Create your best entry (either a new or a remixed entry).
2. Cody 10th Anniversary: Solve your 1st Cody problem today!
If you have any questions about the contest rules or prizes, let us know by replying to this thread.
We hope you enjoy the contests, improve your MATLAB skills, and win prizes! Now, let the party begin!

Attention all Controls Professors, Teaching Assistants, and Students!

The Virtual Hardware and Labs for Controls by Brian Hong is an absolute must-have from the MATLAB Central File Exchange. With the help of Simscape for physical modelling and simulation of mechatronic systems,

  • students can use the interactive experiments to teach themselves some of the concepts of control theory in a learn by doing approach.
  • professors and TA’s can use this to replace or augment actual lab work.

With tightening budgets and/or in person class restrictions this can help you transfer these vital skills to the students in a fun manner. Here is an overview of the available modules:

https://www.mathworks.com/matlabcentral/fileexchange/100064-virtual-hardware-and-labs-for-controls

If you have any questions feel free to leave a comment below and I’ll get back to you.

After 7 weeks of fun, the MATLAB Central community 20th anniversary contests have concluded! Together, we shared the art of MATLAB and contributed to the battle against the global pandemic. See the fantastic stats below.

MATLAB Mini Hack Winners - Week 4

In Week 4, we invited the MATLAB Graphics team to help judge the entries. As the authors of the MATLAB functions used in every entry, they made sure every entry selected used a unique graphics function or technique from the other winners. Here are their choices:

1. Umbrellas by Shanshan Wang

Comment: Cool use of 'swarmchart' to make art from distributions; Only use of one of our newest graphics functions

2. Happy Sheep by Victoria

Comment: Cute!

3. Alien Giant by Jenny Bosten

Comment: Original idea, well textured, and efficient code

4. 3D Ultrasound by Adam Danz

Comment: Replicate source material very well. Effective use of lighting and material. Overall, impressive to produce this image given the limitation

5. Sunset in the Savanna by Sebastian Kraemer

Comment: Looks cool! Nice mix of 'image', 'fill' and 'scatter' commands.

6. Night Flight by Ratul Das

Comment: original; clever use of 'rectangle'

7. Lantern #2 by Tim

Comment: Nice use of 'getframe' to create a texture for 'surf' for a compelling picture

8. Geometric Design (6) by Daniel Pereira

Comment: Looks like some walls at MathWorks

9. Rosette 1313 by Alex P

Comment: Looks cool! Nice use of 'pcolor'

10. Mandelbrot contour by Sumihiro

Comment: Best use of contour!

11. Aim High by Murty PLN

Comment: Largest number of unique graphics objects for the Mini Hack (plot, patch,stairs,stem,text)

In the spirit of Mini Hack, the MATLAB Graphics team also created several cool graphs about the contest. Facing a similar space limit, I have picked only 2.

Bonus Prize Winners - Week 4

Congratulations to our 5 winners for their dual participation in the Treasure Hunt and the MATLAB Mini Hack. Yogiraj Bhagavatula, Pramod Devireddy, Devika U, FruitsLord, and Augusto Mazzei.

Lucky voters - Week 4

Congratulations to the lucky voters who cast the 12000th vote (Gordg Garin), 12500th vote (Eder Esteban Reyes), 13000th vote (Peram Balakrishna), 13500th vote (Emerson Nithiyaraj), 14000th vote(Sekar Naai), 14500th vote (Arika Amasarao), 15000th vote (Nikita Yakovlev), 15500th vote (Kesava Rao), and 16000th vote (Kundi Chandra Sekhar).

Grant Prize Winners

Finally, after validating entries and votes, we have picked the grand prize winners. We appreciate the time and effort you spent and the awesome entries you created. Huge congratulations!

1. Top 10 Authors of most voted entries

Each author will receive 5 customized T-shirts with the winning image and your name on the back of the T-shirts. You can choose the sizes and share them with your family or friends.

2. Top 10 Authors with most total votes

Top 10 contestants on the leaderboard will each get an Amazon gift card. The top 3 winners on the leaderboard will also earn special virtual badges.

  • Ciro Bermudez
  • KSSV
  • Juan Villacrés
  • Murty PLN
  • Pink_panther
  • Jenny Bosten
  • KARUPPASAMYPANDIYAN M
  • Jr
  • Adam Danz
  • Victoria

On behalf of the MATLAB Central community team, we thank you for joining our celebration of the MATLAB Central community’s 20th anniversary with us in the past 7 weeks. We hope you enjoyed these contests and look forward to seeing you in next year’s contests. Question: “What contests would you like to see next?”

MATLAB Mobile makes it convenient to learn and teach in disciplines requiring computational thinking, such as mathematics, science, and engineering. It can also be used for virtual labs by acquiring smartphone sensor data. As an instructor, you can author examples in MATLAB and demonstrate them on your smartphone or tablet. Students can follow along on their mobile device or tablet to instantly connect results to the concepts they are learning. This is especially relevant for distance learning, where some students may have limited or no access to a full-fledged computer.

Educators make their course material more interactive, promote self-directed learning, and increase student engagement through Live Editor. You can now run and edit live scripts on iOS and Android devices.

Get MATLAB Mobile on the Play Store or App Store, or learn how to teach using Live Scripts.