/////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // returns S = input \ delete list wasSubtractSubList(list input, list delete) { do { string tok = llList2String(delete, 0); list clean = input; do { if(llList2String(clean, 0) == tok) { integer idx = llListFindList(input, (list)tok); input = llDeleteSubList(input, idx, idx); } } while(clean = llDeleteSubList(clean, 0, 0)); } while(delete = llDeleteSubList(delete, 0, 0)); return input; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // transposes a square matrix of ord columns list wasMatrixTranspose(list matrix, integer ord) { list result = []; integer mLength = llGetListLength(matrix); integer j = 0; do { integer i = j; do { result += llList2String(matrix, i); i += ord; } while(i<mLength); } while(++j<ord); return result; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // returns the unsigned cofactor of matrix m with ord // columns with the pivot r, respectively c. list wasMatrixCofactor(list m, integer r, integer c, integer ord) { integer idx = 0; integer i = 0; do { integer j = 0; do { if(i == r || j == c) m = llListReplaceList(m, (list)" ", idx, idx); ++idx; } while(++j<ord); } while(++i<ord); return wasSubtractSubList(m, [" "]); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // calulates the determinant of a matrix m with ord // columns. float wasDeterminant(list m, integer ord) { float result = 0; integer i = 0; integer o = -1; do { //i * cof (i) - i * cof(i) + i * cof(i) - ... list cof = wasMatrixCofactor(m, 0, i, ord); if(llGetListLength(cof) == 2) { if(o = ~o) { result -= llList2Float(m, i) * llList2Float(cof, 0); jump next; } result += llList2Float(m, i) * llList2Float(cof, 0); jump next; } if(llGetListLength(cof) == 0) return llList2Float(m, i); if(o = ~o) { result -= llList2Float(m, i) * wasDeterminant(cof, ord-1); jump next; } result += llList2Float(m, i) * wasDeterminant(cof, ord-1); @next; } while(++i<ord); return result; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// list wasMatrixAdjugate(list m, integer ord) { list result = []; integer i = 0; do { integer j = 0; integer o = -1; if(i % 2 == 0) jump compute; o = 0; @compute; do { list cof = wasMatrixCofactor(m, i, j, ord); if(o = ~o) { result += -wasDeterminant(cof, ord-1); jump next; } result += wasDeterminant(cof, ord-1); @next; } while(++j<ord); } while(++i<ord); return wasMatrixTranspose(result, ord); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// // returns the inverse of an matrix m with adjugate // adjugate and determinant determinant. list wasMatrixInverse(list adjugate, float determinant) { // assert(determinant) != 0 if(llGetListLength(adjugate) == 0) return []; float e = llList2Float(adjugate, 0); adjugate = llDeleteSubList(adjugate, 0, 0); return e/determinant + wasMatrixInverse(adjugate, determinant); } key nQuery = NULL_KEY; integer nLine = 0; list matrix = []; integer columns = 0; //pragma inline string nName = ""; default { state_entry() { integer itra = llGetInventoryNumber(INVENTORY_NOTECARD); if(itra >0) jump found_notecard; llSetText("Drop a matrix inside me!", <0,1,0>, 1); return; @found_notecard; llSetText("Reading notecard...\nPlease wait...", <1,1,0>, 1); nName = llGetInventoryName(INVENTORY_NOTECARD, 0); nQuery = llGetNotecardLine(nName, nLine); } dataserver(key id, string data) { if(id != nQuery) return; if(data == EOF) { llSetText("Touch to compute!", <0,1,0>, 1); llRemoveInventory(nName); return; } if(data == "") jump next_line; list input = llParseString2List(data, [" "], []); matrix += input; columns = llGetListLength(input); @next_line; nQuery = llGetNotecardLine(nName, ++nLine); } touch_start(integer num) { if(llGetListLength(matrix) == 0) return; state compute; } changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } on_rez(integer num) { llResetScript(); } } state compute { state_entry() { llMessageLinked(LINK_THIS, 0, "start", NULL_KEY); llShout(0, "-------------------------------"); float det_m = wasDeterminant(matrix, columns); llShout(0, "Determinant is: " + (string)det_m); list adjugate_m = wasMatrixAdjugate(matrix, columns); llShout(0, "Adjugate is: " + llDumpList2String(adjugate_m, " ")); list inverse_m = wasMatrixInverse(adjugate_m, det_m); llShout(0, "Inverse matrix is: " + llDumpList2String(inverse_m, " ")); llShout(0, "-------------------------------"); llMessageLinked(LINK_THIS, 0, "stop", NULL_KEY); state default; } changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } }