Sunday, May 27, 2012

femm in Ubuntu under Wine

Years ago I stumbled across femm, "finite element method magnetics" by David Meeker.  It's a sweet little magnetics solver with good looking results visualization, but alas, at the time it was only available for Windows.  I used it on my work machine - when I worked for companies that would let me do work, that is.   When I made the personal switch to Linux, I had to bid femm a fond farewell from my personal machine.


I have few regrets about my decision to use Ubuntu Linux.  The lack of femm was on that short list.  Fortunately, Dr Meeker & company have continued to work on their program over the years, and I find now that femm runs under Wine, the windows compatibility translation layer for POSIX-compatible operating systems.  Wine, you say?  Ok...


The internet bristles with "I hate Wine" types of comments.  Perhaps that is to be expected...

  • the tinfoil-hatted Linux fanboys love to hate on Winblow$ stuff
  • the Windows crowd loves to sneer at us Linux freetards
  • Wine is a half-breed orphan seeking for the absent love of an adoptive parent
Personally, as long as it's free and open source I'm fine with it.  Heck I'd probably stop dis'ing   Windows if they'd just write specs; it was the constant churn, triggered by the Windows 7 "up" grade, that really ticked me off.


If you plan to do computer stuff for many years, a proprietary OS with no specification is simply a bad idea.  Specs assure you that you'll be able to read your own files later on.  Today, POSIX is the only standard I know of.  The good news is you can sign up with the Open Group and actually read those standards.  Not nerdy enough to worry about specs?  I understand, and honestly most people should be like you...  but if you're not smart enough to recognize the need for specs, then you should not be in charge of the I.T. department.


Enough ranting for now.  Here's a screen grab of femm-wine-ubuntu in action.  The triangle fill function is erratic but flux density shows up well enough for me without it.   



- nzvyyx

Sunday, November 6, 2011

Connecting MySQL to GNU Octave in Ubuntu

In my little world, this is, officially, A Very Big Deal (tm).  
MySQL features a rich API.  GNU Octave has a database package. 
Unfortunately I don't know API from DPI, and Octave's db package pretty much doesn't work for anybody (including me), according to my google results.


So I wrote my own.. it was:

  1. my first foray in .oct file creation, C++, and APIs
  2. successful!  thanks largely to the extensive help available all over the internet

Regardless, I'm disproportionately pleased with myself.  


Note you'll need both octave and MySQL header files, and my goal was to get a .oct that could retrieve data FROM the database, which is different than stuffing data TO the database.


The code below takes in four strings, queries MySQL, and if the query was successful, returns a cell variable to octave.

/*
 * SQL2m.cpp
 *
 *  Created on: Nov 5, 2011
 *      Author: nzvyyx
 */


#include "/usr/include/mysql/mysql.h"
#include "octave/oct.h"
#include "octave/Cell.h"
#include <string>
using namespace std;


#define NUM_INPUTS_REQUIRED (4) // 0 is file name, 1: user name, 2: password, 3: database name, 4: SQL query


#define  NoError 0
#define  Error_NoInputs (NoError + 1)
#define  Error_SQL_QueryError (Error_NoInputs + 1)
#define  Error_UnexpectedTermination (Error_SQL_QueryError + 1)
#define  Error_UserNameNotAString (Error_UnexpectedTermination + 1)
#define  Error_UserPasswordNotAString (Error_UserNameNotAString + 1)
#define  Error_DatabaseNotAString (Error_UserPasswordNotAString + 1)
#define  Error_SQL_Query_NotAString (Error_DatabaseNotAString + 1)
#define  Error_NoOutputs (Error_SQL_Query_NotAString + 1)
#define  Error_SQL_CnxnFailed (Error_NoOutputs + 1)


#define  *ErrorMsgs[] = {
    ">> SUCCESS <<",
    "not enough inputs, expected (name, password, db_name, SQL_query)",
    "SQL query error",
    "unexpected program exit",
    "non-character user name",
    "non-character user password",
    "non-character database name",
    "non-character SQL query",
    "no output assigned",
    "SQL failed to connect",
    NULL
};


char *server = "localhost";
char *username = NULL;
char *password = NULL;
char *database = NULL;
char *SQL_query = NULL;
string str;
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
unsigned long long totalrows, numfields;
int _n;
octave_idx_type _row, _col;
octave_value_list  retval;


DEFUN_DLD (SQL2m, args, nargout,
        "[SQL_result] = SQL2m(database, user_name, user_password, SQL_query)")
{
  if (nargout < 1)
  {
    retval(0) = ErrorMsgs[Error_NoOutputs];
    return retval;
  }
  if (args.length() < NUM_INPUTS_REQUIRED)
  {
    retval(0) = ErrorMsgs[Error_NoInputs];
    return retval;
  }
  for (_n = 0; _n < NUM_INPUTS_REQUIRED; _n++)
  {
    if (!(args(_n).is_string()))
    {
      retval(0) = ErrorMsgs[Error_UserNameNotAString + _n];
      return retval;
    }
  }


  str = args(0).string_value();
  username = new char[str.size() + 1];
  strcpy(username, str.c_str());
  str = args(1).string_value();
  password = new char[str.size() + 1];
  strcpy(password, str.c_str());
  str = args(2).string_value();
  database = new char[str.size() + 1];
  strcpy(database, str.c_str());
  str = args(3).string_value();
  SQL_query = new char[str.size() + 1];
  strcpy(SQL_query, str.c_str());


  conn = mysql_init(NULL);


  if (NULL == mysql_real_connect(conn, server,
      username, password, database, 0, NULL, 0))
  {
    retval(0) = ErrorMsgs[Error_SQL_CnxnFailed];
    return retval;
  }


  if (0 != mysql_query(conn, SQL_query))
  {
    retval(0) = ErrorMsgs[Error_SQL_QueryError];
    return retval;
  }


  res = mysql_store_result(conn);


  totalrows = mysql_num_rows(res);
  numfields = mysql_num_fields(res);
  Cell DATA(totalrows, numfields);


  _row = 0;
  while (row = mysql_fetch_row(res))
  {
    for (_col = 0; _col < numfields; _col++)
    {
      DATA(_row, _col) = octave_value(row[_col]);
    }
    _row++;
  }


  mysql_free_result(res);
  mysql_close(conn);


  return octave_value(DATA);
}

Here's a simple octave .m file to build the .oct file  & test for  results.
You'll need to a MySQL running, and the dummy placeholders for user name, password, etc need functional values from you.
% BuildAndTestSQL2m.m
clear all; clc; 

% build required MySQL API:
% $ sudo apt-get install libmysqlclient-dev
%
% directories given by command line:
% $ mysql_config --cflags
% and
% $ mysql_config --libs
mkoctfile  -I/usr/include/mysql  -L/usr/lib/mysql -lmysqlclient  SQL2m.cpp 

disp("change this script to specify your username, password, database name and SQL query !")
username = 'user';   
password = 'password';
dbname = 'dbname';
SQL_query = 'select field1, field2 from table';

[status, output] = system('rm SQL2m_tests.txt');
diary SQL2m_tests.txt
help SQL2m
% test with combinations of insufficient argument counts
SQL2m()
results = SQL2m()
results = SQL2m(username)
results = SQL2m(username, password)
results = SQL2m(username, password, dbname)

% this should return a cell array - success!
results = SQL2m(username, password, dbname, SQL_query)
diary off

Saturday, July 23, 2011

GNU Octave Custom Colormap

Hello, Unlikely Reader - 
So I wanted to rescale color 3D plot with a more agreeable set of values.  Octave handles this, but I thought I'd write up how because it isn't an everyday task and I'm sure I'll forget how I did it.


Here's some data plotted with the default colormap:


The plot is fine but the wide range of color was subjectively implying more curvature in the data than I meant to.  Of course that's all subjective but the data was supposed to make a point and the colormap was working against it.  






Here's a 3D view that makes my point better, but 3D views on flat surfaces are harder to interpret; for example, the diagonal "valley" of low spots gets a little lost:



So I built my own lowest to highest Red-Yellow-Green colormap and applied it; here's how.
n_levels = (10-7)/0.1 + 1;  % numbers of interest range from 7 to 10


% build RGB channels from red to yellow:
red2yellow_chRed = linspace(1, 1, n_levels/2);
red2yellow_chGreen = linspace(0, 1, n_levels/2);
red2yellow_chBlue = linspace(0, 0, n_levels/2);


% build RGB channels from yellow to green:
yellow2green_chRed = linspace(1, 0, n_levels/2);
yellow2green_chGreen = linspace(1, 1, n_levels/2);
yellow2green_chBlue = linspace(0, 0, n_levels/2);


% create the colormap by stacking and concatenating the channel vectors::
RYG_colormap = [ ...
[red2yellow_chRed'; yellow2green_chRed'] ...
[red2yellow_chGreen'; yellow2green_chGreen'] ...
[red2yellow_chBlue'; yellow2green_chBlue'] ...
];

% set the colormap
colormap(RYG_colormap);


The plot automatically updates and helps support my point that there's not so much curvature in the data.















If you don't like it, you can easily switch back:
colormap("default");
Or if black and white is better for you, there's a predefined grayscale map:
colormap(gray);
















There you go.  Colormaps.   Happy (r)Octave-ing!

- nzvyyx

Tuesday, July 19, 2011

Shuttleworth Kicks Ballmer's ASS

Thanks to LiLi's Live USB Creator I've got a nice clean A:B comparison of M$ vs Linux.  Today's heavy lifting for the OS was to run a perl script (which worked fine under XP):

My shiny new Windows 7 FAILS:




...while Ubuntu running from a 4Gb LiLi Live USB works just fine, thank you:


Best of all, thanks to LiLi's VirtualBox install, I don't even have to choose between operating systems!  Here's Ubuntu running in a virtual machine hosted by my L7 OS.


Maybe I'll be able to get my job done after all.


- nzvyyx

Saturday, July 16, 2011

VNC... high quality & free remote access

Dear Blogspot/Blogger.Com:
Thank you for your wonderful service.  I noticed a sidebar ads pushing a for-pay remote PC access program - which will remain unnamed.  It appears to be a scam to continually charge hapless users for free software.


Dear Reader:
If you need to access computers remotely, look into VNC... you'll probably notice that web searches prioritize non-free programs... caveat emptor!  Those ripoff artists have a lot of time on their hands to bury the high quality, cross-platform free stuff with their own web pages and link overload.


- nzvyyx

Friday, July 15, 2011

... and L7 once again FAILS

Yesterday I had MySQL up and running on my overpriced WindoesNT laptop as provided by MegaCorp Inc.  I logged in/out/in/out both as root and a user.  I pulled in my ginormous database that I had saved from my old burn.  I entered data, set up queries and forms in LibreOffice Base.   All appeared to be working fine.  I was a happy user.


Last night I shut down.  Restart the machine in the morning.... login denied.  No MySQL access.  Denied.  Hopefully I can find a way to get my data back, but regardless that was the last straw and it's official:


I HATE WINDOWS 7.


This is probably due to UAC resetting on a reboot, but no matter what: data loss is unacceptable... and since I can't get to the data, it counts as lost.  No matter what, erratic behavior is frustrating as hell for a user.  This "feature" of resetting UAC on reboots is a built-in frustration.


Next plan is to bring in my cheap-O linux box and do all my real work on it.




- nzvyyx

Thursday, July 14, 2011

Connecting Base to MySQL

Notes on getting my Ubuntu machine to connect Base to MySQL:
sudo apt-get install libmyodbc


Then add a couple of config files (thanks, OpenOffice Wiki)
































 Let Base know what's up:






Connect!






- nzvyyx