linear programming

Is there anything built in or an XOP which can be used for linear programming purposes? E.g.
http://en.wikipedia.org/wiki/Linear_programming

There is code out there:
http://lpsolve.sourceforge.net/5.5/

and I wonder if there were already attempts to make use of that for Igor and if not what would it take to do it?

Cheers
C
I have thought about it (briefly) but have never acted on those thoughts. Right now we are not in a position to pursue such projects, but I certainly have it on the long list of things that would be good to add to Igor.

The link you give is to code licensed under LGPL. Our understanding of this license (which is difficult to understand, and causes long threads on any developer forum where the topic comes up) is that we can use such code, but only with some difficulty. Another option, since you don't have the restrictions resulting from publishing a for-profit application, is to write an XOP that wraps up the API in that library.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote: Another option, since you don't have the restrictions resulting from publishing a for-profit application, is to write an XOP that wraps up the API in that library.


I somehow feared that answer because currently writing an XOP is beyond my skills (I never looked into that and I don't have any experience in C). On the other hand, in my case the number of calls to lp_solve won't be excessive and a work-around for me could be to use Igor to write an input file which can then be processed simply from the command line of the operating system (on Mac in my case). Is there any way of executing a command from the system terminal via Igor and read out whatever lp_solve puts out? I guess that is in a very simplified manner what an XOP does, but would that be feasible?
You can use ExecuteScriptText to run an Apple Script program. You can probably use AppleScript to open a terminal window and run a command-line function, but I don't really know much about how to do that. I know we have customers who have done things like this, hopefully one of them will see this and comment.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
In a nutshell ...

* create a shell script that will run what you need when given two inputs, the input file and the output file
* put that shell script in your $PATH
* call that shell script from Igor using ExecuteScript


ExecuteScript "mylpsolver 'input file name' 'output file name'"


* wait for the return from the ExecuteScript command
* read the output file from Igor

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
johnweeks wrote: You can use ExecuteScriptText to run an Apple Script program. You can probably use AppleScript to open a terminal window and run a command-line function, but I don't really know much about how to do that. I know we have customers who have done things like this, hopefully one of them will see this and comment.

I have not done this with AppleScript, but using Igor's ExecuteScriptText to run a Windows DOS BAT file. Igor was used to create the input file, call the BAT file (which ran a FORTRAN executable), wait for output file read access, read, analyze, and display the results. A bit kludgy, but should work with any executable whose input and output file formats are known.

Here is an example to call the unix "ls -al" command.


Function/S DirList(dstr)
	string dstr

	string exStr, uStr
	
	sprintf uStr, "ls -al \'%s\'" dstr
	sprintf exStr, "do shell script \"%s\"" uStr
	
	ExecuteScriptText exStr
		
	return S_value
end


print DirList("/Users/jjw") --> prints directory listing

Suppose the shell level command in your $PATH is lpsolver with flags -r (recursive). You want to run lpsolver on file /Users/jjw/Documents/Data Files/April 23, 2012/first set/run002.dat. You want the output in the same directory as lp_run002.dat. Here is an example off the top of my head that should work.


Function/S MyLPSolver(iPath,iFile,flags)
	string iPath, iFile, flags

	string iStr, oStr, exStr, uStr

	sprintf iStr, "\'%s/%s\'" iPath,iFile   // define the input file path
        sprintf oStr, "\'%s/lp_%s\'" iPath,iFile  // define the output file path

	sprintf uStr, "lpsolver -%s \'%s\' \'%s\'", flags, iStr, oStr  // generate the shell script command
	sprintf exStr, "do shell script \"%s\"" uStr // generate the ExecuteScriptText command
	
	ExecuteScriptText exStr
		
	return S_value
end


MyLPSolver("/Users/jjw/Documents/Data Files/April 23, 2012/first set","run002.dat","r")

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
The manual actually contains an example function to call a unix command from the terminal, based on ExecuteScriptText. This together with J.J.'s suggestion to wrap the lp-solver commands into a shell script returns the solver output directly as string! That's nice and should do for the moment!

John, would be great if linear programming and even a solver for non-linear constrained optimisation problems could be added in the future but I understand version 7 has priority now.

Thanks everyone!
C
just in case someone is interested - here is my present solution.


function lp_solve(gg, AA, bb)
	wave gg, AA, bb  
	
	// minimises   				sum { x[i] * gg[i] } 			by solving for x[i]
	// subject to the contraint 		AA[i][j] * x[i] = bb[j] 
	
		
	//****************
	// (1) write input file 
	//****************
	
	variable IgorIn
	string fileName = "IgorModel.lp"        // fixed input file name for shell script (see below)
	NewPath/Q/O SolverPath, "Macintosh HD:Users:Christian_At_Work:DropBox:Igor:lp_solver"  // path to lp_solve unix executable folder
	
	variable i, j
	variable numVar = numpnts(gg)
	
	Open/Z/P=SolverPath IgorIn as fileName	
		
	fprintf IgorIn, "min: "
	 
	// write objective function	 
	for (i=0; i<numVar; i+=1)		
		fprintf  IgorIn, num2str(gg[i]) + "x"+num2str(i) + " " 			
	endfor
	fprintf  IgorIn, ";\r"
	
	//write contraints	
	for (j=0; j<Dimsize(AA, 1); j+=1)		
		for (i=0; i<DimSize(AA, 0); i+=1)		
			fprintf  IgorIn, num2str(AA[i][j]) + "x"+num2str(i) 
			if (i < DimSize(AA, 1) )
				fprintf IgorIn, " + "
			endif	
		endfor		
		fprintf IgorIn, " = " + num2str(bb[j]) + ";\r"	
	endfor
	
	Close IgorIn
	
	
	//************************************************************************************
	// (2) run pre-defined unix shell script (here lpsolve.sh) using ExecuteScriptTest; returns lp_solve output in S_value	
	//************************************************************************************
	
	string uCmd = "lpsolve.sh"
	string cmd
	sprintf cmd, "do shell script \"%s\"", uCmd
	ExecuteScriptText cmd
	//Print S_value
	
		
	//******************************************
	//  (3) analyse S_value and writes results to W_LPsolved
	//******************************************
	
	Make/O/D/N=(numVar) W_LPsolved
	
	string buffer	
	buffer = Replacestring("\r", S_value, "") 	 // get rid of carriage return
	buffer = Replacestring(" ", buffer, "")   	// collapse white space
	
	for (i=0; i<numVar; i+=1) 					// format string such that it is analysable using NumberByKey
		buffer = Replacestring( "x" + num2str(i) , buffer, ";x" + num2str(i) + "=")
	endfor
	
	for (i=0; i<numVar; i+=1) 					// extract result values and write to W_lpsolved
		W_LPsolved[i] = NumberByKey("x"+num2str(i), buffer, "=", ";")
	endfor	
	
end



An input file looks like, e.g.


min: -0.275x0 -0.12x1 -0.15x2 ;
1x0 + 1x1 + 0x2 = 0.4;
1x0 + 0x1 + 1x2 = 0.1;


and S_value:


 "
Value of objective function: -0.06350000

Actual values of the variables:
x0                            0.1
x1                            0.3
x2                              0"





The bottleneck here is obviously the writing-to-disk part.