Yesterday I needed a cumulative sum function in Maxima to do the job of **cumsum()** in R and MATLAB, but couldn’t find anything. So here’s a one-liner that does the trick for a list:

cumsum(L):=makelist(sum(L[i],i,1,n),n,1,length(L))$

Skip to content
# The MaximaList

## cumsum(): Cumulative Sum in Maxima

## Plotting Numerical Solutions of Ordinary Differential Equations in Maxima

### wxtimeplot()

### wxphaseplot2d,wxphaseplot3d

### sol_points()

## Jordan Canonical Form in Maxima

## How to fix the \tag{}\label{} glitch in the wxMaxima “export to HTML” output

## Solve Ax=b in Maxima, part 2

## A Little Maxima Function to Find the Dimensions of a Matrix

## Solving the matrix vector equation Ax=b in Maxima

A site for people who use Maxima to do Mathematics

Yesterday I needed a cumulative sum function in Maxima to do the job of **cumsum()** in R and MATLAB, but couldn’t find anything. So here’s a one-liner that does the trick for a list:

cumsum(L):=makelist(sum(L[i],i,1,n),n,1,length(L))$

Maxima comes with a few well-implemented numerical ODE solvers — **rk()** and **rkf45()** — and I’ve written in a previous post about my variable stepsize implementation of the 2nd order backward differentiaion formula for stiff systems **BDF2a()**.

Plotting the resulting numerical solutions — which is a list of lists of the form

[[*indvar, depvar1, depvar2,…* ], [*indvar, depvar1, depvar2,…* ], … ]

with each of the sublists representing the state of the system at a discrete time — requires a little familiarity with list functions like **makelist()** and** map()**.

Here are a few little helper routines to make that quicker:

- wxtimeplot()
- wxphaseplot2d, wxphaseplot3d
- sol_points()

This is mainly a teaching tool for my ordinary differential equations course, taking the output of the solver and, assuming there aren’t more than three dependent variables, plotting all the dependent variables vs the independent variable on the same set of axes, with a representation of the step size.

I wrote about these in another post

This is a more general purpose function. Given the output of the numerical ode solver, this constructs a **points()** subcommand ready to plug into **draw2d(). **This allows for the full generality of draw2d: colors, axis labels, point points,

Especially useful for plotting results from more than one call to the solver, such as when we need to see the effect of changing a parameter value:

Below I’ve pasted the code for the plots, and also for the interesting differential equations from Larter et al in Chaos, V.9 n.3 (1999)

(tw:(cosh((Vi-V3)/(2*V4))^(-1)), m:(1/2)*(1+tanh((Vi-V1)/V2)), w:(1/2)*(1+tanh((Vi-V3)/V4)), aexe:aexe1*(1+tanh(Vi-V5)/V6), ainh:ainh1*(1+tanh((Zi-V7)/V6)) )$ (rhs1:-gCa*m*(Vi-1)-gK*Wi*(Vi-ViK)-gL*(Vi-VL)+I-ainh*Zi, rhs2:(phi*(w-Wi)/tw), rhs3:b*(c*I+aexe*Vi) )$ (V1:-.01,V2:0.15,V3:0,V4:.3,V5:0,V6:.6,V7:0, gCa:1.1,gK:2,gL:0.5,VL:-.5,ViK:-.783,phi:.7,tw:1, b:0.0809,c:0.22,I:0.316,aexe1:0.6899,ainh1:0.695)$ load(rkf45); sol:rkf45([''rhs1,''rhs2,''rhs3],[Vi,Wi,Zi],[.1,.1,.1],[t,0,400], report=true,absolute_tolerance=1e-8)$

sol_points(numsol,nth,mth):=points(map(nth,numsol),map(mth,numsol));

/* wxtimeplot takes the output of sol: rk45 and plots up to 3 dependent variables plus the scaled integration step size vs time*/ wxtimeplot(sol):=block( [t0,t,tt,dt,big,dtbig], t0:map(first,sol), t:part(t0,allbut(1)), tt:part(t0,allbut(length(t0))), dt:t-tt, dtbig:lmax(dt), big:lmax(map(second,abs(sol))), if is(equal(length(part(sol,1)),3)) then( big: max(big,lmax(map(third,abs(sol)))), wxdraw2d(point_type=6, key="y1", points(makelist([p[1],p[2]],p,sol)), color=red, key="y2", points(makelist([p[1],p[3]],p,sol)), color=magenta, key="dt",point_size=.2, points(t,big*dt/dtbig/4),xlabel="t",ylabel="")) elseif is(equal(length(part(sol,1)),2)) then wxdraw2d(point_type=6, key="y1", points(makelist([p[1],p[2]],p,sol)), color=magenta, key="dt",point_size=.2, points(t,big*dt/dtbig/4),xlabel="t",ylabel="") elseif is(equal(length(part(sol,1)),4)) then( big: max(big,lmax(map(third,abs(sol)))), big: max(big,lmax(map(fourth,abs(sol)))), wxdraw2d(point_type=6, key="y1", points(makelist([p[1],p[2]],p,sol)), color=red, key="y2", points(makelist([p[1],p[3]],p,sol)), color=green, key="y3", points(makelist([p[1],p[4]],p,sol)), color=magenta, key="dt",point_size=.2, points(t,big*dt/dtbig/4),xlabel="t",ylabel="")) );

After not easily finding such a thing from a cursory search of the Maxima documentation, I spent a few hours over the weekend beginning to write a Maxima function to compute, for any given square matrix , an invertible matrix so that

where is the Jordan matrix that displays the eigenvalue/vector structure of .

It took several searches for me to find, but of course there’s already such a function — with a not so easily searched-for name — in the diag package: **ModeMatrix()**

To see just the matrix , **diag** provides** jordan()** and **dispJordan()**

**Update** This seems to be fixed in the new windows release of wxMaxima 16.12.x

The work flow in some of my classes involves:

- students doing work in wxMaxima
- exporting to HTML
- printing as PDF
- submitting the resulting document to a Dropbox link

The process is usually very slick, with only a few headaches. Here is one such pain: occasionally the result of a Maxima command will be displayed in the HTML document like as

That seems to happen if the expression name (here the matrix A) has been used before in the same session and the mathjax latex-ish tag labeling gets confused by a multiply-defined tag.

To work around that, unselect the **“Show user-defined labels instead of (%oxx)”** option in Configure/Preferences. That way, unless an exported document is the result non-re-evaluated cells between several Maxima sessions, the labels should be unique.

In a previous post, I included my little coding project to implement a general** backsolve()** function to use with the built-in maxima matrix function **echelon()**, producing an easy-to-call matrix solver **matsolve(A,b)**. The result is meant to solve a general matrix vector equation , including cases when is non-square and/or non-invertible.

Here’s a quicker approach — convert the matrix into an explicit system of equations using a vector of dummy variables, feed the result into the built-in Maxima function** linsolve()**, and then extract the right hand sides of the resulting solutions and put them into a column vector.

The two methods often behave identically, but here’s an example that breaks the **linsolve()** method, where the **backsolve()** method gives a correct solution:

*Note, I’ve found that the symbol rhs is a very popular thing for users to call their problem-specific vectors or functions. Maxima’s “all symbols are global” bug/feature generally wouldn’t cause a problem with a function call to **rhs()**, but the function **map(rhs,*** list of equations***)** ignores that **rhs()** is a function and uses user-defined rhs. For that reason I protect that name in the block declarations so that **rhs()** works as expected in the **map()** line at the bottom. I think I could have done the same thing with a quote: map(‘rhs, *list of equations*).

matsolve2(A,b):=block( [rhs,inp,sol,Ax,m,n,vars], [m,n]:[length(A),length(transpose(A))], vars:makelist(xx[i],i,1,n,1), Ax:A.vars, inp:makelist(part(Ax,i,1)=b[i],i,1,n,1), sol:linsolve(inp,vars), expand(transpose(matrix(map(rhs,sol)))) );

****Update**** I didn’t find it it in documentation for quite a while, but there is a built-in Maxima function **matrix_size()** in the package linearalgebra that does what this little one-liner does******

I really wanted a Maxima function that works something like MATLAB size() to easily determine the number of rows and columns for a matrix In Maxima, **length(M)** gives the number of rows, and so **length(transpose(M))** gives the number of columns. I put those together in a little widget **matsize()** that returns the list [m,n] for an matrix

matsize(A):=[length(A),length(transpose(A))];

*Upadate: I’ve implemented a Maxima matrix-vector equation solver with simpler Maxima-specific algorithm in a later post. That method is based on the built-in function **linsolve()**. In that post I show an example that breaks **linsolve()** but that is handled correctly by the **backsolve()** method.

Is there really not a solver in Maxima that takes matrix A and vector b and returns the solution of ? Of course we could do **invert(A).b**, but that ignores consistent systems where isn’t invertible…or even isn’t square.

Here’s a little function **matsolve(A,b)** that solves for general using the built-in Gaussian Elimination routine **echelon()**, with the addition of a homemade **backsolve()** function. The function in turn relies on a little pivot column detector **pivot()** and my matrix dimension utility **matsize()**. This should include the possibilities of non-square , non-invertible , and treats the case of non-unique solutions in a more or less systematic way.

matsolve(A,b):=block( [AugU], AugU:echelon(addcol(A,b)), backsolve(AugU) ); backsolve(augU):=block( [i,j,m,n,b,x,klist,k,np,nosoln:false], [m,n]:matsize(augU), b:col(augU,n), klist:makelist(concat('%k,i),i,1,n-1), k:0, x:transpose(matrix(klist)), for i:m thru 1 step -1 do ( np:pivot(row(augU,i)), if is(equal(np,n)) then (nosoln:true,return()) else if not(is(equal(np,0))) then (x[np]:b[i], for j:np+1 thru n-1 do x[np]:x[np]-augU[i,j]*x[j]) ), if nosoln then return([]) else return(expand(x)) )$ matsize(A):=[length(A),length(transpose(A))]$ pivot(rr):=block([i,rlen], p:0, rlen:length(transpose(rr)), for i:1 thru rlen do( if is(equal(part(rr,1,i),1)) then (p:i,return())), return(p) )$